Im having a small problem, I'm trying to create an inline editing system with jquery. So when an user clicks on a table field the innerhtml will change into an input field with ofcourse the content of the table field. Onblur this input field is saved in a mysql db and the innerhtml change back to the new content. I want an user to edit the same text multiple times. If I use .live('click',function(){});
Every time the user clicks on the table field the input is added so i get an input replaced by an input with the value of the last input. Very annoying, I solved this using the .one
function but now an user can only edit every table field once! Is there a way to disable an live event till the ajax call is completed?
The Jquery
$(document).ready(function(){
var id = 0;
$('table.editable td').one('click', function(event) {
var content = $(this).html();
id = $(this).parent().find('.id').val();
var class = $(this).attr('class');
$(this).html('<input type="text" id="editablefield" name="'+class+'" value="'+content+'"/>');
$(this).unbind(event);
});
$('#editablefield').live('blur', function() {
var value = $(this).val();
var name = $(this).attr('name');
$.ajax({
type: "POST",
url: "modules/Events/ajax/saveField.php",
data: "id="+id+"&val="+value+"&type="+name,
success: function(data) {
var data = data;
alert(data);
},
error: function(request, status, error) {
alert(request.responseText);
}
});
$(this).parent().html(value);
});
});
THE FRONTEND
<?php
$query = "SELECT * FROM mod_events";
$result = mysql_query($query) or die(mysql_error());
echo "<table class='editable'>";
echo "<tr>";
echo "<th></th>";
echo "<th>Event</th>";
echo "<th></th>";
echo "<th></th>";
echo "<th></th>";
echo "<th>Capacity</th>";
echo "</tr>";
while($row = mysql_fetch_assoc($result)) {
echo ("<tr>");
echo ("<td>");
echo ("<input type='hidden' value='".$row['event_id']."' class='id'>");
echo ("</td>");
echo ("<td colspan='4' class='event_name'>");
echo ($row['event_name']);
echo ("</td>");
echo ("<td class='event_capacity'>");
echo ($row['event_capacity']);
echo ("</td>");
echo ("</tr>")开发者_如何学运维;
}
echo "</table>";
?>
AND THE AJAX SCRIPT
<?php
require_once('../../../../config.php');
require_once("../../../../inc/dbconnect.php");
$id = mysql_real_escape_string($_POST['id']);
$value = mysql_real_escape_string($_POST['val']);
$field = mysql_real_escape_string($_POST['type']);
$query = "UPDATE mod_events SET ".$field." = '".$value."' WHERE event_id = ".$id;
echo mysql_query($query);
?>
Hope you guys can help me out!
You could check if there is already an input in this table cell like this:
$('table.editable td').click(function(event) {
if ($('input',this).length == 0) { //check if there is already an input?
var content = $(this).html();
id = $(this).parent().find('.id').val();
var class = $(this).attr('class');
$(this).html('<input type="text" id="editablefield" name="'+class+'" value="'+content+'"/>');
// $(this).unbind(event); // this shouldn't be needed anymore.
}
});
to avoid the problem described by aularons comment:
but that may cause this scenario: user clicks to edit, changes data to 555, a request is made but not completed yet, then the user changes the data to 333, now this request goes faster (first got routed somewhere slow or got it's packet resent for some reason), now the user will see 333 in the field while on the server it's 555, cuz the 555 request arrived after the 333. What I did was unbinding while the request is running, then binding again: jsfiddle.net/eDJqL – aularon
You need to change the code like following.
$('#editablefield').live('blur', function() {
var value = $(this).val();
var name = $(this).attr('name');
var cell = $(this).closest('td');
cell.data('request-running', true); // set data to remember request is running
$.ajax({
type: "POST",
url: "modules/Events/ajax/saveField.php",
data: "id="+id+"&val="+value+"&type="+name,
success: function(data) {
cell.data('request-running', false); // mark finished ajax call
var data = data;
alert(data);
},
error: function(request, status, error) {
cell.data('request-running', false); // mark finished ajax call
alert(request.responseText);
}
});
$(this).parent().html(value);
});
and
$('table.editable td').click(function(event) {
if ($('input',this).length == 0 || !$(this).data('request-running')) { //check if there is already an input? Or the old request is still runnig.
var content = $(this).html();
id = $(this).parent().find('.id').val();
var class = $(this).attr('class');
$(this).html('<input type="text" id="editablefield" name="'+class+'" value="'+content+'"/>');
// $(this).unbind(event); // this shouldn't be needed anymore.
}
});
The most common way to do this would be to either disable the input, or set a flag that prevents the user from focusing on it / turning it into a edit field. For the latter, you can use jQuery data
The Ajax request's complete/success callback would lift the disabling, or the flag, again.
I did unbinding the event on click, then binding it again after AJAX request is done, to get rid of the following possible scenario (also posted as a comment above):
user clicks to edit, changes data to 555, a request is made but not completed yet, then the user changes the data to 333, now this request goes faster (first got routed somewhere slow or got it's packet resent for some reason), now the user will see 333 in the field while on the server it's 555, cuz the 555 request arrived after the 333.
Here's the result (You will see ugly alert, cuz the test is on jsfiddle.com, so it will go on the ajax error route).
精彩评论