JavaScript doesn’t get nearly as much love as it should. it’s a pretty decent language in its own right and can be used for a lot of different things. Here we’ll take a look at how we can build a simple CRUD application using JavaScript. CRUD is an acronym that stands for “Create, Read, Update and Delete”. These functions are the basis of any database-driven system and this solution can theoretically be extended for use alongside an embedded database with entries being driven through php or AJAX working alongside our JavaScript. For this example, we’ll keep it simple for the most part.
What Is This Application Good For?
The CRUD application we’re going to be building is a useful tool for keeping a small inventory together and to display it dynamically in an HTML webpage generated specifically for that purpose. It uses a JSON object as a temporary storage medium for the field entries, serving as a provisional database solution. This app isn’t meant to be used as a final solution but rather a proof of concept that can be developed upon. While JavaScript is useful and flexible, its ability to deal with database elements and entry is limited at best. So for now, we’ll just look at a very basic, very simple system for keeping an inventory of items together.
The Substitute Database Structure
Within the script, the very first thing that stands out is our substitute database structure, stores within the function “crudApp”. Within the crudApp function we define the basic structure of our database object via ID fields, as well as put together a basic extraction method for getting table headers which we will then use later down to develop our table headings for our dynamically generated output. Using our JSON data, we can extract what we need to be displayed and update the table with those elements. Also within the code are snippets used for doing the basic database manipulation that we need, such as saving, updating and deleting our records. The final structure would look something like this:
var crudApp = new function () {
// This is our array with the relevant values that we’re going to be using
this.myItems = [
{ ID: ‘1’, Generic_Title: ‘Item_1’, Category: ‘Category_1’, Price: 125.60 },
{ ID: ‘2’, Generic_Title: ‘Item_2’, Category: ‘Category_2’, Price: 56.00 },
{ ID: ‘3’, Generic_Title: ‘Item_3’, Category: ‘Category_3’, Price: 210.40 }
]
this.category = [‘Category_1’, ‘Category_2’, ‘Category_3’, ‘Category_4’];
this.col = [];
this.createTable = function () {
// Here we withdraw values to stick into our table
for (var i = 0; i < this.myItems.length; i++) {
for (var key in this.myItems[i]) {
if (this.col.indexOf(key) === -1) {
this.col.push(key);
}
}
}
// Building the table.
var table = document.createElement(‘table’);
table.setAttribute(‘id’, ‘itemTable’); // Assign the table an ID.
var tr = table.insertRow(-1); // Build a row to include the header information.
for (var h = 0; h < this.col.length; h++) {
// Add the table header
var th = document.createElement(‘th’);
th.innerHTML = this.col[h].replace(‘_’, ‘ ‘);
tr.appendChild(th);
}
//Use our JSON Data to build our rows dynamically
for (var i = 0; i < this.myItems.length; i++) {
tr = table.insertRow(-1); // Insert a new row
for (var j = 0; j < this.col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = this.myItems[i][this.col[j]];
}
// Insert the relevant information into the right cells.
this.td = document.createElement(‘td’);
// *** Cancel
tr.appendChild(this.td);
var lblCancel = document.createElement(‘label’);
lblCancel.innerHTML = ‘✖‘;
lblCancel.setAttribute(‘onclick’, ‘crudApp.Cancel(this)’);
lblCancel.setAttribute(‘style’, ‘display:none;’);
lblCancel.setAttribute(‘title’, ‘Cancel’);
lblCancel.setAttribute(‘id’, ‘lbl’ + i);
this.td.appendChild(lblCancel);
// *** Save
tr.appendChild(this.td);
var btSave = document.createElement(‘input’);
btSave.setAttribute(‘type’, ‘button’); // Attribute setup
btSave.setAttribute(‘value’, ‘Save’);
btSave.setAttribute(‘id’, ‘Save’ + i);
btSave.setAttribute(‘style’, ‘display:none;’);
btSave.setAttribute(‘onclick’, ‘crudApp.Save(this)’); // ‘onclick’ Event Handling
this.td.appendChild(btSave);
// *** Update
tr.appendChild(this.td);
var btUpdate = document.createElement(‘input’);
btUpdate.setAttribute(‘type’, ‘button’); // Attribute setup
btUpdate.setAttribute(‘value’, ‘Update’);
btUpdate.setAttribute(‘id’, ‘Edit’ + i);
btUpdate.setAttribute(‘style’, ‘background-color:#44CCEB;’);
btUpdate.setAttribute(‘onclick’, ‘crudApp.Update(this)’); // ‘onclick’ Event Handling
this.td.appendChild(btUpdate);
// *** Delete
this.td = document.createElement(‘th’);
tr.appendChild(this.td);
var btDelete = document.createElement(‘input’);
btDelete.setAttribute(‘type’, ‘button’); // Attribute setup
btDelete.setAttribute(‘value’, ‘Delete’);
btDelete.setAttribute(‘style’, ‘background-color:#ED5650;’);
btDelete.setAttribute(‘onclick’, ‘crudApp.Delete(this)’); // ‘onclick’ Event Handling
this.td.appendChild(btDelete);
}
}
}
Table Operations
Within the created system, we’re going to include a couple operations that we want the user to have access to. These would be: editing data, saving data, creating a new record, removing a record and a cancel system in case the user changes their mind. These functions are the user interface for the functions we included earlier. It allows users to have access to those functions and gives us a bit more flexibility in our database management.
// Cancel Function
this.Cancel = function (oButton) {
// Hide this Button
oButton.setAttribute(‘style’, ‘display:none; float:none;’);
var activeRow = oButton.parentNode.parentNode.rowIndex;
// Remove the Save Button
var btSave = document.getElementById(‘Save’ + (activeRow – 1));
btSave.setAttribute(‘style’, ‘display:none;’);
// Let the user see the Update Button again
var btUpdate = document.getElementById(‘Edit’ + (activeRow – 1));
btUpdate.setAttribute(‘style’, ‘display:block; margin:0 auto; background-color:#44CCEB;’);
var tab = document.getElementById(‘itemTable’).rows[activeRow];
for (i = 0; i < this.col.length; i++) {
var td = tab.getElementsByTagName(“td”)[i];
td.innerHTML = this.myItems[(activeRow – 1)][this.col[i]];
}
}
// Editing
this.Update = function (oButton) {
var activeRow = oButton.parentNode.parentNode.rowIndex;
var tab = document.getElementById(‘itemTable’).rows[activeRow];
// We’ll build a dropdown here to show the available options
for (i = 1; i < 4; i++) {
if (i == 2) {
var td = tab.getElementsByTagName(“td”)[i];
var ele = document.createElement(‘select’); // List of options
ele.innerHTML = ‘<option value=”‘ + td.innerText + ‘”>’ + td.innerText + ‘</option>’;
for (k = 0; k < this.category.length; k++) {
ele.innerHTML = ele.innerHTML +
‘<option value=”‘ + this.category[k] + ‘”>’ + this.category[k] + ‘</option>’;
}
td.innerText = ”;
td.appendChild(ele);
}
else {
var td = tab.getElementsByTagName(“td”)[i];
var ele = document.createElement(‘input’); // Editable Text Box
ele.setAttribute(‘type’, ‘text’);
ele.setAttribute(‘value’, td.innerText);
td.innerText = ”;
td.appendChild(ele);
}
}
var lblCancel = document.getElementById(‘lbl’ + (activeRow – 1));
lblCancel.setAttribute(‘style’, ‘cursor:pointer; display:block; width:20px; float:left; position: absolute;’);
var btSave = document.getElementById(‘Save’ + (activeRow – 1));
btSave.setAttribute(‘style’, ‘display:block; margin-left:30px; float:left; background-color:#2DBF64;’);
// Let the user not be able to see this button
oButton.setAttribute(‘style’, ‘display:none;’);
};
// Deleting
this.Delete = function (oButton) {
var activeRow = oButton.parentNode.parentNode.rowIndex;
this.myItems.splice((activeRow – 1), 1); // Get rid of this row
this.createTable(); // Rebuild the table dynamically
};
// Saving
this.Save = function (oButton) {
var activeRow = oButton.parentNode.parentNode.rowIndex;
var tab = document.getElementById(‘itemTable’).rows[activeRow];
// Insert values into myItems array.
for (i = 1; i < this.col.length; i++) {
var td = tab.getElementsByTagName(“td”)[i];
if (td.childNodes[0].getAttribute(‘type’) == ‘text’ || td.childNodes[0].tagName == ‘SELECT’) { // Let’s see if this is a text box or not
this.myItems[(activeRow – 1)][this.col[i]] = td.childNodes[0].value; // Save this value
}
}
this.createTable(); // Rebuild the table
}
// Creating
this.CreateNew = function (oButton) {
var activeRow = oButton.parentNode.parentNode.rowIndex;
var tab = document.getElementById(‘itemTable’).rows[activeRow];
var obj = {};
// Develop a new value to stick into the existing table.
for (i = 1; i < this.col.length; i++) {
var td = tab.getElementsByTagName(“td”)[i];
if (td.childNodes[0].getAttribute(‘type’) == ‘text’ || td.childNodes[0].tagName == ‘SELECT’) { // Is this a text box?
var txtVal = td.childNodes[0].value;
if (txtVal != ”) {
obj[this.col[i]] = txtVal.trim();
}
else {
obj = ”;
alert(‘all fields are compulsory’);
break;
}
}
}
obj[this.col[0]] = this.myItems.length + 1; // Add a new ID
if (Object.keys(obj).length > 0) { //Make sure object isn’t empty
this.myItems.push(obj); // Add the data to the top of the JSON array
this.createTable(); // rebuild the table.
}
}
Basic Functionality
While this app works well for what it’s designed for, it’s just a simple application. As things become more complex and we need to manage and manipulate more data, a simple internal JSON structure may not be enough for our needs. Dynamic database solutions utilizing SQL server and MySQL come into play at this point, allowing us to build extensibility into our simple program. It’s not an overly complex task to switch this application over to one that uses a database for building its tables from information contained therein.