I have difficulties making the button work - javascript

I have a textbox that matches the word written to id's of hidden containers and fades them in after pressing enter, everything works great except of when i added a button to make the same action...I can't seem to make the button work.
jsFIDDLE
HTML
<input type="text" value="Type the desired page" id="search" class="txtfield" onBlur="javascript:if(this.value==''){this.value=this.defaultValue;}" onFocus="javascript:if(this.value==this.defaultValue){this.value='';}" autocomplete="off"/>
<input type="button" class="btn"/>
<div class="clear"></div>
<div id="content">
<div id="home">home
<br /><i>home content</i>
</div>
<div id="about">about
<br /><i>about content</i>
</div>
<div id="portfolio">portfolio
<br /><i>portfolio content</i>
</div>
<div id="hire">hire me
<br /><i>hire me content</i>
</div>
<div id="contact">contact
<br /><i>contact content</i>
</div>
</div>
Script
var substringMatcher = function (strs, q, cb) {
return (function (q, cb, name) {
var matches, substrRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function (i, str) {
$("#search").val("");
if (substrRegex.test(str) || q.slice(0, 1) === str.slice(0, 1)) {
// the typeahead jQuery plugin expects suggestions to a
// JavaScript object, refer to typeahead docs for more info
matches.push(name(str));
}
});
cb(matches);
}(q, cb, function (n) {
return {
"content": n
}
}));
};
var _matches = $.map($("#content div"), function (v, k) {
return [v.id]
});
var template = {
"content": _matches
};
var search = $('#search').val().toLowerCase();
$("#content div:gt(0)").hide(0);
$('#search').focus().keyup(function (e) {
var search = $(this);
var _search = search.val();
if (e.which === 13){
substringMatcher(template.content, _search, function (d) {
$("#" + d[0].content)
.delay(500)
.fadeIn(500)
.siblings()
.fadeOut(500);
search.val("")
})
}
});

Here's a solution
http://jsfiddle.net/35r0m6rc/12/
This part got changed:
$('#search').focus().keyup(function (e) {
var search = $(this);
var _search = search.val();
if (e.which === 13){
show_page(_search);
}
});
$('.btn').click(function(){
show_page($('#search').val());
});
function show_page(_search) {
substringMatcher(template.content, _search, function (d) {
$("#" + d[0].content)
.delay(500)
.fadeIn(500)
.siblings()
.fadeOut(500);
search.val("")
})
}
I made a func to show the page, used by both RETURN and the button.

Related

Issues with using AJAX and JQuery to multiselect and capture information from JSON file

