Reputation: 8717
I would like to get a better performance for my scripts where the user is able to Create/Read/Update/Delete (CRUD) data.
Currently I send a request after every action and refresh the overview page. Example:
<a href="script.php?action=save">Add</a>
<table>
<tr>
<td>Item 1</td>
<td>
<a href="script.php?action=save&id=123">Edit</a>
<a href="script.php?action=delete&id=123">Delete</a>
</td>
<table>
-
<?php
// script.php -> action=delete
$error = true;
if ($this->database->query("DELETE FROM items WHERE id = :id", array("id" => $_GET["id"]))) {
$error = false;
}
// forward back
header("Location: script.php?error=" . $error);
?>
I don't like it and would like to change it.
What do you think about this:
Loading items (JSON) via AJAX
only modify the items array
collect the updated and deleted items
update and delete onUnload/windowClose
Result: less server requests
Pseudocode:
<script>
var items = null; // items
var items_deleted = null; // items, marked to delete
var items_updated = null; // items, marked to be updated
// builds the html table
function build_html_table() {
// sort the items
items = sortTheItems(items);
html = "<table>";
for (i = 0; i < items.length; i++):
html += '<tr id="'+items[i].id+'">';
html += '<td>'+items[i].name+'</td>';
html += '<td>';
html += '<a href="script.php?action=save&id='+items[i].id+'" class="edit">Edit</a>';
html += '<a href="script.php?action=save&id='+items[i].id+'" class="delete">Delete</a>';
html += '</td>';
html += "</tr>";
endfor;
html += "</table>";
$("#table").html(html);
}
// on clicking the delete-link
$(".delete").click(function() {
// get id
id = $(this).parent().parent().attr("id"); // id of <tr>
// delete item (temp)
for (i = 0; i < items.length; i++)
if (items[i].id == id)
unset(items[i]);
endfor;
// mark for deleting
items_deleted.push(id);
// re-build table
build_html_table();
});
// on clicking the edit-link
$(".edit").click(function() {
// get id
id = $(this).parent().parent().attr("id");
// get the item to edit
item = null;
for (i = 0; i < items.length; i++):
if (items[i].id == id)
item = items[i];
endfor;
// fill the save-form
$("#save_dialog [name='id']").val(item.id);
$("#save_dialog [name='name']").val(item.name);
$("#save_dialog [name='content']").val(item.content);
// open save-form in a dialog
$("#save_dialog").dialog();
});
// on clicking the add link
$(".add").click(function() {
// reset the save-form
$("#save_dialog [name='id']").val("");
$("#save_dialog [name='name']").val("");
$("#save_dialog [name='content']").val("");
// open save-form in a dialog
$("#save_dialog").dialog();
});
// save form
$("#save_form").onSubmit(function() {
id = $(this).find("[name='id']");
if (!id) {
// real add, getting the new id
$(this).ajaxForm({
onSuccess: function(responseText, $form) {
item.id = responseText; // script.php?action=save returns the last inserted/updated ID
item.name = $form.find("[name='name']");
item.content = $form.find("[name='content']");
// add the added item
items.push(item);
});
} else {
// temp. update
// update the old entry
for (i = 0; i < items.length; i++):
if (items[i].id == item.id) {
items[i].name = $(this).find("[name='name']").val();
items[i].content = $(this).find("[name='content']").val();
// mark this item to update
items_updated[items[i].id] = items[i];
}
endfor;
}
// re-build table
build_html_table();
});
// doc ready
$(function() {
// get the items data (json)
items = getJSON("items_json.php");
// build table
build_html_table();
});
// on window close/unload (or after $x minutes)
$.unload(function() {
// real delete
ajaxRequest("script.php?action=delete&ids=", items_deleted);
// real update
ajaxRequest("script.php?action=update", items_updated);
});
</script>
<a href="script.php?action=add" class="add">Add</a>
<div id="table">loading...</div>
<div id="save_dialog" class="hidden">
<form action="script.php?action=save" method="POST" id="save_form">
<input type="hidden" name="id"/>
Name: <input type="text" name="name"/><br/>
Content: <textarea name="content"></textarea><br/>
<input type="submit"/>
</form>
</div>
What do you think about my idea? What could I do better? Are there good jQuery-plugins to get this job done easily?
Thanks in advance!
Note: It's just pseudo-code!
Upvotes: 1
Views: 3306
Reputation: 171698
A big helper is using data-
attributes to save parsing other attributes to get things like ID
, or action
which you have hardcoded in url( keep there for no JS in page) but helpful to access it in handlers also.
/* "data-arbitraryName" can be read using jQuery `data()` method*/
html += '<tr id="'+items[i].id+'" data-id="'+items[i].id+'">';
/* add common class to "controls"*/
'<a href="script.php?action=save&id='+items[i].id+'" class="edit crud_btn" data-action="save">Edit</a>';
/* can now combine a lot in one click handler*/
$('#tableParent').on('click', '.crud_btn', function(e){
var $btn=$(this), $row=$btn.closest('tr'), row_id= $row.data('id');
/* data() method reads "data-" attributes*/
var thisAction=$(this).data('action')
/* create data object to send*/
var dataToServer={/* this data always sent*/
action: thisAction,
id: row_id || 'add';
}
/* additional data as needed based on "action"*/
if( thisAction == 'add'){
$.extend( dataToServer, someFormData);
}
/* use direct file url, if GET, jQUery will append search string from dataToServer object*/
$.getJSON('script.php', dataToServer, function(response){
if( response.success ){
/* psuedo update method*/
updatStoredData( response, action);
/* success handling based on "action"*/
if(thisAction=='delete'){
$row.remove();
}
}
})
return false;
})
Upvotes: 1