Selecting an element dynamically by cicking button in same div - javascript

I am attempting to create a script to add another row in a table with specific html content. The problem is that i'd like to use the same script on each section of a rather long form. Selecting the table id without having to do so with the exact table name seems to be escaping me.
The point here is to just hit the "add" button and it will add an additional item of whatever section that button is in. But before i can have it add I need to be able to select the correct item (the table id) without actually using "getElementById".
I've scoured for an answer and being still pretty new to web javascripting, i'm guessing i'm just not understanding something or attempting the wrong method... any assistance would be greatly appreciated.
HTML
<div id="divOne">
<table id="myTable">
<tr>
<td>Row1 cell1</td>
<td>Row1 cell2</td>
</tr>
</table>
<br />
<button onclick="myFunction()">Test ONE</button>
</div>
<br />
<div id="divTwo">
<table id="testTable">
<tr>
<td>Row1 cell1</td>
<td>Row1 cell2</td>
</tr>
</table>
<br />
<button onclick="myFunction()">Test TWO</button>
</div>
jquery
function myFunction() {
var x = event.currentTarget.parentNode.getAttribute('id');
alert(x); //to test its grabbing correct div THIS ONE WORKS
var child = x.getElementsByTagName('table').getAttribute('id');
alert(child); //to test its grabbing correct THIS ONE DOESNT
}

There are two issues need to be fixed:
According to your implementation, x is the id of the parent div (string value), you can't invoke the 'getElementsByTageName('table') on it. You should get the element reference
getElementsByTagName() will return a HTMLCollection, try to access them like this: children[index]
HTML
<div id="div1">
<table id="ans"></table>
<button onClick="test(event)">test</button>
</div>
JS
function myFunction(e){
var target = e.currentTarget.parentNode;
//fetch id
console.log(target.getAttribute("id"));
//fetch table id
console.log(target.getElementsByTagName("table")[0].getAttribute("id"));
}
Here is the jsfiddle demo

Did you already try jQuery? It has some nice methods which make life easier. You may want to choose .closest() which selects an element depending on your current context.
Also, there's no need to use the awkward getElementById anymore...

You have a bug in your myFunction. This should help: http://jsfiddle.net/2wA38/

In this case, you want to find the sibling table element; you can navigate the DOM using previousSibling until you reach the element:
function myFunction() {
var node = event.currentTarget,
x = node.parentNode.id;
console.log(x);
while (node && node.tagName != 'TABLE') {
node = node.previousSibling;
}
if (node) {
console.log(node.id);
}
}

Related

jQuery selector does not work in dynamically inserted data

I have a problem selecting an element from the html throght jQuery. It could be maybe the fact that the element i am trying to access is dynamically insterted throught getJson, but of course before executing the following js.
What can be the problem and how can be solved?
<table id="myTable">
<tbody>
<!-- inserted with getJson -->
<tr>
<td> <input type='checkbox' id="myInput0"> </td>
<td class="myClass">some text</td>
</tr>
<!-- other rows -->
</tbody>
</table>
var id = "myInput" + 0;
var text = $("#"+id).closest('tr').find('td.myClass').text();
alert(text)
I tried to recreate the scenario using getJSON and inserting an element dynamically, then you can do something like this:
$( document ).ready(function() {
const url = 'https://jsonplaceholder.typicode.com/todos/1';
$.getJSON( url, function( data ) {
$('#main').append(data.title);
});
});
codepen
hope it helps :)
Take a look at this Stack Overflow Q&A - How do I attach events to dynamic HTML elements with jQuery? - there are a few approaches you can take, but the jest of it is that you need to bind to the body or container of your element rather than the element itself.
Welcome to the community user21! Hopefully that info is helpful.

How to identify xpath of an element which do not have any attribute information

