jQuery click event on dynamically generated elements for calendar? - javascript

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.

Related

Sending an array in a javascript function with append

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.

How to get td values from dynamically created table

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());
})
}

Cannot use elements that were created with append method

I have an AJAX call that when it's done i have this code:
$(".results").append('<div class="horizontal result_element"><div class="result_photo"></div><div id="'+user_id+'" class="result_data">'+user_name+'</div></div>');
Later i want something to happen when i click on the class result_element:
$(".result_element").click(function(){
var url = "profile.php?user_id="+$(this).children("[class='result_data']").attr("id");
$(location).attr('href',url);
});
But it doesn't work and my thought is that jQuery create the html elements but doesn't appends them to the DOM.Any idea on how can i make this work with that method?
I assume that you mean with 'later' the time in the user-sight an not the time in the script.
The problem is that the jQuery doesn't know about the element if you create it after explaining that jQuery shell do x on event y. So if you set the click-event in $(document).ready(function(){*here*}) and you create an element afterwards (after the document-ready was fired), jQuery doesn't know these fresh elements.
So to solve your problem, try to add the event after you created the element (creation not equal to appending!):
// created the element
var newElement = $('<div class="horizontal result_element"><div class="result_photo"></div><div id="'+ user_id +'" class="result_data">'+ user_name +'</div></div>');
// now set the event
newElement.click(function () {
var url = "profile.php?user_id="+ $(this).children("[class='result_data']").attr("id");
$(location).attr('href',url);
})
// now append it
newElement.appendTo($(".results"))
// or: $(".results").append(newElement)
And you can reorder the two last steps, so you first append it and then set the event, thats not the point. The point is, that you create the element first and then set the event.
I believe, click is not working on result_element class which is added dynamically. Try with following code snippet.
$(document).on("click",".result_element", function(){
var url = "profile.php?user_id="+$(this).children("[class='result_data']").attr("id");
$(location).attr('href',url);
});

HTML "onclick" event in JavaScript (In a table)

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.

Manipulating row data with Javascript

I have a specific question, I have a link in a table in the third column of each row, when the user clicks that link he loads some ajax and updates the page, what I want to also happen is that in the 2nd column of the row where the link is, change the td's class from false to true, and the value from No to Yes.
Thanks!
Update!
Code Example:
The 2nd column still doesn't get updated on click, perhaps this is because the div where the table is located gets hidden onclick? Anyways here's what I've tried:
<tr>
<td>00839</td>
<td class="false" style="text-align:left;">No</td>
<td>
<a href="#"
onclick="Element.hide('ajax-instruction-view');;
new Ajax.Updater('ajax-instruction-view', '/tasks/show_ajax/839', {asynchronous:true, evalScripts:true, onComplete:function(request){new Effect.Appear("ajax-instruction-view",{});window.scrollTo(0,0);
link = $(link);
var row = link.up('tr');
var cell = row.down('td').next('td');
cell.update('Yes');},
parameters: 'authenticity_token='encodeURIComponent('SYWsdBTWlz17u9HmPXA2R9WmBfZn67g/IAMGyhHEwXw=')}); return false;"
>
Instructions-Notice Board
</a>
</td>
<td>19/04/10</td>
<td class="false">21/04/10</td>
<td class="false" style="text-align:left;">None.</td>
</tr>
It sounds as though at some point, you have a reference to the link the user clicked (either because you have a click handler on it or because you're using event delegation and finding it after a click on the table). Starting with a reference to that link, you can use Prototype's DOM traversal stuff to find the second table cell:
Edit Based on your response to rahul, I would change your link onclick to:
onclick="handleLinkClick(this); return false;"
...and this would be handleLinkClick:
function handleLinkClick(link) {
// Original code (mostly unchanged)
Element.hide('currentdiv');
new Ajax.Updater('someajax', 'ajax.html', {
asynchronous:true,
evalScripts:true,
onComplete: function(request) {
new Effect.Appear("newdiv",{});
window.scrollTo(0,0);
// New code starts here
// Extend the link element
link = $(link);
// Find the row
var row = link.up('tr');
// Find the second column
var cell = row.down('td').next('td');
// Change the cell's "class" and "value" -- I've had to guess a bit at
// what you want to do here
if (cell.hasClassName("true")) {
cell.removeClassName("true").addClassName("false");
cell.update("No");
}
else {
cell.removeClassName("false").addClassName("true");
cell.update("Yes");
}
// End of new code
},
parameters:'authenticity_token=' + encodeURIComponent('SYWsdBTWlz17u9HmPXA2R9WmBfZn67g/IAMGyhHEwXw=')
});
}
That uses Element#up, Element#next, Element#hasClassName, Element#addClassName, Element#removeClassName, and Element#update; docs for them here.
Optional things to consider:
The above is fragile in that if you change the location of that cell (make it the third column rather than the second), it fails. You might use a marker class to find it.
Rather than an onclick attribute, you could use Element#observe.
You can use event delegation to have just one handler on the table, rather than a handler on each link.
But the above should work.
I dont recall how to write it in Scriptaculous but in jQuery it would be:
$(element).click(function(){
// invoke your ajax routine
// change class
$($(this).parent('tr').children().get(1)).attr('class', 'my-classname');
});
Maybe someone can translate :-)

Categories