I'm trying to convert a table I've written in HTML into Javascript because I want the table to be dynamically generated (# of rows). The main issue I'm having is that the individual cells in the table are clickable and open up another html page. Unfortunately, the html "onclick" parameter doesn't work with document.write statements Here is an examples of a table cell in HTML:
<td id="r1c1" align="center" onclick="getTicket(1,'plan',1);"><script language="JavaScript">document.write(getDate(1,"plan", "r1c1")); </script></td>
The functions in this line are predefined and work so I'm not going to post those, but the idea is that the function getTicket(..) is suppose to open up another html page.
My issues is how to get the onclick to work in JavaScript. I can create the cells in Javascript using document.write commands but don't really know how to make those cells clickable to run the function getTicket(..).
Your style of Javascript programming is ancient, to say the least. document.write is a function developed mainly when there were almost no common methods to generate dynamic content.
So, you should generate your elements dynamically with methods like document.createElement, append your content there, then attach the elements to the DOM with modern methods like appendChild.
Then, you can attach event listeners using something more modern than the traditional way like onclick, like addEventListener. Here's a snippet:
var td = document.createElement("td");
td.innerHTML = getDate(1, "plan", "r1c1");
td.addEventListener("click", function() {
getTicket(1, 'plan', 1);
});
row.appendChild(td);
I supposed that row is the row of the table that you're generating.
Unfortunately, IE<9 uses a different method called attachEvent, so it'd become:
td.attachEvent("onclick", function() { ...
You can modify attributes in HTML using function setAttribute(Attribute, Value).
With this function you can generate the cell code and define dinamically the attribute.
You should not use document.write to add elements to your page, there are javascript functions for this:
var myCell = document.createElement('td');
myCell.setAttribute('id', 'r1c1');
myCell.setAttribute('align', 'center');
myCell.onclick = function () {
getTicket(1, 'plan', 1);
};
// myRow is the 'tr' you want this 'td' to be a child of.
myRow.appendChild(myCell);
See it in action: http://jsfiddle.net/teH7X/1/
Can you please try below code, if that is working then let me know I will give you some better option:-
<script>
document.onload = function()
{
document.getElementById('r1c1').onclick = function()
{
getTicket(1,'plan',1);
}
}
</script>
Please check and let me know.
Related
I found some JQuery solutions, but I am limited by school task restrictions to use pure Javascript, and I need to use specific early appended element that is still not in DOM for replacing by my CKEDITOR.
Code:
function newOption(){
...
mainUL = document.getElementById("myUL");
var inputA = document.createElement("input");
inputA.type ="text";
inputA.style = "margin-right: 45px";
inputA.name = "option[]";
inputA.id = inputID;
mainUL.appendChild(inputA );
CKEDITOR.replace(inputID).setData('Type anything you want ...');
...
}
By replacing my input with CKEDITOR will JS fail, because input, commonly, is still not in DOM. I tried to use
mainUL.innerHTML += "all elements like html text";
and this is working and will immediately insert elements into DOM, but I can't to use innerHTML, because it will remove old listeners (for example checked checkboxes that JS will set from checked to unchecked, what is my main problem due to I have to try using append DOM function).
Try changing the code to wrap the call to CKEDITOR.replace in a setTimeout:
setTimeout(function() {
CKEDITOR.replace(inputID).setData('Type anything you want ...');
},0).
This will allow the browser time to insert the element before trying to replace it.
And I assume that inputID has a valid value in it...
The answer to the following question,
var counter = 0;
$("button").click(function() {
$("h2").append("<p class='test'>click me " + (++counter) + "</p>")
});
$("h2").on("click", "p.test", function(){
alert($(this).text());
});
I have a dynamically generated calendar that when you click on an individual day, instead of opening a new web page, it swaps the calendar for the events of the day. The events are listed in a table and I want to be able to click on a row and and have it trigger a function which uses location.assign(). So each row looks like the following,
<tr id="message-7">
New page in calendar loads and creates,
<tr id="message-132">
Clicking does not trigger the function. In the example from the other question, it accesses the text of the element in order to make the element unique as opposed to giving the element a unique id # as in my situation.
Am I approaching the problem the wrong way? Could I add something like a "title=132" tag that I could reference?
Ideally try not to make too much meaning out of the ID. Instead use data as shown here.
So instead of
<tr id="message-7">
use
<tr id="1234567" data-message="7">
Then in code you can address the data as:
var messageVal = $("#1234567").data("message")
And if you need to add a generic click event then you might want to use a dummy css class assignment for all appropriate TR's:
<tr id="1234567" data-message="7" class="messageRow">
so that you can write
$(".messageRow").on("click", function(event){
event.preventDefault()
var messageVal = $(this).data("message")
This is useful in the case where only some TR's will contain clickable content - just don't assign the class to the others.
So here is the situation, im creating a clickable dynamic table by adding row with a button. Each row have informations and can be clicked (the entire row). I look for a way to send the information of the row I clicked to another js function who will copie the row in another dynamic table. But here is the trick : to create a clickable row, I use the function .append and I create the row in a < a> tag which will use href="function_to_add_the_copied_row" to call the other function.
The problem is I cant find out the good syntax. Any suggestion for syntax or other way to do the trick would be appreciated. Here is my code :
//javascript function to make clickable rows
{
var infos = modules_found[i].split("\\t");
rowNum++;
//word ="'Row number : "+infos[0]+"'";
$(".targets").append('<li> <div class="ui-grid-a"><div class="ui-block-a ui-grid-b"><div class="ui-block-a">'+infos[0]+'</div><div class="ui-block-b">'+infos[1]+'</div><div class="ui-block-c">'+infos[2]+'</div></div><div class="ui-block-b ui-grid-b"><div class="ui-block-a">'+infos[3]+'</div><div class="ui-block-b">'+infos[4]+'</div><div class="ui-block-c">'+infos[5]+'</div></div></div></li>');
}
//javascript function who receive the array and add the copied row
function transferArray(infos)
{
alert("in transferArray function");
$(".copied").append('<li> <div class="ui-grid-a"><div class="ui-block-a ui-grid-b"><div class="ui-block-a">'+infos[0]+'</div><div class="ui-block-b">'+infos[1]+'</div><div class="ui-block-c">'+infos[2]+'</div></div><div class="ui-block-b ui-grid-b"><div class="ui-block-a">'+infos[3]+'</div><div class="ui-block-b">'+infos[4]+'</div><div class="ui-block-c">'+infos[5]+'</div></div></div></li>');
}
Here is a high level approach (assuming you know jQuery): instead of wrapping your row inside A tag, better way is to have register a click event listener on your table (via jQuery APIs and not in HTML). In that click handler you can get the index of row clicked easily (make use of jQuery APIs) and once you have the rowindex, you can easily clone the row and move it to somewhere else.
typically how this is handled - if you are not using some type of javascript library like Angular or Knockout is to just store data in the actual HTML with data attributes. you can make as many data attributes as you want as long as they start with data-
ex.
$(".targets").append('<li data-id="xx" data-name="xx" data-custom=""> <a href="...
then I would recommend using jQuery click handler on every row by giving them all a class , ex.
$(".targets").append('<li class="rowClick" data-id="xx" data-name="xx" data-custom=""> <a href="...
then handle the click like this
$(document).on('click' , 'rowClick' , function(e){
var $this = $(this);
//get data of row clicked
var idClicked = $this.attr('data-id');
var nameClicked = $this.attr('data-name');
// you also have the full HTML of the clicked row if you need to copy somewhere
var rowHtml = $(".copied").append($this);
});
You're already using jQuery , so use it to handle the click and then you have the element clicked as a jQuery object right there . You can use native javascript function to handle the click and pass data like you were , but you already are using jQuery and that will automatically bring in a lot more data for you.
Finally, I used native javascript function since the suggested solution didn't work, even if it looks all legit. So here is what I have done:
(...)
//append the js function
$(".FindTable").append('<li id="addedFindRow"><div class="ui-grid-a"><div class="ui-block-a ui-grid-b"><div class="ui-block-a">'+infos[0]+'</div><div class="ui-block-b">'+infos[1]+'</div><div class="ui-block-c">'+infos[2]+'</div></div><div class="ui-block-b ui-grid-b"><div class="ui-block-a">'+infos[3]+'</div><div class="ui-block-b">'+infos[4]+'</div><div class="ui-block-c">'+infos[5]+'</div></div></div></li>');
}
function copyrow(info0,info1,info2,info3,info4,info5)
{
//use data
}
This is quite heavy, but that will do. Would be more chaotic if there was more parameters thought.
I see a lot of similar questions but not one that directly targets my problem. The business logic of my problem is that I allow the user to open a jQuery Dialog where I create table loaded with a data from a database and when the user make a choise I load the selected data info fields from the main screen.
My current problem is with collecting the data from the <tr> which happens on button click. If it was a hard coded table I would just:
$(selector).on('click', function(){
var $item = $(this).closest("tr").find('td');
})
and then do something with $item however the table is created dynamically (from Ajax request) everytime the Ajax request is made the table is destroyed and recreated so basically I can't or at least I don't know a way to use some sort of selector to which to bind the event so I can reproduce the above code.
Instead in the dynamic table I have this:
<td><button onclick="getData();return false">Select</button>
The problems with this (at least how I see it) are two - first, the using of onclick inside HTML element. From what I know it's not a good practice and there are better alternatives and I would appreciate answer showing this. Also, even though I go with this code I'm yet unable to extract the text from each <td> in:
function getData() {
...
}
I tried several approaches including the one which was working with the static table and the binded event handler.
At the end here is a JS Fiddle example where I think I made it clear what I can and what I can not do, so you can refer to it.
Check this fiddle
$(selector).on('click', function(){
var $item = $(this).closest("tr").find('td');
})
Using the above code you are binding a direct event but the one which you want is delegated event
To use delegated event you should use like
$(document).on('click',selector, function(){
var $item = $(this).closest("tr").find('td');
})
so your final code will look something like
$(document).on('click','.get-data' ,function(){
var $item = $(this).closest("tr").find('td');
$.each($item, function(key, value){
alert($(value).text());
})
});
document can be anything which is parent to the table which is going to be created.
Dont forget to add the selector while adding a new table element
I had the same problem and solved it that way.
You can create your table with the database results like this:
for (var i = 0; i < results.length; i++) {
// create table row and append it to the table using JQuery
// next create a td element, append it to the created tr
// and attach a listener to it
$('<td/>').html(results[i].textProperty)
.appendTo($(tr))
.on('click', getData);
}
where getData() is your function.
You can pass arguments to your getData like this:
.on('click', {info: results[i].data}, getData);
Then you can access them in your function:
function getData(event) {
console.log(event.data.info);
}
Hope this helps!
Edit: This way you are creating a listener for each td. An optimization could be to create a listener for the whole class of td elements and to pass data to it via HTML attributes or text value like in the approved answer.
or you can use this pass object in getdata method
$('#build-table').on('click', function(){
$('#temp-table').append('<table><thead><tr><th>Select</th><th>Name</th> </tr></thead>' +
'<tbody><tr><td><button class onclick="getData(this);return false">Select</button></td><td>Name1</td></tr>' +
'<tbody><tr><td><button onclick="getData(this);return false">Select</button></td><td>Name2</td></tr>' +
'</tbody></table>')
});
function getData(ob) {
var $item = $(ob).closest("tr").find('td');
$.each($item, function(key, value){
alert($(value).text());
})
}
I want to update the contents of a TBODY (not the entire TABLE, because there's much more semi-meta data (LOL) in that). I get >= 0 TR's from the server (XHR) and I want to plump those in the existing table. The fresh TR's must overwrite the existing TBODY contents.
I've made a very simple, static example on jsFiddle that works in Chrome and probably all the rest, except for IE (I only use Chrome and test in IE8).
In Chrome, the very first attempt works: plump the TR's in the TBODY. No problem!
In IE it doesn't... I've included a not working example of what I had in mind to get it working.
I'm sure this problem isn't new: how would I insert a string with TR's in an existing TBODY?
PS. jQuery doesn't have a problem with this!? It's used here on SO. jQuery does something to the HTML and then inserts it as HTML nodes..? Or something? I can't read that crazy lib. It happens in this file (look for "html: function(". That's where the magic starts.
Anybody have a function or idea for this to work without JS library?
Here is a good resource about the problems of innerHTML and IE.
The bottom line is that on tbody the innerHTML property is readonly.
Here is a solution presented in one of the comments:
var innerHTML = "<tr><td>Hello world!</td></tr>";
var div = document.createElement("DIV");
div.innerHTML = "<table>" + innerHTML + "</table>";
// Get the tr from the table in the div
var trElem = div.getElementsByTagName("TR")[0];
Regarding the jQuery part of the question:
//inside the html() function:
// If using innerHTML throws an exception, use the fallback method
} catch(e) {
this.empty().append( value );
}
//inside the empty() function (basically removes all child nodes of the td):
while ( elem.firstChild ) {
elem.removeChild( elem.firstChild );
}
//append calls domManip applying this to all table rows:
if ( this.nodeType === 1 ) {
this.appendChild( elem );
}
//domManip as far as I can tell creates a fragment if possible and calls the three lines above with this=each row in turn, elem=the tbody(created if missing)
Using plain JavaScript, you can set the innerHTML property of the relevant element. The text that you set can contain a mix of HTML and text. It will be parsed and added to the DOM.