get the value of table row by cliking with JavaScript - javascript

I have a table structure like:
<table id= "mytable">
<body>
//first row
<tr class = "row">
<td id="rowTable">
<div id="myRow1"> Part 1 </div>
<div id="myRow2"> first </div>
<div id="myRow3"> 123 </div>
</td>
</tr>
//second row
<tr class = "row">
<td id="rowTable">
<div id="myRow1"> Part 2 </div>
<div id="myRow2"> second </div>
<div id="myRow3"> 456 </div>
</td>
</tr>
</body>
</table>
( I know the html part may seems incorrect but to be honest, I am not allowed to change it. I have to work with this structure)
And I want to read the first column of each row when I click on it by using javascript.
When I tried: var Value = $(e.currentTarget).text(); it gave me the value of the whole row which is:
Part 1 first 123
but I only want the value of the first part which is Part 1. Any idea of how to get that value?

You could do something like this:
the HTML:
<table id= "mytable">
<tr class = "row">
<td id="myRow1">Part 1</td>
<td id="myRow2">first</td>
<td id="myRow3">123</td>
</tr>
<tr class = "row">
<td id="myRow1">Part 2</td>
<td id="myRow2">second</td>
<td id="myRow3">456</td>
</tr>
</table>
the JS:
$(document).ready(function() {
$('td').click(function(e) {
val = e.target.innerHTML;
//alert(val);
//Put your code here
});
});

Related

How to get the number of rows from nested table with Xpath?

I have the nested table below for which I want to store in a variable the number of rows in the second tbody.
The Xpath of main table and Xpath of the second table tbody are:
//*[#id="MainTable"]/table
//*[#id='MainTable']/table/tbody/tr/td/table[2]/tbody
Testing in Chrome Console with the code below, I'm getting successfully the second tbody so far.
function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
console.log( getElementByXpath("//*[#id='MainTable']/table/tbody/tr/td/table[2]/tbody") );
But I'm stuck in how to get the number of rows for this second tbody.
May someone help to achieve this getting the number of rows for this tbody or a better way to do it? Thanks for any help.
This is the HTML structure:
<table>
<tbody>
<tr>
<td id = "main">
<table id = "table_x">...</table>
<div>...</div>
<iframe>...<iframe>
<table class="table2_class" summary="MySummary">
<thead>...</thead>
<tbody>
<tr class="a1" >
<td class="td_class">1</td>
<td class="td_class">N</td>
<td class="td_class_1">
<div dir="" class="zzz">
<div class="div_class">
Some text
</div>
</div>
</td>
</tr>
<tr class="b1" >
<td class="td_class">4</td>
<td class="td_class">W</td>
<td class="td_class_1">
<div dir="" class="zzz">
<div class="div_class">
Some text
</div>
</div>
</td>
</tr>
<tr class="a1" >
<td class="td_class">7</td>
<td class="td_class">R</td>
<td class="td_class_1">
<div dir="" class="zzz">
<div class="div_class">
Some text
</div>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Answering my own question.
This code it seems to work:
getElementByXpath("//*[#id='MainTable']/table/tbody/tr/td/table[2]/tbody").rows.length

How to filter out divs containing numbers up to another number?

I've been working on a project where I can use a search term to filter out some div boxes. For example each div contains a number like 100, 200 or 300. When I 250 into the search input, I need it to hide the divs that contain 100 and 200, as they are less than 250. Does this make sense?
This is what I have done so far:
<input type="text" id="search_value" onkeyup="search_filter()">
<div id="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">300</td>
</tr>
</table>
</div>
<div id="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">250</td>
</tr>
</table>
</div>
<div id="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">200</td>
</tr>
</table>
</div>
function search_filter() {
//Get Value of input & convert to Int
var s_value = document.getElementById("search_value").value;
s_value = parseInt(s_value);
//Get Value of in div and convert to Int
var d_value = document.getElementById("div_value").innerHTML;
d_value = parseInt(d_value);
//Hide Divs
if(s_value > d_value){
$(function(){
$(".container").hide();
document.getElementsByTagName(".container")[0].setAttribute("class", "hide_container");
});
}
else {
$(function(){
document.getElementsByTagName(".container")[0].setAttribute("class", "show_container");
});
};
}
I feel like I need to make each div unique but I'm not sure on how to go about creating a long list of div containers with numbers on a table that will hide.
Thanks
You can loop through all the td with class div_value to compare the the text with the value of input element so that you can hide/show based on the condition.
Try with jQuery's .each() the following way:
function search_filter(input) {
$('table tr td.div_value').each(function(){
if(Number($(this).text()) >= Number(input.value))
$(this).closest('.container').css({display: 'block'});
else
$(this).closest('.container').css({display: 'none'});
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="search_value" onkeyup="search_filter(this)">
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">300</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">250</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">200</td>
</tr>
</table>
</div>
Please Note: I will suggest you to ignore inline event listeners.
$('#search_value').on('keyup', function(){
var input = this;
$('table tr td.div_value').each(function(){
if(Number($(this).text()) >= Number(input.value))
$(this).closest('.container').css({display: 'block'});
else
$(this).closest('.container').css({display: 'none'});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="search_value">
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">300</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">250</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">200</td>
</tr>
</table>
</div>
First, most of your selectors are incorrect.
Do not use multiple ids with the same value (container). Change to a class if you need the same name.
Also if you can use jQuery then use it everywhere, or dont use it at all.
function search_filter() {
//Get Value of input & convert to Int
var s_value = parseInt($("#search_value").val());
$('.container').each((i, element) => {
if (s_value > parseInt($(element).find('.div_value').text())) {
$(element).hide();
$(element).addClass('hide_container')
} else {
$(element).show();
$(element).addClass('show_container')
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="search_value" onkeyup="search_filter()">
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">300</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">250</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">200</td>
</tr>
</table>
</div>
Using vanilla Javascript, I would solve it this way.
On every input event on the <input />, walk through the list of .div_value, and set their closest('container')'s display property accordingly.
const valueDivs = [...document.querySelectorAll('.div_value')]
search_value.addEventListener('input', () => {
for (const valueDiv of valueDivs) {
valueDiv.closest('.container').style.display =
Number(valueDiv.textContent) >= Number(search_value.value)
? 'block'
: 'none'
}
})
<label> Filter by number: <input type="number" min="0" id="search_value" /></label>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">150</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">200</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">250</td>
</tr>
</table>
</div>
Here's an example of using a forEach loop to show/hide the divs when you run your function. This uses vanilla javascript.
<input type="text" id="search_value" onkeyup="search_filter()">
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">300</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">250</td>
</tr>
</table>
</div>
<div class="container">
<table class="information">
<tr>
<td class="key">Info</td>
<td class="div_value">200</td>
</tr>
</table>
</div>
function search_filter() {
//Get Value of input & convert to Int
var s_value = document.getElementById("search_value").value;
s_value = parseInt(s_value);
//Get Value of in div and convert to Int
var d_value_containers = document.querySelectorAll(".container");
// Loop through divs and hide divs that have a lower value than the search term
d_value_containers.forEach(function(container){
var d_value = container.querySelector(".div_value");
var d_value_interger = parseInt(d_value.innerHTML);
if(s_value > d_value_interger) {
container.style.display = 'none';
} else {
container.style.display = 'block';
}
});
}

Changing color of a <td> in a static HTML Table, depending if the BackEnd data is true or not in AngularJS without ng-Repeat

Warning: some words are in french in my code on pictures so I will explain what is about here
This is table I am trying to change the color depending on the true of false value
It is a simple disponibility schedule for each employees for the periods of AM,PM and Noon of a Day.
At this moment all I am trying to do is to displayed the values of, if someone is available at that period of this day,the the will turn turn green. In my database, each period displayed here are in bit values.
I will use the combo-box to switch employees(right now it display their ID but it only temporary )
The problem is, I can't get to display them properly, the values are incorrect ! So I am gonna post a paste bin of my code for this part right here.
<!-- The view code-->
<div class="row">
<div class="col-lg-10">
<div class="panel panel-default" style="margin-top:10px;">
<div class="panel-heading">
<b>Horraires des disponibilités </b>
</div>
<div class="panel-body">
<div class="col-lg-5">
<div >
<label> Employer </label>
<select ng-model="emp.EmployerID" ng-change="SelectedEmployer(emp.EmployerID)" class="form-control">
<option ng-repeat="emp in LesDisponibilites" >{{emp.EmployerID}}</option>
</select>
</div>
</div><div class="col-lg-6"><div class="dataTables_filter"><label><b>Search:</b><input type="search" class="form-control input-sm" placeholder="" aria-controls="dataTables-example"></label></div></div>
<!-- /.panel-heading -->
<div class="col-lg-10 ">
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead >
<tr>
<th>Jour</th>
<th>AM</th>
<th>PM</th>
<th>Soir</th>
</tr>
</thead>
<tbody >
<tr >
<td>Lundi</td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Lundi_AM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Lundi_PM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Lundi_Soir)" style="background-color:{{DispoColor}};"></td>
</tr>
<tr>
<td>Mardi</td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Mardi_AM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Mardi_PM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Mardi_Soir)" style="background-color:{{DispoColor}};"></td>
</tr>
<tr>
<td>Mercredi</td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Mercredi_AM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Mercredi_PM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Mercredi_Soir)" style="background-color:{{DispoColor}};"></td>
</tr>
<tr>
<td>Jeudi</td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Jeudi_AM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Jeudi_PM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Jeudi_Soir)" style="background-color:{{DispoColor}};"></td>
</tr>
<tr>
<td>Vendredi</td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Vendredi_AM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Vendredi_PM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Vendredi_Soir)" style="background-color:{{DispoColor}};"></td>
</tr>
<tr>
<td>Samedi</td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Samedi_AM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Samedi_PM)" style="background-color:{{DispoColor}};"></td>
<td ng-required="IsDispo(LesDisponibilites[Lindex].Samedi_Soir)" style="background-color:{{DispoColor}};"></td >
</tr>
</tbody>
</table>
</div>
<!-- /.table-responsive -->
</div>
</div>
<div class="panel-footer">
</div>
</div>
</div>
</div>
// Controller code
myappCtrl.controller('DisponibiliteCtrl', ['$scope', '$http', function ($scope, $http) {
var url = "http://localhost:64124/api/disponibilites"
$scope.DispoColor = "none";
$scope.LesDisponibilites = {};
$scope.Lindex = {};
// Récupère le date
$http.get(url).then(function (result) {
$scope.LesDisponibilites = result.data;
})
$scope.SelectedEmployer = function (index) {
console.log(index);
$scope.Lindex = index -1;
}
// Pour ajouter les couleurs qui indiques les disponibilités
$scope.IsDispo = function (Dispo ) {
if (Dispo == true) {
$scope.DispoColor = "#0ac20a";
}
else {
$scope.DispoColor = "none";
}
}
Also this is weird, but when I switch to ng-model instead of ng-required, It seems to show the correct data, but the console is going crazy with error, as ng-model should not be use for a Function.
I tried a lot of things and I am lost right now. I hope somebody here can help me.
You can use ng-style or ng-class to doing that.
ng-style="expression" or ng-class="expression"
In your case, as an example you can apply following way for your rows.
<td ng-style="LesDisponibilites[Lindex].Lundi_AM ? {'background-color':'#0ac20a'}:'none' ></td>
Try use ng-class property.
https://docs.angularjs.org/api/ng/directive/ngClass
<div class="table-responsive">
<table class="table table-condensed">
<thead>
<tr>
<th class="col-xs-4">COLUMN1</th>
<th class="col-xs-1">COLUMN2</th>
<th class="col-xs-1">COLUMN3</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="obj in anyObject" ng-class="{'info': obj.value1}">
<td class="col-xs-2">{{obj.value1}}</td>
<td class="col-xs-1">{{obj.value2}}</td>
<td class="col-xs-1">{{obj.value3}}</td>
</tr>
</tbody>
</table>
</div>

Insert rows at specific index of another row in ng-repeat

Here's the code:
<tr ng-repeat="param in tags[$index].parameters">
<td class="previewParamName">{{param.name}}</td>
<td>
<div ng-if="is_array(param)">
<div class="previewParamValue limitWidth">List <span class="arrayParamArrow" ng-click="showArrayParams(param)" ng-class="{'glyphicon glyphicon-chevron-down': !arrayCollapsed, 'glyphicon glyphicon-chevron-up': arrayCollapsed}"></span></div>
</div>
<div ng-if="!is_array(param)">
<div class="previewParamValue" tooltip-placement="bottom" tooltip="{{param.value}}" tooltip-trigger="mouseenter">{{param.value | limitTo : 25}}</div>
</div>
</td>
</tr>
<tr ng-hide="!arrayCollapsed" ng-repeat="params in arrayParameter">
<td>{{params.name}}</td>
<td class="wordBreak">{{params.value}}</td>
</tr>
What i want is to be able to put second row ng-repeat below specific row in the first ng-repeat, specifically when ng-if=is_array(param) div is shown, because it indicates that there needs to be more sub rows for that one specific row. Thanks
I'm not sure what is the exact structure for your array and how you get params for rows on click. But to render it you should try to use ngRepeatStart and ngRepeatEnd directives.
Something like this (simplified a little for the demo):
<tr ng-repeat-start="param in tags.parameters" ng-init="param.arrayCollapsed = false">
<td class="previewParamName">{{param.name}}</td>
<td>
<div ng-if="is_array(param)">
<div class="previewParamValue limitWidth" ng-click="param.arrayCollapsed = !param.arrayCollapsed">
List <span class="arrayParamArrow" ng-class="{'glyphicon glyphicon-chevron-down': !arrayCollapsed, 'glyphicon glyphicon-chevron-up': arrayCollapsed}"></span>
</div>
</div>
<div ng-if="!is_array(param)">
<div class="previewParamValue" tooltip-placement="bottom" tooltip="{{param.value}}" tooltip-trigger="mouseenter">{{param.value | limitTo : 25}}</div>
</div>
</td>
</tr>
<tr ng-repeat="p in param" ng-show="param.arrayCollapsed" class="params-row">
<td>{{p.name}}</td>
<td class="wordBreak">{{p.value}}</td>
</tr>
<tr ng-repeat-end></tr>
From here you should be able to adjust it for your code.
Demo: http://plnkr.co/edit/tW3rUYXqoM9fTNHdOf9K?p=info
UPD: Better solution
Original code contains problem is that ngRepeatEnd tr is repeated for each iteration creating bunch of unnecessary empty tr. Not good.
Below is more more straightforward solution which uses two repeaters: one on tbody and the second on inner tr. Multiple tbodies is perfectly valid and it's even feels good that parameter rows are grouped together with their parent row into the same tbody.
<table class="table table-bordered table-condensed">
<tbody ng-repeat="param in tags.parameters" ng-init="param.arrayCollapsed = false">
<tr>
<td class="previewParamName">{{param.name}}</td>
<td>
<div ng-if="is_array(param)">
<div class="previewParamValue limitWidth" ng-click="param.arrayCollapsed = !param.arrayCollapsed">
List <span class="arrayParamArrow" ng-class="{'glyphicon glyphicon-chevron-down': !arrayCollapsed, 'glyphicon glyphicon-chevron-up': arrayCollapsed}"></span>
</div>
</div>
<div ng-if="!is_array(param)">
<div class="previewParamValue" tooltip-placement="bottom" tooltip="{{param.value}}" tooltip-trigger="mouseenter">{{param.value | limitTo : 25}}</div>
</div>
</td>
</tr>
<tr ng-if="is_array(param)" ng-repeat="p in param" ng-show="param.arrayCollapsed" class="params-row">
<td>{{p.name}}</td>
<td class="wordBreak">{{p.value}}</td>
</tr>
</tbody>
</table>
Demo: http://plnkr.co/edit/0V1hDOpl2wukKFeIZC1O?p=info

JavaScript multiple incrementing variable solution

I have a variable ver i = 1.
I have a table as follows;
<table>
<tr class="testrow">
<td class="prev"> </td>
<td class="data"> </td>
<td class="next"> </td>
</tr>
<tr class="testrow">
<td class="prev"> </td>
<td class="data"> </td>
<td class="next"> </td>
</tr>
<tr class="testrow">
<td class="prev"> </td>
<td class="data"> </td>
<td class="next"> </td>
</tr>
<tr class="testrow">
<td class="prev"> </td>
<td class="data"> </td>
<td class="next"> </td>
</tr class="testrow">
<tr>
<td class="prev"> </td>
<td class="data"> </td>
<td class="next"> </td>
</tr>
</table>
The table may have more rows. I want a variable to increase value by 1 when I click next and decrease by 1 for prev. This can be done easily. But I want some variable which is row dependent. When I clicknext in first row, the variable value should be 2, but it should not change when I click either next or prev in any other row. Also this should be the case in all other rows. The minimum value of variable should be 1.
It will be helpful if someone provide me a fiddle with the variable displayed in the middle cell of each row. Note that in this demo, it should not be something to ++ or -- the text or data in the middle cell.
Here is my fiddle.
I'd use jQuery.data() to store the variable in each row, changing it when the user clicks prev/next:
$(function() {
$(".testrow").each(function() {
var $row = $(this);
// set the initial value
$row.data("currentIndex", 1);
$row.find(".prev").click(function() {
$row.data("currentIndex", $row.data("currentIndex") - 1);
alert("currentIndex: "+$row.data("currentIndex"));
});
$row.find(".next").click(function() {
$row.data("currentIndex", $row.data("currentIndex") + 1);
alert("currentIndex: "+$row.data("currentIndex"));
});
});
});
jsFiddle: http://jsfiddle.net/5TPCK/12/
$('table tr .next').click(function() {
alert($(this).closest('tr').index());
});
http://jsfiddle.net/ThiefMaster/5TPCK/2/
Btw, </tr class="testrow"> is horribly wrong - it should only be </tr>.
Couldn't you keep an array of these counters (this would work if the number of rows is known beforehand and static)? Otherwise you could attach the counter to each <tr> element using the jquery data() function.
See: http://api.jquery.com/jQuery.data/

Categories