jquery select and exclude multiple nth-childs - javascript

Is there a way that i can select multiple nth-childs at once like:
$("#table").find("tr > :not(td:nth-child(1,3,5))");
which doesn't work
I want to select all td in each row but not for column 1,3,5 (this can be any combination).
Is there a way to do this? I cannot assign classnames.
thanks for any help!
UPDATE:
I want to search in all rows of a table, but exclude some columns.
I have this code right now:
elem.keyup(function() {
$(options.table).find("tr").hide();
var data = this.value.split(" ");
var jo = $(options.table).find("tr > :not(td:nth-child("+cols+"))");
$.each(data, function(i, v){
jo = jo.filter(":containsIgnoreCase('"+v+"')");
});
jo.parent().show();
});
It works when I pass a single value, but i want to exclude multiple columns.
thanks

From your example, it looks like you're trying to exclude the odd numbers. Try:
$("#table").find("tr > :not(td:nth-child(odd))");
Although, it may be more efficient to just select the even ones.
$("#table").find("tr > td:nth-child(even)");
You can also use formulas in nth-child. See this link for more detail.
Okay, as per comments below/clarification on the question, here is another solution.
$("#table").find("tr > td").filter(function(index){
return index == 1 || index == 2 || index == 5;
});

Related

Javascript hide Gridview rows with blank field

I am rewriting a site in .Net, and I am trying to reproduce some functionality of the original site, but I have hit a stumbling block.
I have a gridview table where the 12th column, column(11) is a date field. I am attempting to keep querying the SQL database, so I am loading all the rows for my criteria, and I have a pair radio buttons. One shows all records, the other I just want to show the records where the date field is blank, or in the case of the Gridview, &nbsp ;
So I have a function that does something similar on another page, but instead of looking for a value in a traditional sense, I am looking for cells that have &nbsp ; in them. Everything I try is failing. Here is what i have, but I am not sure where to go from here:
function refinesearch(x) {
var rows = $("#GridView1 tr:gt(0)");
if (x == 1) {
$("#GridView1 tr").show();
}
else {
$("#GridView1 tr").hide();
var rowToShow = rows.find("td:eq(12)").filter(":contains(' ')").closest("tr");
rows.show().not(rowToShow).hide();
}
}
What I am getting is 0 rows shown. It is working perfectly for non special values, but i don't know enough javascript to fix the test. Anyone have thoughts?
After a good nights sleep, I got this working:
function refinesearch(x) {
$("#GridView1 tr").hide();
var rows = $("#GridView1 tr:gt(0)");
if (x == 1) {
$("#GridView1 tr").show();
}
else {
$("#GridView1 tr").each(function () { //loop over each row
if (($(this).find("td:eq(11)").html() == ' ') || ($(this).find("th:eq(11)").text() == 'Index Date')) { //check value of TD and include table header row
$(this).show(); //show the row
}
});
}
}
I am extremely interested in linq queries after doing some reading on the topic, and I think that going forward, it will be a much more robust solution.

Chosen multiple select becomes huge when many/all options are selected

When using Chosen.js on a multiple select field, if there are over 500 options that the user has selected, the list just becomes ridiculously long.
Is there any way I could limit the number of show elements? For example when chosing over 3 options, the user will have (4) options are selected..., instead of them being listed.
I wonder why there's no such option in their documentation.
Thanks in advance.
You can use something like this:
$('.element').chosen().change(function() {
var totalSelected = $(this).find('option:selected').size();
var placeholder = $(this).find('option:first-child').text();
if(totalSelected > 3) {
$(this).next().find('.chosen-choices').find('li.search-choice').hide(),
$(this).next().find('.chosen-choices').find('.literal-multiple').show();
$(this).next().find('.chosen-choices').find('span.literal-multiple').text(placeholder + " ("+totalSelected+")");
}
});
The class literal-multiple is a custom element to show the totalSelected elements. You need to add it in the prototype of the chosen plugin:
file chosen.jquery.js
Chosen.prototype.set_up_html = function() {
//stuff
if(this.is_multiple) {
var selVal = this.default_text;
this.container.html('<ul class="chosen-choices"><span class="literal-multiple"></span></ul>');
}
};
SOrry I am unable to comment since I don't have enough reputation.
But to add to the previous answer, instead of adding a separate container,
why don't we just append the n users selected as a <li> item.
Something like this -
$('.element').chosen().change(function() {
var totalSelected = $(this).find('option:selected').size();
var placeholder = $(this).find('option:first-child').text();
if(totalSelected > 3) {
$(this).next().find('.chosen-choices').find('li.search-choice').hide(),
$(this).next().find('.chosen-choices')append('<li class="search-choice" <span>'+totalSelected+' users selected. </li>');
}
});
This seems to work for me.

