Javascript find select element in a table cell - javascript

I got a table column with selects and text value cells like this:
<tr>
<td data-key="data1">some text data</td>
</tr>
<tr>
<td data-key="data2">
<select>
<option>1_option</option>
<option>2_option</option>
</select>
</td>
</tr>
I need to grab the data depending on the type of data in the cell. I do it like this:
var obj = $('#myTable tbody tr').map(function() {
var $row = $(this);
var localobj = {};
var cell = $row.find(':nth-child(1)');
dataattr = cell[0].getAttribute('data-key');
var selectObject = cell.find("select");
console.log(selectObject);
if(selectObject){ // always true here, but I need false if there is no select in the cell
localobj[dataattr] = selectObject.val();
}else{
localobj[dataattr] = cell.text();
}
return localobj;
}).get();
It grabs selected values correctly but cannot get the text ones because it always returns true in my if evaluation. Any ideas how to fix it?
Thank you

jQuery wraps everything in it's own object container and therefore selectObject will always evaluate to true as it is an object that is not undefined or null.
You can simply check to make sure the object has at least 1 element via
if (selectObject.length > 0) { ... }

try like this
var tbl = $('#tblHours');
tbl.find('tr').each(function(){
$(this).find('td').each(function(){
alert($(this).find('select :selected').val());
});
});

