Search items in a list, what is good to use? - javascript

It is not really a issue, im just wondering I have a list with alot of names and a search function bounded to it. It is all done in jquery and just put every element on display none when it is not matched with the input
It works perfect but I am not really sure this is the 'cleanest' way to do this, cause every element gets updated with a bunch of css styles everytime.
Is it worth to try out angular or some similar solution to achieve it or a complete overkill for such a small task?
Updated:!
My current code:
var value = $input.val(),
$persons = $teamCatagory.find('li');
$persons.hide();
var found = $persons
.filter(function () {
$persons.hide();
return $(this).text()
.match(new RegExp(value, "gi"))
})
.show()
.length > 0;
if(value.length === 0 ) {
$persons.show().removeAttr('style');
}
if (!found) {
$persons.hide();
console.log("found nothing");
}
};

Related

search within an array in javascript

I've been trying for a while now to search within an array, I've looked at all the other questions that even somewhat resemble mine and nothing works, so I'm asking for any help you can give now..
I have an array with a more complex insides than a simple string array
var elementDefns = [
{"element":"water", "combos": {"air":"steam", "earth":"sand"} },
{"element":"fire", "combos": {"earth":"lava", "air":"energy"} },
{"element":"air", "combos": {"water":"steam", "earth":"dust"} },
{"element":"earth", "combos": {"water":"swamp", "fire":"lava"} },
];
Two elements are picked (by the users) which are combined to create new elements. I'd like to search through the elements for any combos that can be made. Ideally, I'd want to use Array.prototype.find, although I can't figure out how to use polyfills correctly and i'm unsure if i'm writing it correctly, so it continues to not work
var elementOne = $("#board img:first-child").attr('id');
var elementTwo = $("#board img:last-child").attr('id');
function findElement(element) {
return elementDefns.element === elementOne;
}
board is the id div where the element cards go to once clicked. I also tried a loop
for (var i=0, tot=elementDefns.length; i < tot; i++) {
var indexHelp = elementDefns[i].element;
var find = indexHelp.search(elementOne);
console.log(find);
}
I'm trying to post a question that's not too long, but I'm sure there's lots more about my code i need to adjust in order to do this. I guess I'm just asking if there's something obvious you think i could work on. I've looked at most of the answers on this site to similar problems but its all just going horribly wrong so any other support would be greatly appreciated..
I have an array with a more complex insides than a simple string array
Yes, but why? Get rid of the extra layers and this is trivial
var e1 = "water";
var e2 = "air";
var elementDefns = {
"water": {"combos": {"air":"steam", "earth":"sand"} },
"fire": {"combos": {"earth":"lava", "air":"energy"} },
"air": {"combos": {"water":"steam", "earth":"dust"} },
"earth": {"combos": {"water":"swamp", "fire":"lava"} },
};
elementDefns[e1].combos[e2] = > "steam"
If you want to keep your data-structure, you can filter through it like this:
var matches = elementDefns
.filter(e => e.element == first && e.combos[second] !== null)
.map(e => e.combos[second]);
The first row filters out all matches, and the secon maps it over to the actual match-string (element name). The find() you speak of just returns the first value that matches, and i guess you want all, so that would be the filter() method.

How to remove elements from a selector

I'm struggling to get a piece of code to work but I'm not a jquery guy so please bear with me.
I have an outer DIV ($scope). It contains all kinds of inputs.
I find all the entries for each input type and filter them to get the ones with values. These are stored in $entries.
$inputs contains all the inputs regardless of type or status.
What I'm trying to do is remove $entries from $inputs to leave the difference.
It doesn't work, and at the moment I'm not getting any errors firing back, so nothing to go on.
My first thought is that jquery is unable to match the elements in one list with the other as it just holds an index, not the actual object. This could be totally wrong (please refer back to line 1).
Either way, I need to find a way of getting all elements and segegating them into 2 bits - those with values and those without.
All help appreciated.
function inputLoaded(isPostback) {
if (typeof Page_Validators !== "undefined") {
$scope = $(".active-step:first");
$inputs = $scope.find(inputs);
$cb = $scope.find(checkboxes).filter(":checked");
$rb = $scope.find(radios).filter(":checked");
$sb = $scope.find(selects).filter(function () { return $(this).val() !== "None"; });
$ta = $scope.find(textareas).filter(function () { return $(this).val(); });
$tb = $scope.find(textboxes).filter(function () { return $(this).val(); });
$entries = $cb.add($rb).add($sb).add($ta).add($tb);
// Do things with $entries here
// Get elements that have not got entries
$el = $inputs.remove($entries);
}
}
The not() method can take a jQuery object whose contents will be excluded from the jQuery object you apply it to. It looks exactly like what you're looking for:
// Get elements, excluding entries.
$el = $input.not($entries);