I have a live search function that parses information from a JSON file using AJAX and jQuery, and then is clickable. What I'm struggling to figure out is how to have the value (in this case, "happy" or "fat") populate a multiselect, and then once that's accomplished, capture the rest of the data in that JSON array to be utilized later.
$(document).ready(function(){
$.ajaxSetup({ cache: false });
$('#search').keyup(function(){
$('#result').html('');
$('#state').val('');
var searchField = $('#search').val();
var expression = new RegExp(searchField, "i");
$.getJSON('coretype.json', function(data) {
$.each(data, function(key, value){
if (value.identifier.search(expression) != -1)
{
$('#result').append('<li class="list-group-item link-class"> '+value.identifier+'</li>');
}
});
});
});
$('#result').on('click', 'li', function() {
var click_text = $(this).text().split('|');
$('#search').val($.trim(click_text[0]));
$("#result").html('');
});
});
I have gotten all the way to having the value be clickable, and have been unsuccessful figuring out the rest from there.
Here's the JSON file:
[
{
"identifier":"Happy",
"progressbar1": 3,
"progressbar2": 2,
"progressbar3": -2
},
{
"identifier":"Fat",
"progressbar1": -3,
"progressbar2": -2,
"progressbar3": 2
}
]
Ideally I'd like javascript to be able to capture the "progressbarX" values when someone types in the identifier, although I figure there's a much easier way to accomplish this...
<!-- Search -->
<br /><br />
<div class="container" style="width:900px;">
<h2 align="center">EnneaTest</h2>
<br /><br />
<div align="center">
<input type="text" name="search" id="search" placeholder="trait type" class="form-control" />
</div>
<ul class="list-group" id="result"></ul>
<br />
</div>
</div>
</div>
Here's the Plunker file
I created a kind of autocomplete drop down for search from json. And once one of the options from that dropdown is selected, I add that to the result list. At that time the whole object is pushed into searchObjects object. When the item from the list is clicked, that text is used to search the object associated with it. Hope this helps..
<!-- Search -->
<br /><br />
<div class="container" style="width:900px;">
<h2 align="center">EnneaTest</h2>
<br /><br />
<div align="center">
<input type="text" name="search" id="search" placeholder="trait type" class="form-control" />
</div>
<div id="searchResult"></div>
<div>
<ul class="list" id="result" style="color: red;"></ul>
</div>
<br />
</div>
<script>
$(document).ready(function(){
$.ajaxSetup({ cache: false });
$('#search').keyup(function(){
var searchField = $('#search').val();
var regex = new RegExp(searchField, "i");
var output = '<div class="row">';
$.getJSON('coretype.json', function(data) {
$.each(data, function(key, val){
if (val.identifier.search(regex) !== -1) {
console.log(val);
var thisVal = JSON.stringify(val);
output += "<h5 onclick='addToList("+thisVal+")'>" + val.identifier + "</h5>";
}
});
output += '</div>';
$('#searchResult').html(output);
});
});
$('#result').on('click', 'li', function() {
var click_text = $(this).text();
console.log(click_text);
var thisObj = [];
thisObj = findObject(click_text);
console.log(thisObj);
});
});
var searchObjs = [];
function addToList(obj) {
//console.log(obj);
$('#result').append('<li class="list-group-item link-class">'+obj.identifier+'</li>');
$('#searchResult').html('');
var item = {};
item ["identifier"] = obj.identifier;
item ["progressbar1"] = obj.progressbar1;
item ["progressbar2"] = obj.progressbar2;
item ["progressbar3"] = obj.progressbar3;
searchObjs.push(item);
console.log(searchObjs);
}
function findObject(identifier) {
var found = 0;
for (var i = 0, len = searchObjs.length; i < len; i++) {
if (searchObjs[i].identifier === identifier) {
return searchObjs[i]; // Return as soon as the object is found
found = 1;
}
}
if(found === 0) {
return null; // The object was not found
}
} ;
</script>

how to move selected item in a list using up and down arrow keys in javascript?

