Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request to Issue filter_searchTrigger #1522 #1546

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
153 changes: 129 additions & 24 deletions js/widgets/widget-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
filter_selectSourceSeparator : '|', // filter_selectSource array text left of the separator is added to the option value, right into the option text
filter_serversideFiltering : false, // if true, must perform server-side filtering b/c client-side filtering is disabled, but the ui and events will still be used.
filter_startsWith : false, // if true, filter start from the beginning of the cell contents
filter_useParsedData : false // filter all data using parsed content
filter_useParsedData : false, // filter all data using parsed content
filter_searchTrigger : false // array of events / Keys who trigger the search false = search, blur event and enterkey
},
format: function( table, c, wo ) {
if ( !c.$table.hasClass( 'hasFilters' ) ) {
Expand Down Expand Up @@ -458,6 +459,24 @@
c.$table.triggerHandler( 'filterFomatterUpdate' );
}, 100);
}

if(event.type === 'search'){
var triggerSearch = false;
var searchTrigger = wo.filter_searchTrigger === false ? ['search', 'blur' , 13 ] : wo.filter_searchTrigger;
// skip search if not included
for (var t in searchTrigger){
// events
var stType = typeof searchTrigger[t];
if(stType === "string" && event.type === searchTrigger[t]){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work? If the outer wrapper has event.type === 'search' won't this only capture the 'search' and not the 'blur' event?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case only the search event is bind to the table, so the blur event isn't triggered here

triggerSearch = true;
break;
}
}
if(!triggerSearch){
return;
}
}