jQuery grep return on Multidimensional Array

I am learning jQuery and am having issues trying to figure out how to select elements in a multidimensional array. I have a select list with database IDs and I want to set a var with the cost field in the database according to the id that selected. I have all the pieces except for translating the selected ID to a cost. Can someone please help me with getting this right please?
var rangeListData = [{"idrange_list":"1","range_cost":"0","target_range_name":"Self Only"},{"idrange_list":"2","range_cost":"1","target_range_name":"1 Space"},{"idrange_list":"3","range_cost":"2","target_range_name":"2 Spaces"},{"idrange_list":"4","range_cost":"3","target_range_name":"3 Spaces"},{"idrange_list":"5","range_cost":"4","target_range_name":"4 Spaces"},{"idrange_list":"6","range_cost":"5","target_range_name":"5 Spaces"}];
$('#slctPowerTarget').change(function () {
var targetID = $('#slctPowerTarget').val();
var cost $.grep(rangeListData, function(e) { return e.idrange_list == targetID }); // this is the line that is wrong
$('#spanTotalEffectsCost').text(cost);
});
If I put targetID in where cost is it lists fine. But when I try to look this up nothing happens. It is not right somehow and I am not sure what else to try. I think I get how idrange_list == targetID is supposed to match them but not sure how to call the related range_cost.
Thanks for any help you can offer! I read through the docs at jquery.com but can't seem to wrap my head around them.
You can do this :-
// Get the Multidimensional Array first
var data = $.grep(rangeListData, function (e) {
return e.idrange_list === targetID
});
// Get the range cost from the array
var cost = data[0].range_cost;
// Check the value in console for debugging purpose
console.log(cost);
Here is the final code. I also added an IF clause in there in case they select the default setting. This way it will reset instead of tossing an error and keeping page calculations working no matter if they change the drop downs or go back to "Select..."
$('#slctPowerRange').change(function () {
var rangeID = $('#slctPowerRange').val();
if (rangeID > 0) {
var rdata = $.grep(rangeListData, function (e) {
return e.idrange_list === rangeID
});
var rcost = rdata[0].range_cost;
}
else {
var rcost = 0 ;
}
$('#hdnRangeCost').val(rcost);
});

Isotope Search Filter almost figured out

Need some help with the last bit of it...
I have a fiddle here...
I have the filtered searches by button click, and the search by keyword. They work independently, but I can't seem to get them to work together.
I think the function lies somewhere in here, but I'm a bit lost...
function isotopeSearch(kwd)
{
// reset results arrays
var matches = [];
var misses = [];
$('.item').removeClass('match miss'); // get rid of any existing classes
$('#noMatches').hide(); // ensure this is always hidden when we start a new query
if ( (kwd != '') && (kwd.length >= 2) ) { // min 2 chars to execute query:
// loop through brands array
_.each(items, function(item){
if ( item.first.indexOf(kwd) !== -1 ) { // keyword matches element
matches.push( $('#'+item.id)[0] );
} else {
misses.push( $('#'+item.id)[0] );
}
});
// add appropriate classes and call isotope.filter
$(matches).addClass('match');
$(misses).addClass('miss');
$container.isotope({ filter: $(matches) }); // isotope.filter will take a jQuery object instead of a class first as an argument - sweet!
if (matches.length == 0) {
$('#noMatches').show(); // deal with empty results set
}
} else {
// show all if keyword less than 2 chars
$container.isotope({ filter: '.item' });
}
}
EDIT: I'm trying to make it searchable only by first/last name.
It basically looks like your "*" selectors are causing the problem on a couple of All buttons. If you simply make them blanks "" it seems to work.
I put this alert in your code and noticed the selectors got a little weird after a few selections:
var selector = isoFilters.join('');
alert(selector);
You wound up with selectors like **.ar
JSFiddle here: http://jsfiddle.net/TrueBlueAussie/2pasq/14/
There is not a full set of item values to test all combinations, but it seems to work if you drop the two "*" filters.