As
As explained by #Arvind Audacious, jQuery always returns a container. You cannot assume the result of the query is NULL. Instead, you need to check its length in order to verify if it has actually retrieved any elements. See code below for example:
$('#myTable tbody tr td').each(function(){
var selectObject = $(this).find('select');
if(selectObject.length == 0) {
console.log($(this).text())
} else {
console.log(selectObject);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Checking jQuery selector object won't work, as it will be always true. Checking the length of the selector return is the best approach for this. Please check the fiddle - https://jsfiddle.net/nsjithin/r43dqqdy/1/
var obj = $('#myTable tbody tr').map(function() {
var $row = $(this);
var localobj = {};
var td = $row.find('td').first();
var dataattr = td.attr('data-key');
var select = td.find('select');
if(select.length > 0){
console.log(select);
if(select.find('option:selected').length > 0){
localobj[dataattr] = select.val();
}
else{
// If not selected. What to do here??
}
}
else{
localobj[dataattr] = td.text();
}
return localobj;
}).get();
console.log(obj);

Related

How to execute local stored value by search function afther page reload / refresh

I use the following form and script to let users filter a td table on the input they give in. It filters the rows of the table and only shows the rows corresponding to their given value. They can update the rows that they are seeing, after they do this the page refreshes/reloads to refresh the table. After the page is refreshed/reloaded the search filter shows all rows again. I am searching for a way to keep the rows that they had before the update event happend based on their filter input. In other words, as if the refresh never happend.
Search form;
...
<p align='left' style="display:inline">
<table class="userprof" align='left'>
<tr>
<td class="footer">Filter:
<input type="text" id="myInput" name="filter" style="color:black !important;" placeholder="Filter table" onkeyup='saveValue(this);' />
</td>
</tr>
</table>
</p>
...
I use the folowing script to save their input as localstorage.
...
document.getElementById("myInput").value = getSavedValue("myInput"); // set the value to this input
/* Here you can add more inputs to set value. if it's saved */
//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e) {
var id = e.id; // get the sender's id to save it .
var val = e.value; // get the value.
localStorage.setItem(id, val); // Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return ""; // You can change this to your defualt value.
}
return localStorage.getItem(v);
}
...
I use the following script to filter the table rows
...
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 0; i < rows.length; i++) {
var nameCol = rows[i].cells[1].textContent.toUpperCase();
var rankCol = rows[i].cells[2].textContent.toUpperCase();
var rankerCol = rows[i].cells[5].textContent.toUpperCase();
var typeCol = rows[i].cells[6].textContent.toUpperCase();
var emailCol = rows[i].cells[3].textContent.toUpperCase();
if (nameCol.indexOf(filter) > -1 || rankCol.indexOf(filter) > -1 || rankerCol.indexOf(filter) > -1 || typeCol.indexOf(filter) > -1 || emailCol.indexOf(filter) > -1) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document.querySelector('#myInput').addEventListener('keyup', filterTable, false);
...
You are almost there and only need minor modifications to make this happen.
I'd suggest that you change your flow up a bit.
First remove the onkeyup inline listener from your HTML. You are currently listening for that event 3 times on 1 element which seems overkill.
...
<p align='left' style="display:inline">
<table class="userprof" align='left'>
<tr>
<td class="footer">Filter:
<input type="text" id="myInput" name="filter" style="color:black !important;" placeholder="Filter table" />
</td>
</tr>
</table>
</p>
...
Then modify the filterTable to accept just a value, not an event object. This way you can call filterTable at any time and inject a value into it. And it allows you to call it immediately with the stored value when the page loads so that your initial filter will be set (or not if there is nothing stored).
Now listen for the keyup event with only a single listener which will both pass the value of the event to filterTable and the event itself to saveValue so that are both filtering and saving.
// Store the input in a variable for reference.
var myInput = document.getElementById("myInput");
var savedValue = getSavedValue("myInput");
// Immediately filter the table and set the input value.
filterTable(savedValue);
myInput.value = savedValue;
//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e) {
var id = e.id; // get the sender's id to save it .
var val = e.value; // get the value.
localStorage.setItem(id, val); // Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return ""; // You can change this to your default value.
}
return localStorage.getItem(v);
}
function filterTable(value) {
console.log(value);
var filter = value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 0; i < rows.length; i++) {
var nameCol = rows[i].cells[1].textContent.toUpperCase();
var rankCol = rows[i].cells[2].textContent.toUpperCase();
var rankerCol = rows[i].cells[5].textContent.toUpperCase();
var typeCol = rows[i].cells[6].textContent.toUpperCase();
var emailCol = rows[i].cells[3].textContent.toUpperCase();
if (nameCol.indexOf(filter) > -1 || rankCol.indexOf(filter) > -1 || rankerCol.indexOf(filter) > -1 || typeCol.indexOf(filter) > -1 || emailCol.indexOf(filter) > -1) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
myInput.addEventListener('keyup', function(event) {
var value = event.target.value;
saveValue(event);
filterTable(value);
});

add a no results message to table filteration

I have this following code which does filter a table but when there is no result it is blank.
Could someone help me out here to add a "No results found" message show when nothing found?
$(document).ready(function() {
$("#table_search").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#filter tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
<table>
<tbody id="filter"></tbody>
</table>
Firstly note that your use of filter() isn't quite correct. It's intended to be used to reduce a set of elements based on a predicate condition supplied within the function argument which returns a boolean. Instead your current logic is using it as a basic looping mechanism.
With regard to the issue, you can use filter() to find matching rows by their text, then based on the number of filtered rows, hide or display the 'No matches' message. Something like this:
jQuery($ => {
let $rows = $('#filter tr');
let $tfoot = $('tfoot');
$("#table_search").on("input", function() {
var value = this.value.toLowerCase();
if (!value) {
$rows.show();
$tfoot.hide()
return;
}
let $filteredRows = $rows.filter((i, el) => el.innerText.toLowerCase().indexOf(value) != -1);
if ($filteredRows.length) {
$tfoot.hide();
$rows.hide();
$filteredRows.show()
} else {
$rows.hide();
$tfoot.show();
}
});
});
tfoot { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="table_search" />
<table>
<tbody id="filter">
<tr><td>Lorem</td></tr>
<tr><td>Ipsum</td></tr>
<tr><td>Dolor</td></tr>
<tr><td>Sit</td></tr>
<tr><td>Amet</td></tr>
<tr><td>Consectetur</td></tr>
<tr><td>Adipiscing</td></tr>
<tr><td>Elit</td></tr>
</tbody>
<tfoot>
<tr><td>No matches</td></tr>
</tfoot>
</table>
Finally, note the use of input instead of keyup. The latter works better in this instance as it also works for users who copy/paste text in to the search box.

How to get value of text box embeded in cell

I have the following code
<tr val='question'>
<td>
<input style='width: 500px' type='text' placeholder='Q.Enter your question here for radio button? '>
</tr>
How can i find the value of input box embedded in cell .
function saveUserDefQues(){
var table=document.getElementById("QuestionList");
var surveyquestionform=document.forms[0];
var count=$('#QuestionList tr').length
for (var i = 0; i<count; i++) {
var row = table.rows[i];
if(row.getAttribute('val')==='question')
{
var Cells = row.getElementsByTagName("td");;
}
}
}
document.querySelector('tr[val] > td > input').value;
Array.from(document.querySelectorAll('tr[val] > td > input')).forEach(function(entry, index, entries)
{
entry.value; // you may store the value OR process with it AS you see fit
});
Since you are using Jquery this can be done this way.
replace this line of code
var Cells = row.getElementsByTagName("td");
with
var Cells = $(row).find('td');
var inputValue = Cell.find('input').val(); // gives you value of input
Code Refactoring recommended
I would like to refactor your code as below
HTML
<tr data-val='question'> // use data-* attribute to add custom attributes into tags
<td>
<input style='width: 500px' type='text' placeholder='Q.Enter your question here for radio button? '>
</td> // close your td
</tr>
Script
function saveUserDefQues(){
var surveyquestionform = document.forms[0]; // not sure what this is for, so ill leave it as is.
$('#QuestionList tr[data-val="question"]').each(function(){ //loop all tr's which has the data-val set to question
var inputValue = $(this).find('td input').val(); //get the value of input
console.log(inputValue);
});
}
$("tr[val='question'] > td > input").val()
But first you need to write a valid HTML. </td> closing tag is missing. Also you need to put this tr in a <table>.
See this Plunker
function getResult(){
$( "tr" ).each(function( index ) {
console.log($(this).find('input').attr('placeholder') );
});
}

How to unfilter table rows when checkbox is unchecked

I have a jquery script that filters rows with a looping function when a check box is checked, or words are typed in a text box. The textbox works perfectly when you erase the words it will unfilter, however the check boxes when you uncheck them it doesn't unfilter. It will switch between the two check boxes for on and off.
However, you can trick it to unfilter the checkboxes applied filter by filtering by name and typing in the textbox and then erasing what you typed.
Thus,
I don't know why when you uncheck a check box it doesn't unfilter it because how could it keep applying the filter every-time it loops if the box is not checked.
var $rows = $("#data tr"),
$filter = $("#filter");
$("#filter").keyup(function () {
var filterText = $filter.val().toLowerCase();
$rows.each(function () {
var $row = $(this);
$row.toggle($row.text().toLowerCase().indexOf(filterText) > -1);
});
});
var $row_on = $("#data tr"),
$filter_poweron = $("#poweron");
if(($filter_poweron).is(':checked')) {
var filterText_poweron = $filter_poweron.val().toLowerCase();
$row_on.each(function () {
var $row_d = $(this);
$row_d.toggle($row_d.text().toLowerCase().indexOf(filterText_poweron) > -1);
});
}
var $row_off = $("#data tr"),
$filter_poweroff = $("#poweroff");
if(($filter_poweroff).is(':checked')) {
var filterText_poweroff = $filter_poweroff.val().toLowerCase();
$row_off.each(function () {
var $row_do = $(this);
$row_do.toggle($row_do.text().toLowerCase().indexOf(filterText_poweroff) > -1);
});
}
<td width='200' align='left'>
<br><br>Filter: <input type='text' name='' id='filter' value='' style='width:270px;' data-toggle="tooltip" data-placement="left" title="Filter VM List." placeholder='Type to filter'>
<br><input type="checkbox" id="poweron" value="1O">PoweredOn <input type="checkbox" id='poweroff' value="0F"> PoweredOff
</td>
You probably want to move the if(($filter_poweron).is(':checked')) {...} stuff inside an event listener so that it runs every time the checkbox is clicked or changed.
Something like:
var $rows = $("#data tr");
$("#filter").keyup(function() {
var filterText = $(this).val().toLowerCase();
$rows.each(function() {
var $row = $(this);
$row.toggle($row.text().toLowerCase().indexOf(filterText) > -1);
});
});
$("#poweron, #poweroff").on('click change', function() {
var filterText = $(this).val().toLowerCase();
var isChecked = $(this).is(':checked');
$rows.each(function() {
var $row_do = $(this);
var showRow = isChecked ? $row_do.text().toLowerCase().indexOf(filterText) > -1 : true;
$row_do.toggle(showRow);
});
});
A couple side notes:
var $rows = $("#data tr") and var $row_on = $("#data tr") and var $row_off = $("#data tr") are all redundant (querying the dom 3 times with the same query). You just need one variable for $rows. Also, you don't need parens around ($filter_poweron).is().

How to hide any row in a table whose third cell value does not match a given string in JQuery

If i have a table:
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
I have been trying:
$(document).ready(function () {
$('input#myInput').keyup(function (val) {
// for each third td of each row, if this value does not contain: this.val() then hide it
});
});
Something like this:
var $cells = $('#myTable tr td:nth-child(3)'),
$hidden = $();
$('#myInput').keyup(function () {
var search = this.value;
var $to_hide = $cells.filter(function() {
return $(this).text() !== search;
}).parent();
$hidden.not($to_hide.get()).show();
$hidden = $to_hide.hide();
});
I assumed that when you say contains, you mean that the text has to be equal to the provided input (otherwise NoMatch and Match would not make sense). But if the content of cell just has to contain the search string as substring, you can use .indexOf() [docs].
DEMO
There are other things you have to consider, like what should happen when the search string is empty, but this is for you to play around ;)
Use "this" in your key up event handler to get the value of the input.
$(document).ready(function () {
$('input#myInput').keyup(function () {
//add if statement
alert($(this).val());
});
});
Not quite sure what you are trying to do with the table. There is not enough information.
Try this:
jsfiddle
HTML
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
<input id="myInput"/>
Javascript/Jquery
$('#myInput').keyup(function () {
var me = $(this);
var val = me.val();
$("#myTable tr").each(function() {
var tr = $(this);
var td = tr.find("td:eq(2)");
if(td.text().substring(0, val.length) === val) {
tr.show();
} else {
tr.hide();
}
});
});

Categories