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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…