// pass true ( skipFirst ) to prevent the tablesorter.setFilters function from skipping the first
// input ensures all inputs are updated when a search is triggered on the table
// $( 'table' ).trigger( 'search', [...] );
Expand Down Expand Up @@ -836,7 +855,8 @@
wo = table.config.widgetOptions; // make sure "wo" isn't cached
var column = parseInt( $( this ).attr( 'data-column' ), 10 ),
liveSearch = typeof wo.filter_liveSearch === 'boolean' ? wo.filter_liveSearch :
ts.getColumnData( table, wo.filter_liveSearch, column );
ts.getColumnData( table, wo.filter_liveSearch, column ),
searchTrigger = wo.filter_searchTrigger ;
if ( typeof liveSearch === 'undefined' ) {
liveSearch = wo.filter_liveSearch.fallback || false;
}
Expand All @@ -851,13 +871,67 @@
( typeof liveSearch === 'number' && this.value.length < liveSearch ) ||
// let return & backspace continue on, but ignore arrows & non-valid characters
( event.which !== tskeyCodes.enter && event.which !== tskeyCodes.backSpace &&
( event.which < tskeyCodes.space || ( event.which >= tskeyCodes.left && event.which <= tskeyCodes.down ) ) ) ) ) {
( event.which < tskeyCodes.space || ( event.which >= tskeyCodes.left && event.which <= tskeyCodes.down ) )
) && searchTrigger === false ) ) {
return;
// live search
} else if ( liveSearch === false ) {
if ( this.value !== '' && event.which !== tskeyCodes.enter ) {
return;

if (searchTrigger === false) {
if ( this.value !== '' && event.which !== tskeyCodes.enter ) {
return;
}
} else {
var skipSearch = true;
// only allow keyCode
for ( var t in searchTrigger ){
// events
var stType = typeof searchTrigger[t];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be easier to read if searchTrigger[t] was assigned to a variable:

var trigger = searchTrigger[t]; // for example, name it whatever you want

if(stType === "number" && event.which === searchTrigger[t]){
// keycodes
skipSearch = false;
break;
} else if(stType === "object" ){
if(searchTrigger[t].hasOwnProperty('keyCode') && event.which === searchTrigger[t].keyCode){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The searchTrigger[t].hasOwnProperty('keyCode') isn't really necessary here, it will work with just:

if ( event.which === tskeyCodes[ trigger.key ] ) {

// check modifier
var ctrl = true, alt = true, shift = true;
if(searchTrigger[t].hasOwnProperty('ctrl')){
if(searchTrigger[t].ctrl === event.ctrlKey ){
ctrl = true;
}else{
ctrl = false;
}
}
if(searchTrigger[t].hasOwnProperty('alt')){
if(searchTrigger[t].alt === event.altKey ){
alt = true;
}else{
alt = false;
}
}
if(searchTrigger[t].hasOwnProperty('shift')){
if( searchTrigger[t].shift === event.shiftKey ){
shift = true;
}
else{
shift = false;
}
}

Copy link
Owner

@Mottie Mottie May 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above three modifier key checks can be simplified into:

var ctrl= typeof trigger.ctrl === 'undefined' ? true : trigger.ctrl=== event.ctrlKey,
  alt = typeof trigger.alt === 'undefined' ? true : trigger.alt  === event.altKey;
  shift = typeof trigger.shift === 'undefined' ? true : trigger.shift  === event.shiftKey;

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran out of time... I'll review the rest of the code later.

if(ctrl && alt && shift){
skipSearch = false;
}
}
}
}
if(skipSearch){
return;
}


}


}
// change event = no delay; last true flag tells getFilters to skip newest timed input
tsf.searching( table, true, true, column );
Expand All @@ -869,25 +943,56 @@
eventType = event.type,
liveSearch = typeof wo.filter_liveSearch === 'boolean' ?
wo.filter_liveSearch :
ts.getColumnData( table, wo.filter_liveSearch, column );
if ( table.config.widgetOptions.filter_initialized &&
// immediate search if user presses enter
( event.which === tskeyCodes.enter ||
// immediate search if a "search" or "blur" is triggered on the input
( eventType === 'search' || eventType === 'blur' ) ||
// change & input events must be ignored if liveSearch !== true
( eventType === 'change' || eventType === 'input' ) &&
// prevent search if liveSearch is a number
( liveSearch === true || liveSearch !== true && event.target.nodeName !== 'INPUT' ) &&
// don't allow 'change' or 'input' event to process if the input value
// is the same - fixes #685
this.value !== c.lastSearch[column]
)
) {
event.preventDefault();
// init search with no delay
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
tsf.searching( table, eventType !== 'keypress', true, column );
ts.getColumnData( table, wo.filter_liveSearch, column ),
searchTrigger = wo.filter_searchTrigger === false ? ['search', 'blur' , 13 ] : wo.filter_searchTrigger,
triggerSearch = false;

if (table.config.widgetOptions.filter_initialized) {
// Only if liveSearch is disabled
if(liveSearch === false){
for (var t in searchTrigger){
// events
var stType = typeof searchTrigger[t];
if(stType === "string" && eventType === searchTrigger[t]){
triggerSearch = true;
break;
} else if(stType === "number" && event.which === searchTrigger[t] ){
// keycodes
triggerSearch = true;
break;
} else if( stType === "object" ){
if( searchTrigger[t].hasOwnProperty('keyCode') && event.which === searchTrigger[t].keyCode ){
// same keycode
triggerSearch = true;
// check modifier
if( searchTrigger[t].hasOwnProperty('ctrl') && searchTrigger[t].ctrl !== event.ctrlKey ){
triggerSearch = false;
}
if( searchTrigger[t].hasOwnProperty('alt') && searchTrigger[t].alt !== event.altKey ){
triggerSearch = false;
}
if( searchTrigger[t].hasOwnProperty('shift') && searchTrigger[t].shift !== event.shiftKey ){
triggerSearch = false;
}
}
}
}
// change & input events must be ignored if liveSearch !== true
} else if ( ( eventType === 'change' || eventType === 'input' ) &&
// prevent search if liveSearch is a number
( liveSearch === true || liveSearch !== true && event.target.nodeName !== 'INPUT' ) &&
// don't allow 'change' or 'input' event to process if the input value
// is the same - fixes #685
this.value !== c.lastSearch[column]){
triggerSearch = true;
}

if(triggerSearch) {
event.preventDefault();
// init search with no delay
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
tsf.searching( table, eventType !== 'keypress', true, column );
}
}
});
},
Expand Down