Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
667 views
in Technique[技术] by (71.8m points)

how to do local search on formatted column value in jqgrid?

I'm using loadonce to get all data up front and then doing sorting and filtering locally.

One of my column values is an array of objects. In the colModel option I use a formatter function that looks like this:

function my_formatter(cellValue) 
{ 
    return $.map(cellValue, function(element) {return element.human_readable_name;}).join(', '); 
}

I also use a custom sorting function that simply returns the length of the array.

The problem I have is that the toolbar filtering and multi-field dialog filtering aren't working. They seem to be searching on [objects].toString() rather than the formatted value. So I get hits when I search for "[object Object]", but not when I search for the actual values.

Is there a way to get the local filtering to use the formatted value?

Edit based on Oleg's response:

I adapted Oleg's code to add per-column filter formatting. It seems to work well. I removed the _toStr replacement because it didn't seem necessary -- I think it's used to modify the search term (which makes sense in Oleg's accent-stripping case, but not in mine).

// Causes local filtering to use custom formatters for specific columns.
// formatters is a dictionary of the form:
// { "column_name_1_needing_formatting": "column1FormattingFunctionName",
//   "column_name_2_needing_formatting": "column2FormattingFunctionName" }
// Note that subsequent calls will *replace* all formatters set by previous calls.
function setFilterFormatters(formatters)
{
    function columnUsesCustomFormatter(column_name)
    {
        for (var col in formatters)
        {
            if (col == column_name)
            return true;
        }
        return false;
    }

    var accessor_regex = /jQuery.jgrid.getAccessor(this,'(.+)')/;

    var oldFrom = $.jgrid.from;
    $.jgrid.from = function(source, initialQuery) {
        var result = oldFrom(source, initialQuery);
        result._getStr = function(s) {
            var column_formatter = 'String';

            var column_match = s.match(accessor_regex, '$1');
            if (column_match && columnUsesCustomFormatter(column_match[1]))
            {
                column_formatter = formatters[column_match[1]];
            }

            var phrase=[];
            if(this._trim) {
                phrase.push("jQuery.trim(");
            }
            phrase.push(column_formatter+"("+s+")");
            if(this._trim) {
                phrase.push(")");
            }
            if(!this._usecase) {
                phrase.push(".toLowerCase()");
            }
            return phrase.join("");
        }

        return result;
    }; 
}

And it gets called like this:

setFilterFormatters({'column_with_array_of_objects':'my_formatter'});

Testing suggests that this works for 'contains', 'does not contain', 'equals', 'does not equal' (and probably 'begins with' and the other simple string comparisons -- but I'm not using them).

Thanks, Oleg.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In my old answer in the trirand forum I described how to implement custom local filtering and sorting. The demo shows accent free searching and sorting. If you use the same technique you can overwrite some jqGrid functions used for searching (_toStr and _getStr for example) and implement it so that in case of arrays you will use your own it's implementation.

To make my answer more Google friendly I include small code fragment

function myAccentRemovement(s) {
    // the s parameter is always string
    s = s.replace(/[àáa???]/gi,'a');
    s = s.replace(/[èéê?]/gi,'e');
    s = s.replace(/[ìí??]/gi,'i');
    s = s.replace(/[òó????]/gi,'o');
    s = s.replace(/[ùú?ü]/gi,'u');
    s = s.replace(/[y?]/gi,'y');
    s = s.replace(/?/gi,'ae');
    s = s.replace(/?/gi,'oe');
    s = s.replace(/?/gi,'c');
    s = s.replace(/?/gi,'s');
    s = s.replace(/?/gi,'n');
    s = s.replace(/?/gi,'z');
    return s;
}
//...
var oldFrom = $.jgrid.from;
$.jgrid.from = function(source,initalQuery){
    var result = oldFrom(source,initalQuery);
    var old_toStr = result._toStr;
    result._toStr=function(s) {
        return myAccentRemovement(old_toStr(s));
    };
    result._getStr=function(s) {
        var phrase=[];
        if(this._trim){
            phrase.push("jQuery.trim(");
        }
        phrase.push("myAccentRemovement(String("+s+"))");
        if(this._trim){
            phrase.push(")");
        }
        if(!this._usecase){
            phrase.push(".toLowerCase()");
        }
        return phrase.join("");
    }
    return result;
}

It will be solve the problem. I can't gives you more exact suggestions because you posted no information about the exact structure of data which you use.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...