Filter plugin without data-attribute - sorting

How to filter or sort info without data-attribute by plugin of MixItUp/Isototpe?
Maybe filter will be an #url and sort will be class.

Assuming you have a JSON set, you can filter against the values like so (I'm also assuming you have taken the filter/sort value from the DOM already):
Haven't run this so apologies if not exact - and I'm not used to stack overflow formatting yet but any issues and I'll edit. I think the logic should be OK
var dataset = [
{url: '/test'},
{url: '/test2'}
];
var filterValue = '/test2'; // pass this to function or get from DOM
var sortBy = 'url'; // again, pass in somewhere or get from DOM
var sortType = 'asc';
function filter(data, filter) {
var filteredResults = data.filter(function (el) {
return (filter !== '' && el.url.toLowerCase().indexOf(filter.toLowerCase())) !== -1;
})
return filteredResults;
}
function sort(data, sortBy, sortType) {
var sortIndex = sortType === "asc" ? 1 : -1;
data.sort(function (a, b) {
if (a[sortBy] < b[sortBy]) {
return -1 * sortIndex;
} else if (a[sortBy] > b[sortBy]) {
return 1 * sortIndex;
}
return 0;
})
}
var filteredResults = filter(dataset, filterValue);
sort(dataset, sortBy, sortType); //dataset will be sorted

Related

How do I add html tags in jquery plugins?

I am doing the live search using the jquery plugins. When I tried to search that doesn't exist, it only shows the table. I would like to put some message "No result found" if it doesnt exist. The question is how can I add message "No result found"
Note: In my codes I add some validation, the user need input minimum of 3 characters
/**
**options to have following keys:
**searchText: this should hold the value of search text
**searchPlaceHolder: this should hold the value of search input box placeholder
**/
(function($)
{
$.fn.tableSearch = function(options)
{
if(!$(this).is('table'))
{
return;
}
var tableObj = $(this),
searchText = (options.searchText)?options.searchText:'Search: ',
searchPlaceHolder = (options.searchPlaceHolder)?options.searchPlaceHolder:'',
divObj = $('<div style="font-size:20px;">'+searchText+'</div><br /><br />'),
inputObj = $('<input style="min-width:25%;max-width:50%;margin-left:1%" type="text" placeholder="'+searchPlaceHolder+'" />'),
caseSensitive = (options.caseSensitive===true)?true:false,
searchFieldVal = '',
pattern = '';
inputObj.off('keyup').on('keyup', function(){
searchFieldVal = $(this).val();
if(searchFieldVal.length == 0)
{
tableObj.find('tbody tr').show();
}
else if(searchFieldVal.length >= 3)
{
pattern = (caseSensitive)?RegExp(searchFieldVal):RegExp(searchFieldVal, 'i');
tableObj.find('tbody tr').hide().each(function()
{
var currentRow = $(this);
currentRow.find('td').each(function()
{
var result = "No result";
$("tbody tr").append(result);
if(pattern.test($(this).html()))
{
currentRow.show();
return false;
}
});
});
}
});
tableObj.before(divObj.append(inputObj));
return tableObj;
}
}(jQuery));
Here into JQ plugin(Posted at your question), the handler for empty result is exist. See piece of code from it.
else if(searchFieldVal.length >= 3)
{
pattern = (caseSensitive)?RegExp(searchFieldVal):RegExp(searchFieldVal, 'i');
tableObj.find('tbody tr').hide().each(function()
{
var currentRow = $(this);
currentRow.find('td').each(function()
{
var result = "No result";
$("tbody tr").append(result);
if(pattern.test($(this).html()))
{
currentRow.show();
return false;
}
});
});
}
Paraphrase you mistaken at your end. Re check it.

Chain filter conditions dynamically

How to chain multiple conditions in RethinkDB? This is what I got right now and what works if I only pass live or sports as a parameter. As soon as I pass the live and sports parameter, sports obviously always overwrites the filter variable and the live parameter is ignored.
app.get('/bets', function (req, res) {
var live = req.query.live;
var sports = req.query.sports;
var filter = {};
if (live === undefined) {
filter = r.or(r.row('live').eq(0), r.row('live').eq(1));
} else {
filter.live = parseInt(live);
}
if (sports !== undefined) {
var sports = sports.split(',');
filter = function (doc) {
return r.expr(sports).contains(doc("sport"));
}
}
r.table('bets').filter(filter).limit(100).run(connection, function(err, cursor) {
// ...
});
});
You can chain filters with RethinkDB.
Something along the lines of this (warning, untested) :
app.get('/bets', function (req, res) {
var live = req.query.live;
var sports = req.query.sports;
var liveFilter, sportFilter;
if (live === undefined) {
liveFilter = r.or(r.row('live').eq(0), r.row('live').eq(1));
} else {
liveFilter = function (doc) { return true; };
}
if (sports !== undefined) {
sports = sports.split(','); // no need to redefine the variable here
sportFilter = function (doc) {
return r.expr(sports).contains(doc("sport"));
}
} else {
sportFilter = function (doc) { return true; };
}
r.table('bets')
.filter(liveFilter) // apply the first filter
.filter(sportsFilter) // apply the second filter
.limit(100)
.run(connection, function(err, cursor) {
// ...
});
});
Alternatively you could make one filter function that would handle both the live and sport filters (equally untested, this is to get you started) :
app.get('/bets', function (req, res) {
var live = req.query.live;
var sports = req.query.sports.split(',');
var filter = function(doc){
var sportPass, livePass;
if (live === undefined) {
livePass = r.or(r.row('live').eq(0), r.row('live').eq(1))(doc);
} else {
livePass = parseInt(live); // not sure what you meant by filter.live here
}
if (sports !== undefined) {
sportPass = r.expr(sports).contains(doc("sport"));
}
return sportPass && livePass;
};
r.table('bets').filter(filter).limit(100).run(connection, function(err, cursor) {
// ...
});
});

Get Specific Data From ngStorage

I have a bunch of data on JSON using LocalStorage from ng-storage like this,
[Object { judul="Just", isi="Testing"}, Object { judul="To", isi="Get"}, Object { judul="Specific", isi="Data"}]
but I want to get one specific data to get the "isi" value, how to do that ?
You can do this by adding a get function to your factory
for example :
.factory ('StorageService', function ($localStorage) {
$localStorage = $localStorage.$default({
things: []
});
var _getAll = function () {
return $localStorage.things;
};
//-----
var _get = function (isi) {
for( var i = 0; i < $localStorage.things.length ; i++ ){
if( $localStorage.things[i].isi === isi ){
return $localStorage.things[i];
}
}
}
return {
getAll: _getAll,
get : _get
};
})
and in your controller you can get the specific data by passing the id of your object
var objectInlocal = StorageService.get(Thing.isi);

nightwatch assert ALL elements, not ANY

I'm trying to test that, when the Submit button is clicked on an empty form, all the "please fill in this field" labels are displayed.
I'm doing so with this:
page.click('#btn_submit');
page.expect.element('#validation_label_required').to.be.visible;
where #validation_label_required is represented by the CSS selector:
input[required] ~ p.error-message-required
However, this test passes if ANY of the validation labels are visible. The test should only pass if they ALL are.
How can I achieve this?
You will need to create a custom assertion for that where you locate all elements by selenium commands and then loop to verify condition. It should look something like this
var util = require('util');
exports.assertion = function (elementSelector, expectedValue, msg) {
this.message = msg || util.format('Testing if elements located by "%s" are visible', elementSelector);
this.expected = expectedValue;
this.pass = function (value) {
return value === this.expected;
};
this.value = function (result) {
return result;
};
this.command = function (callback) {
var that = this.api;
this.api.elements('css selector',elementSelector, function (elements) {
elements.value.forEach(function(element){
that.elementIdDisplayed(element.ELEMENT,function(result){
if(!result.value){
callback(false);
}
});
});
callback(true);
});
return this;
};
};
I've just ended up with another custom assertion that check how many elements are visible by given css selector.
/**
* Check how many elements are visible by given css selector.
*
*/
var util = require('util');
exports.assertion = function(elementSelector, expectedCount, msg) {
this.message = msg || util.format('Asserting %s elements located by css selector "%s" are visible', expectedCount, elementSelector);
this.expected = expectedCount;
this.count = 0;
this.pass = function(value) {
return value === this.expected;
};
this.value = function(result) {
return this.count;
};
this.command = function(callback) {
var me = this, elcount = 0;
this.count = 0;
this.api.elements('css selector', elementSelector, function(elements) {
if(elements.value && elements.value.length > 0){
elcount = elements.value.length;
}else{
return callback(false);
}
elements.value.forEach(function(element) {
me.api.elementIdDisplayed(element.ELEMENT, function(result) {
if (result.value) {
me.count++;
}
elcount--;
if (elcount === 0) {
callback(me.count);
}
});
});
});
};
};

Bootstrap Multiselect filtering values based on another dropdown

I'm working on cascading the multi-select based on the values of the data-attributes on another.
I have this method which is called inside the onChanged event of the parent. By parent I mean what to filter the child by i.e
Parent = Department Multiselect
Child = Staff Multiselect.
The child element has a data attribute of data-departmentid.
function cascadeMultiselect(control, targetControl, key) {
this.control = control;
this.targetControl = targetControl;
this.key = key;
this.toHide = [];
this.toShow =[];
//Get controls selectedIds
this.selectedIds = function() {
var selected = [];
_.each($(this.control + " option:selected"), function(c) {
selected.push($(c).val());
});
return selected;
};
//Now filter
this.filter = function() {
//Get target control attribute values
_.each($(targetControl + " option"), function(tc) {
//Use the val as an identifier
var val = $(tc).val();
var data = $(tc).attr("data-" + key);
data = data.split(",");
var isMatch = anyMatchInArray(data, this.selectedIds());
if(!isMatch){
$(tc).hide();
}
});
}
this.filter();
$(targetControl).multiselect('rebuild');
}
It's being called like so:
onChange: function() {
cascadeMultiselect('#departmentlist', '#stafflist', "DepartmentID");
}
The problem is I can't hide the elements. The filter works just fine, I've tried:
$(tc).hide(); // tc = targetControl option
I've also tried to refresh instead of rebuild.
Since it seems the only way to do this was to store the values of the multiselect, and then remove / add the relevant values.
I decided to use a rudimentary Cache class:
var Cache = (function () {
this.all = [];
function Cache(control) {
this.control = control;
}
Cache.prototype.getAll = function () {
return this.all;
};
Cache.prototype.setAll = function (all) {
this.all = all;
};
return Cache;
})();
Function now looks like:
function cascadeMultiselect(control, targetControl, key, cache) {
this.control = control;
this.targetControl = targetControl;
this.key = key;
this.toHide = [];
this.toShow =[];
//To reset the multiselect
this.reset = function(){
$(targetControl).html('');
$(targetControl).multiselect('dataprovider', cache.all)
}
//Get controls selectedIds
this.selectedIds = function() {
var selected = [];
_.each($(this.control + " option:selected"), function(c) {
selected.push($(c).val());
});
return selected;
};
//Now filter
this.filter = function() {
//Get target control attribute values
_.each($(targetControl + " option"), function(tc) {
//Use the val as an identifier
var val = $(tc).val();
var data = $(tc).attr("data-" + key);
data = data.split(",");
var isMatch = anyMatchInArray(data, this.selectedIds());
console.log($(tc));
if(!isMatch){
$(tc).remove();
}
});
}
//If nothing selected then reset the multiselect
if(this.selectedIds().length == 0){
this.reset();
return;
}else{
this.filter();
}
$(targetControl).multiselect('rebuild');
}
When I first populate the multiselect with the dataprovider I add the data to the cache:
if(cache != null){
cache.setAll(this.dataToAdd);
}

Resources