Scripts not working after pjax reload container

Hi guys,

I am using pjax with Yii2 and I have faced a problem with pjax. All scripts are working correctly and fine only the first time and after sending a pjax request and updating the table content, scripts and pjax not working. If I remove the line


$.pjax.reload({container:'#products-table'});

all scripts are working again correctly but the table content is not updating and I have to update the page manually in order to see the changes. Please if someone had already this kind of issues please share with your solutions. Thanks!


$("form.products-input-style").on('beforeSubmit', function(e){


        var form = $(this);


        $.ajax({

            type : "POST",

            url: form.attr('action'),

            data: new FormData(this),

            processData: false,

            contentType: false,

            success  : function(response) {

                $.pjax.reload({container:'#products-table', timeout: false});

            },

            error : function(response){

                console.log(response);

            }

        });


        return false;


    }).on('submit', function(e){

        e.preventDefault();

    });

VIEW :

=============


<?php Pjax::begin(['id' => 'products-table']); ?>

        <table class="table table-hover table-striped">

            <thead>

            <th>Product image</th>

            <th>Title</th>

            <th>Price</th>

            <th>Show/Hide</th>

            <th>Actions</th>

            </thead>

            <tbody>

            <?php foreach($dataProvider as $product): ?>

                <tr id="productRow-<?php echo $product->id; ?>">

                    <?php $editForm = ActiveForm::begin([

                            'id' => 'products-edit-form-'.$product->id,

                            'action' => ['products/product-edit'],

                            'enableClientValidation'=>false,

                            'method' => 'post',

                            'options' => [

                                'enctype' => 'multipart/form-data',

                                'class' => 'products-input-style',

                            ]

                    ]); ?>

                    <td>

                        <?php

                        echo $editForm->field($model, 'id')->hiddenInput(['value'=>$product->id])->label(false);

                    </td>

                    <td>

                        <span class="product-name-value">

                            <?php echo $product->productName; ?>

                        </span>

                        <span class="product-name-input" style="display:none">

                            <?= $editForm->field($model, 'productName')->textInput(['class'=>'form-control productName', 'value'=>$product->productName])->label(false); ?>

                        </span>

                    </td>

                    <td>

                        <span class="product-cost-value">

                            <?php echo "<i class=\"fa fa-eur\"></i>

                            <span>". number_format(round($product->cost, 2), 2); ?></span>

                        </span>

                        <span class="product-cost-input" style="display:none">

                            <?= $editForm->field($model, 'cost')->textInput(['class'=>'form-control productCost', 'value'=>$product->cost])->label(false); ?>

                        </span>

                    </td>

                    <td>

                        <?php if($product->available == 'Y'){ ?>

                            <input type="checkbox" name="toggle" checked="checked" class="toggle toggle-change" id="<?php echo $product->id; ?>" >

                            <label for="<?php echo $product->id; ?>"></label>


                        <?php } else{ ?>

                            <input type="checkbox" class="toggle" name="toggle toggle-change" id="<?php echo $product->id; ?>">

                            <label for="<?php echo $product->id; ?>"></label>

                        <?php } ?>

                    </td>

                    <td>

                        <ul class="products-action">

                            <li><a href="#" class="edit" id="<?php echo $product->id; ?>"><i class="fa fa-pencil fa-2x"></i></a></li>

                            <li><a href="#" class="delete" id="<?php echo $product->id; ?>"><i class="fa fa-trash fa-2x"></i></a></li>

                            <ul class="delete-confirm-div" style="display: none;">

                                <li><a href="#" class="delete-cancel" id="<?php echo $product->id; ?>">No</a></li>

                                <li><a href="#" class="delete-confirm" id="<?php echo $product->id; ?>">Yes</a></li>

                            </ul>

                        </ul>

                        <div class="save-btn" style="display: none">

                            <?= Html::submitButton('Save', ['class'=>'btn btn-success product-edit-submit', 'id'=>$product->id]); ?>

                        </div>

                    </td>

                </tr>

                <?php ActiveForm::end(); ?>

            <?php endforeach;?>

            </tbody>

        </table>

        <?php Pjax::end(); ?>

