How do you set the tablesorter default filter type - tablesorter

I have a tablesorter table with titles in the cells. I'd like to be able to search on multiple, non-contiguous words in the title. The fuzzy match (~) does the job. How do I get this to be the default matcher? I don't want my users to have learn/remember it.
I tried a custom filter like this
....
widgetOptions: {
filter_external: '.search', // input box that user input goes into
filter_columnFilters: false,
filter_functions : {
1: function (e, n, f, i, $r) {
return this.filter.types.fuzzy( e, '~' + n, f, i, $r);
}
}
}
.....
but that didn't work. Ideas?

I just added a new filter widget option filter_defaultFilter in the working branch of the GitHub repository
To use it, include the column class name or index and a filter mask with the filter selector (~ in your case) and a query tag ({query} or {q}).
$(function () {
$('table').tablesorter({
theme: 'blue',
widgets: ['zebra', 'filter'],
widgetOptions: {
filter_defaultFilter: {
// set default fuzzy match on first column
0 : '~{q}'
}
}
});
});
Here is a demo applying a default exact match to filter selects for issue #704.
The documentation is available now in the working branch. The main documentation won't be updated until this weekend.

Related

Tablesorter value should always be visible when choosing a filter

I am currently using table sorter and just want to know if there is a way to have a value by default always shows up regardless of the selected filter from the filter-select list. I tried using filter functions, but after I added a filter function for a column that has a filter-select, it loses the filter-select list with all of the available values.
For example, here is the filter function that I tried using, it should show "John" regardless of the values that are selected:
0 : function(e, n, f, i, $r, c, data) {
var x = e===f;
var y = e==='John';
var show = x|y;
return show;
},
Am I missing something?
In javascript, the OR operator requires two vertical bars:
0 : function(e, n, f, i, $r, c, data) {
var x = e===f;
var y = e==='John';
var show = x || y;
return show;
},
Maybe a better method would be to use the filter_defaultFilter option which can be used as follows (demo):
$(function() {
$('table').tablesorter({
theme: 'blue',
widgets: ['zebra', 'filter'],
widgetOptions: {
filter_defaultFilter: {
// Ox will always show
// {q} is replaced by the user query
2: '{q}|Ox'
}
}
});
});
Also, make sure to include a "filter-match" class name in the header cell:
<th class="filter-match">...</th>
otherwise "OR" queries default to exact cell content matches.

Free Text Entry in Angular Material mdAutoComplete

I want my angular material autocomplete to be a list of suggestions but not requirements. However I'm not sure how to implement as their is no clear example from the Angular Material docs.
In the example below my model is $ctrl.item.category
Clearly the example below is wrong, as my model is linked to md-selected-item, but this only works if I select an item. I want the user to be able to free enter the text if the item is not in the list. Basically how autocomplete already works in most browsers.
I see plenty of questions on how to disable this, but they are not trying to disable so much as clean up the left over text when an item is not selected. In these cases when an item is not selected then the model value is null, but text is left in the input.
I want the text left int he input to be the model value if the person does not select (or a match is not made).
md-autocomplete(
md-floating-label="Category Name"
flex="50"
md-input-name="category"
md-selected-item="$ctrl.item.category"
md-search-text="catSearch"
md-items="category in $ctrl.categories"
md-item-text="category"
md-min-length="0"
md-select-on-match=""
md-match-case-insensitive=""
required=""
)
md-item-template
span(md-highlight-text="catSearch" md-highlight-flags="^i") {{category}}
My options ($ctrl.categories) is an array of strings ['Food','Liqour'] and I wan the user to be able to use one of those or free enter Tables as their choice.
In this case you should link md-search-text to your model.
If you want to implement fuzzy search you have to write the filter method yourself. Look at this example:
template:
<md-autocomplete
md-items="item in $ctrl.itemsFilter()"
md-item-text="item.label"
md-search-text="$ctrl.query"
md-selected-item="$ctrl.selected"
>
<md-item-template>
<span md-highlight-text="$ctrl.query">{{item.label}}</span>
</md-item-template>
<md-not-found>
No item matching "{{$ctrl.query}}" were found.
</md-not-found>
<div ng-messages="$ctrl.myValidator($ctrl.query)">
<div ng-message="short">Min 2 characters</div>
<div ng-message="required">Required value</div>
</div>
</md-autocomplete>
controller:
var items = [ ... ];
ctrl.itemsFilter = function itemsFilter() {
return ctrl.query ? filterMyItems(ctrl.query) : items;
};
ctrl.myValidator = function (value) {
return {
short: value && value.length < 2,
required : value && value.length < 1,
};
};
then you just need to add filterMyItems method to filter your items
To improve the answer of #masitko, I have implemented the filter in a way, that it adds the query to the filtered list. So it becomes selectable and a valid option. So it's possible to make the autocomplete a suggestion box.
I'm using ES6 in my projects. But it should be easily adaptable to ES5 code.
myFilter() {
if (!this.query) return this.items;
const
query = this.query.toLowerCase(),
// filter items where the query is a substing
filtered = this.items.filter(item => {
if (!item) return false;
return item.toLowerCase().includes(query);
});
// add search query to filtered list, to make it selectable
// (only if no exact match).
if (filtered.length !== 1 || filtered[0].toLowerCase() !== query) {
filtered.push(this.query);
}
return filtered;
}

