ReynierPM ReynierPM - 3 months ago 9
Ajax Question

Force page refresh on redirect

I am working on some bug fixes for a old Zend Framework 1.10 project and I am having some issues with redirection and page refresh.

The problem: make an AJAX call, check if the person has insurance assigned and if so do not allow to delete the person until it does not have any insurances.

The solution:

The controller:

crud/application/controllers/personController.php


class PersonController extends Zend_Controller_Action
{
// this will fetch all the persons from DB and send to the view
public function indexAction()
{
$persons = new Application_Model_DbTable_Person();
$this->view->persons = $persons->fetchAll();
}

// this will check whether the person has or not insurances
public function hasinsurancesAction()
{
$hasInsurances = new Application_Model_DbTable_Person();

return $this->_helper->json(
['count' => count($hasInsurances->personHasInsurances($this->_getParam('id')))]
);
}

...

// this will delete the person from DB and will make a redirection to indexAction
public function deleteAction()
{
if ($this->getRequest()->isPost()) {
$person_id = (int) $this->getRequest()->getPost('id');

$person = new Application_Model_DbTable_Person();
$person->deletePerson($person_id);

$this->_helper->redirector('index');
}
}
}


The view:
crud/application/views/scripts/company/index.phtml


<table>
<tr>
<th>Title</th>
<th>&nbsp;</th>
</tr>
<?php foreach ($this->persons as $person) : ?>
<tr>
<td><?php echo $this->escape($person->title); ?></td>
<td>
<a href="<?php echo $this->url(
[
'controller' => 'person',
'action' => 'edit',
'id' => $person->id,
]
); ?>">Edit</a>
<a class="delete"
data-id="<?php echo $person->id ?>"
data-href="<?php echo $this->url(
[
'controller' => 'person',
'action' => 'delete',
'id' => $person->id,
]
); ?>"

data-delete-href="<?php echo $this->url(
[
'controller' => 'person',
'action' => 'hasInsurances',
]
); ?>"
href="#">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</table>


The Javascript/jQuery:
crud/public/js/delete.js


$(function () {
$('.delete').on('click', function () {
id = $(this).data('id');
href_attr = $(this).data('href');
delete_attr = $(this).data('delete-href');

$.ajax({
url: delete_attr,
data: {'id': id},
success: function (result) {
if (result.count > 0) {
alert('You can not delete this person. Try deleting associated insurances first.')
} else {
$.ajax({
url: href_attr,
data: {'id': id},
type: 'POST'
});
}
}
});
})
});


The issue: the code above works fine but has a gap, when
deleteAction()
is called and person gets deleted it tries a redirection to
indexAction()
there I am still seeing the deleted person and I shouldn't. As soon as I refresh the page using
F5
or
CTRL+R
the row disappear because it was deleted and this should be the right behavior.

The question: what is wrong in my solution? is there any way to force page refresh either from the controller or from the jQuery code when the second AJAX call is made?

Answer

If you delete_attr is the URL that makes the call to PersonController->deleteAction() your problem is that your browser does an Ajax request (which is redirected) but the returned data is getting back to your ajax call (success: function (result) {) and the page the user is currenltly viewing is the same.

What you can do is add a new variable (do_redirect => true) and the url you want to redirect your user to, and if your success function get that url - it should do the redirect:

class PersonController extends Zend_Controller_Action {
    ...
    // this will delete the person from DB and will make a redirection to indexAction
    public function deleteAction()
    {
        if ($this->getRequest()->isPost()) {
            ...
            $person->deletePerson($person_id);

            return $this->_helper->json(
                ['do_redirect' => TRUE, 'redirect_url' => 'index.php']
            );
        }
    }
}

And in your ajax call you should check for do_redirect:

$.ajax({
    url: delete_attr,
    data: {'id': id},
    success: function (result) {
        if ('do_redirect' in result && 'redirect_url' in result) {
            window.location.href = result.redirect_url
        }
        if (result.count > 0) {
            alert('You can not delete this person. Try deleting associated insurances first.')
        } else {
            $.ajax({
                url: href_attr,
                data: {'id': id},
                type: 'POST',
                success: function(result) {
                    if ('do_redirect' in result && 'redirect_url' in result) {
                        window.location.href = result.redirect_url
                    }
                }
            });
        }
    }
});
Comments