Javascript placing table rows between rows with greater and smaller ID

I'm building a system which outputs a list of cars on a screen(in a table element). The page loads the updates automatically with an HTTP call to the server.
Every car has an ID, a status and some irrelevant things.
Now when the user loads the page, the cars without the statuses 'maintenance' and 'wrecked' are shown and every five seconds new JSON data will be loaded from the server. If there comes a car out of the maintenance this one should be added to the table. The table is sorted by the car id and here comes the problem.
I have written a bit of pseudo code to clarify my problem:
if (row_with_greater_id_exits && row_with_lower_id_exists) {
place_row_between_firstRowWithGreaterId_and_FirstRowWithLowerId();
} else if (is_row_with_greater_id) {
jQuery('table#cars tbody').append(generatedHtml);
} else if (is_row_with_lower_id) {
jQuery('table#cars tbody').prepend(generatedHtml);
}
The problem is I don't know how to find the first row with a greater id or the first row with a smaller ID. The ID's are not always succeeding because some cars are wrecked and have the status wrecked.
I hope someone here has had a similar problem and can help me on my way to the solution.
Many thanks in advance!
You need to loop over the rows, and compare the ids. When your new row has and ID less than the current row in the loop, insert the new row before the current row, and break the loop.
rows.each(function(i, el) {
if (+newrow.id < +el.id) {
$(el).before(newrow);
return false;
}
})
if (!newrow.parentNode)
rows.parent().append(newrow);
This code assumes rows is a jQuery object that has a collection of all the rows, and newrow is a DOM element representing the new row.
Also assumes that the IDs are simple numbers. Note that numeric IDs are only valid in HTML5.
Personally, I'd just use the native API for this:
var tbody = document.querySelector("tbody");
tbody.insertBefore(newrow, [].reduce.call(tbody.rows, function(bef, el) {
return bef || +newrow.id > +el.id ? bef : el;
}, null));
No need to test for the isFirstLoad. When the tbody is empty, it'll still work. But you'll need a .reduce() shim for older browsers.
I have this: id="car-1" data-id="1"
I'll assume that data attribute is on the tr elements. Obviously you can adapt the following if it is on a cell within a row.
Loop through the table checking each row's id, and insert the new row immediately before the first row that has an id greater than the new one:
// assume newId is the new ID, somehow set from your JSON
var rowInserted = false;
jQuery('#invoices-outstanding tbody tr').each(function() {
var $row = $(this);
if (+$row.attr("data-id") > newId) {
$row.before(generatedHtml);
rowInserted = true;
// break out of each loop
return false;
}
});
if (!rowInserted)
jQuery('#invoices-outstanding tbody').append(generatedHtml);

jquery - filter elements based on matched values from clicked filter option and container element values