I want to identify an element which is a text "My Portal" from td tag. Below is my HTML
<tbody>
<tr>
<td>
<!-- rendered always true, custom column names are also label -->
My Portal
<!-- rendered always false, this feature is not required -->
</td>
</tr>
</tbody>
I have tried below xpaths as shown below, but none of them works:
1. .//td[text()="My Portal"]
2. .//td[contains(text(),"My Portal")]
After some search in the internet I found normalize-space() method which will remove the trailing and unnecessary white spaces. I have tried the method using the below xpath
.//td[normalize-space()="My Portal"]
Am able to identify the element, but in the firebug it is showing as 2 matching nodes. Please find the attachment for the highlighted elements in the firebug
My questions are:
Why two tags are getting highlighted?
Why .//td[contains(text(),"My Portal")] does not work?
How to identify the "My Portal" uniquely?
Can anyone please help?
There are several solutions. An efficient approach is to specify the exact path from the root node to the td you want. Something like
/html/body/table/tbody/tr/td/table/tbody/tr/td[normalize-space()='My Portal']
If you know that there are no more than two nesting tables, you can shorten this to
//td//td[normalize-space()='My Portal']
If you want the td in the innermost table regardless of table structure, try
//td[not(.//table) and normalize-space()='My Portal']
This isn't very efficient though. If you know that the text "My Portal" appears in an immediate text child of td, try
//td[text()[normalize-space()='My Portal']]
To uniquely identify the second td, what you have to do is add an additional filter. So if you look at the difference between the 2 tags highlighted, the parent has a class and the child doesn't. So if you need the second td, the xpath would be //td[normalize-space()='My Portal' and not(#class='rich-table-cell')]
If you need the parent then: //td[normalize-space()='My Portal' and #class='rich-table-cell']
Instead of using text() try .
.//td[contains(.,"My Portal")]
To Answer your questions:
1- Because you are using a global selector, "//", with this selector XPAth will find all the elements into the tree, so if you want select only one td you should specific the path, something like this
/table/tbody/table/td[contains(text(),"My Portal")]
2- The command that you are using it should work, I already tried, check your path again, maybe you are not selecting his parent or you are starting from the wrong path.
function xpath(){
var input = document.getElementById("xpath").value
var cell = document.evaluate( input, document, null, XPathResult.ANY_TYPE, null );
var cellvalue = cell.iterateNext();
console.log(cellvalue);
alert(cellvalue.data);
};
<html>
<head>
</head>
<body>
<input type="text" id="xpath" value='//body/table/tbody/tr/td/table//td[contains(text(),"My Value")]/text()'/> <input type="button" onclick="xpath()" value="Execute"/>
<table>
<tbody>
<tr>
<td>
<table>
<tbody>
<tr>
<td>
My Value
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>

Use JQuery to Unhide Table Rows

I have a table containing Employee Names. I would like to add a hidden row after each row that contained contact information for that particular employee. I would like to use JQuery to do a slideDown animation that reveals that information.
If I was using Javascript, I would do something like name the TR element with an ID such as "employee-xx" and the hidden line as "hidden-xx" where xx is the employeeid. I would do an onClick event that called a function(using the employeeid as a parameter) to hide or unhide the line. As I am just starting JQuery, I don't know how to code this elegantly. I would like to tell it "When you click a visible line in the table, slideDown the invisible line below it", but don't know how to do that. If I use the ID of the row, how do I access the ID via JQuery? I know it's probably simple, but I am stuck.
Thank you,
John
http://www.w3schools.com/jquery/jquery_traversing_siblings.asp
var clickhandler = function(e) {
$(e.target).next().show();
}
btw, this has been answered on here before.
Retrieve previous and next rows in a table using jQuery
EDIT: Fixed a derpy mistake with missing class name. Fiddle has been updated.
I think this is what you want? Clicking on a row with a name causes the hidden row underneath to slide down. Click again to retract.
HTML:
<table>
<tr class="show">
<td>Bob Robertson</td>
</tr>
<tr class="hide">
<td>
<div>(555)123-4567</div>
</td>
</tr>
<tr class="show">
<td>Richard Johnson</td>
</tr>
<tr class="hide">
<td>
<div>(000)000-0000</div>
</td>
</tr>
</table>
JS:
$('.hide').toggle().find('div').slideToggle();
$('.show').on('click', function () {
var next = $(this).next();
if (next.css('display') == 'none') {
next.toggle();
next.find('div').slideToggle();
} else {
next.find('div').slideToggle(function () {
next.toggle();
});
}
});
Here's a fiddle.

