I'm working my way through a JQuery Solution and for the most part it works but I"m stumped on seemingly a small detail I know I'm overlooking. Heck, maybe my implementation/approach needs to be reconsidered.
Here's the flow of what works.
1. Click an anchor that adds to a table.
2. Add CSS Class.
3. Disable (Unbind) click on after preappend().
4. From the table of dynamically added record remove table based on ID.
5. delete class that was added in step 2.
6. Bind 'click'
However, although I can bind the click and alert on it. The expected functionality does not allow me to step through the above process again.
The code in question:
HTML SAMPLE:
link that starts the process:
table that holds new records after click of link
<table id="carrier-table"><tbody></tbody></table>
JQUERY and Custom Javascript Function
<script type="text/javascript" id="removeCarrier">
function removeCarrierFromList(obj) {
var i = obj.parentNode.parentNode.rowIndex;
document.getElementById('carrier-table').deleteRow(i);
$('a#' + obj.id).removeClass('delete-carrier-company');
//alert(obj.id); //.hasClass('add-carrier-company').tostring() ); //
$('a#' + obj.id).bind('click', function() {
//alert('User clicked on ' + obj.id);
});
}
</script>
<script type="text/javascript" id="carrierListJS">
$(function() {
// Link
// This adds a carrier to a list
$('.add-carrier-company').click(
function() {
var target = $(this).attr("id");
alert(target);
$("#carrier-table").prepend("<tr id='carrierRow_" + target + "'>" +
"<td><a href='#' id='" + target + "' class='delete' onclick='removeCarrierFromList(this)'> </a></td>" +
"<td class='carrier-list-text'>" + target + " " + $("#name_" + target).val() + "</td>" +
"</tr>");
return false;
});
$('.add-carrier-company').click(
function() { $(this).addClass('delete-carrier-company').unbind('click'); }
);
});
</script>
There were a few issues I noticed with the code. For one thing, as #RussellUresti mentioned, you create two tags with the same ID. For another thing, if you're using ID's in a selector in jQuery, don't include the tag name, just use the id (ie. use $('#id') not $('a#id')) it will be faster (it won't break your code though).
I have created a jsfiddle to answer your question (though I rewrote most of it). :) I think it's what you're looking for.
Here's the code:
Test HTML
aa
bb
cc
10002
10003
<table id="carrier-table" style="border:1px solid #000"><tbody></tbody></table>
JavaScript
function addCarrier() {
var target = $(this).attr("id");
$("#carrier-table").prepend("<tr id='carrierRow_" + target + "'>" + "<td><a href='#' id='a" + target + "' class='delete'> </a></td>" + "<td class='carrier-list-text'>" + target + " " + $("#name_" + target).val() + "</td>" + "</tr>");
$('#a' + target).click(removeCarrierFromList);
$(this).addClass('delete-carrier-company').unbind('click');
return false;
}
function removeCarrierFromList() {
var $this = $(this);
var id = $this.attr('id').replace("a","");
$this.closest('tr').remove();
$('#' + id).removeClass('delete-carrier-company').click(addCarrier);
}
$(function() {
// Link
// This adds a carrier to a list
$('.add-carrier-company').click(addCarrier);
});
Related
I've created a table using an AJAX request to the database of items in our inventory displaying a picture/part name/price/stock remaining. When the table displays I would like to be able to click on any part of one of the rows and have it link to the item page associated with that item but it won't work.
I've tried the on.click with a static table written right into the html and it worked fine. Also if I direct the on.click script to just the table id instead of the table id and tr i can make the entire table clickable to the first row's href. So it appears that since the tr doesn't really exist in the html the javascript won't find it. Is there a way to get the script to recognize each 's href attribute?
HTML CODE + on.click script:
<html>
<body>
<table id="ctable">
<tbody id="tbody1" class="tbody1">
</tbody>
</table>
<script>
$('#ctable tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
</script>
</body>
</html>
.JS File CODE that creates table from .php file/mysql database
document.addEventListener('DOMContentLoaded', function() {
$.post('test.php', function(data) {
$("#tbody1").empty();
$.each(JSON.parse(data), function (index, value){
var eachrow = "<tr>" +
"<td class=\"image\">" + '<img src="images/thumbs/' +
value.image + '">' + "</td>" +
"<td>" + '<a href="' + value.link + '">' + value.part + "
</td>" +
"<td>" + value.price + "</td>"
"<td>" + value.stock + "</td>"
"</tr>";
$('#tbody1').append(eachrow);
});
});
}, false);
If you are dynamically adding rows, you need to either restructure your click event to listen from the context of the parent as in:
$("#tbody1").on("click", "tr", function(e) {
});
Assuming #tbody1 is a good place to start since you probably don't want the header row to be clickable. Or, every time you dynamically add rows, since the code is rebuilding the table, you can reattach the click event handlers:
$("#tbody1").empty();
$.each(JSON.parse(data), function (index, value){
var eachrow = "..
$('#tbody1').append(eachrow);
});
// or .on("click", function() { })
$("#tbody1 tr").click(function() { });
If you attach click handler via on, it would be good to then do an off as in:
$("#tbody1").off("click", "tr");
To remove the existing click handlers.
Hello and thank you for your time.
I have one doubt because I am trying to associate the ID I am reading from the Firebase database to the ID which identifies the button. It is important because of this button leads us to the event's modify page so then the event's ID is the one we use to load its data.
However those buttons' IDs look like they are one position forward let's see:
As you can see button 0 has ID Ejemplo nuevo which is the following row's event and so on.
Events:
Code:
Function's code:
function insertPlans() {
setReferences();
$("#title").html("Planes");
resetAllData();
$("#table thead").html("<tr>" +
"<td>ID</td> <td>Capacidad</td> <td>Fecha</td> <td>Descripción</td> <td>Ubicación</td> " +
"<td>Título</td> <td>Organizador</td> <td>Precio</td> <td>Prioridad</td><td>Asistentes</td>" +
"<td>Visibilidad</td></tr>");
dbRef.child('plans').once('value', function (snap) {
snap.forEach(function (planID) {
dbRef.child('plans/' + planID.key.toString()).once('value', function (snap) {
var row = "<tr><td><button id='new-button' class='btn btn-primary' onclick='saveEventName(this.id)'>Modificar evento</button>" + planID.key.toString() + "</td>";
$("#new-button").attr('id', planID.key.toString());
snap.forEach(function (fields) {
row += "<td>" + fields.val() + "</td>";
});
$("#table").find("tbody").append(row + "</tr>");
});
$("#table").find("tbody").append("</tr>");
});
});
}
Also if I do a console log as:
It prints the correct IDs:
Could you help me please?
$(‘#new-button’) is always referencing the previous row because we haven’t attached the row to the document yet.
You can first insert row then you can use the selector to change its id
Thank you for your help digitil. As you said I was editing the previous row because of the current one was not been added to the document.
The solution:
function insertPlans() {
setReferences();
$("#title").html("Planes");
resetAllData();
$("#table thead").html("<tr>" +
"<td>ID</td> <td>Capacidad</td> <td>Fecha</td> <td>Descripción</td> <td>Ubicación</td> " +
"<td>Título</td> <td>Organizador</td> <td>Precio</td> <td>Prioridad</td><td>Asistentes</td>" +
"<td>Visibilidad</td></tr>");
dbRef.child('plans').once('value', function (snap) {
snap.forEach(function (planID) {
dbRef.child('plans/' + planID.key.toString()).once('value', function (snap) {
var row = "<tr><td><button id='new-button' class='btn btn-primary' onclick='saveEventName(this.id)'>Modificar evento</button>" + planID.key.toString() + "</td>";
snap.forEach(function (fields) {
row += "<td>" + fields.val() + "</td>";
});
$("#table").find("tbody").append(row + "</tr>");
$("#new-button").attr('id', planID.key.toString());
});
$("#table").find("tbody").append("</tr>");
});
});
}
I am using javascript in my project.
I have on HTML table <table id='idDocList'> and I am doing append some html on this table as below code.
But I want to hide respective <tr> when user click on Delete anchor tag.
$("#idDocList").append("<tr><td>" + file.name + "</td><td>" + sz + "</td><td><a onclick=deleteDocument(this,'" + file.name + "')> Delete</a></td></tr>");
How can i do this using Jquery?
The following example does not work
function deleteDocument(CurAnchorTag, fileName) {
$(CurAnchorTag).closest('tr').hide();
}
I don't want to use ID for <a> tag as I have many Documents.
As a quick fix, you can use like this,
$(CurAnchorTag).closest('tr').hide();
Replaced <tr> with tr
You can remove the inline function call with jquery like this way,
$("#idDocList").on("click", "td a", function() {
$(this).closest("tr").hide();
var filename = $(this).closest("td").prev().text();
});
I would suggest you to change your code to:
var newRow = $("<tr><td>" + file.name + "</td><td>" + sz + "</td><td><a href='#'> Delete</a></td></tr>").appendTo("#idDocList");
newRow.find( 'a' ).click( function( e ) {
e.preventDefault();
$( this ).closest('<tr>').hide();
});
You would better use event delegation and get rid of inline onclick handlers all together:
$('#idDocList').on('click', '.btn-delete', function() {
$(this).closest('tr').hide();
// read filename: $(this).data('filename')
});
And use it with HTML (the sting you append):
"<tr><td>" + file.name + "</td><td>" + sz + "</td><td><a class="btn-delete" data-filename='" + file.name + "'>Delete</a></td></tr>"
Note the part:
<a class="btn-delete" data-filename="filename">Delete</a>
you can just use
$(".delete_link").click(function(){$(this).closest('tr').hide();}
Jquery will use the this of which ever element called it. There will be no need for the onclick on the html file.
You recommend you to use event for a class using the jquery
$("#idDocList").append("<tr><td>" + file.name + "</td><td>" + sz + "</td><td><a class='delete_link'> Delete</a></td></tr>");
The code below will add the event and need to execute always after add a "tr", unless you use a delegate to this
$(".delete_link").click(function(){ $(this).closest("tr").hide() });
If you don't want to use a class you can use this
$("#idDocList td > a").click(function(){ $(this).closest("tr").hide() });
I have a list of elements that are dynamically appended after an Ajax call. I am using a plugin that creates a lightbox click event for the anchors dynamically appended. It works fine except sometimes it says that the title is undefined. I realize this is because the plugin gets initiated before the title attribute is completely done appending to the DOM. I know of several ways to do this, but what is the BEST way to check that all these elements are completely appended?
Ajax call is already made and data parsed with this function (colorbox title is the one that evaluates to 'undefined' for only some):
function pageImages(images,_q){
for(var i = 0; i < images.count; i++){
$('#pageImages').append('<div class="pageImageItem"><a href="' + images.data[i]._clickurl + '" title= "' + images.data[i]._title + '">\
<img src="' + images.data[i]._thumbnailUrl + '" alt= "' + images.data[i]._title + '"/>\
</a><div class="hoverInfo"><h2>' + images.data[i]._title + '</h2><p>' + limitCharacters(images.data[i]._clickurl,40) + '</p></div></div>');
}
$(".pageImageItem a").colorbox({maxWidth:'95%', maxHeight:'95%', title: function(){
var url = $(this).attr('href'),
title = $(this).attr('title');
console.log(title);
return '<h2>' + title + '</h2>' + limitCharacters(url,40) + '';
}});
}
And here is a picture of what is happening (anchor highlighted is the element that clearly has a title attribute but is showing undefined in lightbox):
You can wrap the jQuery element find block in a timeout without timevalue. The timeout will wait for all javascript to be finished with all processes. Example:
window.setTimeout(function() {
$(".pageImageItem a").colorbox({maxWidth:'95%', maxHeight:'95%', title: function(){
var url = $(this).attr('href'),
title = $(this).attr('title');
console.log(title);
return '<h2>' + title + '</h2>' + limitCharacters(url,40) + '';
}});
});
I have this <ul>
<ul id="select_opts" class="bullet-list" style="margin-left:15px;"></ul>
This javascript code which is meant to go throug a JSON object and add the options
to the UL:
$.each(q.opts, function(i,o)
{
var str='';
str+="<li id='li_" + i + "'><input type='text' id='opt_" + i + "' value='" + o.option + "'>";
str+=" (<a href='javascript:delOpt(" + i + ");'>Delete</a>) </li>";
$("#select_opts").append(str);
});
If I do console.log() I can see that the looping is working. If I do:
console.log($("#select_opts").html());
It shows the HTML being updated as expected. However in the browser window, it shows the
UL as empty!
What am I doing wrong?
$("select_opts").append(str);
should be
$("#select_opts").append(str);
you're referring to object by id so you missed #
$.each(q.opts, function(i,o)
{
var str='';
str+="<li id='li_" + i + "'><input type='text' id='opt_" + i + "' value='" + o.option + "'>";
str+=" (<a href='javascript:delOpt(" + i + ");'>Delete</a>) </li>";
$("#select_opts").append(str);
// ^
}
I can't really see what's wrong, but try this instead, just to see if it works...
$(str).appendTo("#select_opts");
Both should work.
Is this a typo?:
$("select_opts").append(str);
Did you mean?:
$("#select_opts").append(str);
UPDATED:
Try this:
$.each(q.opts, function(i, o) {
var li = $('<li>').attr('id', 'li_' + i);
var in = $('<input>').attr('type', 'text').attr('id', 'opt_' + i).val(o.option);
var aa = $('<a>').attr('href', 'javascript:delOpt(' + i + ');').text('Delete');
li.append(in).append(aa)
$("#select_opts").append(li);
});
The tag Input should be closed - if don't, when using not valid html in append() on Internet Explorer, the div is not put into DOM tree, so you cannot access it with jQuery later.
I'd imagine input needs to be properly self-closed.
I found the bug, another part of the code was emptying the <ul> when i clicked a certain button.