jQuery live Search - javascript

I am using the method of live search with jQuery, does this code work in anyones opinion, i think there is a bug in it. It does work, although there is a bug in the code. I am using the method of live search with jQuery, does this code work in anyones opinion, i think there is a bug in it. It does work, although there is a bug in the code.
<script>
$(document).ready(function(){
$("#discount_credits").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = $(this).val(), count = 0;
// Loop through the comment list
$(".commentlist li").each(function(){
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).fadeOut();
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
count++;
}
});
// Update the count
var numberItems = count;
$("#filter-count").text("Number of meals = "+count);
});
});
</script>
<script>
$(document).ready(function(){
$("[type=range]").change(function(){
var newval=$(this).val();
$("#slidernumber").text(newval);
});
});
</script>
<div id="search_wrap">
<form id="live-search" action="" class="styled" method="post">
<fieldset>
<input type="range" min="0" step="1" max="100" name="discount_credits" id="discount_credits">
<span>£</span><span id="slidernumber">25</span>
<span id="filter-count"></span>
</fieldset>
</form>
</div>
<ul class="commentlist">
<li>22.02</li>
<li>21.99</li>
<li>21.99</li>
<li>12.00</li>
<li>42.00</li>
<li>61.99</li>
<li>2.00</li>
</ul>

The problem is in your condition. It currently does a regex match between the value in the <li> tag and the value you're putting on your range. To correct that, you should parse the content text as an int value and compare it to your filter :
// If the list item does not contain the text phrase fade it out
if (parseInt($(this).text()) > filter) {
$(this).fadeOut();
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
count++;
}

Related

Generate Dynamic Inputs with Unique Names in jQuery

