Hi im trying to make a filter for a list of spans im having trouble putting what is in the spans to lower case or ignorecase.
Any ideas?
$("#filterinput2").keyup(function () {
var filter = ($(this).val()).toLowerCase(); // get the value of the input, which we filter on
console.log("lower filter" + filter);
if (filter) {
// hide tr's for songs not matching and show tr's for songs matching
$(".tonelist").find(".song:not(:contains(filter))").parent().parent().parent().fadeOut("slow");
$(".tonelist").find(".song:contains(filter)").parent().parent().parent().fadeIn();
if (window.console != undefined) {
console.log($(".tonelist").find(".song:not(:contains(" + filter + "))").parent().parent().parent().innerHTML);
}
$(".tonelist").find(".grouptitle:not(:contains(" + filter + "))").parent().fadeOut("slow");
$(".tonelist").find(".grouptitle:contains(" + filter + ")").parent().fadeIn();
if (window.console != undefined)
console.log($(".tonelist").find(".grouptitle:not(:contains(" + filter + "))").parent().parent().parent().innerHTML);
} else
// if input field is empty, show all tr's
$(".tonelist").find("tr").fadeIn();
ColorLines();
});
You're going to have to check the contents of each of those spans yourself. You can do that by using the .html() function to get the contents of each song/grouptitle as a string. Something like this might work (although I haven't tested it):
$("#filterinput2").keyup(function () {
var filter = ($(this).val()).toLowerCase(); // get the value of the input, which we filter on
console.log("lower filter" + filter);
if (filter) {
// hide tr's for songs not matching and show tr's for songs matching
spans = $(".tonelist").find(".song, .grouptitle")
for (s in spans) {
el = $(spans[s]);
if ( el.html().match( new RegExp(filter, "i") ) ) {
el.fadeIn();
} else {
el.fadeOut("slow");
}
}
} else
// if input field is empty, show all tr's
$(".tonelist").find("tr").fadeIn();
ColorLines();
});
The reason is that the :contains() css selector is case-sensitive, and there's no way I know of to change that.
Related
I have a table with a bunch of data in it. Currently, my code compares textfield input to the data in the table. If there's a match, it will show that particular table row. Here's my code:
$(document).on('keyup','#filterText',function(){
$('.all').hide(); // hide everything
$('tfoot').hide(); // hide everything
var s = $(this).val().toLowerCase(); //get input string
if(s==''){$('.all').show(); $('tfoot').show();}; // if no input then show everything
$('#report tbody tr td').each(function(i,td) {
//go through each table cell and compare
if($(td).text().toLowerCase().indexOf(s)!==-1){
$(td).closest('tr').show(); // show table row
}
});
}); //.but_filterText
This works great. But now, I need to modify this so that a user could do multiple searches at the same time, separated by a comma. So here's what I did and nothing happens:
$(document).on('keyup','#filterText',function(){
$('.all').hide();
$('tfoot').hide();
var s = $(this).val().toLowerCase().split(',');
if(s === undefined || s.length == 0){
$('.all').show(); $('tfoot').show();
};
$('#report tbody tr td').each(function(i,td) {
if(s.indexOf($(td).text().toLowerCase())!==-1){
$(td).closest('tr').show();
}
});
}); //.but_filterText
Seems like it should work but can't get it going. What am I doing wrong. Thank you
I thinks the issue is because in the input field you type space after comma, e.g. text 1, text 2 instead of text 1,text 2
i made a small (similar to yours code) example: (in this example you can type with or without space, since it will be replaced)
$('[name="search"]').on('keyup', function() {
var $tds = $('td');
var s = this.value.toLowerCase().replace(/\,\s/,',').split(',');
// consider replacing comma+space (/\,\s/) with just a comma
// and also i would recommend using filter function for finding matches,
// it will return an array of matched elements, empty if there is no match
$tds = $tds.filter(function(i, td) {
return s.indexOf($(td).text().toLowerCase()) >=0;
});
$tds.addClass('selected');
});
Here is the jsfillde - http://jsfiddle.net/zqdbso1w/1/
UPDATE (based on your comment)
Here is the jsfillde - http://jsfiddle.net/zqdbso1w/3/
simply make second iteration to seek for a substring in haystack
$('[name="search"]').on('keyup', function() {
var $tds = $('td');
var s = this.value.toLowerCase().replace(/\,\s/,',').split(',');
$tds.removeClass('selected');
$tds.each(function() {
var text = $(this).text().toLowerCase();
var r = s.filter( function(t) {
if (!t.length) return false;
return text.indexOf(t) >= 0;
});
if (r.length) $(this).addClass('selected');
});
});
UPDATE regex should be global, and remove all spaces after all commas
Here is the jsfiddle - http://jsfiddle.net/zqdbso1w/4/
I would like to perform the following actions on my DOM:
Filter a list via multiple controls (combined):
Checkboxes
Select boxes
Free text input (like e.g http://vdw.github.io/HideSeek/)
So for example, the user can select a city from the select box, which filters the displayed items. When typing into the input field, the filter from the select is still in place, further filtering the displayed items by the entered text.
I normally write something by hand to combine multiple choices from different select boxes, but it's not ideal. Also, for a "free text" filter, I have always used jQuery-Plugins, and they tend to reset the selection when you start typing.
With tables, I use the datatables plugin, which brings along multiple filters. It's extremely feature-rich, but also quite heavy - and designed for tables, not for any type of lists.
What are the general recommendations / outlines on how to achieve this?
PS: Here's how I do it now. a) it's extremely proprietary and b) I haven't managed to combine it with a text filter yet:
function showItems(selectedCanton,showTypeOne,showTypeTwo){
var typeOneSelector = '';
var typeTwoSelector = '';
if (selectedCanton=='all'){
var cantonSelector = '';
}
else {
var cantonSelector = '.list-item[data-canton="'+selectedCanton+'"]';
}
if (showTypeOne){
if (showTypeTwo){
selector = cantonSelector;
//selector = cantonSelector+'[data-type="one"],'+cantonSelector+'[data-type="two"]';
}
else {
selector = cantonSelector+'[data-type="one"]';
}
}
else if (showTypeTwo){
selector = cantonSelector+'[data-type="two"]';
}
$('.list-item').hide();
console.log(selector);
$(selector).show();
}
$(document).ready(function($){
$(".filter-select").change(function() {
var selectedCanton = $("#canton").val();
var showTypeOne = $("#type-one").prop('checked');
var showTypeTwo = $("#type-two").prop('checked');
showItems(selectedCanton,showTypeOne,showTypeTwo);
});
});
you can use filter function of jquery.
try something like
$('.list-item').hide();
$('.list-item').filter(function (index, e) {
var condition = true;
var el = $(e);
if(showTypeOne)
{
condition = condition && (el.data("type") === "one");
}
if(showTypeTwo)
{
condition = condition && (el.data("type") === "two");
}
if(selectedCanton!='all')
{
condition = condition && (el.data("canton") === selectedCanton);
}
return condition;
})
.show();
you could add text filter easly that way..
working sample : http://jsfiddle.net/CufMp/1/
I need to remove one element from javascript array. The element I want to remove is the value of 'NT'. I have a HTML input
<input type="text" id="caseType" size="50"/>
We populate it with
var caseTypeJson = jQuery.parseJSON('${crFilingCaseDetailForm.caseTypes}');
I want to remove one element from the javascript array
jQuery(function () {
jQuery.each(caseTypeJson, function (index, item) {
if(("NT") == item.value){ // remove this element
caseTypeJson.splice(index,1);
}
if (item.value == '${crFilingCaseDetailForm.selectedCase.caseType}') {
jQuery('#caseType').val(item.value + ' - ' + item.description);
jQuery('#selectedCaseType').val(item.value);
}
});
});
This splice approach is not working. In doing some prior research I also tried the javascript delete too and that left the undefined element. Does this seem like a good way to do this?
Thanks,
Tom
You could try using grep.
var values = jQuery.grep(caseTypeJson, function(item) {
if (("NT") != item.value) return item;
});
This will give you an array without the NT value.
I have 5 div tags with the same class. Each div tag has a textbox and a dropdownlist with numbers.
How can I check if all these div tags' textboxes and dropdownlists are empty or not and if it is "do something".
$step is an array with all of my div tags.
var $step = $(".wizard-step2:visible");
My Textbox have a class Comment and my Dropdownlist have a class Grade.
I have coded this so far but its wrong, I dont want it to check on each div tag, I want it to check all of them.
This is the code that is wrong:
var Comment = $step.find(".Comment").val();
var Grade = $step.find(".Grade").val();
for (var i = 0; i < $step.length; i++) {
if (Comment != null && Grade > 0) { {
// do this
}
} else {
alert("You must enter both fields");
}
}
EDIT:
I think that I did not explain my question well, my code works like all of the answers I got on this question. I dont want to make this if statement to check each div tag. I want to be able to check if all of the div tags have any empty fields do something " else if all the div tags fields are filled do something.
Users are allowed to leave the fields empty, but if all of the div tags fields are filled do something.
I do not want to do a if statement for each div tag, I want to do a if statement if all the div tags have any empty fields or if all are field.
Lets say I have 5 div tags. I have filled 4 of them and when I filled the last one 5 div tags are filled. Here I want this " do something ", else nothing should happen. I dont want the if statements to be executed on div tag 1, 2, 3, 4 that are filled I want the if statement to happen when the 5th is filled beacuse then all the div tags are filled else nothing should happen
Find the filled elements of each class, and use the length of the resulting selections to perform your tests:
var $step = $(".wizard-step2:visible");
// returns true if the element's value is not null
function filled() {
return !!this.value;
}
// count the number of non-empty elements
var n_step = $step.length;
var n_comments = $step.find('.Comment').filter(filled).length;
var n_grades = $step.find('.Grade' ).filter(filled).length;
if (n_comments === n_step && n_grades === n_step) {
// all filled
} else if (n_comments === 0 && n_grades === 0) {
// all empty
} else {
// mixed - do nothing
}
Something like this:
$(".wizard-step2:visible").each(function(){
var Comment = $(this).find(".Comment").val();
var Grade = $(this).find(".Grade").val();
if (Comment != '' && Grade > 0) {
{
// do this
} else {
alert("You must enter both fields");
}
});
You can iterate over a collection or array like this:
$(".wizard-step2:visible").each(function(count){
var isCommentEmpty = $(this).find(".comment").val().length == 0;
if(isCommentEmpty){
alert('Comment on div ' + count + ' is empty!';
}
});
try to get your comment inside of each something like
var bOK, Comment, Grade ;
$step.each(function(){
Comment = $(this).find(".Comment").val();
Grade = $(this).find(".Grade").val();
if(put your condition here)
else {
bOK = false;
return false
}
});
// Now test your condition with bOK
You should use the jQuery each() method to iterate over your $(".wizard-step2:visible") array of divs.
Have a look at this jsFiddle i've created to show how you can achieve this
EDIT :
This is the jist of the jsFiddle code here: -
$('.wizard-step2:visible').each(function(){
var txtBox = $(this).find('.comment');
var Select = $(this).find('.Grade');
var thisDiv = $(this).attr('id');
if(txtBox.val().length > 0 && Select.val().length > 0)
{
alert("values for " +thisDiv+ " are fine");
}
else
{
alert("please fill in both values for " + thisDiv);
}
});
Hello there JavaScript and Jquery gurus, I am getting and then displaying list of a facebook user's friend list by using the following code:
<script>
function getFriends(){
var theword = '/me/friends';
FB.api(theword, function(response) {
var divInfo = document.getElementById("divInfo");
var friends = response.data;
divInfo.innerHTML += '<h1 id="header">Friends/h1><ul id="list">';
for (var i = 0; i < friends.length; i++) {
divInfo.innerHTML += '<li>'+friends[i].name +'</li>';
}
divInfo.innerHTML += '</ul></div>';
});
}
</script>
graph friends
<div id = divInfo></div>
Now, in my Facebook integrated website, I would eventually like my users to choose their friends and send them gifts/facebook-punch them..or whatever. Therefore, I am trying to implement a simple Jquery filter using this piece of code that manipulates with the DOM
<script>
(function ($) {
// custom css expression for a case-insensitive contains()
jQuery.expr[':'].Contains = function(a,i,m){
return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
function listFilter(header, list) { // header is any element, list is an unordered list
// create and add the filter form to the header
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) {
// this finds all links in a list that contain the input,
// and hide the ones not containing the input while showing the ones that do
$(list).find("a:not(:Contains(" + filter + "))").parent().slideUp();
$(list).find("a:Contains(" + filter + ")").parent().slideDown();
} else {
$(list).find("li").slideDown();
}
return false;
})
.keyup( function () {
// fire the above change event after every letter
$(this).change();
});
}
//ondomready
$(function () {
listFilter($("#header"), $("#list"));
});
}(jQuery));
</script>
Now, This piece of code works on normal unordered list, but when the list is rendered by JavaScript, it does not. I have a hunch that it has to do something with the innerHTML method. Also, I have tried putting the JQuery filter code within and also right before tag. Neither seemed to work.
If anyone knows how to resolve this issue, please help me out. Also, is there a better way to display the friends list from which users can choose from?
The problem is here:
$(list).find("a:not(:Contains(" + filter + "))").parent().slideUp();
$(list).find("a:Contains(" + filter + ")").parent().slideDown();
Since you're rendering this:
divInfo.innerHTML += '<li>'+friends[i].name +'</li>';
There is no anchor wrapper, the text is directly in the <li> so change the first two lines to look in those elements accordingly, like this:
$(list).find("li:not(:Contains(" + filter + "))").slideUp();
$(list).find("li:Contains(" + filter + ")").slideDown();
You could also make that whole section a bit faster by running your Contains() code only once, making a big pact for long lists, like this:
$(input).bind("change keyup", function () {
var filter = $(this).val();
if(filter) {
var matches = $(list).find("li:Contains(" + filter + ")").slideDown();
$(list).find("li").not(matches).slideUp();
} else {
$(list).find("li").slideDown();
}
});
And to resolve those potential (likely really) innerHTML issues, build your structure by using the DOM, like this:
function getFriends(){
var theword = '/me/friends';
FB.api(theword, function(response) {
var divInfo = $("#divInfo"), friends = response.data;
divInfo.append('<h1 id="header">Friends/h1>');
var list = $('<ul id="list" />');
for (var i = 0; i < friends.length; i++) {
$('<li />', { text: friends[i].name }).appendTo(list);
}
divInfo.append(list);
});
}
By doing it this way you're building your content all at once, the <ul> being a document fragment, then one insertion....this is also better for performance for 2 reasons. 1) You're currently adding invalid HTML with the .innerHTML calls...you should never have an unclosed element at any point, and 2) you're doing 2 DOM manipulations (1 for the header, 1 for the list) after the much faster document fragment creation, not repeated .innerHTML changes.