tablesorter to sort columns which has <br> within them

I have a table which has one of the column's as datetime: eg: 1/11/2011 12:34 PM
Unfortunately, the width of the column does not allow me to display datetime in full length in one line, hence I am displaying the contents in two lines, like
1/11/2011
12:34 PM
But tablesorter will not work if the column contents have a <br> in them. Any idea how I can achieve sorting via tablesorter for this issue? I am having tablesorter revision 2.0.5b. I cannot upgrade to newer version because it might break existing features of the rails app.
tablesorter is the jquery plugin
You'll probably need a custom parser to remove the carriage return; honestly, I don't think a <br> needs to be added if the text is allowed to wrap, and you set a width for that column.
Anyway, try this code (demo)
$(function () {
$.tablesorter.addParser({
// set a unique id
id: 'date',
is: function (s, table, cell) {
// return false so this parser is not auto detected
return false;
},
format: function (s, table, cell, cellIndex) {
// replace extra spacing/carriage returns
var str = s.replace(/\s+/g," "),
date = new Date( str );
return date instanceof Date && isFinite(date) ? date.getTime() : s;
},
// set type, either numeric or text
type: 'numeric'
});
$('table').tablesorter({
theme: 'blue',
headers: {
7: { sorter: 'date' }
}
});
});

Using tablesorter custom parser only for filtering

