Question:
I have a jQuery search function however it searches for words together not individually. e.g. "ASUS B350" not "ASUS" and "B350" this can be seen when searching for Asus STRIX B350-F GAMING, "ASUS B350" produces no result but "ASUS" and "B350" would.
Code:
$("#mySearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr:not(.discarded) td:nth-child(1)").filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
Expected Result:
I also want if the string is encased in "" it searches for those words in order.
If you need any more details please let me know
Thanks
You can split the words at every space and check if those individual words exist in the text using every:
Now if you search for "Asus strix" in the below snippet, both ASUS results will be shown
$("#mySearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr:not(.discarded) td:nth-child(1)").filter(function() {
let toggle = value.split(" ").every(i => !i || $(this).text().toLowerCase().indexOf(i) > -1);
$(this).parent().toggle(toggle);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="mySearch" />
<table id="myTable">
<tr><td>Asus STRIX B350-F GAMING</td></tr>
<tr><td>Asus ROG Strix SCAR II Gaming</td></tr>
<tr><td>Dell G7 15 Gaming Laptop</td></tr>
</table>
You could use a regexp pattern to find out if individual words are occurring in the string:
$("#mySearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
if(!(value.startsWith('"')&&value.endsWith('"'))){
value=value.replace(" ", "|");
value= value.trim();
}else {
value=value.replace("\"", "");
}
$("#myTable tr:not(.discarded) td:nth-child(1)").filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().match(value));
});
});
Related
I have this following code which does filter a table but when there is no result it is blank.
Could someone help me out here to add a "No results found" message show when nothing found?
$(document).ready(function() {
$("#table_search").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#filter tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
<table>
<tbody id="filter"></tbody>
</table>
Firstly note that your use of filter() isn't quite correct. It's intended to be used to reduce a set of elements based on a predicate condition supplied within the function argument which returns a boolean. Instead your current logic is using it as a basic looping mechanism.
With regard to the issue, you can use filter() to find matching rows by their text, then based on the number of filtered rows, hide or display the 'No matches' message. Something like this:
jQuery($ => {
let $rows = $('#filter tr');
let $tfoot = $('tfoot');
$("#table_search").on("input", function() {
var value = this.value.toLowerCase();
if (!value) {
$rows.show();
$tfoot.hide()
return;
}
let $filteredRows = $rows.filter((i, el) => el.innerText.toLowerCase().indexOf(value) != -1);
if ($filteredRows.length) {
$tfoot.hide();
$rows.hide();
$filteredRows.show()
} else {
$rows.hide();
$tfoot.show();
}
});
});
tfoot { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="table_search" />
<table>
<tbody id="filter">
<tr><td>Lorem</td></tr>
<tr><td>Ipsum</td></tr>
<tr><td>Dolor</td></tr>
<tr><td>Sit</td></tr>
<tr><td>Amet</td></tr>
<tr><td>Consectetur</td></tr>
<tr><td>Adipiscing</td></tr>
<tr><td>Elit</td></tr>
</tbody>
<tfoot>
<tr><td>No matches</td></tr>
</tfoot>
</table>
Finally, note the use of input instead of keyup. The latter works better in this instance as it also works for users who copy/paste text in to the search box.
My goal is to flag when a user enters the same text into one input that matches at least one other input's text. To select all of the relevant inputs, I have this selector:
$('input:text[name="employerId"]')
but how do I select only those whose text = abc, for instance?
Here is my change() event that checks for duplicate text among all the inputs on the page. I guess I am looking for something like :contains but for text within an input.
var inputsToMonitorSelector = "input[type='text'][name='employerId']";
$(inputsToMonitorSelector).change(function() {
//console.log($(this).val());
var inputsToExamineSelector = inputsToMonitorSelector
+ ":contains('" + $(this).val() + "')";
console.log(inputsToExamineSelector);
if($(inputsToExamineSelector).length > 1) {
alert('dupe!');
}
});
Or is there no such selector? Must I somehow select all the inputsToMonitorSelector's and, in a function, examining each one's text, incrementing some local variable until it is greater than one?
With input you need to use [value="abc"] or .filter()
$(document).ready(function() {
var textInputSelector = 'input[type="text"][name="employerId"]';
$(textInputSelector).on('input', function() {
$(textInputSelector).css('background-color', '#fff');
var input = $(this).val();
var inputsWithInputValue = $(textInputSelector).filter(function() {
return this.value && input && this.value == input;
});
var foundDupe = $(inputsWithInputValue).length > 1;
if(foundDupe) {
console.log("Dupe found: " + input);
$(inputsWithInputValue).css('background-color', '#FFD4AA');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="employerId" value="abc">
<input type="text" name="employerId" value="">
<input type="text" name="employerId" value="">
<input type="text" name="employerId" value="">
[value="abc"] means if the value is abc
[value*="abc"] * means if the value contains abc
[value^="abc"] ^ means if the value starts with abc
[value$="abc"] $ means if the value ends with abc
Note: :contains() not for inputs , and word text not used with inputs and <select>.. inputs and <select> has a value
In your case .. instead of using
$(inputsToExamineSelector).length > 1)
You may need to use .filter()
$(inputsToExamineSelector).filter('[value*="abc"]').length > 1)
OR
$('input[type="text"][name="employerId"]').filter(function(){
return this.value.indexOf('abc') > -1
// for exact value use >> return this.value == 'abc'
}).length;
And to use a variable on it you can use it like
'[value*="'+ valueHere +'"]'
Something like this works. Attach isDuplicated(myInputs,this.value) to a keyup event listener attached to each input.
var myInputs = document.querySelectorAll("input[type='text']");
function isDuplicated(elements,str){
for (var i = 0; i < myInputs.length; i++) {
if(myInputs[i].value === str){
myInputs[i].setCustomValidity('Duplicate'); //set flag on input
} else {
myInputs[i].setCustomValidity(''); //remove flag
}
}
}
Here's another one. I started with vanilla js and was going for an answer like Ron Royston with document.querySelector(x) but ended up with jquery. A first attempt at several things but here you go:
$("input[type='text']").each(function(){
// add a change event to each text-element.
$(this).change(function() {
// on change, get the current value.
var currVal = $(this).val();
// loop all text-element-siblings and compare values.
$(this).siblings("input[type='text']").each(function() {
if( currVal.localeCompare( $(this).val() ) == 0 ) {
console.log("Match!");
}
else {
console.log("No match.");
}
});
});
});
https://jsfiddle.net/xxx8we6s/
How would I go about outputting a list (whether as individual values or as an array) from a comma-separated value in a single input field?
Example
User enters the following into a text input field: Steve, Bruce, Matt, Natasha, Peter
Result:
Steve
Bruce
Matt
Natasha
Peter
Just split the input on comma, and generate the list
var input = "Steve, Bruce, Matt, Natasha, Peter",
ul = $('<ul />');
input.split(',').forEach(function(item) {
ul.append(
$('<li />', { text : item })
)
});
$('body').append(ul);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
hope it helps you:
var myArray = $('input').val().split(',');
Using jQuery
Since you put jquery in your tags i guess you want a jQuery solution.
First of all you would want to split the values, and after that create a list (ul or ol) and add list elements (li)
$(function() {
$("#valuesForm").submit(function(e) {
e.preventDefault();
var values = $("#textfieldId").val().split(",");
if (values) {
for (var i in values) {
var value = values[i].trim(),
$valueList = $("#valueList"),
$valueItem = $("<li />");
$valueItem.text(value);
$valueList.append($valueItem);
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form id="valuesForm">
<input type="text" id="textfieldId">
<input type="submit" value="Split!">
</form>
<ul id="valueList">
</ul>
There are several options.
1 Splitting
var aux = "Steve, Bruce, Matt, Natasha, Peter";
aux = aux.split(',');
This one gives you the names within an array but with the space after the comma.
2 White Space Removal
var aux = "Steve, Bruce, Matt, Natasha, Peter";
aux = aux.split(', ');
This one does resolve the white-space after the comma.
3 Alternative
var aux = "Steve, Bruce, Matt, Natasha, Peter";
aux = aux.split(',');
aux = jQuery.map( aux, function( n, i ) {
return n.trim();
});
This last one is more flexible and i'm showing it just to give an example.
So here is my current js fiddle
http://jsfiddle.net/sbyLb93n/6/
I have tried adding
.replace(/\W*/mg, "")
to wordsArr and valuesArr before I turn the string of text into an array of strings with .split(" ") (so right after i use .trim() on valuesArr and .toLowerCase() on wordsArr). should I iterate through the array after splitting and say 'for each arr in wordsArr, if arr has a character that isn't in a-z or 0-9, then remove that character and return this new string" ? if so, from where should i start to achieve this loop through the arrays? thanks dogs!
You do this using the filterCallback option of the filterable widget. Basically, override the default filter to compare the search text against the text with all punctuation stripped out:
<form class="ui-filterable">
<input id="myFilter" data-type="search"></input>
</form>
<div class="elements" data-filter="true" data-input="#myFilter">
<p class="parag">This is paragraph one or 1; it's not number 2</p>
<p class="parag">Next is two too 2.</p>
<p class="parag">Three 3! is after 2</p>
<p class="parag">Finally is, 4 four but; 'not" two.</p>
</div>
$(document).on("pagecreate", "#page1", function()
$(".elements").filterable('option', 'filterCallback', NoPunctuation);
});
function NoPunctuation( idx, searchValue ) {
var ret = false;
if (searchValue && searchValue.length > 0){
var filttext = $(this).data("filtertext") || '';
filttext = filttext.toLowerCase();
var text = $(this).text().toLowerCase();
var punctRE = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#\$%&\(\)\*\+,\-\.\/:;<=>\?#\[\]\^_`\{\|\}~]/g;
var spaceRE = /\s+/g;
text = text.replace(punctRE, '').replace(spaceRE, ' ');
console.log(text);
if( text.indexOf(searchValue.toLowerCase()) < 0 && filttext.indexOf(searchValue.toLowerCase()) < 0){
ret = true; //filter this one out
}
}
return ret;
}
To strip punctuation, I used an answer from here: How can I strip all punctuation from a string in JavaScript using regex?
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