I am trying to implement up and down arrow buttons for a list in HTML. the up arrow moves the selected element of list upwards and the down arrow moves the selected list element downwards. I tried this code, but not working ::
function reorder_up(node) {
$(".go_up").click(function() {
var $current = $(this).closest('li')
var $previous = $current.prev('li');
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
});
}
function reorder_down(node) {
$(".go_down").click(function() {
var $current = $(this).closest('li')
var $next = $current.next('li');
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
});
}
// for adding to the result page i am using this function, where i am creating a list dynamically and provinding the id to the selected element when clicking on it. I need to move up - down in the result section of the list ::
function add_to_result() {
//var moparent = document.getElementById("parent").innerHTML;
var moname = document.getElementById("moselect").innerHTML;
var node = document.createElement('LI');
node.setAttribute('onclick', 'giveid_Result(this)');
node.setAttribute('ondblclick', 'fillprops()');
var text = document.createTextNode(moname);
node.appendChild(text);
document.getElementById("result").appendChild(node);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" class='go_up' onclick="reorder_up(this)" style="height:40px;width:40px">↑</button>
<button type="button" class='go_down' onclick="reorder_down(this)" style="height:40px;width:40px">↑</button>
<div id="results">
<div class="boxheader">
<STRONG>RESULTS</STRONG>
</div>
<div class="boxcontent">
<ul id="result">
</ul>
</div>
</div>
Your jQuery click event listeners are added after the click event happens so they are never handled, on the click event you are just binding the click handler. Move the $().click outside of the onclick and since you are using jQuery selectors for the buttons you can get rid on onclick
$(".go_up").click(function() {
var $current = $(this).closest('li')
var $previous = $current.prev('li');
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
});
$(".go_down").click(function() {
var $current = $(this).closest('li')
var $next = $current.next('li');
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" class='go_up' style="height:40px;width:40px">↑</button>
<button type="button" class='go_down' style="height:40px;width:40px">↑</button>
<div id="results">
<div class="boxheader">
<STRONG>RESULTS</STRONG>
</div>
<div class="boxcontent">
<ul id="result">
</ul>
</div>
</div>
var selected;
for(var x=0;x<5;x++){
addToResult("Node:"+x);
}
$("li").click(function(){
console.log("pressing"+$(this).attr("id"));
select($(this))
});
$(".go_up").click(function(){reorder_up(selected)});
$(".go_down").click(function(){reorder_down(selected)});
function reorder_up(node) {
var dnode=node;
console.log("RUP");
var $current = $(dnode).closest('li')
$current.css("background-color","blue");
var $previous = $current.prev('li');
$previous.css("background-color","yellow");
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
}
function reorder_down(node) {
console.log("RDO");
var dnode=node;
var $current = $(dnode).closest('li')
$current.css("background-color","blue");
var $next = $current.next('li');
$next.css("background-color","yellow");
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
}
// for adding to the result page i am using this function, where i
//am creating a list dynamically and provinding the id to the selected
//element when clicking on it. I need to move up - down in the result section of the list
// ::
function addToResult(id) {
var node = document.createElement('li');
node.setAttribute('id',id);
// node.setAttribute('onclick', 'select(id)');
node.setAttribute('ondblclick', 'fillprops()');
var text = document.createTextNode(id);
node.appendChild(text);
document.getElementById("result").appendChild(node);
}
function select(selector){
selector.css("background-color","green");
console.log("youre pressing"+selector.attr("id"));
selected=selector;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class='go_up' style="height:40px;width:40px">↑</button>
<button type="button" class='go_down' style="height:40px;width:40px">↓</button>
<div id="results">
<div class="boxheader">
<STRONG>RESULTS</STRONG>
</div>
<div class="boxcontent">
<ul id="result">
</ul>
</div>
</div>
The $(something).click query executes when you click on that something. So it doesn't make sense to put into a function. You want it to trigger some function execution.
I added the dnode var to keep the scope of the node since this is no longer attached to the node when you call reorder node. So I substituted this with dnode and it works fine. Here is the fully working code:
Javascript:
for(var x=0;x<5;x++){
add_to_result("Node"+x);
}
$("li").click(function(){
select($(this))
});
$(".go_up").click(function() {
reorder_up(selectedNode);
});
$(".go_down").click(function() {
reorder_up(selectedNode);
});
function reorder_up(node) {
var dnode=node;
var $current = $(dnode).closest('li')
var $previous = $current.prev('li');
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
}
function reorder_down(node) {
var dnode=node;
var $current = $(node).closest('li')
var $next = $current.next('li');
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
}
You can remove the onclik attribute from html. It is not needed
About the add to result function: There is no element with the moselect id, so moname is null and the compiler gives an error. Next, you never call it so it will never execute. You should add a loop somewhere to add the elements. You don't need to set attribute onclick, just use a jquery
selector.I added set attribute id to pass it to select function. By the way, I don't see give_id function anywhere so I created a function to select the node to be moved
function add_to_result(id) {
var node = document.createElement('li');
node.setAttribute('id',id);
node.setAttribute('ondblclick', 'fillprops()');
var text = document.createTextNode(id);
node.appendChild(text);
document.getElementById("result").appendChild(node);
}
function select(selector){
selector.css("background-color","green");
console.log("youre pressing"+selector.attr("id"));
selected=selector;
}

Couldn't append span element to array object in Angularjs/Jquery

Am struggling hard to bind an array object with list of span values using watcher in Angularjs.
It is partially working, when i input span elements, an array automatically gets created for each span and when I remove any span element -> respective row from the existing array gets deleted and all the other rows gets realigned correctly(without disturbing the value and name).
The problem is when I remove a span element and reenter it using my input text, it is not getting added to my array. So, after removing one span element, and enter any new element - these new values are not getting appended to my array.
DemoCode fiddle link
What am I missing in my code?
How can I get reinserted spans to be appended to the existing array object without disturbing the values of leftover rows (name and values of array)?
Please note that values will get changed any time as per a chart.
This is the code am using:
<script>
function rdCtrl($scope) {
$scope.dataset_v1 = {};
$scope.dataset_wc = {};
$scope.$watch('dataset_wc', function (newVal) {
//alert('columns changed :: ' + JSON.stringify($scope.dataset_wc, null, 2));
$('#status').html(JSON.stringify($scope.dataset_wc));
}, true);
$(function () {
$('#tags input').on('focusout', function () {
var txt = this.value.replace(/[^a-zA-Z0-9\+\-\.\#]/g, ''); // allowed characters
if (txt) {
//alert(txt);
$(this).before('<span class="tag">' + txt.toLowerCase() + '</span>');
var div = $("#tags");
var spans = div.find("span");
spans.each(function (i, elem) { // loop over each spans
$scope.dataset_v1["d" + i] = { // add the key for each object results in "d0, d1..n"
id: i, // gives the id as "0,1,2.....n"
name: $(elem).text(), // push the text of the span in the loop
value: 3
}
});
$("#assign").click();
}
this.value = "";
}).on('keyup', function (e) {
// if: comma,enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(e.which)) $(this).focusout();
if ($('#tags span').length == 7) {
document.getElementById('inptags').style.display = 'none';
}
});
$('#tags').on('click', '.tag', function () {
var tagrm = this.innerHTML;
sk1 = $scope.dataset_wc;
removeparent(sk1);
filter($scope.dataset_v1, tagrm, 0);
$(this).remove();
document.getElementById('inptags').style.display = 'block';
$("#assign").click();
});
});
$scope.assign = function () {
$scope.dataset_wc = $scope.dataset_v1;
};
function filter(arr, m, i) {
if (i < arr.length) {
if (arr[i].name === m) {
arr.splice(i, 1);
arr.forEach(function (val, index) {
val.id = index
});
return arr
} else {
return filter(arr, m, i + 1)
}
} else {
return m + " not found in array"
}
}
function removeparent(d1)
{
dataset = d1;
d_sk = [];
Object.keys(dataset).forEach(function (key) {
// Get the value from the object
var value = dataset[key].value;
d_sk.push(dataset[key]);
});
$scope.dataset_v1 = d_sk;
}
}
</script>
Am giving another try, checking my luck on SO... I tried using another object to track the data while appending, but found difficult.
You should be using the scope as a way to bridge the full array and the tags. use ng-repeat to show the tags, and use the input model to push it into the main array that's showing the tags. I got it started for you here: http://jsfiddle.net/d5ah88mh/9/
function rdCtrl($scope){
$scope.dataset = [];
$scope.inputVal = "";
$scope.removeData = function(index){
$scope.dataset.splice(index, 1);
redoIndexes($scope.dataset);
}
$scope.addToData = function(){
$scope.dataset.push(
{"id": $scope.dataset.length+1,
"name": $scope.inputVal,
"value": 3}
);
$scope.inputVal = "";
redoIndexes($scope.dataset);
}
function redoIndexes(dataset){
for(i=0; i<dataset.length; i++){
$scope.dataset[i].id = i;
}
}
}
<div ng-app>
<div ng-controller="rdCtrl">
<div id="tags" style="border:none;width:370px;margin-left:300px;">
<span class="tag" style="padding:10px;background-color:#808080;margin-left:10px;margin-right:10px;" ng-repeat="data in dataset" id="4" ng-click="removeData($index)">{{data.name}}</span>
<div>
<input type="text" style="margin-left:-5px;" id="inptags" value="" placeholder="Add ur 5 main categories (enter ,)" ng-model="inputVal" />
<button type="submit" ng-click="addToData()">Submit</button>
<img src="../../../static/app/img/accept.png" ng-click="assign()" id="assign" style="cursor:pointer;display:none" />
</div>
</div>
<div id="status" style="margin-top:100px;"></div>
</div>
</div>

how to receive numbers with input and return only even numbers in javascript & jquery?

how to receive numbers with input and return only even numbers in javascript & jquery?
$(document).ready(function() {
$("#submit").click(function() {
var nums = $("#nums").val();
var numsf = nums.split(',');
var res = numsf.join(", ");
var even =
$("p").append(even + "<br>");
});
});
Use modulus 2 to detect if it is an even number
$(document).ready(function () {
$("#submit").click(function () {
var nums = parseInt($("#nums").val());
var isEven = nums % 2 == 0;
if(isEven){
$("p").append(nums);
}
});
});
Update
$(document).ready(function() {
$("#submit").click(function() {
var nums = $("#nums").val();
var numsf = nums.split(',');
var evens = [];
for (var i = 0; i < numsf.length; i++) {
if (parseInt(numsf[i]) % 2 == 0) {
evens.push(numsf[i]);
}
}
var res = evens.join(", ");
$("p").append(res + "<br>");
});
});
This fixes your issue. I have provided the demo link.
Demo
$("document").ready(function() {
$("#submit").click(function() {
var nums = $("#nums").val();
var numsf = nums.split(','); //array of comma separated values
var evens = [];
//loops through the array. see documentation for jQuery.each()
$.each(numsf,function(i, _this){
if (!isNaN(_this) && parseInt(_this) % 2 == 0)
evens.push(_this);
});
var res = evens.toString();
$("p").append(res + "<br>");
});
});
jQuery.each()
Try this
$(document).ready(function() {
var numsf = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$.each(numsf, function(a, b) {
if (b % 2 == 0) {
alert(b);
return b;
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'd personally suggest the following – written on the assumption that the element with the id="nums" is meant to take a comma-separated string of numbers:
// binding an anonymous function tot he click event
// of the element with 'id="submit"', passing the
// event ('e') into the function:
$("#submit").click(function (e) {
// preventing any default behaviour of the
// element's click event:
e.preventDefault();
// updating the text of the <p> element(s)
// (it would be better, in practice, to use
// a more specific selector):
$('p').text(function () {
// splitting the value of the '#nums' element on the
// comma (',') character to form an array; using
// Array.prototype.filter() to filter that array:
return $('#nums').val().split(',').filter(function (n){
// the first argument to the anonymous function
// (here 'n') is the array element of the array
// over which we're iterating.
// we trim the number-string (removing leading
// and trailing spaces), and then use parseInt()
// to convert that to a number in base 10 (the
// second, the radix, argument to parseInt());
// if the remainder of the division of that number
// by two is 0 then the number is even and
// the assessment evaluates to true, so we
// keep that number (discarding those numbers
// for which the assessment evaluates to false):
return parseInt(n.trim(), 10) % 2 === 0;
// joining the filtered-array back together:
}).join(', ');
});
});
$("#submit").click(function(e) {
e.preventDefault();
$('p').text(function() {
return $('#nums').val().split(',').filter(function(n) {
return parseInt(n.trim(), 10) % 2 === 0;
}).join(', ');
});
});
p::before {
content: 'Even numbers: ';
display: block;
color: #999;
}
p:empty::before {
content: '';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="">
<fieldset>
<label>Enter comma-separated numbers:
<input id="nums" type="text" placeholder="1,2,3,4..." />
</label>
</fieldset>
<fieldset>
<button id="submit" type="button">Submit</button>
</fieldset>
</form>
<p></p>
External JS Fiddle demo, for experimentation/development, etc.
Incidentally, this can be done similarly in plain JavaScript – without the use of a library, such as jQuery – with the following:
// getting the element with 'id="submit"' and binding an
// anonymous function as the click event-handler, passing
// the event ('e') into the function:
document.getElementById('submit').addEventListener('click', function (e) {
// preventing any default actions the element might have:
e.preventDefault();
// retrieving the <form> associated with the clicked element,
// then getting the next element sibling, and setting its
// text-content:
this.form.nextElementSibling.textContent = document
// getting the element with the id of 'nums':
.getElementById('nums')
// retrieving its value, splitting that value on comma
// characters to form an array:
.value.split(',')
// filtering that array, using Array.prototype.filter():
.filter(function (n) {
// exactly the same as above:
return parseInt(n.trim(), 10) % 2 === 0;
}).join(', ');
});
document.getElementById('submit').addEventListener('click', function(e) {
e.preventDefault();
this.form.nextElementSibling.textContent = document
.getElementById('nums')
.value.split(',').filter(function(n) {
return parseInt(n.trim(), 10) % 2 === 0;
}).join(', ');
});
p::before {
content: 'Even numbers: ';
display: block;
color: #999;
}
p:empty::before {
content: '';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="">
<fieldset>
<label>Enter comma-separated numbers:
<input id="nums" type="text" placeholder="1,2,3,4..." />
</label>
</fieldset>
<fieldset>
<button id="submit" type="button">Submit</button>
</fieldset>
</form>
<p></p>
External JS Fiddle demo, for experimentation/development, etc.
References:
JavaScript:
Array.prototype.filter().
Array.prototype.join().
Event.preventDefault().
parseInt().
String.prototype.split().
String.prototype.trim().
jQuery:
event.preventDefault().
text().
val().

Javascript search and display divs with matching keywords

What I'm looking for:
I'm working on creating an easy way for a user to search a list of people, and for results to instantly display below the search field. The results MUST display "close" results, rather than exact. For example: User searches for "Mr. Smith" and The following existing result is displayed: "John Smith" (since there is no "Mr. Smith" entry, it displayed one with the keyword "smith")
What I have:
I have a working code that lets the user enter some characters and all divs that include a string matching the input is displayed (see in jsfiddle: http://jsfiddle.net/891nvajb/5/ Code is also below)
Unfortunately, this only displays results that match EXACTLY.
<body>
<input type="text" id="edit_search" onkeyup="javascript: find_my_div();">
<input type="button" onClick="javascript: find_my_div();" value="Find">
<script>
function gid(a_id) {
return document.getElementById (a_id) ;
}
function close_all(){
for (i=0;i<999; i++) {
var o = gid("user_"+i);
if (o) {
o.style.display = "none";
}
}
}
function find_my_div(){
close_all();
var o_edit = gid("edit_search");
var str_needle = edit_search.value;
str_needle = str_needle.toUpperCase();
if (str_needle != "") {
for (i=0;i<999; i++) {
var o = gid("user_"+i);
if (o) {
var str_haystack = o.innerHTML.toUpperCase();
if (str_haystack.indexOf(str_needle) ==-1) {
// not found, do nothing
}
else{
o.style.display = "block";
}
}
}
}
}
</script>
<div id="user_0" style="display:none">Andy Daulton<br/>Owner Nissan<br/><br/></div>
<div id="user_1" style="display:none">Doug Guy<br/>Bug Collector<br/><br/></div>
<div id="user_2" style="display:none">Sam Hilton<br/>Famous Celebrity in Hollywood<br/><br/></div>
<div id="user_3" style="display:none">Don Grey<br/>Old man<br/><br/></div>
<div id="user_4" style="display:none">Amy Hinterly<br/>Cook<br/><br/></div>
<div id="user_5" style="display:none">Gary Doll<br/>Racecar Driver<br/><br/></div>
<div id="user_6" style="display:none">Tod Akers<br/>Football Player<br/><br/></div>
<div id="user_7" style="display:none">Greg Barkley<br/>Interior designer<br/><br/></div>
<div id="user_8" style="display:none">Alen Simmons<br/>8th place winner<br/><br/></div>
Split the words in the search string with a regex like
searchString.split(/\W/);
and do a OR search over each of the words in the resulting array.
Updated fiddle
var searchStrings = str_needle.split(/\W/);
for (var i = 0, len = searchStrings.length; i < len; i++) {
var currentSearch = searchStrings[i].toUpperCase();
if (currentSearch !== "") {
nameDivs = document.getElementsByClassName("name");
for (var j = 0, divsLen = nameDivs.length; j < divsLen; j++) {
if (nameDivs[j].textContent.toUpperCase().indexOf(currentSearch) !== -1) {
nameDivs[j].style.display = "block";
}
}
}
}
One further approach, is as follows:
function gid(a_id) {
return document.getElementById(a_id);
}
function close_all() {
// applies the Array.prototype.forEach() method to the array-like nodeList
// returned by document.querySelectorAll() (the string passed to which finds all
// elements with an id that starts with ('^=') the string 'user_':
[].forEach.call(document.querySelectorAll('[id^=user_]'), function(div) {
// 'div' is the array element (the node) itself:
div.style.display = 'none';
});
}
function find_my_div() {
close_all();
// getting the trimmed lower-cased string from the input element, split
// on white-space characters to create an array:
var keywords = gid('edit_search').value.trim().toLowerCase().split(/\s+/),
// as above, selecting all elements whose id starts with the string 'user_':
haystack = document.querySelectorAll('[id^="user_"]'),
// working out whether text is accessed by node.textContent, or node.innerText:
textProp = 'textContent' in document.body ? 'textContent' : 'innerText',
// an initialised variable, for later:
userWords,
// filters the haystack (the divs whose id starts with 'user_'):
found = [].filter.call(haystack, function(user) {
// assigns the lower-cased string to the created-variable:
userWords = user[textProp].toLowerCase();
// returns those div elements whose text contains some of
// the words returned, earlier, as the keywords:
return keywords.some(function (word) {
return userWords.indexOf(word) > -1;
});
});
// iterates over the found elements, and shows them:
[].forEach.call(found, function(user) {
user.style.display = 'block';
});
}
<body>
<input type="text" id="edit_search" onkeyup="javascript: find_my_div();">
<input type="button" onClick="javascript: find_my_div();" value="Find">
<script>
function gid(a_id) {
return document.getElementById(a_id);
}
function close_all() {
[].forEach.call(document.querySelectorAll('[id^=user_]'), function(div) {
div.style.display = 'none';
});
}
function find_my_div() {
close_all();
var keywords = gid('edit_search').value.trim().toLowerCase().split(/\s+/),
haystack = document.querySelectorAll('[id^="user_"]'),
textProp = 'textContent' in document.body ? 'textContent' : 'innerText',
userWords,
found = [].filter.call(haystack, function(user) {
userWords = user[textProp].toLowerCase();
return keywords.some(function (word) {
return userWords.indexOf(word) > -1;
});
});
console.log(found);
[].forEach.call(found, function(user) {
user.style.display = 'block';
});
}
</script>
<div id="user_0" style="display:none">Andy Daulton
<br/>Owner Nissan
<br/>
<br/>
</div>
<div id="user_1" style="display:none">Doug Guy
<br/>Bug Collector
<br/>
<br/>
</div>
<div id="user_2" style="display:none">Sam Hilton
<br/>Famous Celebrity in Hollywood
<br/>
<br/>
</div>
<div id="user_3" style="display:none">Don Grey
<br/>Old man
<br/>
<br/>
</div>
<div id="user_4" style="display:none">Amy Hinterly
<br/>Cook
<br/>
<br/>
</div>
<div id="user_5" style="display:none">Gary Doll
<br/>Racecar Driver
<br/>
<br/>
</div>
<div id="user_6" style="display:none">Tod Akers
<br/>Football Player
<br/>
<br/>
</div>
<div id="user_7" style="display:none">Greg Barkley
<br/>Interior designer
<br/>
<br/>
</div>
<div id="user_8" style="display:none">Alen Simmons
<br/>8th place winner
<br/>
<br/>
</div>
References:
CSS:
Attribute-presence and value selectors.
JavaScript:
Array.prototype.every().
Array.prototype.filter().
Array.prototype.forEach().
Array.prototype.some().
document.querySelectorAll().
Function.prototype.call().
String.prototype.indexOf()

Categories

Resources