How to Create a Simple CRUD Application using only JavaScript

You can use plain JavaScript to create a basic Single Page Application. Today you can find many comprehensive JavaScript frameworks for building complex front-end applications. I personally have worked with AngularJS and found it very useful. However, for some good reason, I still use JavaScript and let me show you how to create a Simple CRUD application (a Single Page Application) using only JavaScript.

A basic CRUD operation requires data. CRUD stands for Create, Read, Update and Delete and these are four basic functions to manipulate data in a database. It can be any database. For my CRUD application, I am using data in a JSON object.

Create a Simple CRUD Application using JavaScript

See this demo

1) I have data stored in a JSON object (in my application). I’ll extract the data and display it in a dynamically created HTML table.

2) Each row has few more dynamically created HTML elements like buttons, textboxes and Dropdown Lists, to perform functions like, update, delete, save, create new and cancel.

3) Button’s and textboxes will have events attached, dynamically.

What does this Application Do?

The application is a Books inventory. It will show a list of books, in a distinct category with a price. See the above image. This Application allows users to Views the list, create or add new books to the existing list (database), update or edit a rows data and delete the data (the entire row).

Every transaction will affect an Array of JSON objects, a temporary database.

Now, lets create the app.

The Markup, CSS and the Script

I only have a DIV element in <body> section that will serve as container. Every other element that I’ll create dynamically using JavaScript, will be attached to this container.

<!DOCTYPE html>
<html>
<head>
    <title>CRUD Application using JavaScript</title>
    <style>
        table 
        {
            width: 100%;
            font: 17px Calibri;
        }
        table, th, td 
        {
            border: solid 1px #DDD;
            border-collapse: collapse;
            padding: 2px 3px;
            text-align: center;
        }
      
        input[type='button'] 
        {
            font: 15px Calibri;
            cursor: pointer;
            border: none;
            color: #FFF;
        }
        
        input[type='text'], select 
        {
            font: 17px Calibri;
            text-align: center;
            border: solid 1px #CCC;
            width: auto;
            padding: 2px 3px;
        }
    </style>
</head>
<body>
    <div id="container" style="width:700px;">
    </div>
</body>

