Reputation: 7491
I'm trying to make a list of items editable and update with AJAX using jQuery.
HTML
<ul>
<li data-id="1">
<span class="title">Title 1</span><span><a href="#" class="changeLink">Change</a></span>
</li>
<li data-id="2">
<span class="title">Title 2</span><span><a href="#" class="changeLink">Change</a></span>
</li>
<li data-id="3">
<span class="title">Title 3</span><span><a href="#" class="changeLink">Change</a></span>
</li>
</ul>
jQuery
$('a.changeLink').on('click', function(e)
{
e.preventDefault();
// get parent LI element
var li = $(this).closest('li');
// catch current title
var title = li.children('span.title').text();
// replace span
li.children('span.title').html('<input type="text" value="'+title+'" />');
// change the link class and label
$(this).removeClass('changeLink').addClass('saveLink').text('Save');
});
$('a.saveLink').on('click', function(e)
{
e.preventDefault();
// get parent LI element
var li = $(this).closest('li');
// get the id for the AJAX query
var id = li.attr('data-id');
// get the input value
var title = li.children('span.title input').val();
// restore span text with new
li.children('span.title').text(title);
// restore link
$(this).removeClass('saveLink').addClass('changeLink').text('Change');
// make AJAX post to save new title
$.post('updatetitle.php',{ 'id': id, 'title': title }, function(){ alert('OK'); });
});
My problem seem to be that the saveLink click event never occurs. Also the changeLink click event seem to happen more than once. Why does this happen - the link don't have the changeLink
class anymore?
I put this in a jsFiddle here: http://jsfiddle.net/jtheman/SZk4h/1/
Glad if I can get some input, what is my error?
Upvotes: 0
Views: 1399
Reputation: 55750
The event will be associated to an element and not specifically to a class..
If you want to work it with class you might need to delegate the event
UPDATED CODE
$('ul#list').on('click', 'a.changeLink , a.saveLink', function(e) {
e.preventDefault();
if ($(this).hasClass('changeLink')) {
var li = $(this).closest('li');
var title = li.children('span.title').text();
li.children('span.title')
.html('<input type="text" value="' + title + '" />');
$(this).removeClass('changeLink')
.addClass('saveLink').text('Save');
}
else if ($(this).hasClass('saveLink')) {
var li = $(this).closest('li');
var id = li.attr('data-id');
var title = li.children('span.title').find('input').val();
li.children('span.title').text(title);
$(this).removeClass('saveLink')
.addClass('changeLink').text('Change');
//$.post('updatetitle.php',
// { 'id': id, 'title': title }, function(){ alert('OK'); });
}
});
Your problem was this line
var title = li.children('span.title input').val();
.children()
will only get the immediate children of the element.
Replace it with
var title = li.children('span.title').find('input').val();
Upvotes: 2
Reputation: 191779
.saveLink
does not exist in the DOM the first time you bind the event. One possible solution is to bind it once the .saveLink
class is added. Another is to use delegation. Ideally, the ul
would have an id
attribute (otherwise you will have to use another parent up to document
:
$("#ul-id").on('click', '.saveLink', function () { ...
Additionally, the .changeLink
callback is never unbound from the links it is bound to originally. This can be solved using delegation in the same way, or you can unbind the event in the callback.
Upvotes: 1
Reputation: 756
use .live() instead. This is because
$('a.saveLink').on('click', function(e)) //in this moment not elements exists,
the .addClass('saveLink') // execute after
Upvotes: 1