I have a table with checkbox column for which filter is used so I can get only selected rows.
I've added custom parser for that column to use checkboxes' "checked" prop values for filtering.
The thing is that parser is added to column using 'sorter' property in 'headers' option for tablesorter initializer, so that when I click on some checkbox and trigger 'update' event, sorting is applied to checkbox column and selected rows are moved to the bottom of the table.
Is there a way to add parser to column so that it's used only for filtering, not for sorting?
UPD: I think I should clarify what I'm trying to do.
I have a custom parser for checkboxes that looks like the following:
var myCustomParser = {
id: 'myCustomParser',
is: function() { return false; },
format: function(cellText, table, cellNode, cellIndex) {
return $(cellNode).find('.checkbox-to-find').prop('checked') ? '1' : '0';
},
parsed: true,
type: 'text'
};
Then I add it to tablesorter and use in initializer:
$.tablesorter.addParser(myCustomParser);
//...
$table.tablesorter({
// ...
headers: {
0: {sorter: 'myCustomParser'}
},
//...
);
This enables filtering but sorting is also applied. I have a checkbox for selecting all rows in header cell for that column and when I click it sorting is applied and checkboxes are sorted.
This is what I use for now to disable sorting:
$table.tablesorter({
//...
textSorter: {
0: function() { return 0; }
},
headers: {
0: {sorter: 'myCustomParser'}
},
//...
);
Stub sorter practically disables sorting while leaving filter enabled. But this seems wrong. According to docs I can't use parser option for setting parser name. filter option also seems to be only for false and parsed values. I'd like to be able to do something like this:
$table.tablesorter({
// ...
headers: {
0: {parser: 'myCustomParser'}
},
//...
);
If this would enable parsing (and make filtering use these parsed values) while keeping sorting disabled, that would be great.
P.S. I've found out there's a parser for checkboxes in repo, but the question remains: how do I specify parser so that sorting is not enabled.
I am guessing that you are using my fork of tablesorter. If that is the case, setting the column to not sort does not stop the parser from processing the information in that column. Here is some information you may have missed in the documentation.
Column features (sort, filter or parsing) can be disabled using any of the methods within the associated section (they all do the same thing), in order of priority:
Disable sort (ref)
Parsing of column content still occurs
jQuery data data-sorter="false".
Metadata class="{ sorter: false }". This requires the metadata plugin.
Headers option headers : { 0 : { sorter: false } }.
Header (<th>) class name class="sorter-false".
Disable filter (ref)
jQuery data data-filter="false".
Metadata class="{ filter: false }". This requires the metadata plugin.
Headers option headers : { 0 : { filter: false } }.
Header (<th>) class name class="filter-false".
If using the "all" column external filter, the disabled column will be included in the query. You can exclude the disabled column by setting a range in the column attribute of the external filter (ref)
<input class="search" type="search" data-column="0-2,4,6-7">
Disable parsing (ref)
When parsing is disabled, both sorting and filtering are automatically disabled, and the column data stored within the cache is set to an empty string.
jQuery data data-parser="false".
Metadata class="{ parser: false }". This requires the metadata plugin.
Headers option headers : { 0 : { parser: false } }.
Header (<th>) class name class="parser-false".
Update: In your case, I would disable sorting (using any sorter methods above), then use a custom textExtraction function that targets the column containing checkboxes:
textExtraction : {
0 : function(node, table, cellIndex) {
return $(node).find('.checkbox-to-find').prop('checked') ? '1' : '0';
}
}

extjs4 grid - changing column editor per row basis

ExtJS4 grid anticipates appropriate editor (cellEditor or rowEditor) per column.
If a column's header field is dateField - date selector will be applied on every row in that column.
What I need is an editor with different field editors per row, not per column.
The Extjs3 solution is provided here - unfortunately doesn't fit in Extjs4 case.
(please check that link to see explanatory images, cause I can't post images yet)
There's also a single column solution called property grid, but again - it supports only one column and is very deviated from the standard Ext.grid component
I have tried manually changing grid editor by customizing column.field and reloading grid.editingPlugin.editor, but always get a blank rowEditor panel with no fields.
//by default rowEditor applies textField to all cells - I'm trying to force custom numberFiled on apropriate row
var numberField=Ext.form.field.Number();
grid.columns[0].field=numberField;
//destroy current rowEditor's instance
delete grid.editingPlugin.editor;
//now, upon doubleClick on apropriate cell it should reinitialize itself (initEditor()) - and it does, but is an empty panel
what am I missing here? once I delete editingPlugin.editor everything should start from the beginning like during the first time rowEditor is called, but it looses all the fields
Solution for Ext4:
I was looking for a solution for this and this guy said the property grid has this behavior.
I have adapted it to work in a clean way for me
on initComponent I declared:
this.editors = {
'date' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Date', {selectOnFocus: true})}),
'string' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Text', {selectOnFocus: true})}),
'number' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'int' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'boolean' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.ComboBox', {
editable: false,
store: [[ true, 'Sim' ], [false, 'Não' ]]
})})
};
I used these functions to help me (copied):
this.renderCell = function(val, meta, rec) {
var result = val;
if (Ext.isDate(val)) {
result = me.renderDate(val);
} else if (Ext.isBoolean(val)) {
result = me.renderBool(val);
}
return Ext.util.Format.htmlEncode(result);
};
this.getCellEditor = function(record, column) {
return this.editors[record.get('type')];
};
And finally, associate these functions to the column:
{text: "Valor", name : 'colunaValor', width: 75, sortable: true, dataIndex: 'valor', width:200,
renderer: Ext.Function.bind(this.renderCell, this),
getEditor: Ext.Function.bind(this.getCellEditor, this)
}

Resources