UPDATE 2:
Thanks so much for all your help. While all three solutions worked, I like Bill's in terms of readability and performance. As always, I'm amazed by the level of expertise and help here. REALLY appreciate the help.
UPDATE:
Put demo up on jsfiddle: http://jsfiddle.net/FC4QE/17/
I need to create a filter. Users click on a brand name link and if there is a match then I need to filter out the other products. The brand is contained in a product name, so I'm searching for a match and if there is one or many, I need to hide the other products.
I have the following javascipt/jquery code:
$(function(){
$('#filter-by-brand li a').click(function(){
// get html string of clicked item
var brandNameSelected = $(this).html();
var productContainer = $('#product-collection div.productBoxWrapper');
// reset products in the view
if (brandNameSelected == 'All Brands'){
productContainer.fadeIn("slow");
}
// for each product title (a tag)
$("#product-collection h4 a").each(function(){
var productTitle = jQuery(this).html();
// if item clicked is contained inside product title, hide all
// products and only show the ones where the title matched
if(productTitle.indexOf(brandNameSelected) != -1){
// hide container of all products, this hides all products
productContainer.fadeOut("slow");
// then show only ones that match. the problem is that only the one product is
// displayed since we're inside the .each. How can I show all products where product title contains the item clicked?
$(this).parent().parent().parent().parent().fadeIn("slow");
}
});
});
});
I explained everything in the comments inside the code, but basically, while the code works, because I'm showing the products where item clicked is contained inside the .each method, it only shows the last item matched. How can I show all the matched ones inside the .each or is this impossible and is there another way?
Hope this makes sense and that someone might have some advice!
Thanks.
I got the nicest looking results from this:
$('#filter-by-brand li a').click(function()
{
var brandNameSelected = $(this).html();
var productContainer = $('#product-collection .product-container');
if (brandNameSelected == 'All Brands')
{
productContainer.fadeIn("slow");
}
else {
$(".product-container")
.fadeOut(100)
.delay(100)
.filter(function() {
return $(this).html().indexOf(brandNameSelected) > -1;
})
.each(function(index, item) {
$(item).fadeIn("slow");
});
}
});
You can play with it at http://jsfiddle.net/tu8tc/1/;
For "all brands", bail out. For specific brand names, hide all productContainers unconditionally then selectively fadeIn those that meet the criterion.
$(function() {
$('#filter-by-brand li a').click(function() {
var brandNameSelected = $(this).html();
var productContainer = $('#product-collection .product-container');
if (brandNameSelected == 'All Brands') {
productContainer.fadeIn("slow");
return;
}
productContainer.hide();
$("#product-collection h4 a").each(function() {
var productTitle = $(this).html();
if(productTitle.indexOf(brandNameSelected) != -1) {
$(this).closest(".product-container").stop().fadeIn("slow");
}
});
});
});
See update of your fiddle
Note how jQuery's .closest() avoids the ugly .parent().parent().parent().
.stop() is precautionary, just in case a fadeout() is already running on the element. Not necessary if this is the only code that animates productContainers.
EDIT...
Or to be concise and more efficient, with judicious use of jQuery's .filter you can do almost everything in one statement (though readability suffers):
$(function() {
$('#filter-by-brand li a').click(function() {
var brandNameSelected = $(this).html();
$('#product-collection').find('.product-container').hide().end().find('h4 a').filter(function() {
return (brandNameSelected == 'All Brands') || ($(this).html().indexOf(brandNameSelected) != -1);
}).closest(".product-container").stop().fadeIn("slow");
});
});
See further update to fiddle
Why not simply hide products that you want filtered out?
if(productTitle.indexOf(brandNameSelected) == -1)
{
$(this).parent().parent().parent().fadeOut("slow");
}
See http://jsfiddle.net/2Sduq/1/ .

Jquery Isotope Checkbox filtering

I'm using jQuery isotope. Everything is ok but I have problem with filtering. I want to use multiple categories I have 5 checkboxes and I can't use them at the same time. What can I do?
$("#classic").click(function() {
if($("#classic").is(":checked")) {
$('#box').isotope({ filter: '.classic' });
} else {
$('#box').isotope({ filter: '' });
}
});
Example
my items = a,b,c,d,e,f,g,h
categories = x ( a,b,e) y (c,h) z(d,f,g)
now if I choose the x and z checkbox it only show the a,b,e,d,f,g
but I can't do that. How can I do ?
Here is a solution for checkbox filtering:
http://jsfiddle.net/3nY9V/6/
Looks like you have a js error in the code(missing single quote) and also at one place classic is used as an id and at another place as a class. Just wanted to find if thats not the issue. Try this.
function checkIsoTope(){
var ids = [];
$("#classic, #den, #wer").filter(":checked").each(function(){
ids.push("." + this.id);
});
$('#box').isotope({ filter: ids.join(',')});
}
$("#classic, #den, #wer, #allCheckboxId").click(checkIsoTope);

Categories

Resources