Skip to main content
Engineering LibreTexts

7.4: Integrating the CRUD Application with the Server

  • Page ID
    27576
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    The last step in developing the CRUD program to access the server is to integrate the HTTP transactions into the program. This section will do this.

    7.4.1 Changes to the application

    There some minor differences between the CRUD application from Chapter 6 and the application as presented here. The differences all relate to the removal of the Save to File and Read from File buttons. These buttons were removed to better match the operations of the REST interface to the server.

    The first thing the application now does when it loads is read the data from the server. There is no need to specify that the data is to be read, and the Read from File button was removed.

    Next the read, update, and delete operations will immediately affect the data in the server, and not the local copy in an array of the data. All operations are therefore automatically saved, and the entire modified copy of the data in the local array does not need to be save back at the end of the execution of the program, and the Save to File button was removed.

    This requires that one other change be made. When a user changes the data on the server in any way, all of the data from the server is requested and used to repopulate the list of items on the server.

    7.4.2 Populating the drop-down list of map items

    The drop-down list of map items is the first GUI component that will be implemented. This component will be created and populated when the application first comes up, and each time the data server is changed, and so is abstracted as a function. The code to implement this drop-down list is as follows:

    Program 120 – XMLHttpRequest example to load the drop-down
    
    function readDataFromServer() {
        // clear out the list and array
        $("#dataRecords").empty();
        records = new Array();
        
        // get the records array from remote server
        let xmlhttp = new XMLHttpRequest();
        let url = "mapData"
        xmlhttp.open("GET", url, true);
        xmlhttp.setRequestHeader("Content-Type", "application/json");
        xmlhttp.onreadystatechange = function (){
            if(xmlhttp.readyState === 4) {
                if(xmlhttp.status === 200) {
                    let arr = JSON.parse(xmlhttp.responseText);
                    // Get each map, parse it, and put it in the records
                    // array and list.
                        for (var i = 0; i < arr.length; i++) {
                            records[i] = new MyMap(arr[i]);
                            $('#dataRecords').append($("<option></option>")
                                             .attr("value", records[i].id)
                                             .text(records[i].title));
                        }
                    }
                    else {
                        var allText = xmlhttp.responseText;
                        $("#UserMessage").val("status = " + xmlhttp.status
                            +"text=" +allText)
                    }
                }
            }
            xmlhttp.send()
    }                                                                                                     
    

    In the GUI code for accessing the server, note that the value field in the drop-down is now the id. This is hidden from the user but is how the database will be accessed.

    The rest of the code for this GUI is in the file CRUDOnLoad.js file in the WebApplication directory that codes with this textbook. It is presented without comment.

    Program 121 – Complete Map CRUD application with server to persist data
    
    $(function() {
        /*
            display the map
         */
         let map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM(),
                })     
            ], 
            
            view: new ol.View({
                center: ol.proj.fromLonLat([-77.2113732910156, 39.849999999999994]), zoom: 10
            })
        });
        
        /*
            Get records from server
         */
         function readDataFromServer() {
            // clear out the list
            $("#dataRecords").empty();
            
            // get the records from remote server
            var xmlhttp = new XMLHttpRequest();
            var url = "mapData"
            xmlhttp.open("GET", url, true);
            xmlhttp.setRequestHeader("Content-Type", "application/json");
            xmlhttp.onreadystatechange = function ()
            {
                if(xmlhttp.readyState === 4)
                {
                    if(xmlhttp.status === 200)
                    {
                        let arr = JSON.parse(xmlhttp.responseText);
                        
                        // Each record was set to JSON independently. Get
                        // each record, parse it, and put it in the list
                        for (var i = 0; i < arr.length; i++) {
                            $('#dataRecords').append($("<option></option>")
                                             .attr("value", arr[i].id)
                                             .text(arr[i].title));
                            }                                         
                        }
                        else
                        {
                            var allText = xmlhttp.responseText;
                            $("#UserMessage").val("status = " +
                                xmlhttp.status + " text = " + allText)
                        }
                    }
                }
                xmlhttp.send()
            }
            
            readDataFromServer();
            
            /*
                Implement the ability to change options
             */
             
             function changeOptions() {
                
                let center = new Array(2);
                center[0] = parseFloat(document.getElementById("longitude").value);
                center[1] = parseFloat(document.getElementById("latitude").value );
                
                let zoomLevel = parseInt(map.getView().getZoom());
                let maxZoom = zoomLevel;
                let minZoom = zoomLevel
                if ($("#resize").prop("checked")) {
                    maxZoom = 28;
                    minZoom = 0;            
                }
                
                if ($("#recenter").prop("checked")) {
                    let view=new ol.View({
                    center: ol.proj.fromLonLat(center),
                    zoom: zoomLevel,
                    minZoom: minZoom,
                    maxZoom: maxZoom,
                    extent: ol.proj.transformExtent([-180, -90, 180, 90], 'EPSG:4326', 'EPSG:3857'),
                    });
                    map.setView(view);
                }
                else {
                    let view=new ol.View({
                        center: ol.proj.fromLonLat(center),
                        zoom: zoomLevel,
                        minZoom: minZoom,
                        maxZoom: maxZoom,
                        extent: ol.proj.transformExtent([center[0], center[1], center[0], center[1]], 'EPSG:4326', 'EPSG:3857'),
                    });
                    map.setView(view);
                }
            }
            
            $("#recenter").click( () => {
                changeOptions();
            });
            
            $("#resize").click( () => {
                changeOptions();        
            });
                        
        /*
            Function:    Delete a Map record
            Purpose:     To respond to the delete button
         */
         $("#delete").click( () => {
         
            // get record to read from list
            let myID = $("#dataRecords").val();
            let myName= $("#dataRecords option:selected").text();
            
            // Record is not found, throw exception
            if (myID == null)
            {
                $("#userMessage").show();
                $("#userMessage").val("Record does not exist - Make sure a record is selected" );
                    throw "The title does not exist";
            }
            
            // Confirm Delete
            let retVal = confirm("Do you want to delete " + myName + " ?");    
            if( retVal == true ){
                var xmlhttp = new XMLHttpRequest();
                var url = "/mapData/" + myID;
                xmlhttp.open("delete", url, true);
                xmlhttp.setRequestHeader("Content-Type", "application/json");
                xmlhttp.onreadystatechange = function ()
                {
                    if(xmlhttp.readyState === 4)
                    {
                        if(xmlhttp.status === 200)
                        {
                            var allText = xmlhttp.responseText;
                            console.log("status = " + xmlhttp.status + " text = " + allText);
                            readDataFromServer();
                        }
                        else
                        {
                            var allText = xmlhttp.responseText;
                            console.log("status = " + xmlhttp.status + " text = " + allText);
                            readDataFromServer();
                        }
                    }
                }
                // send request
                xmlhttp.send()
            }
        });
            /*
            Function:    Save record data from new button
            Purpose:     To respond to the New Button
             */
             $("#new").click( ()=> {
             
            var saveObj = readDataFromForm();
            var xmlhttp = new XMLHttpRequest();
            var url = "/mapData"
            xmlhttp.open("POST", url, true);
            xmlhttp.setRequestHeader("Content-Type", "application/json");
            xmlhttp.onreadystatechange = function ()
            {
                if(xmlhttp.readyState === 4)
                {    
                    if((xmlhttp.status === 200) || (xmlhttp.status === 201))
                    {
                        var allText = xmlhttp.responseText;
                        console.log("succeeded - status = " + xmlhttp.status + " text = " + allText)                        
                        // hide the input form
                        $("#inputForm").hide();
                        readDataFromServer();
                    }
                    else
                    {
                        var allText = xmlhttp.responseText;
                        console.log("failed - status = " + xmlhttp.status + " text = " + allText)
                        readDataFromServer();
                    }
                }
            }
            
            xmlhttp.send(JSON.stringify(saveObj));
        });
        /*
            respond to the list box
         */
         
         $("#dataRecords").click( () => {
            // get record to read from list
            let myID = $("#dataRecords").val();
            let myName= $("#dataRecords option:selected").text();
            
            // Retrieve record from server
            // get the records from remote server
                let xmlhttp = new XMLHttpRequest();
                let url = "mapData/"+ myID;
                xmlhttp.open("GET", url, true);
                xmlhttp.setRequestHeader("Content-Type", "application/json");     
                xmlhttp.onreadystatechange = function ()
                {
                    if(xmlhttp.readyState === 4)
                    {
                        if(xmlhttp.status === 200)
                        {
                            let allText = xmlhttp.responseText;
                            let obj1 = JSON.parse(allText);
                            let center = [obj1.longitude, obj1.latitude]        
                            console.log(obj1);
                            writeDataToForm(obj1);
                            let view=new ol.View({
                                center: ol.proj.fromLonLat(center),
                                zoom: 10,
                                // This does not work and needs to be fixed...
                                //minZoom: minZoom,
                                //maxZoom: maxZoom,
                                //extent: ol.proj.transformExtent([-180, 90, 180, 90], 'EPSG:4326', 'EPSG:3857'),
                            });
                            map.setView(view);
                        }
                        else
                        {
                            var allText = xmlhttp.responseText;
                            console.log("status = " + xmlhttp.status + " text = " + allText)
                        }
                    }                                        
                }
                xmlhttp.send()
        });
        
        /*
            Set a listener for when the map is moved.
         */
        map.on('moveend', function() {
            let center = ol.proj.toLonLat(map.getView().getCenter());
            document.getElementById("longitude").value = center[0];
            document.getElementById("latitude").value = center[1];
            return true;                                                                                       
        });
        
    });                                                                                                                                                                              
    

    This page titled 7.4: Integrating the CRUD Application with the Server is shared under a CC BY license and was authored, remixed, and/or curated by Charles W. Kann III.

    • Was this article helpful?