Skip to content

Problems with Ajax loaded datagrid #130

Closed

Description

@morferic

First of all Hi to all!
I have problems with Ajax loaded datagrid.
I have a form with 4 filter fields (City, Name, etc) and when I submit the form all goes well: datagrid was loaded and correctly filtered.
But when I use pager the page reloads (obviously without themes) and the filters are cleared (i.e. the grid show me all values).
I try to change pager in this way (I report only the modified part of it):


= grid.pagecount-1 %}disabled="disabled"{% endif %} onclick="sendRequest('{{grid_url('page', grid, grid.page+1)}}','#output');"/> {{ 'of %count%'|trans({'%count%': grid.pagecount}) }}

sendRequest is a jscript that simply send an XMLHttpRequest and fill the #output tag with the results (i.e. the Datagrid).
In this way the datagrid loaded correctly and page is not reloaded, but not filtered, completely resetted and page counter remain on 1 and doesn't change. I want that the filters remain the same and the page goes to next or previous value.
I have not yet implemented the column ordering, but I suppose that I will have the same problem.
Can you help me?
Thank you!

Activity

  1. Abhoryo commented on May 25, 2012

    @Abhoryo
    Member

    The session of the grid is killed if the referer isn't set or different from the grid url without query string.

    I think a default XMLHttpRequest doesn't add the referer. You have two work arounds:

    • Sets the referer of your request with x.setRequestHeader("Referer", <grid_url>);
    • Sets to true the persistence of the session with $grid->setPersistence(true); But if you do that the grid is only reset if you kill your session by closing your webbrowser or by killing the cookie)

    Try the second solution, and if it's worked, use the first solution.
    I'll try later to add a condition for an XMLHttpRequest.

  2. morferic commented on May 25, 2012

    @morferic
    ContributorAuthor

    Thank you.
    I will try these solutions!

    Eric

  3. morferic commented on May 25, 2012

    @morferic
    ContributorAuthor

    If I set the grid persistence to true the pager works, but filters are resetted.
    Because of my lack of knowledge of javascript and jquery do not know where and how to properly set the referer.

  4. morferic commented on May 25, 2012

    @morferic
    ContributorAuthor

    Ok, I've set the referer but the things remains the same.
    If I set the referer and I do not set the persistence, nothing happens, however the grid reload completely, without filters.
    Thanks anyway!

  5. Abhoryo commented on May 25, 2012

    @Abhoryo
    Member

    Do you use isReadyForRedirect ?

  6. Abhoryo commented on May 25, 2012

    @Abhoryo
    Member

    If you want to work, add a condition in line 227 of the grid.php file :

    <?php
    // Grid/Grid.php line 227
    
    // Before
    if (!$this->persistence && $this->request->headers->get('referer') != $this->request->getUriForPath($this->request->getPathInfo())) {
    
    // After
    if (!$this->request->isXmlHttpRequest() && !$this->persistence && $this->request->headers->get('referer') != $this->request->getUriForPath($this->request->getPathInfo())) {

    Or download the last version.

    And don't use isReadyForRedirect().

  7. Abhoryo commented on May 25, 2012

    @Abhoryo
    Member

    My working test:

    My controler:

    <?php
    class MemberController extends Controller
    {
        /**
         * @Route("/list", name="member_list")
         * @Template
         */
        public function listAction()
        {
            return array();
        }
    
        /**
         * @Route("/ajax", name="member_ajax")
         * @Template
         */
        public function ajaxAction()
        {
            $source = new Entity('MyBundle:Member');
    
            $grid = $this->get('grid')
                ->setId("grid12")
                ->setLimits(array(1 => '1'))
                ->setSource($source);
    
            return array('grid' => $grid);
        }
    }

    My list template:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html lang="en">
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    </head>
    <body>
        <input type="text" class="filter" id="viewname" name="grid_grid12[viewname]" onkeypress="if (event.which == 13){doFilter(this.id);}">
    
        <div id="grid"></div>
    
        <script type="text/javascript">
        function doFilter (id) {
    
            var data = {};
    
            var name = $('#'+id).attr('name');
    
            data[name] = $('#'+id).val();
    
            $.ajax({
                  type: "POST",
                  url: "{{ path('member_ajax') }}",
                  data: data,  
                }).done(function( msg ) {
                  $('#grid').html(msg);
                });
        }
        </script>
    </body>
    </html>

    My ajax template:

    {% block grid_pager %}
    <div class="pager">
        {{ 'Page'|trans }}
        {% spaceless %}
        <input type="button" class="prev" {% if grid.page <= 0 %}disabled="disabled"{% endif %} value="<" onclick="doPage('{{grid_url('page', grid, grid.page-1)}}');"/>
        <input type="text" value="{{grid.page+1}}" size="2" onkeypress="if (event.which == 13) { doPage('{{grid_url('page', grid) }}'+(parseInt(this.value)-1)); return false; }"/>
        <input type="button" value=">" class="next" {% if grid.page >= grid.pagecount-1 %}disabled="disabled"{% endif %} onclick="doPage('{{grid_url('page', grid, grid.page+1)}}');"/> {{ 'of %count%'|trans({'%count%': grid.pagecount}) }}
        {% endspaceless %}
        {{ ', Display'|trans }}
        <select onchange="window.location.href='{{grid_url('limit', grid)}}'+this.value">
        {% for key, value in grid.limits %}
            {% if key == grid.currentlimit %}
                <option value="{{key}}" selected="selected">{{value}}</option>
            {% else %}
                <option value="{{key}}">{{value}}</option>
            {% endif %}
        {% endfor %}
        </select> {{ 'Items per page'|trans }}
    </div>
    
    <script type="text/javascript">
    function doPage (url) {
    
        $.ajax({
              url: url,
            }).done(function( msg ) {
              $('#grid').html(msg);
            });
    }
    </script>
    {% endblock grid_pager %}
    
    {{ grid(grid, _self) }}
  8. morferic commented on May 31, 2012

    @morferic
    ContributorAuthor

    Thank you so much!
    I used a personalized filter form that filtered directly the source of the datagrid.
    Instead I've missed to overwrite datagrid filters with:

    <input type="text" class="filter" id="viewname" name="grid_grid12[viewname]" onkeypress="if (event.which == 13){doFilter(this.id);}"> 

    Because the Datagrid template I used is very complicated, I have extended the template in another file with:

    {{ grid(grid, "MyBundle:foldername:datagrid_external_template.html.twig", "gridname", {"param1": param1, "param2":param2, "param3": param3}) }}

    and all goes well.
    Thank you.
    Eric

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions