Search Through a list By jquery (with case insensitive) - javascript

I am trying to search through the list by search box. This is my HTML:
<input type="text" id="query" value=""/>
<ol id="abbreviations" >
<li>Cars</li>
<li>bars</li>
.
.
<ol>
And this is the jQuery code I have:
<script>
var abbrs = {};
$('ol#abbreviations li').each(function(i){
abbrs[this.firstChild.nodeValue] = i;
});
$('#query').focus().keyup(function(e){
if(this.value.length >= 2){
$('ol#abbreviations li').hide();
var filterBy = this.value;
for (var abbr in abbrs) {
if (abbr.indexOf(filterBy) !== -1) {
var li = abbrs[abbr];
$('ol#abbreviations li:eq('+li+')').show();
}
}
} else {
$('ol#abbreviations li').show();
}
if(e.keyCode == 13) {
$(this).val('');
$('ol#abbreviations li').show();
}
});
</script>
My code is working perfectly, but it's case sensitive. For example if I type "Cars" it will filter the list, but if I type "cars" it doesn't work. So how can I make this jQuery search insesitive? I tried to changing var filterBy = this.value.toLowerCase();, but it won't match upper case letters. How can I make it work?

You need to convert to lowercase both the filterValue and abbr:
var filterBy = this.value.toLowerCase();
...
if (abbr.toLowerCase().indexOf(filterBy) !== -1) {
...
Also see this SO question

Related

Searching through both .text() and data- attribute with jQuery

I have a search box:
<input id="box" type="text" />
where I search through a list:
<ons-list class="ng-scope list ons-list-inner">
<ons-list-item data-alt-name="Granny Smith" class="list__item">Apple</ons-list-item>
<ons-list-item data-alt-name="Valencia" class="list__item">Orange</ons-list-item>
<ons-list-item data-alt-name="Hokkaido" class="list__item">Melon</ons-list-item>
</ons-list>
with:
$('#box').keyup(function() {
var valThis = $(this).val().toLowerCase();
if (valThis == "") {
$('.list > .list__item').show();
} else {
$('.list > .list__item').each(function() {
var text = $(this).text().toLowerCase();
if (text.indexOf(valThis) >= 0) {
$(this).show()
} else {
$(this).hide();
}
});
};
});
The problem is, it's only searching .text() but I want it to search also data-alt-name so that it shows if it matches EITHER of them. I already tried with $(this).attr("data-alt-name") but for some reason it's not working.
Any help or hint is greatly appreciated :)
Here is a working snippet using $(this).data("alt-name")
$('#box').keyup(function() {
var valThis = $(this).val().toLowerCase();
if (valThis == "") {
$('.list > .list__item').show();
} else {
$('.list > .list__item').each(function() {
var text = ($(this).text() + $(this).data("alt-name")).toLowerCase();
if (text.indexOf(valThis) >= 0) {
$(this).show()
} else {
$(this).hide();
}
});
};
});
.list__item {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="box" type="text" />
<ons-list class="ng-scope list ons-list-inner">
<ons-list-item data-alt-name="Granny Smith" class="list__item">Apple</ons-list-item>
<ons-list-item data-alt-name="Valencia" class="list__item">Orange</ons-list-item>
<ons-list-item data-alt-name="Hokkaido" class="list__item">Melon</ons-list-item>
</ons-list>
Instead of show/hide you can use:
.toggle( display ): where display can be true to show the element or false to hide it.
You can change:
var text = $(this).text().toLowerCase();
if (text.indexOf(valThis) >= 0) {
$(this).show()
} else {
$(this).hide();
}
With:
var text = ($(this).text().toLowerCase() +
$(this).data('altName')).toLocaleLowerCase();
$(this).toggle(text.indexOf(valThis) != -1);
$('#box').on('input', function(e) {
var valThis = $(this).val().toLowerCase();
if (valThis == "") {
$('.list > .list__item').show();
} else {
$('.list > .list__item').each(function() {
var text = ($(this).text().toLowerCase() + $(this).data('altName')).toLocaleLowerCase();
$(this).toggle(text.indexOf(valThis) != -1);
});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="box" type="text" />
<ons-list class="ng-scope list ons-list-inner">
<ons-list-item data-alt-name="Granny Smith" class="list__item">Apple</ons-list-item>
<ons-list-item data-alt-name="Valencia" class="list__item">Orange</ons-list-item>
<ons-list-item data-alt-name="Hokkaido" class="list__item">Melon</ons-list-item>
</ons-list>
Try with the data() method:
$(this).data("alt-name")
This works perfectly with data attributes and will return the secondary value to perform a search on.
You could also try with
this.attributes["data-alt-name"].value
This will also improve performance
One other simple solution in your case would be to search the outer HTML
var text = $(this)[0].outerHTML
Selecting by text is unpleasant. I'd take a step back and before you bind your keyup handler, create a new data- attribute that has the text you want.
var els = $(".list > .list__item").text(function(i, txt) {
this.setAttribute("data-text", txt.trim().toLowerCase());
this.setAttribute("data-alt-name", this.dataset.altName.toLowerCase());
return txt;
});
Then you can use the selector engine cleanly.
$('#box').keyup(function() {
var valThis = this.value.trim().toLowerCase();
if (valThis == "") {
els.show();
} else {
els.hide()
.filter(`[data-text*='${valThis}'], [data-alt-name*='${valThis}']`)
.show();
};
});
Full demo:
var els = $(".list > .list__item").text(function(i, txt) {
this.setAttribute("data-text", txt.trim().toLowerCase());
this.setAttribute("data-alt-name", this.dataset.altName.toLowerCase());
return txt;
});
$('#box').keyup(function() {
var valThis = this.value.trim().toLowerCase();
if (valThis == "") {
els.show();
} else {
els.hide()
.filter(`[data-text*='${valThis}'], [data-alt-name*='${valThis}']`)
.show();
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="box" type="text" />
<ons-list class="ng-scope list ons-list-inner">
<ons-list-item data-alt-name="Granny Smith" class="list__item">Apple</ons-list-item>
<ons-list-item data-alt-name="Valencia" class="list__item">Orange</ons-list-item>
<ons-list-item data-alt-name="Hokkaido" class="list__item">Melon</ons-list-item>
</ons-list>

Finding exact text in <li> with the inputted value

I have a list of words
<li>name</li>
<li>myname</li>
<li>yourname</li>
and i have an input box input type="text" value="name" id="the_value" with the value of "name" and a submit button with the id "submit_me". What is the exact code for this.
$("#submit_me").click(function(){
var ans = $("#the_value").val();
var list_item = //list items that will match the inputted value;
if(ans == list_item){
list_item.css("color","blue");
}
else{
alert("No word found on list item");
}
})
for the output, the list item with the value "name" will be in color blue.
Use .contains() if you don't want an exact match.
https://api.jquery.com/contains-selector/
Get the value from the input. Select the list items using contains.
If you need an exact match, pseudo code:
$('li').filter(() => $(this).text('THE EXACT TEXT'))
You can loop through the objects using .each() and compare contents using .text():
$("#submit_me").click(function(){
var found = false;
var ans = $("#the_value").val()
$("#list_items li").each( function(){
if( $(this).text() == ans ){
$(this).css("color","blue");
found = true;
}
});
if ( found == false ){
alert("No word found on list item");
}
});
Expects HTML like:
<ul id="list_items">
<li>name</li>
<li>myname</li>
<li>yourname</li>
</ul>
<input type="text" name="the_value" id="the_value" />
<button id="submit_me">Submit</button>
See fiddle here: https://jsfiddle.net/29ee12dj/
Loop through each li using each() and then change the color if the desired text is found.
$("#submit_me").click(function() {
var ans = $("#the_value").val(),
list_item;
$('li').each(function() {
if ($(this).text() == ans) {
list_item = $(this);
}
});
if (list_item) {
list_item.css("color", "blue");
} else {
alert("No word found on list item");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>name</li>
<li>myname</li>
<li>yourname</li>
</ul>
<input type="text" value="name" id="the_value">
<input type="button" id="submit_me" value="Click"/>

How to list autocomplete suggestions as text instead of links

I got this code from a tutorial that I am following for Elasticsearch and AngularJS.
Trying to figure out how to have the autocomplete function form a list of sugggestions in a dropdown as user input is typed instead of displaying links as suggestions.
Here is the html markup:
<ul class="suggestions" ng-show="showAutocomplete">
<li ng-repeat="suggestion in autocomplete.suggestions" ng-show="suggestion.options.length > 0">
<small>Search for —</small> {{suggestion.options[0].text}}
<li ng-repeat="result in autocomplete.results">
{{result._source.title}}
</li>
Here is the js:
//Autocomplete
$scope.autocomplete = {
suggestions: []
};
$scope.showAutocomplete = false;
$scope.evaluateTerms = function(event) {
var inputTerms = $scope.searchTerms ? $scope.searchTerms.toLowerCase() : null;
if (event.keycode === 13) {
return;
}
if (inputTerms && inputTerms.length > 3) {
getSuggestions(inputTerms);
}
else if (!inputTerms) {
$scope.autocomplete = {};
$scope.showAutocomplete = false;
}
};
$scope.searchForSuggestion = function() {
$scope.searchTerms = $scope.autocomplete.suggestions[0].options[0].text;
$scope.search();
$scope.showAutocomplete = false;
};
var getSuggestions = function(query) {
searchService.getSuggestions(query).then(function(es_return) {
var suggestions = es_return.suggest.phraseSuggestion;
var results = es_return.hits.hits;
if (suggestions.length > 0) {
$scope.autocomplete.suggestions = suggestions;
}
else {
$scope.autocomplete.suggestions = [];
}
if (suggestions.length > 0) {
$scope.showAutocomplete = true;
}
else {
$scope.showAutocomplete = false;
}
});
};
The first list item in the html markup gives 1 suggestion (in the form of a link) and the second list item gives a list of links as suggestions. I like the list idea of multiple suggestions, but just want text phrases instead of links that the user can select. Any ideas?
Something like this should work, but I don't' have you object structure so I had to guess in a few places.
<select class="" style="font-size: 12px"
ng-options="suggestion.options[0].text as suggestion for suggestion in autocomplete.suggestions"
ng-change="searchForSuggestion()"
ng-show="suggestion.options.length > 0">
</select>

Javascript/jQuery compare input value to array

I'm relatively new to javascript and jquery. Right now I have a list of words in a txt file. I store this list in an array, and I want to compare the contents of that array to some user input. If there's a match, that specific word should be displayed.
I also use Jasny Bootstrap to perform some typeahead functions to predict which words the user would like to search for.
In the current stage, my function finds matches on the first input character. When using more characters the function returns that no match has been found. Why is that?
Here's my HTML:
<div class="container">
<div class="appwrapper">
<div class="content">
<h3>OpenTaal Woordenboek</h3>
<p>Voer uw zoekopdracht in:<p>
<p><input name="searchinput" id="searchinput" data-provide="typeahead" type="text" placeholder="Zoeken...">
<p class="dict"></p>
</div>
</div>
</div> <!-- /container -->
And here's the jQuery:
<script src="bootstrap/js/jquery.js"></script>
<script src="bootstrap/js/bootstrap-typeahead.js"></script>
<script type="text/javascript">
var data;
var myArray = [];
var txtFile = new XMLHttpRequest();
txtFile.open("GET", "OpenTaal-210G-basis-gekeurd.txt", true);
txtFile.onreadystatechange = function() {
if (txtFile.readyState === 4) { // Makes sure the document is ready to parse.
if (txtFile.status === 200) { // Makes sure it's found the file.
allText = txtFile.responseText;
data = txtFile.responseText.split("\n"); // Will separate each line into an array
myArray = [data];
} //"\r\n"
}
}
//console.write(data);
searchinput.onkeypress = function() {
//alert("The function is working!");
var formInput = document.getElementById("searchinput").value;
if (myArray == formInput) {
alert("There's a match!");
$('.dict').append('<div class="result">' + myArray + '</div>')
} else {
alert("No match has been found..");
}
};
You didn't use jquery, just native javascript.
After your script reading file, just do:
$(searchinput).on("keypress", function() {
if ($.inArray(formInput,myArray) > -1) {
alert("There's a match!");
}
});
UPDATE
$(searchinput).on("blur", function() {
if ($.inArray(formInput,myArray) > -1) {
alert("There's a match!");
}
});
You need to search the entire array, not just compare it to the value:
if ($.inArray(formInput,myArray)>=0) { // returns -1 if no match
alert("There's a match!");
http://api.jquery.com/jQuery.inArray/
Loop through the array and match the input value with array elements like :
for(var i in myArray) {
var arrayElement = myArray[i];
if (arrayElement == formInput) {
//Do your stuff
}
}

How to checkall only filtered items in the list

I have a Search Filter for Check box List using Jquery and java Script....Also i have Checkall and UncheckAll radio buttons..If i enable CheckAll button...it will check all checkboxes in that list...If i filter the list using search filter, also it will check all checkboxes in that list...
Now i want to check only filtered items in the list should checked, if i click checkall....
If i not filter means it will check all items in the list...
My codings are below...
CheckAll coding:
<script>
function checkall(formname,checkname,thestate)
{
var el_collection=eval("document.forms."+formname+"."+checkname);
for (c=0;c<el_collection.length;c++)
el_collection[c].checked=thestate
}
</script>
Search Filter Coding:
<script>
(function ($) {
jQuery.expr[':'].Contains = function(a,i,m){
return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
function listFilter(header, list) {
var form = $("<form>").attr({"class":"filterform","action":"#"}),
input = $("<input>").attr({"class":"filterinput","type":"text"});
$(form).append(input).appendTo(header);
$(input)
.change( function () {
var filter = $(this).val();
if(filter) {
$(list).find("a:not(:Contains(" + filter + "))").parent().slideUp();
$(list).find("a:Contains(" + filter + ")").parent().slideDown();
} else {
$(list).find("li").slideDown();
}
return false;
})
.keyup( function () {
$(this).change();
});
}
$(function () {
listFilter($("#header"), $("#list"));
listFilter($("#header1"), $("#list1"));
});
}(jQuery));
</script>
<script type="text/javascript">
function show()
{
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","location.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
var x=xmlDoc.getElementsByTagName("value");
for (i=0;i<x.length;i++)
{
var name=x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
var link = document.createElement( "a" );
var list = document.createElement( "li" );
var cb = document.createElement( "input" );
cb.type = "checkbox";
cb.id = "c1";
cb.value = name;
cb.name="v1";
cb.checked = false;
link.appendChild(cb);
link.innerHTML+=name;
var lists=document.getElementById('list');
list.appendChild(link);
lists.appendChild(list);
}
}
</script>
My body Tag codings:
<form id="tracklocation">
<ul id="list" style="list-style:none">
</ul>
<h1 id="header1">DVD Collection</h1>
<input type="radio" value="ca" name="dt" onclick="checkall('tracklocation','v1',true)">Check All <input type="radio" value="ua" name="dt" onclick="checkall('tracklocation','v1',false)">Uncheck All
</form>
How to checkall only filtered items in the list..please help me....
This doesn't answer your question but it's much better formatted as an answer than a comment.
Please don't use eval where square bracket notation is by far the better option. Where you have:
> var el_collection=eval("document.forms."+formname+"."+checkname);
presuming that checkname is the name of a radio button set, then it should be:
var el_collection = document.forms[formname][checkname];
Note also that if there is only one such input, el_collection will be a reference to that element and not an HTMLCollection, so you should check for that.
Change checkall function like this using Jquery...it will work fine....
function checkall(formname,checkname,thestate)
{
if ($('li').is(':hidden')) {
var visible = $('input[type=checkbox]:visible').each(function() {
this.checked = thestate; }
);
}
else
{
var visible = $('input[type=checkbox]').each(function() {
this.checked = thestate; }
);
}
}

Categories