CListView - style, jquery are not working after pagination.

Hi guys,

I have some internal css style and jquery in Itemview.

It works fine when I first time load the page. Once I select page 2, all these styles and js stop working.

Please give me some advice.

Many thanks

I am using the default yii user view, model, controller.

I add some styles in the itemview file:




<style type="text/css">

    .user_view li {

        float: left;

        position: absolute;

    }

</style>

<script type="text/javascript">

    $(document).ready(function() {

        $("#user_view_li_id_<?php echo $data->id;?>").css('left', 100);

        $("#user_view_li_name_<?php echo $data->username;?>").css('left', 400);

        $("#user_view_li_pass_<?php echo $data->password;?>").css('left', 800);

        $("#user_view_li_email_<?php echo $data->email;?>").css('left', 1200);

    });

</script>


<div class="view">

    <ul class="user_view">

        <li id="user_view_li_id_<?php echo $data->id; ?>">

            <b><?php echo CHtml::encode($data->getAttributeLabel('id')); ?>:</b>

            <?php echo CHtml::link(CHtml::encode($data->id), array('view', 'id'=>$data->id)); ?>

            <br />

        </li>


        <li id="user_view_li_name_<?php echo $data->username;?>">

            <b><?php echo CHtml::encode($data->getAttributeLabel('username')); ?>:</b>

            <?php echo CHtml::encode($data->username); ?>

            <br />

        </li>


        <li id="user_view_li_pass_<?php echo $data->password;?>">

            <b><?php echo CHtml::encode($data->getAttributeLabel('password')); ?>:</b>

            <?php echo CHtml::encode($data->password); ?>

            <br />

        </li>


        <li id="user_view_li_email_<?php echo $data->email;?>">

            <b><?php echo CHtml::encode($data->getAttributeLabel('email')); ?>:</b>

            <?php echo CHtml::encode($data->email); ?>

            <br />

        </li>

        <div class="clear"></div>

    </ul>

</div>




The first page is correct.

The 2nd page is wrong.

The problem is

If there is $(document).ready() in CListView itemview, then the ready() function only be called for the first time. Once switch to diffrent page, the $(doc).ready function won’t be called again.

Any1 had the same problem before ?

I’ve been having similiar problems with CListView and pagination. In my case links that use jquery on the subsequent pages appear to have lost the click eventhandler. The issue resolves it self with a page refresh or a button click on an ajax element on the same page.

I’m not sure what the solution is. I’d hope that the more experienced folks would chime in.

Originally, I thought the answer might be in where the .ready() function was called but it is obvious that it needs to wrap the jquery on each specific page so it would not be possible to call it at a different higher context. Just thinking out loud.

I read somewhere that linking too many jquery libraries can cause problems. I’m still not sure how to prevent loading more than one jquery library.

I’m missing something. I really like to understand these issues so that I could be more productive. No fun spinning your wheels.

Mike

Take a look at this.

http://blog.reybango.com/2010/08/11/the-case-for-jquerys-delegate-method-for-dynamic-event-binding/

Let me know if this helps you. Thanks.

Hi,

As for javascript and ajax, I’m in the habit not to include scripts in the ajax response.

So, this probably isn’t a kind of answer that you are expecting …

But I think that you can do without a javascript to style your list.

In main view …




<style type="text/css">

    .user_view li {

        float: left;

        position: absolute;

    }

    .user_view li.id {

        left: 100px;

    }

    .user_view li.name {

        left: 400px;

    }

    ...

</style>



And in partial view for items …




<div class="view">

    <ul class="user_view">

        <li class="id">

            <b><?php echo CHtml::encode($data->getAttributeLabel('id')); ?>:</b>

            <?php echo CHtml::link(CHtml::encode($data->id), array('view', 'id'=>$data->id)); ?>

            <br />

        </li>


        <li class="name">

            <b><?php echo CHtml::encode($data->getAttributeLabel('username')); ?>:</b>

            <?php echo CHtml::encode($data->username); ?>

            <br />

        </li>

        ...



Isn’t it much more simple?

Thanks for your reply.

This is just to show what the problem it is.

Problem has been resolved.

Thanks

How was the problem resolved?

Thanks, Mike

I think the problem is,

Yii called $(document).ready() as well. So the code we write in ready() will be overwrite by Yii. So I think we just need to use Yii::app()->getClientScript()->registerScript, or registerScriptFile register the js code instead of putting it directly inside ready().

That is all I know so far.

Thx

Hi Kungfu Panda

How was exactly your solution? I have similar problem with Clistview and Jquery script.

I have register my js file as follow:

<?php Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl.’/js/index.js’, CClientScript::POS_END);?>

But it’s only working on a fresh page loading, after clicking pagination ‘next’ the script is not working.

Thanks.

Problem solved!

Since items of listview are dynamic, binding event directly to each on of them would cause binding-lost whenever the list is partially rendered.

Thus, it’s necessary to use delegate() or on() to attached event that we want.

http://api.jquery.com/delegate/

Solved!

Here is an example of the on() event-delegation that Masapri is talking about above.

My CGridView has buttons in CButtonColumn. Besides normal functions, these buttons must also perform some css tasks when clicked.

So I added the class "sayHello" to these buttons and in a separate javascript file I had this code.




$('.sayHello').click(function(){

	alert ("Hello");

}



But, when the gridview was paged, these buttons lost their click events. So I changed the function to this:




$("body").on("click", ".sayHello", function() {

	alert ("Hello");

}



This new event-delegation code is connected to the "body", and is looking out for click events bubbling up from any underlying elements of class ".sayHello".

It does this, regardless of whether these elements still have their own attached click-events or not.

Since the event-delegation code is connected to the "body", you can add the "sayHello" class to any underlying element in the "body" - such as gridview buttons, links, pictures, etc.

1 Like

@Michael G

works for me Thanks for the post.