Using array as selectors in jQuery - javascript

I am having a little trouble in jQuery.
$(document).on('change', '.filter-status, .filter-week', function() {
var filter = [];
filter.push({
week: $('.filter-week').val(),
status: $('.filter-status').val(),
})
//filter.week('week', $('.filter-week').val());
filter.status = $('.filter-status').val();
var tags = [];
//console.log(filter);
$.each(filter, function(index, value) {
if (value != 'all') {
tags.push(value);
}
});
});
I have a table row that looks as follows:
<tr>
<td>1</td>
<td>Some text...
<td>
<button class="tag" data-tag="1234"></button>
<button class="tag" data-tag="1235"></button>
</td>
</tr>
<tr>
<td>2</td>
<td>Some text...
<td>
<button class="tag" data-tag="1234"></button>
</td>
</tr>
What I am trying to do is to hide a tr that does not contain tag 1234 and 1235.
Edit
To be a bit more clear.
The tags object contains id 1234 and 1235. I want to hide all table rows that do not have both these tags. So if a table row only has 1234 it should be hidden. If it has only 1235 it should be hidden as well. If it has both 1234 and 1235 it should NOT be hidden.

The following will hide any rows that have the same values as your tags array (I have added a class to your button column).
The compare function has been taken from this question
Array.prototype.compare = function(testArr) {
if (this.length != testArr.length) return false;
for (var i = 0; i < testArr.length; i++) {
if (this[i].compare) {
if (!this[i].compare(testArr[i])) return false;
}
if (this[i] !== testArr[i]) return false;
}
return true;
}
var tags = [1234, 1235]; // example tags array
$('.button-holder').filter(function() {
// put data attributes into an array
var buttonsData = [];
$(this).find('button.tag').each(function() {
buttonsData.push(parseInt($(this).data('tag')));
});
return !tags.compare(buttonsData); // compare the arrays
}).closest('tr').hide(); // hide the row if the values are not the same
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
<td>Some text...
<td class="button-holder"> <!-- add class to button column -->
<button class="tag" data-tag="1234"></button>
<button class="tag" data-tag="1235"></button>
</td>
</tr>
<tr>
<td>2</td>
<td>Some text...
<td class="button-holder">
<button class="tag" data-tag="1234"></button>
</td>
</tr>
<tr>
<td>3</td>
<td>Some text...
<td class="button-holder">
<button class="tag" data-tag="1234"></button>
<button class="tag" data-tag="1235"></button>
<button class="tag" data-tag="1236"></button>
</td>
</tr>
</table>
If you are wanting to show all the rows that may have the tags values plus extras, you can use the following containsAll function instead of the compares function above:
Array.prototype.containsAll = function(needles){
for(var i = 0 , len = needles.length; i < len; i++){
if($.inArray(needles[i], this) == -1) return false;
}
return true;
}
var tags = [1234, 1235];
$('.button-holder').filter(function() {
var buttonsData = [];
$(this).find('button.tag').each(function() {
buttonsData.push(parseInt($(this).data('tag')));
});
return !buttonsData.containsAll(tags);
}).closest('tr').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
<td>Some text...
<td class="button-holder">
<button class="tag" data-tag="1234"></button>
<button class="tag" data-tag="1235"></button>
</td>
</tr>
<tr>
<td>2</td>
<td>Some text...
<td class="button-holder">
<button class="tag" data-tag="1234"></button>
</td>
</tr>
<tr>
<td>3</td>
<td>Some text...
<td class="button-holder">
<button class="tag" data-tag="1234"></button>
<button class="tag" data-tag="1235"></button>
<button class="tag" data-tag="1236"></button>
</td>
</tr>
</table>

You can use .filter():
$('table tr').filter(function(i, el) {
return $(el).find('button').eq(0).data('tag') != '1234' ||
$(el).find('button').eq(1).data('tag') != '1235'
}).hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
<td>Some text...</td>
<td>
<button class="tag" data-tag="1234"></button>
<button class="tag" data-tag="1235"></button>
</td>
</tr>
<tr>
<td>2</td>
<td>Some text...</td>
<td>
<button class="tag" data-tag="1234"></button>
</td>
</tr>
</table>

