CGridView auto send filter request with delay #387

Closed
jayala opened this Issue Feb 22, 2012 · 10 comments

3 participants

@jayala
jayala commented Feb 22, 2012

Something I think will be really useful is send automatically the request without pressing the enter key. Many frameworks do that and this one should too ;)

I done this by replacing the filter onChange event with this:

$(document).on('change keyup', inputSelector, function (e) {
                    var data = $(inputSelector).serialize();
                    if (settings.pageVar !== undefined) {
                        data += '&' + settings.pageVar + '=1';
                    }
                    if(e.type == 'change')
                    {
                        if($grid.attr('to') == null)
                            $('#' + id).yiiGridView('update', {data: data});
                        else
                            $grid.attr('to', null);
                    }
                    else if(e.type == 'keyup' && e.keyCode != 13)
                    {
                        clearTimeout($grid.attr('to'));
                        to = setTimeout(function(){ $('#' + id).yiiGridView('update', {data: data}); }, 400);
                        $grid.attr('to', to);
                    }
                });
@samdark
Member
samdark commented Feb 22, 2012

Using this code it will send a request every key press. That's definitely not the thing we want.

@jayala
jayala commented Feb 22, 2012

Maybe a trigger mode option can be added to CGridView and provide this as one of them.

@samdark
Member
samdark commented Feb 22, 2012

I meant if you want this kind of thing you should use technique like this http://benalman.com/projects/jquery-throttle-debounce-plugin/ not to kill server with too many queries.

@jayala
jayala commented Feb 22, 2012

Well, it is using setTimeout for avoiding the problem of the massive requests but that plugin can definitely do it better!

@samdark
Member
samdark commented Feb 22, 2012

So this can be dont w/o changing framework itself.

@mdomba what's your opinion on this behavior change?

@mdomba
Member
mdomba commented Feb 23, 2012

The above code is not good as it enables this by default...

We should not enable this by default as some users maybe does not want this functionality at all as even with the timeout it makes ajax calls that on a high load server are not good.

If we decide to go with this option, then one idea is to do it like it's done for the validation in CACtiveForm where we have "validateOnChange", "validateOnType" and "validationDelay"

with that analogy here we would have "filerOnChange" and "filterOnType", and "filterDelay" so that user can adjust the filterOnType timeout time

@mdomba mdomba was assigned Nov 20, 2012
@mdomba
Member
mdomba commented Nov 20, 2012

Is this needed in a grid ?

@jayala
jayala commented Nov 21, 2012

Yes, I use it for the filters of an CGridView.

@mdomba
Member
mdomba commented Nov 21, 2012

do you have an example how you solved it or are you using @speedlog solution ?

@jayala
jayala commented Nov 22, 2012

Yes I do, it's not @speedlog solution. I preferred to add it as a external functionality to Yii's component.
The problem is that it sends the form twice, I think that happens because first sends setupGridView's request and then Yii's default configured request.
This is the code:

I'm using the plugin: http://benalman.com/projects/jquery-throttle-debounce-plugin/

var compSelector = 'input:visible,button:visible,select:visible,textarea:visible';

function setupGridView(grid)
{
    $('tr.filters ' + compSelector, grid).focus(function() {
        $(document).data($(this).closest('.grid-view').attr('id') + '-lastFocused', $(this).attr('name'));
    });
    $('tr.filters ' + compSelector, grid).keyup($.debounce(800, function (e) {
        var data = $(compSelector).serialize();
        if(e.type == 'keyup' && e.keyCode != 13)
        {
            $(grid).yiiGridView('update', {
                data: data
            });
        }
    }));
}

// Default handler for afterAjaxUpdate event
function afterAjaxUpdate(id, options)
{
    var grid = $('#' + id);
    var lf = $(document).data(grid.attr('id') + '-lastFocused');
    // If the function was not activated
    if(lf == null) return;
    // Get the control
    fe = $('[name="'+lf+'"]', grid);
    // If the control exists..
    if(fe!=null)
    {
        if(fe.get(0).tagName == 'INPUT' && fe.attr('type') == 'text')
            // Focus and place the cursor at the end
            fe.cursorEnd();
        else
            // Just focus
            fe.focus();
    }
    // Setup the new controls again
    setupGridView(grid);
}

And this is the grid:


$this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'orden-grid',
    'dataProvider' => $model->search(),
    'filter' => $model,
    'columns' => array(
        array(
            'name' => 'tipo_movimiento',
            'value' => '$data->tipoMovimiento',
            'filter' => array('compra' => 'Compra', 'venta' => 'Venta'),
        ),
        'fecha_orden',
        'numero_factura',
        array(
            'name' => 'id_deposito',
            'value' => '$data->deposito->nombre',
        ),
        array(
            'name' => 'id_socio',
            'value' => '$data->socio->nombre',
        ),
        array(
            'name' => 'id_categoria_factura',
            'value' => '$data->categoriaFactura->nombre',
            'filter' => array(1=>'Exenta', 2=>'IVA'),
        ),
        array(
            'name' => 'condicion_pago',
            'value' => '$data->condicionPago',
            'filter' => array('contado' => 'Contado', 'credito' => 'Crédito'),
        ),
        array(
            'id' => '$data->id_orden',
            'name' => 'total',
            'value' => 'Fnc::fc($data->totalMoneda,$data->moneda->id_moneda)',
            'filter' => '',
            'htmlOptions' => array(
                'style' => 'text-align:right;',
            ),
        ),
        array(
            'class' => 'CButtonColumn',
        ),
    ),
    'afterAjaxUpdate' => "function(id, options) { afterAjaxUpdate(id, options); }",
));
@samdark samdark closed this Nov 17, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment