How to push different elements in an array in JavaScript - javascript

Below is my HTML doc. I want to push the number which is clicked in an array named as "number".
Right now If I click on 1 the number adds but if I click on 2 or 3 then too number 1 is added to the array.
I know the reason as it is taking the same id, but how to mae it add different numbers?
<html>
<body>
<table>
<tr>
<td id="key" onClick="addNumber()">1</td>
<td id="key" onClick="addNumber()">2</td>
<td id="key" onClick="addNumber()">3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
</body>
<script>
let number = [];
function addNumber() {
var num = document.getElementById("key").innerHTML;
number.push(num);
}
</script>
</html>

You can pass the current element to your function like this:
onClick="/myFunction( this )"
Now you can read from this element as it's the first argument passed in:
function myFunction( element ){ .. use element... }
let number = [];
function addNumber( element ) {
var num = element.innerHTML;
number.push(num);
console.log( number )
}
<table>
<tr>
<td onClick="addNumber(this)">1</td>
<td onClick="addNumber(this)">2</td>
<td onClick="addNumber(this)">3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
Personally, I would approach it slightly differently, as adding onClick to your elements in HTML is mixing the interactive parts (JS) with your pure content, making this cumbersome to work on later. I would approach it purely in my script, just for separation of church and state:
let numbers = [];
function addNumber( event ){
numbers.push( event.target.innerHTML );
// Here we will print the numbers array into the output id
document.getElementById( 'output' ).innerText = '[numbers]: ' + numbers.join( ', ' );
}
// document.querySelectorAll selects all <td> elements
// [ ... ] will spread them out into an Array, which will
// expose the forEach method of standard Arrays on your selection
[ ...document.querySelectorAll( 'td' ) ].forEach(td => {
// Here we will listen for the click events
td.addEventListener( 'click', addNumber );
})
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
<p id="output"></p>

Please try this one:
<html>
<body>
<table>
<tr>
<td id="key" onClick="addNumber(1)">1</td>
<td id="key" onClick="addNumber(2)">2</td>
<td id="key" onClick="addNumber(3)">3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
</body>
<script>
let number = [];
function addNumber(num) {
number.push(num);
}
</script>
</html>

Related

How do I get and pass the field of the row having class="name" in the following html?