Why does this Javascript only run once per page?

I have this Try-it-Yourself section to my website but for some reason when I am wanting to have more than one Try-it-Yourself section it will only work for the one at the top of the page. So if I had three of them on a page the top one would work in the way I want but the next two would do nothing.
I have the following HTML:
<div class="tryit">
<table>
<tr>
<td>Try It Yourself</td>
</tr>
<tr>
<td><textarea id="input" rows="10" cols="47"></textarea></td>
</tr>
<tr>
<td><input onclick="update();" type="button" value="Update"></td>
</tr>
<tr>
<td><iframe id="output" name="output" width="600" height="300" ></iframe></td>
</tr>
</table>
</div>
And the following Javascript:
function update()
{
var tryitoutput = document.getElementById('input').value;
window.frames['output'].document.documentElement.innerHTML = tryitoutput;
}
Thank you.
As others mentioned, this is happening because there can't be more than one HTML element with same value of ID attribute. In your case javascript only finds the first element, that's why it doesn't work on later Update buttons. The simplest approach would be to set different ID attribute values for different "Try it yourself" boxes:
Slightly modify your JS, see following jsFiddle example
function update(tryItIndex) {
var tryItOutput = document.getElementById('input-' + tryItIndex).value;
window.frames['output-' + tryItIndex].document.documentElement.innerHTML = tryItOutput;
}
That's because you are referring to the textarea and the output by id which means it will always just retrieve the first one. A quick fix would be having unique id's for these fields and send the names as parameters to the update function like update(inputId, outputId)

Change table row display property

I have an html page with a table that contains a hidden row:
<table>
<tr id="hiddenTr" style="display:none">
...
</tr>
</table>
I need to make it visible at client side using jquery. I tried this
$('#hiddenTr').show();
and this
$('#hiddenTr').css('display', 'table-row');
Both implementations don't work for me. Furthemore the second one is not crossbrowser.
UPD. Sorry, guys. That was my fault: I mistyped tr element id. That's strange $('hiddenTr') didn't return null...
I always set the style.display property to "" (empty string) to show a hidden table row:
var row = document.getElementById('row_id');
row.style.display = ""; // shows the row
To hide it again:
row.style.display = "none"; // hides the row
in jQuery , this would be:
$("#row_id").css("display", ""); // show the row
or
$("#row_id").css("display", "none"); // hides the row
IE doesn't seem to like the 'table-row' value for display. And 'block' is not correct, and it seems to screw up the display in other browsers sometimes.
The first one should work. Are you wrapping it in $(document).ready(function(){}); ?
$(document).ready(function(){
$('#hiddenTr').show();
});
You could try setting display:auto, but honestly, I've had nothing but trouble manually setting the display property for table rows/cells.
What I've found usually works is creating a CSS class called "hidden" that has display:none. Rather than show()ing, I just remove that class.
tried ?
$('#hiddenTr').css('display','block');
Also, you should put in a <TD></TD> with something in it, at least a so the row is not collapsed by your browser client. Diffrent clients behave diffrently...
You can try this code.
CSS style
<style>
.hiddenTr {display: none;}
</style>
HTML Table Content
<table>
<tr class="hiddenTr">
<td>Hidden Table Row</td>
</tr>
<tr><td>Table Row</td></tr>
<tr><td>Table Row</td></tr>
</table>
HTML button code
<button onclick="myFunction()">Click Me</button>
Include jQuery CDN
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
Create a custom javascript function
<script>
function myFunction() {
$('.hiddenTr').toggle();
};
</script>

Categories