Can you show us the minimum code of your view and controller that reproduces the problem?

This works for me:




$.pjax.reload({container: "#w0", timeout: false});



pjax times out way too early.

Hi guys,

I am trying to submit the form via pjax and after submission I want to refresh the table but after submitting the form and trying to reload (


$.pjax.reload({container:'#products-table'});

) the jquery scripts are not working anymore. Even I added


pjax:success

but if I don’t reload the table, all scripts are working and sending the requests and then I have to reload manually in order to see the changes. Or I have tried to submit form without pjax and the page reloads by Yii and then again proplems with scripts. Please your feedbacks. Thanks!


$(document).on('ready pjax:success', function(){

$("form.products-input-style").on('beforeSubmit', function(e){


        var form = $(this);


        $.ajax({

            type : "POST",

            url: form.attr('action'),

            data: new FormData(this),

            processData: false,

            contentType: false,

            success  : function(response) {

                $.pjax.reload({container:'#products-table'});

                $.notify({

                    icon: "pe-7s-check",

                    message: "Product is updated."


                },{

                    type: type[2],

                    timer: 10,

                    placement: {

                        from: 'top',

                        align: 'right'

                    }

                });

            },

            error : function(response){

                console.log(response);

                $.notify({

                    icon: "pe-7s-close-circle",

                    message: "Error! " + response


                },{

                    type: type[4],

                    timer: 10,

                    placement: {

                        from: 'top',

                        align: 'right'

                    }

                });

            }

        });


        return false;


    }).on('submit', function(e){

        e.preventDefault();

    });

});

I have updated my question and now you can see the source code. Thanks!

Thanks for the response but it didn’t work. How can load all scripts after page render? Now If I submit the form without pjax, my page is reloading and I am rendering the page but then again problem with scripts.

Your scripts do not work because the element on which you attach handler disappears when you reload pjax




$("#products-table").on('beforeSubmit', "form.products-input-style", function(e) {

...

}



Probably you need to attach the handler level higher than $("#products-table")

For example, assume the following document:

<div id="a">
<?php Pjax::begin() ?>
  <div id="b">
  ...
  </div>
<?php Pjax::end() ?>
</div>

Now, when you want to handle the event of "#b", you may want to write like this:

<script>
$("#b").on("someEvent", function(){…});
</script>

But it only works for the first event. The event handler will be lost when “#b” is updated by pjax.
It won’t work for the 2nd event and after.

The script should be:

<script>
$("#a").on("someEvent", "#b", function(){…});
</script>

This will attach an event handler to “#a”, but the handler handles the event of “#b”. And because “#a” is outside the pjax area, the event handler won’t be lost when “#b” is updated by pjax.

@Soul
Can we use the "id" of the Pjax widget as the selector for the handler? I mean, is it considered outside?

1 Like

[color="#008000"]/* topics merged */[/color]

Yes, I checked it out

Thank you! I was not sure about that.

This helps me to fix a similar pjax refresh issue

Thank you

1 Like

Thanks for this knowledge

Just had this problem, thank you.

This should work

$(document).ready(delete_record);
$(document).ajaxSuccess(delete_record);

function delete_record(){
$(’.pjax-delete-link’).on(‘click’, function(e) {
e.preventDefault();
var deleteUrl = $(this).attr(‘delete-url’);
var pjaxContainer = $(this).attr(‘pjax-container’);
var result = confirm(‘Delete this item, are you sure?’);
if(result) {
$.ajax({
url: deleteUrl,
type: ‘post’,
error: function(xhr, status, error) {
alert(‘There was an error with your request.’ + xhr.responseText);
}
}).done(function(data) {
$.pjax.reload(’#’ + $.trim(pjaxContainer), {timeout: false});
});
}
});
}