<tbody>
<tr>
<td>gibberish</td>
<td class="name" hidden>200398</td>
<td>iPhone X 64Gb Grey</td>
<td>$999.00</td>
<td>1</td>
<td>
<button onclick="fetchdata(parameter)">Fetch Details</button>
</td>
</tr>
</tbody>
In the above html, I want that the function fetchdata('parameter') to contain the text content of the td which has a class of name and is hidden, as the parameter.
OR
I need a way in which I can get the text content of the td having class of name in my javascript function.
i.e.
function fetchdata() {
const name = document.somethingThatGivesMeName()
}
NOTE: There are going to be multiple rows that I may require to get the name of so I can't directly do document.queryselector('.name')
Sorry, This might be pretty simple but I can't quite figure it out.
When clicking the button find the first row up in the tree relative to the button with the closest method. Then from the row select the element with the class name and read the textContent or innerText of that element.
const buttons = document.querySelectorAll('.js-fetch-details');
function fetchDetails(event) {
const row = event.target.closest('tr');
const name = row.querySelector('.name').textContent;
console.log(name);
}
buttons.forEach(button => button.addEventListener('click', fetchDetails));
<table>
<tbody>
<tr>
<td>gibberish</td>
<td class="name" hidden>200398</td>
<td>iPhone X 64Gb Grey</td>
<td>$999.00</td>
<td>1</td>
<td>
<button class="js-fetch-details">Fetch Details</button>
</td>
</tr>
</tbody>
</table>
You just need the quotes ':
function fetchdata(value){
console.log(value)
}
<tbody>
<tr>
<td>gibberish</td>
<td class="name" hidden>200398</td>
<td>iPhone X 64Gb Grey</td>
<td>$999.00</td>
<td>1</td>
<td>
<button onclick="fetchdata('parameter')">Fetch Details</button>
</td>
</tr>
</tbody>
or you can use event listener and data value:
document.querySelectorAll('button').forEach(el => {
el.addEventListener('click', e => {
e = e || window.event;
e = e.target || e.srcElement;
console.log(e.dataset.value)
})
})
<tbody>
<tr>
<td>gibberish</td>
<td class="name" hidden>200398</td>
<td>iPhone X 64Gb Grey</td>
<td>$999.00</td>
<td>1</td>
<td>
<button data-value="parameter">Fetch Details</button>
</td>
</tr>
</tbody>
You can use document.getElementsByClassName('name')
This will get all the elements that have class of name.
I would put the listener on the <tbody> instead.
document.querySelector('tbody').addEventListener('click', (e) => {
// Clicking on the whole row
if (e.target.nodeName === 'TR') {
const name = e.target.querySelector('.name').textContent;
console.log(name);
}
// Clicking on the button
// Give the button a class
if (e.target.classList.contains('.somebuttonclass')) {
const name = e.target.parentNode.parentNode.querySelector('.name').textContent;
console.log(name);
}
});
UPDATE
closest would also work
document.querySelector('tbody').addEventListener('click', (e) => {
// Clicking on the whole row
if (e.target.nodeName === 'TR') {
const name = e.target.querySelector('.name').textContent;
console.log(name);
}
// Clicking on the button
// Give the button a class
if (e.target.classList.contains('.somebuttonclass')) {
const name = e.target.closest('tr').querySelector('.name').textContent;
console.log(name);
}
});
First you get all elements with class="name", then you pick just (the first) one with the attribute "hidden".
It's a way to do it anyway.
function fetchdata() {
const tds = document.getElementsByClassName("name")
for(let i = 0; i < tds.length; i++){
if(tds[i].getAttribute("hidden") != null) {
console.log(tds[i].innerHTML)
}
}
}
<table>
<tr>
<td class="name">gibberish</td>
<td class="name" hidden>200398</td>
<td>iPhone X 64Gb Grey</td>
<td>$999.00</td>
<td class="name">1</td>
<td>
<button onclick="fetchdata()">Fetch Details</button>
</td>
</tr>
</table>
With jQuery you can just do:
function fetchdata() {
console.log($('.name[hidden]').html());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>gibberish</td>
<td class="name" hidden>200398</td>
<td>iPhone X 64Gb Grey</td>
<td>$999.00</td>
<td>1</td>
<td>
<button onclick="fetchdata()">Fetch Details</button>
</td>
</tr>
</table>
Note that you need to have a table around your structure for any of this to work properly. You can't have tbody, tr and td outside a table.
If you use document.getElementsByClassName you will get what you want.
However, if there will be a case where more than one instance of that class name will occur, then you need to iterate through the classes and get their values.
The following should solve your problem
<html>
<head>
<script>
function fetchdata(){
var data = document.getElementsByClassName("data");
var t = data.length;
for(i = 0; i< t; i++){
var content = data[i].innerHTML;
alert (content);
}
}
</script>
<body>
<table>
<tbody>
<tr>
<td>gibberish</td>
<td class="data" hidden>200398</td>
<td>iPhone X 64Gb Grey</td>
<td>$999.00</td>
<td>1</td>
<td>
<button onclick="fetchdata()">Fetch Details</button>
</td>
</tr>
</tbody>
</table>
</body>
</html>

how to introduce pagination and sorting for a dynamic html table using javascript?

My html page contains ajax, which helps to create a table dynamically.
<title>Clients</title>
</head>
<body>
<table style="width:100%" id="clients_data">
<caption>Clients</caption>
<tr>
<th>Clients</th>
<th>Number of Sites</th>
<th>Reset the Processing</th>
</tr>
</table>
<script>
var myTable;
$(document).ready(function () {
loadCustomers();
});
function loadCustomers() {
$.ajax({
type: 'GET',
url: 'http://localhost:8080/cache/getCustomers',
dataType: 'json',
success: function(data) {
var rows = [];
$.each(data,function(id,value) {
rows.push('<tr><td><a href="clientSiteInfo.html?client='+id+'">'+id+'</td><td>'+value+'</td><td><button type="button" onclick="reset(\''+id+'\')">Reset</td></tr>');
});
$('#clients_data').append(rows.join(''));
}
});
};
</script>
</body>
</html>
At runtime, i may have 100s of rows populated in the table. How can I add pagination ,sorting fro this table using jquery?
Here is a very basic example using jQuery each(), index(), toggle(), and an Anonymous function. I'm leveraging HTML 5 data-* attributes to keep track of my position and set the number of items to increase/decrease.
You can use plugins or write your own code to make pagination as simple or complex as you would like. Although I would strongly suggest using AJAX to populate your results, as loading 1000's of results to hide/show could potentially slow down a system.
/* Variable Defaults */
var total = $('tbody > tr').length;
var position = $('tbody').data('position');
var jump = $('tbody').data('jump');
var paginate = function(position, jump) {
/* Show Default Items */
$('tbody > tr').each(function() {
/* Variable Defaults */
var index = $(this).index();
/* Condition */
var condition = (index >= position) && (index < position + jump);
/* Hide/Show Item */
$(this).toggle(condition);
/* Set Disabled Status */
$('.less').prop('disabled', (position - jump) < 0);
$('.more').prop('disabled', (position + jump) >= total);
});
};
/* Set Default Text */
$('.count').text(jump);
/* Init Paginate */
paginate(position, jump);
/* Bind Click Events to "Less" and "More" Button */
$('.less, .more').on('click', function() {
/* Decrease/Increase Position */
position = $(this).hasClass('less') ? $('tbody').data('position') - jump : $('tbody').data('position') + jump;
/* Paginate */
paginate(position, jump);
/* Update Position */
$('tbody').data('position', position);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Email</td>
</tr>
</thead>
<tbody data-position="0" data-jump="2">
<tr>
<td>1</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>2</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>3</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>4</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>5</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>6</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>7</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>8</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>9</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
<tr>
<td>10</td>
<td>Test McTester</td>
<td>test#gmail.com</td>
</tr>
</tbody>
</table>
<button class="less">Back <span class="count">0</span></button>
<button class="more">Forwards <span class="count">0</span></button>
You can use Datatables for your purpose :
https://datatables.net/examples/basic_init/alt_pagination.html
You can also use Tablesorter :
http://tablesorter.com/docs/

Javascript function not working

My jsp page contains a table ,the code for the same is given below:
<table width="400" border="1" cellpadding="0" cellspacing="1" id="student_table">
<thead>
<tr>
<th scope="row">ID</th>
<th scope="row">Name</th>
<th scope="row">Country</th>
<th scope="row">Marks</th>
<th scope="row">Rank</th>
</tr>
<tbody>
<tr>
<td>1</td>
<td>Smith</td>
<td>US</td>
<td><input type="text" name="marks" value="40"/></td>
<td>20</td>
</tr>
<tr>
<td>2</td>
<td>John</td>
<td>England</td>
<td><input type="text" name="marks" value="80"/></td>
<td>29</td>
</tr>
<tr>
<td>3</td>
<td>William</td>
<td>Australia</td>
<td><input type="text" id="nm" name="marks" value="60" onblur="return(myFunction1())"/></td>
<td>33</td>
</tr>
<tr>
<td>4</td>
<td>Michael</td>
<td>Germany</td>
<td><input type="text" name="marks" value="90"/></td>
<td>29</td>
</tr>
I have a javascript function which compares the values in two cells. But the javascript function is not working. I cannot find out why. Please anyone help me with a solution. I know that there are other ways to validate. but i need to get it done this way. This is an example of a big program which i need to get done in this way. Please help
function myfunction11(){
var myTable = document.getElementById('student_table').tBodies[0];
// first loop for each row
for (var r=0, n = myTable.rows.length; r < n; r++) {
// this loop is getting each colomn/cells
for (var c = 0, m = myTable.rows[r].cells.length; c < m; c++) {
if(myTable.rows[r].cells[c].childNodes[0].value){
var rank = myTable.rows[r].cells[4].innerText;
var marks = myTable.rows[r].cells[c].childNodes[0].value;
if(rank>marks){
alert("rank cannot be greater than marks:"+marks);
myTable.rows[r].cells[c].childNodes[0].value="0";
return false;
}
}
}
}
return true;
}
In your HTML, you have:
onblur="return(myFunction1())
but your actual function's name is:
myfunction11()
Once the names are matched, your function runs. But, you do have one (at least) issue with your code. You are comparing rank > marks but marks comes from an input field. All HTML data is strings, so you must convert that string to a number to do any kind of mathematical operation on it. Also, innerText is non-standard code, use textContent instead. See comments in code.
function myFunction1(){
var myTable = document.getElementById('student_table').tBodies[0];
// first loop for each row
for (var r=0, n = myTable.rows.length; r < n; r++) {
// this loop is getting each colomn/cells
for (var c = 0, m = myTable.rows[r].cells.length; c < m; c++) {
if(myTable.rows[r].cells[c].childNodes[0].value){
// All HTML data is strings. If you expect a number, you have to convert it.
// Also, use textContent to get the text of an element. innerText is non-standard
var rank = parseInt(myTable.rows[r].cells[4].textContent,10);
var marks = parseInt(myTable.rows[r].cells[c].childNodes[0].value, 10);
if(rank > marks){
alert("rank cannot be greater than marks: " + marks);
myTable.rows[r].cells[c].childNodes[0].value = "0";
return false;
}
}
}
}
return true;
}
<table width="400" border="1" cellpadding="0" cellspacing="1" id="student_table">
<thead>
<tr>
<th scope="row">ID</th>
<th scope="row">Name</th>
<th scope="row">Country</th>
<th scope="row">Marks</th>
<th scope="row">Rank</th>
</tr>
<tbody>
<tr>
<td>1</td>
<td>Smith</td>
<td>US</td>
<td><input type="text" name="marks" value="40"/></td>
<td>20</td>
</tr>
<tr>
<td>2</td>
<td>John</td>
<td>England</td>
<td><input type="text" name="marks" value="80"/></td>
<td>29</td>
</tr>
<tr>
<td>3</td>
<td>William</td>
<td>Australia</td>
<td><input type="text" id="nm" name="marks" value="60" onblur="return(myFunction1())"/></td>
<td>33</td>
</tr>
<tr>
<td>4</td>
<td>Michael</td>
<td>Germany</td>
<td><input type="text" name="marks" value="90"/></td>
<td>29</td>
</tr>
</table>
Now, to correct your code and have it use modern standards so that it works when you leave any of the fields, we'd write:
// Don't use inline HTML event handling attributes like "onclick", "onblur", etc.
// Instead, use modern standards of separating all your JavaScript from your HTML
// Get a collection of all the input fields. There are many ways to do this, but here
// we are getting all the elements that use the marks class (HTML adjusted above)
var inputs = document.querySelectorAll(".marks");
// Loop through the collection and assign the checkMarks function as the blur event
// callback funciton to each of them.
for(var i = 0; i < inputs.length; i++){
inputs[i].addEventListener("blur", checkMarks);
}
function checkMarks(evt){
// Just check the marks and the rank next to it
// All HTML data is strings. If you expect a number, you have to convert it.
// The parseInt() function can extract numbers from a string.
// Also, use textContent to get the text of an element. innerText is non-standard
// All event handling functions automatically recieve an argument representing the
// event that they are responding to (evt in this case). That event object, in turn,
// has a property (target) that references the element that triggered the event in the
// first place. To get to the table cell that comes after an input field, we start at
// the input field (evt.target) and then get the parent element of that (the <td> element
// that the input is inside of) and then the next element that is a sibling of that (the <td>
// that contains the rank.
var rank = parseInt(evt.target.parentNode.nextElementSibling.textContent, 10);
// To get the value of the input, just look at evt.target's value
var marks = parseInt(evt.target.value, 10);
if(rank > marks){
alert("rank cannot be greater than marks: " + marks);
evt.target.value = "0";
}
}
<table width="400" border="1" cellpadding="0" cellspacing="1" id="student_table">
<thead>
<tr>
<th scope="row">ID</th>
<th scope="row">Name</th>
<th scope="row">Country</th>
<th scope="row">Marks</th>
<th scope="row">Rank</th>
</tr>
<tbody>
<!-- Form elements should generally have unique names so you can tell them apart when
they submit their data. -->
<tr>
<td>1</td>
<td>Smith</td>
<td>US</td>
<td><input type="text" class="marks" name="US_Marks" value="40"/></td>
<td>20</td>
</tr>
<tr>
<td>2</td>
<td>John</td>
<td>England</td>
<td><input type="text" class="marks" name="England_Marks" value="80"/></td>
<td>29</td>
</tr>
<tr>
<td>3</td>
<td>William</td>
<td>Australia</td>
<td><input type="text" id="nm" class="marks" name="Austrailia_Marks" value="60"></td>
<td>33</td>
</tr>
<tr>
<td>4</td>
<td>Michael</td>
<td>Germany</td>
<td><input type="text" class="marks" name="Germany_Marks" value="90"/></td>
<td>29</td>
</tr>
</table>
try changing onblur="return(myFunction1())" to onblur="return(myFunction11())"

How can I make an array of one table's column?

I want to make an array of all numbers. Here is my code:
$(function(){ // dom ready
$('tr').each(function() {
var nums = $(this).map(function() {
return (this).find('td:nth-child(3)').text()
}).get();
console.log(nums);
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>760</td>
<td>John</td>
</tr>
<tr>
<td>532</td>
<td>Peter</td>
</tr>
<tr>
<td>201</td>
<td>Martin</td>
</tr>
<tr>
<td>12</td>
<td>Barman</td>
</tr>
</tbody>
</table>
What's wrong with it and how can I fix it?
Firstly you're missing a $ prefix on the (this) in the map() handler. Then to get the numbers use :nth-child(1), not :nth-child(3). Also you can just use map() directly, no need for each(). Finally, assuming you want the values to actually be numerical and not strings, use parseInt() on them, like this:
$(function() { // dom ready
var nums = $('tr').map(function() {
return parseInt($(this).find('td:nth-child(1)').text(), 10)
}).get();
console.log(nums);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>760</td>
<td>John</td>
</tr>
<tr>
<td>532</td>
<td>Peter</td>
</tr>
<tr>
<td>201</td>
<td>Martin</td>
</tr>
<tr>
<td>12</td>
<td>Barman</td>
</tr>
</tbody>
</table>
Small Mistake,
change return (this).find('td:nth-child(3)') to return $(this).find('td:nth-child(1)')
$(function(){ // dom ready
$('tr').each(function() {
var nums = $(this).map(function() {
return $(this).find('td:nth-child(1)').text()
}).get();
console.log(nums);
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>760</td>
<td>John</td>
</tr>
<tr>
<td>532</td>
<td>Peter</td>
</tr>
<tr>
<td>201</td>
<td>Martin</td>
</tr>
<tr>
<td>12</td>
<td>Barman</td>
</tr>
</tbody>
</table>
Change like this parseInt($(this).find('td:nth-child(1)').text()).parseInt() its used to change the string to number
Whats Wrong?
Missing $in return statement
And numbers column is a first cell find('td:nth-child(1)')
But you are trying to create a array with 3rd cell .but is not there.only two column is available
$(function(){ // dom ready
$('tr').each(function() {
var nums = $(this).map(function() {
return parseInt($(this).find('td:nth-child(1)').text())
}).get();
console.log(nums);
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>760</td>
<td>John</td>
</tr>
<tr>
<td>532</td>
<td>Peter</td>
</tr>
<tr>
<td>201</td>
<td>Martin</td>
</tr>
<tr>
<td>12</td>
<td>Barman</td>
</tr>
</tbody>
</table>
I think this is ist a 'lighter' version:
var nums=[];
$('td:nth-child(1)').each(function(){
nums.push(parseInt(this.innerHTML));
});
console.log(nums);
//[760, 532, 201, 12]

Moving values in cells within a table onclick of button

I'm trying to move cell values within a three by three table. But I am moving one cell at a time with the click of a button. Is this possible with jQuery or JS? I have the following table:
[1][2][3]
[4][5][6]
[7][8][9]
and I want to click a button to move right like so:
[4][1][2]
[7][5][3]
[8][9][6]
and so on..
this is my HTML:
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr><tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr><tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
<button id="moveStuff">Move!</button>
This is so hacky and I don't necessarily advise it, but it should give you a place to start out from. Basically what you can do is create a function that grabs all the tds and based on their index value, rearrange them. Every time the function is called, it recreates the cells variable, meaning it will always start out fresh with the correct index values associated with the correct cells.
Source: http://jsfiddle.net/9nfvc/
Demo: http://jsfiddle.net/9nfvc/show
HTML
<table id="rotation">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr><tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr><tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</table>
<button id="moveStuff">Move!</button>
javascript
document.getElementById('moveStuff').onclick = (function(){
var cells = document.getElementById('rotation').getElementsByTagName('td');
var rows = document.getElementById('rotation').getElementsByTagName('tr');
rows[2].appendChild(cells[5].parentNode.removeChild(cells[5]));
rows[1].appendChild(cells[2].parentNode.removeChild(cells[2]));
rows[1].insertBefore(cells[5].parentNode.removeChild(cells[5]), cells[3]);
rows[0].insertBefore(cells[2].parentNode.removeChild(cells[2]), cells[0]);
});
EDIT
I like this way better.
Source: http://jsfiddle.net/ZquQL/
Demo: http://jsfiddle.net/ZquQL/show
javascript
document.getElementById('moveStuff').onclick = (function(){
var parent = document.getElementById('rotation');
var cells = [];
var rows = parent.getElementsByTagName('tr');
var patern = [3,0,1,6,4,2,7,8,5];
for (var i = 0; i < rows.length; i++) {
while(rows[i].firstChild) {
var node = rows[i].removeChild(rows[i].firstChild)
if(node.nodeType === document.ELEMENT_NODE) cells.push(node);
}
}
row = -1;
for(i in cells) {
if(i%3 === 0) row++;
rows[row].appendChild(cells[patern[i]]);
}
});

Categories

Resources