ReynierPM
ReynierPM

Reputation: 18660

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?

Upvotes: 0

Views: 420

Answers (1)

Dekel
Dekel

Reputation: 62566

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
                    }
                }
            });
        }
    }
});

Upvotes: 1

Related Questions