I'm trying to implement a quick search/filter function to my table using jquery. In essence I want to hide all the rows that don't have the string I'm looking for from a searchbox to be hidden.
I have a dynamically created table and a text field used as the filter for the list.
Table:
<table id="report-table" class="table">
<thead>
<tr>
<th class="">client</th>
<th class="">coach</th>
<th class="">groups</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name">John</td>
<td class="coach">Peter </td>
<td class="groups"> Skiers </td>
</tr>
</tbody>
Ihave a function tied to the change event of the search text box. In this function I essentially want to choose all tr that do not contain the text string in name or coach column and add a class to them. I have tried many things but have not gotten the syntax right, how should it be written?
hideSearch: function(e){
console.log("hideSearch called");
var searchValue = this.$el.find('.search-text').val();
if(!searchValue ){
console.log("hideSearch: empty search param");
this.$el.find('tr').removeClass('hidden');
}
else{
console.log("hideSearch: searched for: " + searchValue);
//$('(#name, #groups):contains:not("'+searchValue+'")').parent().addClass('hidden');
var selection =$('#name, #groups').('*:contains("'+searchValue+'")');
console.log(selection);
//console.log($('#name, #groups').('*:contains("'+searchValue+'")'));
//$('(#name, #groups):contains("'+searchValue+'")').parent().addClass('hidden');
//$('#name, #groups').('*:contains:not("'+searchValue+'")').parent().addClass('hidden');
}
$('#name, #groups').('*:contains("'+searchValue+'")'); would basically try to access the property *:contains("foo") (assuming searchValue is "foo") of the object returned by $('#name, #groups'). I believe I don't have to say that jQuery objects don't have properties with such strange names.
First of all you have to give all the cells a common class instead of an ID. Then you should select all rows and see if either .name or .coach contain the search value. Use .filter to get those for which neither cell matches:
$('#report-table > tbody > tr').filter(function() {
return $(this).children('.name').text().indexOf(searchValue) === -1 &&
$(this).children('.coach').text().indexOf(searchValue) === -1;
}).addClass('hidden');
The filter callback returns true if neither the .name cell nor the .coach cell contain the search value. Those rows for which the callback returns true are kept in the selection and are getting the class hidden added to them.
Related
I am trying to delete a row in html via jquery or javascript. I'm reading from a directory, but if there's no information within a row, I don't want it to be visible. Let's just assume I have two rows, and a user within the directory doesn't have a mobile number, how to remove it for them?
I have genuinely tried so many things but I must be missing something.
<tr>
<td>email: %%email%%</td>
</tr>
<tr>
<td>mobile: %%MobileNumber%%</td>
</tr>
I would assume the row would delete just for the user without a mobile number.
You need to set the text as a variable, then find the substring after the ":" which will return the %%MobileNumber%%.
If the substring is empty, then we hide it.
As you can see the third td does not have the required text, so it is hidden.
$(function() {
$('td').each(function() {
var str = $(this).text();
var sub = str.substring(
str.indexOf(':', 1) + 1
);
if (sub == '') {
// or .remove()
$(this).hide();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>email: %%email%%</td>
</tr>
<tr>
<td>mobile: %%MobileNumber%%</td>
</tr>
<tr>
<td>mobile:</td>
</tr>
</tbody>
</table>
And if you only want it for the td containing "mobile:"
// find if a td starts with "mobile:" and if the substring after is empty
if ( str.match("^mobile:") && sub == '' ) {
$(this).hide();
}
Add a id to the row you want to hide, put the mobile: outside <td> then use JQuery to achieve the same
<tr id="hideIfNoData">
mobile:<td> %%MobileNumber%%</td>
</tr>
$('#hideIfNoData > tr td:empty').parent().hide()
I have dynamic table that has table cell with checkbox field. This fields are populated from DB so my table is dynamic. I would like to loop through checkboxes based on their class name. In that loop I want to check value for each check box. For example if value is equal 1 I want checkbox to be checked, if not unchecked. Alo I'm not sure if possible but I would like to set unique ID for each of these check boxes. Since my table is dynamic my fields need to have unique ID's. Here is example of my code:
<table>
<thead>
<tr>
<th>#</th>
<th>Time Slots</th>
<th>Block</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>~(SLOT_LABEL)</td>
<td>
<span>
<input type="checkbox" name="CF-[Events]" class="block" id="block_"+Value that will make this ID unique. value="~(SLOT_ID)"/>
</span>
</td>
</tr>
</tbody>
</table>
Also in current language that I work with to read values from DB I have to use NAME tag. If anyone can help please let me know. Thank you.
You can use the attribute selector to retrieve elements by both their name and value. Try this:
$('input[name="CF-[Events]"][value="1"]').prop("checked", true);
Working example
If you don't want a jQuery solution, it is also possible to fetch these elements with the querySelector:
var inputs = document.querySelectorAll("input.block");
for(var i = 0; i < inputs.length; i++) {
inputs[i].checked = true;
}
you can do it in jquery by each loop
$('.ClassName').each(function(i, o) {
// o is object in your case checkbox
// i is index
// your code
});
$("input[name='CF-[Events]']").each(function() {
if($(this).val() === "1")
{
$(this).prop("checked", true);
}
});
I am trying to create a prepopulated form that pulls values from any selected row in a HTML table . The HTML page is populated by a JSP .
my table looks like this
<table id="data-table" id="test">
<thead>
<tr>
<th>value1</th>
<th>value2</th>
<th>value3</th>
<th>value4</th>
</tr>
</thead>
<tbody>
<tr>
<td id="class1"><%= value.valueOne() %></td>
<td id="class2"><%= value.valueTwo() %></td>
<td id="class3"><%= value.valueThree() %></td>
<td id="class4"><%= value.valueFour() %></td>
</tr>
<%
}
%>
</tbody>
</table>
I want to obtain a prepopulated form with the row values on click of a particular row . I have some js code that does this .
$(document).on("click", ".data-table .class1", function(e) {
var value = $(this).closest('tr').val();
console.log(value);
// Just to check if I get the correct value
});
unfortunately I cannot understand how to get the values for that particular row from the DOM and populate it in a form , That I want to overlay over the table . I would appreciate any pointers . I really would have written more code but I dnt know Jquery and am stuck
Your general strategy should be this:
Populate the table on the server side: done
Have the form pre-existing in the page, but hidden with css (display:none)
Register a click listener on all tr elements to:
find the values inside each td within the tr
select the corresponding form inputs
populate the inputs using jQuery's val(value) function.
unhide the form if it's hidden
With this in mind, I would change your click listener from document to something like this. (Note: I'm assuming value.valueOne() are just numbers or strings, and don't contain any html.
//target just TR elements
$('tr').click(function(){
values = [];
$(this).children().each(function(){
//add contents to the value array.
values.push($(this).html())
});
//fill in the form values
populateForm(values);
});
Populate form would completely depend on your form's HTML, but to get you started here's an idea of what it might look like:
function populateForm(values){
//set the value of the input with id of name to the value in the first td.
$('#name').val(values[0]);
//show the form (id inputForm) now that it's populated
$('#inputForm').show();
}
A couple things are wrong with your html markup and your JQuery selector. You'll never be able to execute the code you've provided...
You have two 'id' parameters in this element, <table id="data-table" id="test">... This will work with the JQuery I've fixed below, but it's malformed html either way.
In your selector, you are using the syntax for finding an element based on it's css class attribute, however your elements in your HTML have those values set as 'id' attributes. Thus, this, $(document).on("click", ".data-table .class1", function(e) {... should be written as follows, $(document).on("click", "#data-table #class1", function(e) {
Now, if you are attempting to get the values within all of the 'td' elements within a row, then all you really need to do is get the parent element of the 'td' that was clicked, and then get it's children. Then, for each child, get their values.
Like this...
$(document).on("click", "#data-table #class1", function(e) {
var elements = $(this).parent().children();
$.each(elements, function(index, el){
alert($(el).html());
});
});
I've saved a JSFiddle for you to see this in action... http://jsfiddle.net/2LjQM/
val() is used to return value of form inputs. You are using it to try to get the value of a row and row has no value.
Without seeing what your output into the TD as html, I assume it is a form control
Try
$(document).on("click", ".data-table .class1", function(e) {
var value = $(this).find(':input').val(); // `:input pseudo selector wull access any form control input,select,textarea
console.log(value);
// Just to check if I get the correct value
});
EDIT: if the TD contains text
var value = $(this).text();
Instead of scraping the DOM, you could invert the logic, and build the rows using javascript instead. Check out this jsBin to see the solution in action: http://jsbin.com/aligaZi/2/edit?js,output
Start with an empty table:
<table class="data-table" id="test">
<thead>
<tr>
<th>value1</th>
<th>value2</th>
<th>value3</th>
<th>value4</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Since you need to fill a form with the data, I'll be using a simple one as an example:
<form class="data-form">
<label>Value1<input class="value1" /></label>
<label>Value2<input class="value2" /></label>
<label>Value3<input class="value3" /></label>
<label>Value4<input class="value4" /></label>
</form>
Then, on the javascript side:
$(function() {
// Interpolate the values somehow.
// I'm not familiar with JSP syntax, but it shouldn't be too hard.
// I will use dummy data instead.
var tableData = [
{
value1: "row1-v1",
value2: "row1-v2",
value3: "row1-v3",
value4: "row1-v4"
}, {
value1: "row2-v1",
value2: "row2-v2",
value3: "row2-v3",
value4: "row2-v4"
}
];
// For each object, create an HTML row
var rows = $.map(tableData, function(rowData) {
var row = $("<tr></tr>");
row.append($('<td class="class1"></td>').html(rowData.value1));
row.append($('<td class="class2"></td>').html(rowData.value2));
row.append($('<td class="class3"></td>').html(rowData.value3));
row.append($('<td class="class4"></td>').html(rowData.value4));
// When this row is clicked, the form must be filled with this object's data
row.on("click", function() {
fillForm(rowData);
});
return row;
});
$(".data-table").append(rows);
function fillForm(rowData) {
var form = $(".data-form");
form.find("input.value1").val(rowData.value1);
form.find("input.value2").val(rowData.value2);
form.find("input.value3").val(rowData.value3);
form.find("input.value4").val(rowData.value4);
}
});
I am attempting to take a generated table and create an object out of it using jquery. I have looked up examples but am getting some odd behavior when I try to implement. Given this simplified version of my table (generated via Spring MVC):
<table id="notices">
<thead>
<tr>
<td class="columnheader">Order</td>
<td class="columnheader" style="display: none;">ID</td>
<td class="columnheader">Title</td>
</tr>
</thead>
<tbody>
<tr>
<td class="formlabel"><input class="fields" size="2" type="text" value="3"></td>
<td class="formlabel" style="display: none;">JP-L2913666442781178567X</td>
<td class="formlabel">*Notice1</td>
</tr>
<tr>
<td class="formlabel"><input class="fields" size="2" type="text" value="2"></td>
<td class="formlabel" style="display: none;">JP-L2913666442760937100X</td>
<td class="formlabel">Quiz Notice - Formative</td>
</tr>
</tbody>
</table>
And snippet of my current script:
var noticeMap = $('#notices tbody tr').map(function() {
var $row = $(this);
return {
sequence: $row.find(':nth-child(1)').text(),
noticeUID: $row.find(':nth-child(2)').text()
};
});
When I de[fire]bug, noticeMap looks like this:
Object { sequence="*Notice1", noticeUID="JP-L2913666442781178567X"},
Object { sequence="Quiz Notice - Formative", noticeUID="JP-L2913666442760937100X"}
Somehow :nth-child(1) is retrieving the title, the third td. I believe it has to do with retrieving the value of the input, but am not sure where to go from here. Maybe because the input field is within the td child I am specifying, it is not considered a direct descendant, so the proper text is not retrieved? Just seems odd to me that it would then skip to the 3rd td. Alas, I am still learning with jquery, and humbly request any ideas and guidance.
Thanks!
You're right about the input being the issue, you have to get the value of the input inside then td, which is not defined as a text node, but as its own element, therefore you have to specify the child element within the jQuery selector. Also .text() won't work for input elements, you can read its value with .val().
This will work for you to get the right value into your object:
$row.find(':nth-child(1) input').val();
Or using .eq()
var noticeMap = $('#notices tbody tr').map(function() {
var $cells = $(this).children();
return {
sequence: $cells.eq(0).children('input').val(),
noticeUID: $cells.eq(1).text()
};
});
Or into a single object with key/value pairs:
var noticeMap = {};
$('#notices tbody tr').each(function() {
var $cells = $(this).children();
noticeMap[$cells.eq(0).children('input').val()] = $cells.eq(1).text();
});
I'm not too sure tho why your original attempt returns the text inside the 3rd td. That is really odd. I'll have a tinker with it.
Edit
It seems to me that .find() is somehow being smart about what it returns, it seems to realise that calling .text() does not return anything on the first match it finds (the first td), it therefore travels down the DOM to find the next element which does have a :first-child, which matches the a tag inside the 3rd td, then it returns the text of that a tag. When I removed the a around the title, .find() started returning "" again, I think that is because it couldn't find another match after the first one didn't return anything useful.
Using .children() would be safer in this case, as it only finds direct descendants and doesn't travel down the DOM.
For better performance, use .eq() on the matched set:
var noticeMap = $('#notices tbody tr').map(function() {
var $cells = $(this).children();
return {
sequence: $cells.eq(0).find('input').val(),
noticeUID: $cells.eq(1).text()
};
});
I´m new in JQuery and I have a trouble. I want to read a specific cell value from a table row where I have a checkbox. I have an event that handles the checkbox checked event. This is my code:
$("#businesses input:checkbox").change(function (
var $this = $(this);
if ($this.is(":checked")) {
//Here I want to read a value from a column in a row where is the checkbox
} else {
//Here I want to read a value from a column in a row where is the checkbox
}
});
I have a table called "businesses" and it has this format
<table id="businesses">
<tr>
<th>Select Value</th>
<th>Value</th>
</tr>
<tr>
<td><input type="checkbox" class="selectedService" title="Seleccionar" /></td>
<td>125</td>
</tr>
<tr>
<td><input type="checkbox" class="selectedService" title="Seleccionar" /></td>
<td>126</td>
</tr>
</table>
What I want to do, is that when I select a checkbox, get the value field of its row.
If I press the first checkbox I want to get 125.
Thanks!!!
Starting from your checkbox (this in the event handler function), you need to go up to the containing <td> element, across to the next <td> element, then get its text:
$('#businesses input:checkbox').change(function(e) {
if(this.checked) {
var value = parseInt($(this).closest('td').next('td').text(), 10);
// above will convert it from a string to an integer
}
else {
// same as above? Seems redundant
}
});
Use siblings() of the parent:
$this.closest('td').siblings().text();
If this is not the only other <td> siblings() would return all of the rest so use appropriate selector to filter them.
You could access it with:
$this.parent().next().text();
Try this...
$("#businesses input:checkbox").on ('change', function (e)
if ($(this).is(":checked")) {
$( e.target ).closest("td").text();
} else {
//Here I want to read a value from a column in a row where is the checkbox
}
});
Greetings.