You can find the element and then go back with parents() to find the related <tr>:
$(':not([data-tag="1235"])').each(function() {
$(this).parents('tr').hide();
});
Edited due comments that I misunderstanding the question:
hide a tr that does not contain tag 1234 and 1235.
I missed the not when I read it

Related

JQuery/Javascript Accessing a table with checkbox and retrieve the id of one specific <td>

Trying to :
Verify if a checkbox got selected.
2.Retrieve the value.
Save a value in an array.
So my array would have the following values: [1,21,111]
What him I missing, any guidance would be appreciated.
After I've figured this out... will go and create another array to store the automationName.
var SelectedItems = [];
$('.btn1').on('click', function() {
SelectedItems.length = 0;
$('#flowtable tbody tr').each(function() {
// if ($(this).is(':checked')) {
// if ($('.scheduleMe').is(':checked')) {
if ($('td .scheduleMe').is(':checked')) {
SelectedItems.push($(this).attr("id"));
}
});
console.log('Checked #' + SelectedItems.length);
console.log("list 2= " + SelectedItems);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<h1>jQuery Crash Course</h1>
</header>
<div id="container">
<form id="form">
<table id="flowtable">
<tbody>
<tr class="selected">
<td id="1"></td>
<td class="automationName"> automation 1</td>
<td><input type="checkbox" class="scheduleMe" name="vehicle1"></td>
</tr>
<tr>
<td id="21"></td>
<td class="automationName">automation 21</td>
<td><input type="checkbox" class="scheduleMe" name="vehicle21"></td>
</tr>
<tr>
<td id="111"></td>
<td class="automationName">automation 111</td>
<td><input type="checkbox" class="scheduleMe" name="vehicle111"></td>
</tr>
</tbody>
</table>
<button type="button" class="btn1">check list box</button>
</form>
</div>
Firstly, give the checkboxes a value which is the id they relate to, not the the sibling/parent td.
From there you can simplify your logic by using map() to build an array of the selected values only once, when the button is clicked, not having to maintain additions/deletions from the higher scoped array when a change is made.
Below is a working example. Note the use of label elements to make the clickable area of the checkboxes bigger.
$('.btn1').on('click', function() {
let selectedItems = $('.scheduleMe:checked').map((i, el) => el.value).get();
console.log(selectedItems);
// work with the array as required here, eg. pass to a fnuction for processing...
});
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<header>
<h1>jQuery Crash Course</h1>
</header>
<div id="container">
<form id="form">
<table id="flowtable">
<tbody>
<tr class="selected">
<td id="1"></td>
<td class="automationName"><label for="vehicle1">automation 1</label></td>
<td><input type="checkbox" value="1" class="scheduleMe" name="vehicle1" id="vehicle1" /></td>
</tr>
<tr>
<td id="21"></td>
<td class="automationName"><label for="vehicle21">automation 21</label></td>
<td><input type="checkbox" value="21" class="scheduleMe" name="vehicle21" id="vehicle21" /></td>
</tr>
<tr>
<td id="111"></td>
<td class="automationName"><label for="vehicle111">automation 111</label></td>
<td><input type="checkbox" value="111" class="scheduleMe" name="vehicle111" id="vehicle111" /></td>
</tr>
</tbody>
</table>
<button type="button" class="btn1">check list box</button>
</form>
</div>
If, for whatever reason, you can't change the HTML, then you can read the value from the td in map() like this:
let selectedItems = $('.scheduleMe:checked').map((i, el) => $(el).closest('tr').find('td[id]').prop('id')).get();
callMe() is a function that is handling all logic.
I am just checking if the checkBox is checked or not by using default property of input type checkbox checked.
If it is checked then we are pushing it in array, just making sure the item is not already there by using includes(). method.
var SelectedItems = [];
const tableRows = document.querySelectorAll("#flowtable tr");
const checkBoxes = document.querySelectorAll("#flowtable tr td > input");
const btn = document.querySelectorAll("#btn1");
function callMe() {
checkBoxes.forEach(checkBox => {
if (checkBox.checked) {
const currentParent = checkBox.parentElement.parentElement;
const getId = currentParent.querySelectorAll("td[id]")[0];
const val = getId.id;
if (SelectedItems.includes(val)) return;
SelectedItems.push(val);
}
})
if (SelectedItems === undefined || SelectedItems.length == 0) {
// array does not exist or is empty
console.log("No checkbox is checked.");
} else {
console.log(SelectedItems);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<h1>jQuery Crash Course</h1>
</header>
<div id="container">
<form id="form">
<table id="flowtable">
<tbody>
<tr class="selected">
<td id="1"></td>
<td class="automationName"> automation 1</td>
<td><input type="checkbox" class="scheduleMe" name="vehicle1"></td>
</tr>
<tr>
<td id="21"></td>
<td class="automationName">automation 21</td>
<td><input type="checkbox" class="scheduleMe" name="vehicle21"></td>
</tr>
<tr>
<td id="111"></td>
<td class="automationName">automation 111</td>
<td><input type="checkbox" class="scheduleMe" name="vehicle111"></td>
</tr>
</tbody>
</table>
<button type="button" id="btn1" onclick="callMe();">check list box</button>
</form>
</div>

How to sort the rows of a table dynamically based on data-sort attribute in tr tag when its value changes

I have a table and I want to sort the rows by the user,Each row contains one input, for enter a row number. Here rows are sorted by data-sort Attribute in tr and each input has a rownum attribute whose value is equal to the value of the tr data-sort attribute.There are 6 rows here. We want to take the input value of each row, and move that row there, and the values of the attributes are the same as the input.For example, if you enter 1 in the input of one of the rows, that row will be our first row.
The following code runs for the first time, but after moving one of the rows does not work anymore.When its value changes. where is my mistake?
jsfiddle
$('.m').on('change', function () {
var Des = parseInt($(this).val());
var RowNum = parseInt($(this).attr('rownum'));
$('tr[data-sort="' + RowNum + '"]').attr('data-sort', -100);
$('input[rownum="' + RowNum + '"]').attr('rownum', -100);
if (Des > RowNum) {
for (var i = RowNum + 1; i <= Des; i++) {
var newVal = i - 1;
$('tr[data-sort="' + i + '"]').attr('data-sort', newVal);
$('input[rownum="' + i + '"]').attr('rownum', newVal);
}
}
if (Des < RowNum) {
for (var i = Des + 1; i <= (RowNum - 1); i++) {
var newVal = i + 1;
$('tr[data-sort="' + i + '"]').attr('data-sort', newVal);
$('input[rownum="' + i + '"]').attr('rownum', newVal);
}
}
$('tr[data-sort="-100"]').attr('data-sort', Des);
$('input[rownum="-100"]').attr('rownum', Des);
var divList = $("tr");
divList.sort(function (a, b) {
return (parseInt($(a).data("sort")) - parseInt($(b).data("sort")))
});
$("tbody").html(divList);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h4>
inter value between 1-6
</h4>
<table class="table table-hover">
<tbody>
<tr id="1" data-sort="1">
<td>One</td>
<td>
<input rownum="1" class="m" />
</td>
</tr>
<tr id="2" data-sort="2">
<td>Two</td>
<td>
<input rownum="2" class="m" />
</td>
</tr>
<tr id="3" data-sort="3">
<td>Three</td>
<td>
<input rownum="3" class="m" />
</td>
</tr>
<tr id="4" data-sort="4">
<td>Four</td>
<td>
<input rownum="4" class="m" />
</td>
</tr>
<tr id="5" data-sort="5">
<td>Five</td>
<td>
<input rownum="5" class="m" />
</td>
</tr>
<tr id="6" data-sort="6">
<td>six</td>
<td>
<input rownum="6" class="m" />
</td>
</tr>
</tbody>
</table>
</div>
as you rebuild and replace html piece of code on which you have your listener, you have to rebind event listener to the new created elements with class "m". Something as below (not elegant,only here to show a working example - and you don't need all your test. You just need to assign input value to data-sort attribut and then reorder with sort function)
$('.m').on('change', function (evt) {
changeOrder(evt);
})
function changeOrder(evt){
$this=$(evt.currentTarget);
var Des = parseInt($this.val());
var RowNum = parseInt($this.attr('rownum'));
$this.parent().parent().data("sort",Des)
var divList = $("tbody").find("tr").sort(function (a, b) {
return (parseInt($(a).data("sort")) - parseInt($(b).data("sort")))
});
$("tbody").html(divList);
$('.m').on('change', function (evt) {
changeOrder(evt);
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
<h4>
inter value between 1-6
</h4>
<table class="table table-hover">
<tbody>
<tr id="1" data-sort="1">
<td>One</td>
<td>
<input rownum="1" class="m" />
</td>
</tr>
<tr id="2" data-sort="2">
<td>Two</td>
<td>
<input rownum="2" class="m" />
</td>
</tr>
<tr id="3" data-sort="3">
<td>Three</td>
<td>
<input rownum="3" class="m" />
</td>
</tr>
<tr id="4" data-sort="4">
<td>Four</td>
<td>
<input rownum="4" class="m" />
</td>
</tr>
<tr id="5" data-sort="5">
<td>Five</td>
<td>
<input rownum="5" class="m" />
</td>
</tr>
<tr id="6" data-sort="6">
<td>six</td>
<td>
<input rownum="6" class="m" />
</td>
</tr>
</tbody>
</table>
</div>

Parsing HTML with Javascript / jQuery or PHP

<table>
<tbody>
<tr>
<td>
<span class="big">Fruits</span>
</td>
</tr>
<tr>
<td>
<span class="small">Apple</span>
</td>
</tr>
<tr>
<td>
<span class="small">Apricot</span>
</td>
</tr>
<tr>
<td>
<span class="small">Carrot</span>
</td>
</tr>
<tr>
<td>
<span class="big">Colors</span>
</td>
<tr>
<td>
<span class="small">Red</span>
</td>
</tr>
<tr>
<td>
<span class="small">Blue</span>
</td>
</tr>
</tbody>
</table>
I have more than 10k tables like this, and need to parse them like
Fruits: Apple Apricot Carrot
Colors: Red Blue
Categories have different class names and objects have different class names, but they are all in the same table.
Here's my implementation:
var items = {};
var lastItem = null;
$('.big, .small').each(function() {
var content = $(this).text();
var cls = $(this).attr('class');
if ( cls == 'big' )
{
lastItem = content;
items[lastItem] = [];
return;
}
items[lastItem].push(content);
});
console.log(items);
var items = {};
var lastItem = null;
$('.big, .small').each(function() {
var content = $(this).text();
var cls = $(this).attr('class');
if ( cls == 'big' )
{
lastItem = content;
items[lastItem] = [];
return;
}
items[lastItem].push(content);
});
console.log(items);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>
<span class="big">Fruits</span>
</td>
</tr>
<tr>
<td>
<span class="small">Apple</span>
</td>
</tr>
<tr>
<td>
<span class="small">Apricot</span>
</td>
</tr>
<tr>
<td>
<span class="small">Carrot</span>
</td>
</tr>
<tr>
<td>
<span class="big">Colors</span>
</td>
<tr>
<td>
<span class="small">Red</span>
</td>
</tr>
<tr>
<td>
<span class="small">Blue</span>
</td>
</tr>
</tbody>
</table>

Sorting tr elements alphabetically

I'm trying to sort tr but I've no luck by far.
Here is my tr structure.
<tr>
<td>
<a href="./BlueSky-TexasHealthResources/index.php" >Blue Sky-Texas</a>
</td>
<td>
View Data
</td>
<td id="blue_sky_texas">
</td>
</tr>
<tr>
<td id = 'bj'>
<a href="./BountyJobs/index.php" >Bounty Jobs</a>
</td>
<td>
View Data
</td>
</tr>
Here is Javascript that I've tried by far.
<script type="text/javascript">
var $tr = $("tr");
$(document).ready(function () {
var alphabeticallyOrderedTr = $tr.sort(function (a, b) {
return $(a).find("a:first").text().toLowerCase().localeCompare($(b).find("a:first").text().toLowerCase());
});
$("#container").html(alphabeticallyOrderedTr);
});
</script>
And below is the image for table (unsorted using above code :( ).
.sort() is Array.prototyope method, not jQuery method. Try adding .get() or .toArray() before .sort(function(){}) called ; e.g., $tr.get().sort(
$(document).ready(function() {
var $tr = $("tr");
var alphabeticallyOrderedTr = $tr.get().sort(function(a, b) {
return $(a).find("a:first").text().toLowerCase().localeCompare($(b).find("a:first").text().toLowerCase());
});
$("#container").append(alphabeticallyOrderedTr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table id="container">
<tr>
<td>
<a>Y Jobs</a>
</td>
</tr>
<tr>
<td>
<a>Z Jobs</a>
</td>
</tr>
<tr>
<td id='bj'>
Bounty Jobs
</td>
<td>
View Data
</td>
</tr>
<tr>
<td>
<a>X Jobs</a>
</td>
</tr>
<tr>
<td>
Blue Sky-Texas
</td>
<td>
View Data
</td>
<td id="blue_sky_texas">
</td>
</tr>
</table>

Manipulating rows and columns in HTML table with multi-row cells

I have an html table with cells that span multiple rows:
<table border="1" style=""><tbody id="x">
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td rowspan="3">**</td>
<td>AAAA</td>
<td> </td>
</tr>
<tr id="row2">
<td>BBBB</td>
<td> </td>
</tr>
<tr>
<td>CCCC</td>
<td> </td>
</tr>
<tr>
<td style=""> </td>
<td id="ee">EEEE</td>
<td> </td>
</tr>
<tr>
<td style=""> </td>
<td id="dd">DDDD</td>
<td> </td>
</tr>
</tbody></table>
<script type="text/javascript">
alert ("index of dd before delete =" + document.getElementById("dd").cellIndex);
document.getElementById("row2").style.display="none";
alert ("index of dd after delete =" + document.getElementById("dd").cellIndex);
</script>
I am trying to manipulate it in Javascript, eg hide row2.
When I do that, the multi-row cell containing "**" moves down, shifting all the cells in row 3 by 1 to the right. Evidently I have to reduce its rowSpan.
But it seems when I am looking at row 1, I have no way of knowing that there is a multi-row cell intersecting this row - it seems I have to scan all the rows above row2 for multi-row cells.
Is there a better/quicker way to find out what multi-row cells affect the hiding (or deleting) operation?
Try this using javascript... It is working properly.
Change the value of currRowToDelete for Range [1 to 6].
Refer for working code: http://jsfiddle.net/arunkumrsingh/cdS2D/1/
<table id="tbl" border="1" runat="server" >
<tr id="row1">
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr id="row2">
<td rowspan="3">**</td>
<td>AAAA</td>
<td> </td>
</tr>
<tr id="row3">
<td>BBBB</td>
<td> </td>
</tr>
<tr id="row4">
<td>CCCC</td>
<td> </td>
</tr>
<tr id="row5">
<td style=""> </td>
<td id="ee">EEEE</td>
<td> </td>
</tr>
<tr id="row6">
<td style=""> </td>
<td id="dd">DDDD</td>
<td> </td>
</tr>
</table>
<script type="text/javascript">
var trs = document.getElementById("tbl").getElementsByTagName("tr");
var tds;
var bDeleted = false;
var currRowToDelete = 3;
for(var i=0;i<currRowToDelete;i++)
{
tds = trs[i].getElementsByTagName('td');
for(var j=0;j<tds.length;j++)
{
var currRowSpan = tds[j].rowSpan;
if(currRowSpan > 1)
{
if(eval(i + 1) == currRowToDelete)
{
var cell = document.createElement("td");
cell.innerHTML = tds[j].innerHTML;
trs[i + 1].insertBefore(cell, trs[i + 1].getElementsByTagName('td')[0]);
document.getElementById("tbl").deleteRow(i);
bDeleted = true;
document.getElementById("tbl").rows[i].cells[0].rowSpan = eval(currRowSpan -1);
}
else
{
if(eval(currRowSpan + i) >= currRowToDelete)
document.getElementById("tbl").rows[i].cells[0].rowSpan = eval(currRowSpan -1);
}
}
}
}
if(bDeleted == false)
document.getElementById("tbl").deleteRow(currRowToDelete -1);
</script>
I have a solution, in which you don't have to calculate the Rowspan and Colspan.
Step 1: Get the content of HTML (As mentioned above) and save as EXCEL file.
Step 2: Delete the particular Row (ie Row 2).
Step 3: Save as HTML file and Read the HTML content.
You will get the HTML in correct format.

Categories