In my HTML form, it's possible to add additional inputs dynamically by clicking a button. I've got this part to work, however I need each input to have a unique name.
This is my code so far,
<div class="control-group field_wrapper">
<label class="control-label"><strong> Phone Number 1</strong></label>
<input type="text" class="input-medium" name="phone_number[]">
<button class="btn btn-success add-number" type="button" title="Add">Add</button>
</div>
<div class="additionalNumber"></div>
My JS as below,
$(document).ready(function(){
var maxField = 10;
var addButton = $('.add-number');
var wrapper = $('.additionalNumber');
function fieldHTML(inputNumber) {
return `<div class="control-group field_wrapper">\
<label class="control-label"><strong> Phone Number ${inputNumber}</strong></label>\
<input type="text" class="input-medium" name="phone_number[${inputNumber}]">\
<button class="btn btn-danger remove" type="button">Remove</button>\
</div>`;
}
var x = 1;
$(addButton).on('click', function(e) {
if (x < maxField) {
x++;
$(wrapper).append(fieldHTML(x));
}
if (x >= maxField) {
alert('Limited to 10.');
}
});
$(wrapper).on('click', '.remove', function(e) {
e.preventDefault();
$(this).parents('.control-group').remove();
x--;
});
});
Using this code, I can get unique name for each input which are created by dynamically. But my problem is name[x] index not works properly when it is removing. That mean, just think I have added 3 input and delete second one and again I am adding new one, then it has same name twice. In this case, it is phone_number[3] for second input and phone_number[3] for thirt one also.
This is the fiddle from above code. Any help is appreciated.
You don't need to index the inputs for PHP either - 3x inputs named phone_number[] will automatically be indexed 0 - 2 on the back end:
<input type="text" name="phone_number[]">
<input type="text" name="phone_number[]">
<input type="text" name="phone_number[]">
[phone_number] => Array
(
[0] => a
[1] => b
[2] => c
)
That doesn't help with your plain text Phone Number n label though. And maybe you have your own reasons to want an input name index.
If you think about it, if you're going to allow deletions of any item in the list, and you need the results to be sequential, the only option is to renumber everything each time you make a change. You don't need to include any numbering when you add a new element, just regenerate all numbering.
Here's a working snippet doing that. My changes:
No need to pass the count x to fieldHTML(), we're going to renumber everything after you add the element;
Add a <span class='count'></span> in your label, which we can target and update;
Add a reNumber() function which will iterate over all inputs on the page and number them sequentially;
Call that function after any change;
Notes:
The 2 separate tests if (x < maxField) and if (x >= maxField) can be combined into a single if/else;
If you want to get rid of the duplication of your HTML block, you could give the first one an id like template, and then instead of duplicating that HTML in your JS, just copy the template, eg :
let $copy = $('#template').clone();
wrapper.append($copy);
wrapper and addButton are already jQuery objects, no need to wrap them with $() a second time to use them;
If you do want to number your input names, for consistency the first should probably be phone_number[1];
$(document).ready(function() {
var x = 1;
var maxField = 10;
var addButton = $('.add-number');
var wrapper = $('.additionalNumber');
function fieldHTML() {
return `<div class="control-group field_wrapper">\
<label class="control-label"><strong> Phone Number <span class='count'></span></strong></label>\
<input type="text" class="input-medium" name="phone_number[]">\
<button class="btn btn-danger remove" type="button">Remove</button>\
</div>`;
}
/**
* Iterate over all inputs and renumber sequentially
*/
function reNumber() {
let count;
wrapper.find('.field_wrapper').each(function (i) {
// .each() index is 0-based, and input #1 is already on the page,
// so extras start at #2
count = i + 2;
$('.count', $(this)).html(count);
// If you want to index your input names, but you can safely leave
// this out, PHP will index them anyway
$('input', $(this)).attr('name', 'phone_number[' + count + ']')
});
}
addButton.on('click', function(e) {
if (x < maxField) {
x++;
wrapper.append(fieldHTML());
reNumber();
} else {
alert('Limited to 10.');
}
});
wrapper.on('click', '.remove', function(e) {
e.preventDefault();
$(this).parents('.control-group').remove();
x--;
reNumber();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="control-group field_wrapper">
<label class="control-label"><strong> Phone Number 1</strong></label>
<input type="text" class="input-medium" name="phone_number[]">
<button class="btn btn-success add-number" type="button" title="Add">Add</button>
</div>
<div class="additionalNumber"></div>

Matching input value with text inside span

I am able to match the input value with the span; however, I am only to retrieve the first span in the list I am comparing to. I need to compare to both list items. If the input is equal to either list item then it should be true. I am only getting a match for the first value.
HTML
<input id="search" type="text" class="input">
<ul> <li id="111" class="active" style="display: list-item;"><span style="display:none">111</span><span style="display: inline;">1-1-1</span></li>
<li id="222" style="display: list-item;"><span style="display:none">222</span><span style="display: inline;">2-2-2</span></li>
</ul>
JS
$('#search').on('input',function(){
if( $('#search').val() != $('ul li a span:eq(0)').text()){
return console.log('false')
}
else if( $('#search').val() == $('ul li a span:eq(0)').text()) { return console.log ('true') }
});
jsfiddle
I think that when you call .text() on a list of elements it will return the text of the first element. So you need to iterate through the spans you are interested in and check each one.
Here is an example:
$('#search').on('input',function(){
var found = false;
$('ul li a span:first-child').each(function (i, el){
if ($(el).text() == $('#search').val()) {
found = true;
return;
}
})
console.log(found);
});
Or, you could trim off all HTML tags with regex, and search the content.
function noTags(body) {
var regex = /(<([^>]+)>)/ig;
return body.replace(regex, "");
}

Filtering data using textbox and checkboxes simultaneously with jQuery?

I wanted to filter my attractions stored in paragraphs by following using jQuery with:
Textbox, where I put substring the attraction starts with
Checkboxes, which should show only attractions with certain categories. When you tick multiple boxes, it should show items which have any of listed categories.
I have done that, but these filters don't work simultaneously. One filter overrides results of another, because they work on whole list and invoke show() and hide() on whole list separately.
Html:
<h3>Search:</h3>
<div>
<input type="text" id="search-box" class="form-control" placeholder="Search">
</div>
<h3>Categories:</h3>
<div id="options" class="checkbox">
<label>
<input type="checkbox" rel="club">Club</label>
<label>
<input type="checkbox" rel="other">Other</label>
</div>
<div id="attractions" style="font-size: x-large">
<p class="club" style="display: block;">Cocomo
</p>
<p class="club" style="display: block;">Princess
</p>
<p class="club" style="display: block;">Le Secret
</p>
<p class="other" style="display: block;">Wyspa piasek
</p>
<p class="other" style="display: block;">C# Operational Base
</p>
</div>
Javascript:
$('div.checkbox').delegate('input[type=checkbox]', 'change', function() {
var $lis = $('#attractions > p').hide();
var $checked = $('input:checked');
if ($checked.length) {
($checked).each(function() {
$lis.filter('.' + $(this).attr('rel')).show();
}).find('input:checkbox').change();
} else {
$lis.show();
}
});
$('#search-box').keyup(function() {
var valThis = this.value.toLowerCase();
$('div#attractions > p').each(function() {
var text = $(this).text(),
textL = text.toLowerCase();
(textL.indexOf(valThis) === 0) ? $(this).show(): $(this).hide();
});
});
I suppose there must be some way to achieve simultaneous results. I'd be grateful for showing me right direction, maybe even suggesting to drop this code and use some filter plug-in?
I think this solves your problem in a clean and clear way. Explanations are in the comments.
//Triger filterAttractions when something changes.
$("#search-box, #options input").change(filterAttractions);
$("#search-box").keyup(filterAttractions);
function filterAttractions() {
//Get the text of the textbox.
var searchtext = $("#search-box").val();
//Get an array with the rel attributes of the checked checkboxes.
var categories = $("#options input:checked").map(function() {
return $(this).attr("rel");
}).get();
//Perform this once for every attraction.
$("#attractions p").each(function() {
var attraction = $(this);
//See if it has any of the checked categories.
var category = false;
for(i=0; i<categories.length; i++)
if(attraction.hasClass(categories[i]))
category = true;
//See if it starts with the right text.
var text = attraction.text().indexOf(searchtext) === 0
//Show or hide the attraction depending on the result.
attraction.toggle(category && text);
});
}
Fiddle.

Character Counter for multiple text areas

I have a form that has 3 text areas, a copy button, and a reset button. I want to add all the characters to one sum, then display that sum next to the copy/reset button. There is a 500 character limit, and the counter should start at 49 characters. Should I just take all my textareas and "Funnel" them into a var, then count that var? I'm not sure how I should approach this. I've tried this technique
but it only works with one text area, not the sum of all. If the char count goes above 500, I'd like the text to turn red and say "you've gone over your character limit." I do not want to restrict or limit the text once its over 500. I'm a little fried trying to find a solution, and I'm an obvious html/javascript novice.
I do not need to worry about the carriage return issue in firefox/opera since everyone will be using IE11.
<h1>
Enter your notes into the text boxes below
</h1>
<p>
Please avoid using too many abbreviations so others can read your notes.
</p>
<form>
<script type="text/javascript"><!--
// input field descriptions
var desc = new Array();
desc['kcall'] = 'Reason for Call';
desc['pact'] = 'Actions Taken';
desc['mrec'] = 'Recommendations';
function CopyFields(){
var copytext = '';
for(var i = 0; i < arguments.length; i++){
copytext += desc[arguments[i]] + ': ' + document.getElementById (arguments[i]).value + '\n';
}
var tempstore = document.getElementById(arguments[0]).value;
document.getElementById(arguments[0]).value = copytext;
document.getElementById(arguments[0]).focus();
document.getElementById(arguments[0]).select();
document.execCommand('Copy');
document.getElementById(arguments[0]).value = tempstore;
document.getElementById("copytext").reset();
}
--></script>
<p> Reason For Call: </p> <textarea rows="5" cols="40" id="kcall"></textarea><br>
<p> Actions Taken: </p> <textarea rows="5" cols="40" id="pact"></textarea><br>
<p> Recommendations: </p> <textarea rows="5" cols="40" id="mrec"></textarea><br>
<br>
<button type="button" onclick="CopyFields('kcall', 'pact', 'mrec');">Copy Notes</button>
<input type="reset" value="Reset"/>
</form>
I think this question is a little more tricky that you think, and is not cause the complex of count the number of character inside of a textarea thats is actually pretty simple. in jquery:
$("textarea").each(function(index, item){
sum += $(this).val().length;
});
The problem begins whit the keyup event since and how you manage that event, in my follow example, I pretty much manage when the user press the key like in regular state but if you start holding a key then stoping and copy and paste really quick, the event get lost a little bit and recover after the second keyup. Any way here is my full example with count of character counter, change from red to black and black to red if you over pass the max characters and validation for submit or not the form
Fiddle:
https://jsfiddle.net/t535famp/
HTML
<textarea></textarea>
<textarea></textarea>
<textarea></textarea>
<button class="reset"></button>
You have use <span class="characters"></span> of <span class="max"></span>
<button class="submit">submit</button>
JS
$(function(){
var counter = 0; //you can initialize it with any number
var max = 400; //you can change this
var $characters = $(".characters");
var $max = $(".max");
var submit = true;
$characters.html(counter);
$(".max").html(max);
function count(event){
var characters = $(event.target).val().length;
$characters.html(counter);
//sum the textareas
var sum = 0;
$("textarea").each(function(index, item){
sum += $(this).val().length;
});
counter = sum;
if(counter > max) {
$characters.css({ color : "red" });
submit = false;
}else{
$characters.css({ color : "black" });
submit = true;
}
}
$(document).on("keyup","textarea",count);
$(document).on("click",".submit",function(){
if(submit)
alert("done");
else
alert("you have more characters than " + max);
});
})
Good luck my 2 cents
function textareaLength() {
var charCount = 0;
Array.prototype.forEach.call(document.querySelectorAll('textarea'), function (textarea) { charCount += textarea.value.length; });
return charCount;
}
That will return the count of all textareas on the page. Change the querySelector to be more specific if you only want to count specific textareas.
One option would be to add onchange events to your textareas which call a function like below:
<script>
function validate() {
if(textareaLength() >= 500) {
//limit reached
}
}
function textareaLength() {
var charCount = 0;
Array.prototype.forEach.call(document.querySelectorAll('textarea'), function (textarea) { charCount += textarea.value.length; });
return charCount;
}
</script>
<textarea onchange="validate()"></textarea>
<textarea onchange="validate()"></textarea>
<textarea onchange="validate()"></textarea>
Count
Here's a really simple function:
function TextLength() {
return Array.prototype.reduce.call(
document.querySelectorAll('textarea'),
function(b,a) { return b+a.value.length }, 0);
}
Or with ES6:
const TextLength = () => Array.from(document.querySelectorAll('textarea')).reduce((b,a) => b + a.value.length, 0)
To use this:
TextLength();
Change
Now add this:
Array.prototype.forEach.call(document.querySelectorAll('textarea'), function (e) { e.oninput = TextLength });
And again, ES6:
Array.from(document.querySelectorAll('textarea')).forEach(e => e.oninput = TextLength );
Since the button is in the same form as the textarea elements, you can get a reference to the form using the button's form property. You can also get all the text area elements in the form using querySelectorAll, then loop over them, adding up the characters in each.
The following just counts the total number of characters in the textarea elements:
<button type="button" onclick="count(this)">Copy Notes</button>
and the function:
function count(el) {
var tas = el.form.querySelectorAll('textarea');
var numChars = 0;
for (var i=0, iLen=tas.length; i<iLen, I++) {
numChars += tas[i].value.length;
}
return numChars;
}
If you can rely on ES5+ methods, then you can do:
function count(el) {
return Array.prototype.reduce.call(el.form.querySelectorAll('textarea'),
function(numChars, ta){return numChars += ta.value.length}, 0);
}
Note that by convention, functions starting with a capital letter are reserved for constructors, so CopyFields should be copyFields.
Here's a working example:
function count(el) {
return Array.prototype.reduce.call(el.form.querySelectorAll('textarea'),
function(numChars, ta){return numChars += ta.value.length}, 0);
}
<form>
<textarea name="ta0"></textarea>
<textarea name="ta1"></textarea>
<textarea name="ta2"></textarea><br>
<input type="text" name="numChars">
<button type="button" onclick="this.form.numChars.value = count(this)">count</button>
<input type="reset">
</form>
If you have more than one textarea (Multiple) and you want to display character count on each textarea, you may try below code, as its working me like a charm.
$(document).ready(function () {
$('textarea').on("load propertychange keyup input paste",
function () {
var cc = $(this).val().length;
var id=$(this,'textarea').attr('id');
$('#'+id).next('p').text('character Count: '+cc);
});
$('textarea').trigger('load');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<textarea id="one">hello</textarea>
<p></p>
<textarea id="two"></textarea>
<p></p>
<textarea id="three"></textarea>
<p></p>

how to filter using jquery

html
<div class="adds">
<input type="text" value="" class="ip1" id="ip1" />
<input type="button" value="ADD" class="btn1" id="btn1" />
</br>
<div class="add">
<ul class="justList">
<li>police</li>
</ul>
</div>
</div>
<div class="filter">
<input type="text" value="" class="ip2" id="ip2" />
<input type="button" value="Filter" class="btn2" id="btn2" />
<div class="filter">
<ul>
</ul>
</div>
</div>
JS
$(document).ready(function(){
$("#btn1").on("click",function(){
var occ = $("#ip1").val();
if(occ.length)
{
$('<li />', {html: occ}).appendTo('ul.justList')
$("#ip1").val('');
}
});
});
Hi Here if i give "xxxx" and click "ADD" button the text ll append in the list of ul li, i need if i click filter i need only text that equal to what i gave second input box. it should filter all "xxxx" and it must show only that. any one help me.
See if this code works
$("#btn2").click(function () {
var value = $("#ip2").val();
$(".justList li").each(function () {
var curr_text = $(this).text();
if (curr_text == value)
console.log("equal");
else
$(this).hide();
});
});
Working Code:JSFIDDLE
You can try this using jQueries :contains selector :
$("#btn2").on("click", function () {
var occ = $("#ip2").val();
if (occ.length) {
$matches = $('.justList li:contains("'+occ+'")');
$matches.show();
$('.justList li').not($matches).hide();
}
else{
$('.justList li').show();
}
});
Demo
Update
If you want a case insensitive filter, you can create custome jQuery selector by adding the following script:
jQuery.expr[':'].Contains = function(a, i, m) {
return jQuery(a).text().toUpperCase()
.indexOf(m[3].toUpperCase()) >= 0;
};
and use it in the previous script.
Demo
For a filter, use jQuery filter. That is designed for this type of work.
The function passed to filter receives each element in turn and if you return true it retains it. if you return false it removes it.
Partial string matching:
It also uses match with a case-insensitive RegEx (so you can specify POL, pol or Pol and still match police in your example):
JSFiddle: http://jsfiddle.net/TrueBlueAussie/Wu2x3/2/
$("#btn2").on("click", function () {
var occ = $("#ip2").val();
var $li = $('.justList li');
if (occ.length) {
// Hide all, then show matches
$li.hide();
$li.filter(function(){
// return true if case-insensitive match occurs
return $(this).text().match(new RegExp(occ, "i"));
}).show();
}
else{
// Show everything
$li.show();
}
});
This converts the text values to lowercase before comparison to make the check case-insensitive.
*Note: These solutions will also work with strings containing quotes
Whole string matching:
If you want to match the full string only (bit odd for a filter, but as you specified):
JSFiddle: http://jsfiddle.net/TrueBlueAussie/Wu2x3/4/
$("#btn2").on("click", function () {
var occ = $("#ip2").val();
var $li = $('.justList li');
if (occ.length) {
occ = occ.toLowerCase();
// Hide all, then show matches
$li.hide();
$li.filter(function(){
// return true if case-insensitive match occurs
return $(this).text().toLowerCase() == occ;
}).show();
}
else{
// Show everything
$li.show();
}
});

Categories

Resources