<script>
    var crudApp = new function () {

        // AN ARRAY OF JSON OBJECTS WITH VALUES.
        this.myBooks = [
            { ID: '1', Book_Name: 'Computer Architecture', Category: 'Computers', Price: 125.60 },
            { ID: '2', Book_Name: 'Asp.Net 4 Blue Book', Category: 'Programming', Price: 56.00 },
            { ID: '3', Book_Name: 'Popular Science', Category: 'Science', Price: 210.40 }
        ]

        this.category = ['Business', 'Computers', 'Programming', 'Science'];
        this.col = [];

        this.createTable = function () {

            // EXTRACT VALUE FOR TABLE HEADER.
            for (var i = 0; i < this.myBooks.length; i++) {
                for (var key in this.myBooks[i]) {
                    if (this.col.indexOf(key) === -1) {
                        this.col.push(key);
                    }
                }
            }

            // CREATE A TABLE.
            var table = document.createElement('table');
            table.setAttribute('id', 'booksTable');     // SET TABLE ID.

            var tr = table.insertRow(-1);               // CREATE A ROW (FOR HEADER).

            for (var h = 0; h < this.col.length; h++) {
                // ADD TABLE HEADER.
                var th = document.createElement('th');
                th.innerHTML = this.col[h].replace('_', ' ');
                tr.appendChild(th);
            }

            // ADD ROWS USING JSON DATA.
            for (var i = 0; i < this.myBooks.length; i++) {

                tr = table.insertRow(-1);           // CREATE A NEW ROW.

                for (var j = 0; j < this.col.length; j++) {
                    var tabCell = tr.insertCell(-1);
                    tabCell.innerHTML = this.myBooks[i][this.col[j]];
                }

                // DYNAMICALLY CREATE AND ADD ELEMENTS TO TABLE CELLS WITH EVENTS.

                this.td = document.createElement('td');

                // *** CANCEL OPTION.
                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');      // SET ATTRIBUTES.
                btSave.setAttribute('value', 'Save');
                btSave.setAttribute('id', 'Save' + i);
                btSave.setAttribute('style', 'display:none;');
                btSave.setAttribute('onclick', 'crudApp.Save(this)');       // ADD THE BUTTON's 'onclick' EVENT.
                this.td.appendChild(btSave);

                // *** UPDATE.
                tr.appendChild(this.td);
                var btUpdate = document.createElement('input');

                btUpdate.setAttribute('type', 'button');    // SET ATTRIBUTES.
                btUpdate.setAttribute('value', 'Update');
                btUpdate.setAttribute('id', 'Edit' + i);
                btUpdate.setAttribute('style', 'background-color:#44CCEB;');
                btUpdate.setAttribute('onclick', 'crudApp.Update(this)');   // ADD THE BUTTON's 'onclick' EVENT.
                this.td.appendChild(btUpdate);

                // *** DELETE.
                this.td = document.createElement('th');
                tr.appendChild(this.td);
                var btDelete = document.createElement('input');
                btDelete.setAttribute('type', 'button');    // SET INPUT ATTRIBUTE.
                btDelete.setAttribute('value', 'Delete');
                btDelete.setAttribute('style', 'background-color:#ED5650;');
                btDelete.setAttribute('onclick', 'crudApp.Delete(this)');   // ADD THE BUTTON's 'onclick' EVENT.
                this.td.appendChild(btDelete);
            }


            // ADD A ROW AT THE END WITH BLANK TEXTBOXES AND A DROPDOWN LIST (FOR NEW ENTRY).

            tr = table.insertRow(-1);           // CREATE THE LAST ROW.

            for (var j = 0; j < this.col.length; j++) {
                var newCell = tr.insertCell(-1);
                if (j >= 1) {

                    if (j == 2) {   // WE'LL ADD A DROPDOWN LIST AT THE SECOND COLUMN (FOR Category).

                        var select = document.createElement('select');      // CREATE AND ADD A DROPDOWN LIST.
                        select.innerHTML = '<option value=""></option>';
                        for (k = 0; k < this.category.length; k++) {
                            select.innerHTML = select.innerHTML +
                                '<option value="' + this.category[k] + '">' + this.category[k] + '</option>';
                        }
                        newCell.appendChild(select);
                    }
                    else {
                        var tBox = document.createElement('input');          // CREATE AND ADD A TEXTBOX.
                        tBox.setAttribute('type', 'text');
                        tBox.setAttribute('value', '');
                        newCell.appendChild(tBox);
                    }
                }
            }

            this.td = document.createElement('td');
            tr.appendChild(this.td);

            var btNew = document.createElement('input');

            btNew.setAttribute('type', 'button');       // SET ATTRIBUTES.
            btNew.setAttribute('value', 'Create');
            btNew.setAttribute('id', 'New' + i);
            btNew.setAttribute('style', 'background-color:#207DD1;');
            btNew.setAttribute('onclick', 'crudApp.CreateNew(this)');       // ADD THE BUTTON's 'onclick' EVENT.
            this.td.appendChild(btNew);

            var div = document.getElementById('container');
            div.innerHTML = '';
            div.appendChild(table);    // ADD THE TABLE TO THE WEB PAGE.
        };

        // ****** OPERATIONS START.

        // CANCEL.
        this.Cancel = function (oButton) {

            // HIDE THIS BUTTON.
            oButton.setAttribute('style', 'display:none; float:none;');

            var activeRow = oButton.parentNode.parentNode.rowIndex;

            // HIDE THE SAVE BUTTON.
            var btSave = document.getElementById('Save' + (activeRow - 1));
            btSave.setAttribute('style', 'display:none;');

            // SHOW 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('booksTable').rows[activeRow];

            for (i = 0; i < this.col.length; i++) {
                var td = tab.getElementsByTagName("td")[i];
                td.innerHTML = this.myBooks[(activeRow - 1)][this.col[i]];
            }
        }


        // EDIT DATA.
        this.Update = function (oButton) {
            var activeRow = oButton.parentNode.parentNode.rowIndex;
            var tab = document.getElementById('booksTable').rows[activeRow];

            // SHOW A DROPDOWN LIST WITH A LIST OF CATEGORIES.
            for (i = 1; i < 4; i++) {
                if (i == 2) {
                    var td = tab.getElementsByTagName("td")[i];
                    var ele = document.createElement('select');      // DROPDOWN LIST.
                    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');      // TEXTBOX.
                    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;');

            // HIDE THIS BUTTON.
            oButton.setAttribute('style', 'display:none;');
        };


        // DELETE DATA.
        this.Delete = function (oButton) {
            var activeRow = oButton.parentNode.parentNode.rowIndex;
            this.myBooks.splice((activeRow - 1), 1);    // DELETE THE ACTIVE ROW.
            this.createTable();                         // REFRESH THE TABLE.
        };

        // SAVE DATA.
        this.Save = function (oButton) {
            var activeRow = oButton.parentNode.parentNode.rowIndex;
            var tab = document.getElementById('booksTable').rows[activeRow];

            // UPDATE myBooks ARRAY WITH VALUES.
            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') {  // CHECK IF ELEMENT IS A TEXTBOX OR SELECT.
                    this.myBooks[(activeRow - 1)][this.col[i]] = td.childNodes[0].value;      // SAVE THE VALUE.
                }
            }
            this.createTable();     // REFRESH THE TABLE.
        }

        // CREATE NEW.
        this.CreateNew = function (oButton) {
            var activeRow = oButton.parentNode.parentNode.rowIndex;
            var tab = document.getElementById('booksTable').rows[activeRow];
            var obj = {};

            // ADD NEW VALUE TO myBooks 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') {      // CHECK IF ELEMENT IS A TEXTBOX OR SELECT.
                    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.myBooks.length + 1;     // NEW ID.

            if (Object.keys(obj).length > 0) {      // CHECK IF OBJECT IS NOT EMPTY.
                this.myBooks.push(obj);             // PUSH (ADD) DATA TO THE JSON ARRAY.
                this.createTable();                 // REFRESH THE TABLE.
            }
        }

        // ****** OPERATIONS END.
    }

    crudApp.createTable();
