I'm going to apply a letter-based navigation to filter the content of a table and a list. When clicking one of the letters, filters the list/table to show only the items in the list/table that start with that letter.
But the problem i'm facing is "All List". I need to display "all" link as well, Can any one please help me to add "All" link..
$(function () {
var _alphabets = $('.alphabet > a');
var _contentRows = $('#countries-table tbody tr');
_alphabets.click(function () {
var _letter = $(this), _text = $(this).text(), _count = 0;
_alphabets.removeClass("active");
_letter.addClass("active");
_contentRows.hide();
_contentRows.each(function (i) {
var _cellText = $(this).children('td').eq(0).text();
if (RegExp('^' + _text).test(_cellText)) {
_count += 1;
$(this).fadeIn(400);
}
});
});
});
Here is the Demo link...
Thanks...
Apply the Regex only when the text is not equal to All
$(function () {
var _alphabets = $('.alphabet > a');
var _contentRows = $('#countries-table tbody tr');
_alphabets.click(function () {
var _letter = $(this),
_text = $(this).text(),
_count = 0;
_alphabets.removeClass("active");
_letter.addClass("active");
_contentRows.hide();
_contentRows.each(function (i) {
var _cellText = $(this).children('td').eq(0).text();
if (_text === 'All') {
_count += 1;
$(this).fadeIn(400);
} else {
if (RegExp('^' + _text).test(_cellText)) {
_count += 1;
$(this).fadeIn(400);
}
}
});
});
});
Check Fiddle
Just show all tr onclick()
$('a').first().click(function(){
$('#countries-table tbody tr').fadeIn(400);
});
link to jsfiddle
[updated]
an easy one
Just add this line :
if(_text == 'All') _text = '.';
DEMO
Edit :
according to your wish, this code allows you to fade the letters that don't have words:
_alphabets.not(':first').css('opacity','0.5');
_contentRows.each(function(){
var beg = $(this).children('td:first').text().trim()[0];
$('.alphabet a:eq('+(beg.charCodeAt(0)-64)+')').css('opacity','1.0');
});
DEMO
Explanation: what I did here is getting the first letter of each first td in all trs then convert it to ascii (A=65 ..) then deduct 64 so that the first index starts from 1 (A) and so on (since index 0 is for "All")
Note: you don't have to use regex at all since you are just comparing the first characters, you can increase the efficiency by eleminating the regex .
Related
I have a form with few fields which does a small calculation. Once all the dropdowns are populated and clicked on Add Button It will display time for specific task. Likewise If you do the calculation couple of times the data will display in the table. and all values in time column will sum add together and display in another row. I have already implemented that. But it keeps adding to the existing value each time.
Refer to the image:
JS Fiddle
$(document).ready(function () {
$('#calculate').click(function () {
let tr = $("<tr/>").appendTo("#data tbody");
$('#calc input, #calc select').each( function (index) {
var input = $(this);
$(tr).append('<td class=row-'+ $(input).attr("id") + '>' + $(input).val() + '</td>');
});
const componentFactor = $(tr).children(".row-component").text();
const units = $(tr).children(".row-units").text();
const total = componentFactor*units;
$(tr).append('<td>' + total + '</td>');
$("#calc")[0].reset();
$("#total").html(sumColumn(5));
function sumColumn(index) {
var total = 0;
$("td:nth-child(" + index + ")").each(function() {
total += parseInt($(this).text(), 10) || 0;
});
return total;
}
});
});
The problem is that you are including the total line in your sum function. The .each correctly hits every TD element at the right index, but it is also including the first line.
If you modify your sum function like so, it works.
function sumColumn(index) {
var total = 0;
$("td:nth-child(" + index + ")").each(function() {
if(this.id !== 'total') {
total += parseInt($(this).text(), 10) || 0;
}
});
return total;
}
Same conclusion, you are adding total in your code; you can also use the following option:
function sumColumn(index) {
var total = 0;
$("tr> td:nth-child(" + index + ")").not(':first').each(function(i,item) {
total += parseInt($(this).text(), 10) || 0;
});
return total;
}
You can see it working here: JSFiddle demo
I know little about javascript. From what I can see, this shows a set of rows that contain a value (in this case, the author of a WP plugin).
What I'd like to do, instead of finding the data-name value in the row, is find if the first letter of this value is "A". And hopefully I should be able to work on the preceding code to get to this part... :)
Thanks so much.
<script>
var authors = [];
$('.pba-id').each(function () {
var author = $(this).attr('data-author');
if (-1 == $.inArray(author, authors))
authors.push(author);
});
$.each(authors, function (i, author) {
$select.append($('<option>').html(author));
});
$select.change(function(){
var value = $(this).val();
if ('__pba_none' == value) {
$('#the-list tr').show();
return;
}
$('#the-list tr').each(function(){
var $row = $(this);
if ($row.find('.pba-id[data-author="' + value + '"]').length)
$row.show();
else
$row.hide();
});
</script>
Use Attribute Starts With Selector [name^=”value”] selector.
Selects elements that have the specified attribute with a value beginning exactly with a given string.
$('#the-list tr').each(function() {
var value = "A";
var $row = $(this);
if ($row.find('.pba-id[data-name^="' + value + '"]').length) {
//---------------------------^^^
$row.show();
} else {
$row.hide();
}
});
Try this :
$('#the-list tr').each(function() {
// var value = "any value" ;
var $row = $(this);
if ($row.find('.pba-id[data-name^="' + value[0] + '"]').length) {
$row.show();
} else {
$row.hide();
}
});
I am trying to implement a search functionality in to an table. some thing went wrong here, put the search(filter) only considers the last column of the table.
any one help me to find out the issue please?
here is the live :
jsFiddle
my js:
var table = $('table');
$('#search').keyup(function () {
var tdText = table.find('tbody tr').find('td');
var text = $.trim($(this).val());
if(!text){
table.find('tbody tr').show();
};
tdText.filter(function() {
var reText = $(this).text();
if (reText.indexOf(text) >= 0) {
$(this).parent('tr').show();
}
else if (reText.indexOf(text) < 0) {
$(this).parent('tr').hide();
}
});
});
because when you iterating through each td, you are hiding the tr if the text is not matching so when you are iterating the last td you are hiding the row if the text is not matched
var table = $('table');
$('#search').keyup(function () {
var tdText = table.find('tbody tr').find('td');
var text = $.trim($(this).val());
if(!text){
table.find('tbody tr').show();
}else{
table.find('tbody tr').hide();
tdText.filter(function() {
var reText = $(this).text();
return reText.indexOf(text) >= 0;
}).parent().show();
}
});
Demo: Fiddle
I think you can simplify it to
var table = $('table'), $trs = table.find('tbody tr');
$('#search').keyup(function () {
var tdText = table.find('tbody tr').find('td');
var text = $.trim($(this).val());
if(!text){
$trs.show();
}else{
$trs.hide().has('td:contains('+text+')').show();
}
});
Demo: Fiddle
var tdText = table.find('tbody tr').find('td');
Will find multiple td's. This line loops through the elements and replaces tdText with the next column till last is reached.
Solution is to loop yourself
var tablecells = $('table tbody tr').find('td');
var rowText = "";
$(tablecells).each(function() {
rowText = rowText + trim($(this).val());
});
You are going through all td of all tr, but for each td you show or hide the parent row based on the search result for that td – so naturally only the result for the last td checked is what “survives” in the end for each row.
First of all, you need to split your loop, that goes over all td of all tr in one go, into two nested loops – one over the tr, and inside that one over all td of that row.
And then you should set a flag to determine whether something was found in any of the td in the row – and then at the end, you show or hide the row based on that flag.
var table = $('table');
$('#search').keyup(function () {
var text = $.trim($(this).val());
if(!text){
table.find('tbody tr').show();
}
else {
var rows = table.find('tbody tr');
rows.each(function() {
var cells = $(this).find('td'),
found = false;
cells.each(function(j, cell) {
if($(this).text().indexOf(text) >= 0) {
found = true;
}
});
if(found) {
$(this).show(); // this is here the row again
}
else {
$(this).hide();
}
});
}
});
Untested – but something along these lines should work.
Notice that I replaced .filter by .each here – your use of the former made little sense, since you where not actually doing any filtering here (that would have required that your callback function returned true or false for each element).
I want after remove one of the rows (Ex: Row 2) in html code changed to in name element by jQuery.
For example we first have in html as:
Row 1: name="check[0][]"
Row 2(removed): name="check[1][]"
Row 3: name="check[2][]"
Row 4: name="check[3][]"
Now if we remove the second row, In fact, after removed the row 2, we have rows like this:
Row 1: name="check[0][]"
Row 3: name="check[2][]"
Row 4: name="check[3][]"
But i want it in result (after remove one of rows ex: row 2) as:
Row 1: name="check[0][]"
Row 3: name="check[1][]"
Row 4: name="check[2][]"
I tried as (see my full code) but Don't work: http://jsfiddle.net/k3wne/
Js:
$('.remove_input').live('click', function (e) {
e.preventDefault();
var remove = $(this).closest($class);
remove.fadeOut('slow', function () {
$('.add_units').each(function (idx, val) {
var num = $('.add_units').length;
NumIdx = (num - (num - idx));
//for(var i = 0; i < num-1; i++){
$(this).closest($class_guide).next($class_guide).each(function (idx, val) {
$('.add_units input[type="checkbox"]').attr('name', function (idx, str) {
var int = parseInt(str.match(/\d+/)[0], 10);
return str.replace(int, NumIdx);
})
});
//}
})
});)
}
Here
DEMO
$('.remove_input').live('click', function (e) {
e.preventDefault();
var remove = $(this).closest('.RowCheck');
remove.fadeOut('slow', function () {
$(this).remove(); // or change next line to $('.RowCheck:visible')
$('.RowCheck').each(function (idx) {
var checkBoxes = $('input[type="checkbox"]',this);
checkBoxes.each(function(i) {
var str = $(this).attr('name');
var currentIdx = parseInt(str.match(/\d+/)[0], 10);
$(this).attr('name', str.replace(currentIdx,idx));
})
});
});
});
This code will work if you either
remove the row for real - also suggested by Explosion Pills or
test for visible like Simon did
http://jsfiddle.net/k3wne/1/
A couple of things: You never actually remove the element once it's faded out which screws up your counts, and the last selector (.RowCheck input[type="checkbox"]) affects all checkboxes so they will all have the highest number.
In my changes, only the current row in the iteration is affected.
Most of you code is correct, however the some changes needed:
change to use $('.RowCheck:visible').each()
as fadeOut is just hide that row but not really delete, and the inner loop should use $('input[type="checkbox"]', this)
Code looks something like following:
$('.remove_input').live('click', function (e) {
e.preventDefault();
var remove = $(this).closest('.RowCheck');
remove.fadeOut('slow', function () {
debugger;
$('.RowCheck:visible').each(function (idx, val) {
var num = $('.RowCheck:visible').length;
NumIdx = (num - (num - idx));
//for(var i = 0; i < num-1; i++){
//$(this).closest('.RowCheck').next().each(function (idx, val) {
$('input[type="checkbox"]', this).attr('name', function (idx, str) {
var int = parseInt(str.match(/\d+/)[0], 10);
return str.replace(int, NumIdx);
})
//});
//}
});
});
});
DEMO
<ul id="myid">
<li>microsoft</li>
<li>microsoft</li>
<li>apple</li>
<li>apple</li>
</ul>
I want to remove duplicates from li by using jquery.
How can I do that?
example
I find that the script is faster
var liText = '', liList = $('#myid li'), listForRemove = [];
$(liList).each(function () {
var text = $(this).text();
if (liText.indexOf('|'+ text + '|') == -1)
liText += '|'+ text + '|';
else
listForRemove.push($(this));
});
$(listForRemove).each(function () { $(this).remove(); });
uniqueLi = {};
$("#myid li").each(function () {
var thisVal = $(this).text();
if ( !(thisVal in uniqueLi) ) {
uniqueLi[thisVal] = "";
} else {
$(this).remove();
}
})
This build an index (an object) of unique values. For your example, uniqueLi will look like this afterwards:
{
"microsoft": "",
"apple": ""
}
So whenever a value is encountered that has been added to the index before, the associated <li> gets removed.
You could use
var inner = [];
$('li').each( function(index, Element){
if (jQuery.inArray(this.innerHTML, inner) == -1){
inner.push(this.innerHTML);
}
else {
$(this).remove();
}
});
Here's a function that will do it, a slightly different way:
function removeDuplicateItems(id) {
var ul = $('#' + id);
$('li', ul).each(function() {
if($('li:contains("' + $(this).text() + '")', ul).length > 1)
$(this).remove();
});
}
Call with removeDuplicateItems('myid');
I have used #Thariama solution in the past, but I have compatibility problems with IE6 (I still needs to support this dinosaur).
If the item repeats, so remove it from ul. It works with dynamic added li.
var seen = {};
$("ul#emails_exclusion_list").find("li").each(function(index, html_obj) {
txt = $(this).text().toLowerCase();
if(seen[txt]) {
$(this).remove();
} else {
seen[txt] = true;
}
});