How can I track the objects parents while searching in a multidimensional object in json?

My function to implement the search is below. The issue I have is I need to track what rows I have to go through to find the URL. I'm building a navigation "widget" and I need it to expand to the correct place based on the URL. Seeing as the URL could be N rows deep, I need a method to track the rows that it passed through.
E.G: row[1].tree.row[3].tree.row[0] , this way I know to expand the navigation for the second element, then the fourth element, then highlight the first element in that list.
The issue is with the rowNum = rowNum+"x"+x; that I pass back to the function. I think I might be overtired when I thought that would work, I didn't think it through.
Suggestions?
Thanks!
I had another question out there about this same function, but this question is different. Is it bad form to submit an additional question?
function lmIntra_LeftNavBuilder_findURL(url)
{
return lmIntra_LeftNavBuilder_searchJson(jsonLNav.tree[0],url,null);
}//end findURL
function lmIntra_LeftNavBuilder_searchJson(tree,url,rowNum)
{
if(rowNum == null)
{
rowNum="";
}
for(var x=0; x<=tree.rows.length-1;x++)
{
var cururl = "";
if(typeof tree.rows[x] ==="undefined")
{
cururl="";
}else
{
var cururl = tree.rows[x].url;
}
if(url == cururl )
{
//return tree.rows[x].title;
return rowNum + " treeDepth:"+tree.pos;
}//end if
else
{
if(typeof tree.rows[x]!= "undefined")
{
if(typeof tree.rows[x].tree.rows != "undefined")
{
rowNum = rowNum+"x"+x;
var t = lmIntra_LeftNavBuilder_searchJson( tree.rows[x].tree,url,rowNum);
if (t) return t;
}//end if
}//end if typeof tree.rows[x].tree!= "undefined"
}//end else
}//end for
}//end searchJson
Here's a simpler json object. It's fully formed, it just doesn't have the depth. The full one is 38K characters, so I'll leave it out.
var jsonLNav = {itemClassName:"NodeLink",linkClassName:"NodeLinkTitle",linkHideClassName:"HideFromProd",navCategoryClassName:"NavCategory",onLoadJS:"",tree:[{pos:1,wid:"263a97c2-7cb9-470c-bf86-cadc28ae1323",pid:"1",rows:[{hide:0,title:"More IT Help",isNC:0,isMig:0,url:"http://vm-hsspdv-d09p/en-us/Help/Pages/ITHelp.aspx",isOL:0,tree:{pos:2,wid:"263a97c2-7cb9-470c-bf86-cadc28ae1323",pid:"3"}},{hide:0,title:"Office 2010",isNC:0,isMig:1,url:"http://office2010.lmig.com/Pages/Default.aspx",isOL:0,tree:{pos:2,wid:"263a97c2-7cb9-470c-bf86-cadc28ae1323",pid:"9"}},{hide:0,title:"E-mail Management",isNC:0,isMig:0,url:"http://vm-hsspdv-d09p/en-us/Help/EmailManagement/Pages/default.aspx",isOL:0,tree:{pos:2,wid:"8be66348-8da1-4e5c-90c5-0930d2f52d1a",pid:"123"}},]}]};
If you really want to stick with the approach you have, though, I don't think it's really too far off. If I understand what you want, the biggest problem is that you need to do something like:
if(url == cururl )
{
rowNum = rowNum+"x"+x;
return rowNum + " treeDepth:"+tree.pos;
}
Presumably everything that exists in this tree maps to something that exists in the DOM, right? I think the most sensible option would be to stop traversing this object to find what you want, use a library like jQuery with a selector engine to select the node you want, and then use said library to traverse back up the DOM. Even traversing the DOM without a library might be easier for you.

Categories

Resources