</script>
</html>
Try it

I have a global function named crudApp(), which has other functions for the CRUD operations to work.

First, I have declared an Array of JSON objects with values in myBooks. This is my data, with which I’ll work.

this.myBooks = [ ];

I have another JSON object array named category. I’ll use the category object to populate the SELECT dropdown lists, which I’ll add in every row of the table.

The list (or data) is displayed in an HTML table. Since I have not included the table element in the design mode, I’ll create the table dynamically using JSON data. To do this I have declared a function named createTable().

this.createTable = function () { }

Create an HTML Table Dynamically

1) The for loop extracts the values from the array myBooks for the table header and stores it in another array called col[]. I have used this array in many functions in this application.

2) While creating the table, I am adding (or attaching) few elements dynamically to each row of the table.

The first element is a label that shows a (lblCancel.innerHTML = '✖') sign. The function of this label is like a button, to Cancel. Clicking this element will cancel the update function. Therefore, it has onclick event attached to it, which calls a function named Cancel().

lblCancel.setAttribute('onclick', 'crudApp.Cancel(this)');

Similarly, I am creating and adding three buttons (input element of type button) with events and ids. Each has a function to save, update and delete.

You can add other features using the setAttribute() method.

3) Finally, I am completing the table creation part by adding a row at the end of the table, which will have two blank textboxes and a SELECT dropdown list, followed a button (Create) at the last column. This is for creating new data for the list.

Functions for CRUD Operation

I have five different functions to perform different operations. These functions are

1) this.Cancel () – This will cancel the update procedure. Every row of the table has an Update button. Clicking this button will show two more buttons, to cancel and to save. Clicking the cancel button will call the function this.cancel() that takes a parameter as the calling element.

Using the object’s reference, you can get the active row, its elements and values.

2) this.Update () – This functions is called when you click the Update button in any row. It only shows the input elements like textbox and a dropdown list with values. So now, you can edit the values in each cell of the selected row (except the first column).

In-addition, it will show the button (to cancel) and the Save button. See the image.

Update Operation in a CRUD Application in JavaScript

3) this.Delete() – This function uses JavaScript splice() method to remove the data from JSON array.

this.myBooks.splice((activeRow - 1), 1);

The splice() usually takes three parameters, explained here. I have provided two. The first parameter is the location in the array (that’s why I am using activeRow - 1), which I want to remove. The second parameter is the number of items (I’ve 1) that I want to remove from the array. Add the value 2 and see what happens.

4) this.Save() - This function will update or save the rows data in the Array. It is associated with Update operations. The Save option is activated when the user click’s the Update button in any row.

5) this.Create() – The last row has blank boxes and a button named Create at the last column. Clicking the Create button will call this function and it will add a new set of data in the exiting list inside the myBooks array.

See this demo

Its a very basic application. You can add many more functions. The purpose of sharing this example is to show how easily, without using any JS Framework, you can create a basic CRUD application using only JavaScript.

The data that I have used in this application is a JSON array, a temporary data source. You can use a more dynamic database like SQL Server, and use Web API methods to manipulate data.

The Ajax XMLHttpRequest object is another option to make API calls in JavaScript. Here’s an example that you might use in this application.

Also Read: How to Create a Basic CRUD Application in AngularJS using $http and Asp.Net Web API MVC 4

Thanks for reading.

Previous - What is the Simplest Way to Get the Length of an Object in JavaScriptNext - Dynamically Create Checkboxes based on Textbox Values using JavaScript



Like this Article? Subscribe now, and get all the latest articles and tips, right in your inbox.

Enter your email id

Delivered by FeedBurner
Tweet this article Google+

Related Posts:

Join our Google Plus Community and be a part of a discussion!