jqueryhtmlresponsive-design

jQuery: Creating a responsive datagrid


I'm trying to create a responsive datagrid in which I can edit and add rows. The rows come from a database, and upon edit or creation of a new row it should be updated/inserted in the database. In the old days I would just have used a plain form and a submit to handle the data in PHP, now I'm trying to learn the same stuff in a more modern way.

I've come a long way already, I can update a row and a can insert a new one, returning the id and using it in the table. What however doesn't work is updatein a row that was just inserted. When I click the edit icon for such a row, it does seem to go to edit mode, but instead it is inserting a new row in the background. Any idea where I'm going wrong?

I'm also wondering if there is a less complicated way to do this, it seems I have to write a load of code for a table with just 3 fields, any advice?

The HTML part looks like this:

<table class="table table-bordered" id="schedules">
            <thead>
                <tr>
                    <th>Time from</th>
                    <th>Time to</th>
                    <th>Enabled</th>
                                        <th></th>
                </tr>
            </thead>
            <tbody>
                
                                <tr id="1">
                    <td id="time_from">16:01</td>
                    <td id="time_to">23:01</td>
                    <td id="enabled">true</td>
                    <td id="edit"><i class="fa fa-pencil-square-o fa-fw" id="editicon"></i></td>
                </tr>
                                <tr id="2">
                    <td id="time_from">10:00</td>
                    <td id="time_to">11:00</td>
                    <td id="enabled">false</td>
                    <td id="edit"><i class="fa fa-pencil-square-o fa-fw" id="editicon"></i></td>
                </tr>
                                
            </tbody>
        </table>
                
            <i class="fa fa-plus" id="addRow"></i>
            

The JavaScript/jQuery part looks like this:

<script>
                //function for when the addrow action is used
                $('#addRow').on('click',function(){ 
                    $('#schedules > tbody:last-child').append('<tr id="newrow"><td id="time_from"><input id="time_from"/></td><td id="time_to"><input id="time_to"/></td><td id="enabled"><input id="enabled"/></td><td id="saveicon"><i class="fa fa-check fa-fw" id="saveicon"></i></td></tr>');
                
                    //function for when the save new row icon is pressed
                    $('#saveicon').on('click',function(){ 
                        //Send data to script to store as now row in db
                        $.get( "/settings/insertSchedule/" + $('#newrow input#time_from').val() + "/" + $('#newrow input#time_to').val() + "/" +   $('#newrow input#enabled').val()  , function( data ) {
                            
                            //Change input fields to text fields
                            $('#newrow td#time_from').text($('#newrow input#time_from').val());
                            $('#newrow td#time_to').text($('#newrow input#time_to').val());
                            $('#newrow td#enabled').text($('#newrow input#enabled').val());
                            
                            //change checkmark icon into edit icon
                            $('#newrow i#saveicon').attr('class', 'fa fa-pencil-square-o fa-fw');
                            $('#newrow i#saveicon').attr('id', 'editicon');                
                            $('#newrow td#saveicon').attr('id', 'edit');                
                            
                            $('#newrow').attr('id',data);                
                            console.log(data);
                        });
                    });
                });
    
                
                //function for when the edit row icon is clicked
                var arr = {};
                $('#schedules').on('click','#edit',function() {
                    var rowid = ($(this).parent().attr('id'));
                    $(this).siblings().each(
                        function(){
                                //end of editing, change the icon back to a pencil and change the fields back to text
                                if ($(this).find('input').length){
                                $(this).text($(this).find('input').val());
                                $('#editicon').attr('class', 'fa fa-pencil-square-o fa-fw');
                                arr[this.id] = $(this).html()
                            }
                            else {
                                //start of editing, change fields to input fields and icon to checkmark
                                var t = $(this).text();
                                $(this).html($('<input />',{'value' : t}).val(t));
                                $('#editicon').attr('class', 'fa fa-check fa-fw');
                            }
                    });
                    
                    //Send updated data to script to store in DB.
                    if (Object.keys(arr).length > 0){
                        $.get( "/settings/updateSchedule/" + rowid + "/" + arr.time_from + "/" + arr.time_to    , function( data ) {});
                        
                    }
                }); 

                
                
                </script>
            

Edit: I've simulated the problem in a slightly modified form in jsfiddle: jsfiddle.net/15dd3j3v


Solution

  • Here the JSfiddle https://jsfiddle.net/15dd3j3v/5/

    HTML:

    <table class="table table-bordered" id="schedules" border="1">
      <thead>
        <tr>
          <th>Time from</th>
          <th>Time to</th>
          <th>Enabled</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
    
        <tr id="1">
          <td class="td_time_from">16:01</td>
          <td class="td_time_to">23:01</td>
          <td class="td_enabled">true</td>
          <td class="button"><button class="editBtn"><i class="fa fa-pencil-square-o fa-fw" ></i> edit</button></td>
        </tr>
        <tr id="2">
          <td class="td_time_from">10:00</td>
          <td class="td_time_to">11:00</td>
          <td class="td_enabled">false</td>
          <td class="button"><button class="editBtn"><i class="fa fa-pencil-square-o fa-fw"></i> edit</button></td>
        </tr>
    
      </tbody>
    </table>
    
    <button id="addRow"><i class="fa fa-plus"></i> add row</button>
    

    JS:

    var fakeId = 3;
    
    function getRowForSaving(){
        return '<tr id="newrow"><td class="td_time_from"><input class="input_time_from"/></td><td class="td_time_to"><input class="input_time_to" /></td><td class="td_enabled"><input class="input_enabled" /></td><td><button class="saveBtn"><i class="fa fa-check fa-fw"></i>save</button><button class="cancelBtn">&times;</button></td></tr>';
    }
    
    function getRowWithData(id, time_from, time_to, enabled){
        return '<tr id="'+id+'"><td class="td_time_from">'+time_from+'</td><td class="td_time_to">'+time_to+'</td><td class="td_enabled">'+enabled+'</td><td><button class="editBtn"><i class="fa fa-pencil-square-o fa-fw" ></i> edit</button></td></tr>';
    }
    function getRowForEdit(id, time_from, time_to, enabled){
        return '<tr id="'+id+'"><td class="td_time_from"><input class="input_time_from" value="'+time_from+'" /></td><td class="td_time_to"><input class="input_time_to" value="'+time_to+'" /></td><td class="td_enabled"><input class="input_enabled" value="'+enabled+'" /></td><td><button class="saveEditBtn"><i class="fa fa-pencil-square-o fa-fw" ></i> Save edit</button></td></tr>';
    }
    
    //function for when the addrow action is used
    $('#addRow').on('click', function() {
      $('#schedules > tbody:last-child').append(getRowForSaving());
    });
    
    $('#schedules').on('click', '.cancelBtn', function(){
        $(this).parents('tr').remove();
    });
    
    $('#schedules').on('click', '.saveBtn', function(){
        var $row = $(this).parents('tr');
      var time_from = $row.find('.input_time_from').val();
      var time_to = $row.find('.input_time_to').val();
      var enabled = $row.find('.input_enabled').val();
      console.log("Save this datas \ntime_from: " + time_from + "\ntime_to: " + time_to + "\nenabled:"+enabled);
    
      // SAVING FUNCTION
    
      $row.replaceWith(getRowWithData(fakeId,time_from, time_to, enabled));
      fakeId++;
    });
    
    $('#schedules').on('click', '.editBtn', function(){
        var $row = $(this).parents('tr');
      var id = $row.attr('id');
      var time_from = $row.find('.td_time_from').text();
      var time_to = $row.find('.td_time_to').text();
      var enabled = $row.find('.td_enabled').text();
    
      console.log("EDIT MODE for row: " + id );
    
      $row.replaceWith(getRowForEdit(id, time_from, time_to, enabled));
    });
    
    $('#schedules').on('click', '.saveEditBtn', function(){
        var $row = $(this).parents('tr');
      var id = $row.attr('id');
      var time_from = $row.find('.input_time_from').val();
      var time_to = $row.find('.input_time_to').val();
      var enabled = $row.find('.input_enabled').val();
      console.log("Save the edit this datas \nid: "+id+"\ntime_from: " + time_from + "\ntime_to: " + time_to + "\nenabled:"+enabled);
    
      // SAVE EDIT FUNCTION
    
      $row.replaceWith(getRowWithData(id, time_from, time_to, enabled));
    });
    

    I've re-written some part of your code to make what you require. I've tried to use your style of coding to much as possible. Some parts are written long-winded to aid comprehension.

    However I suggest you use a pre written library like JQuery Grid http://www.trirand.com/blog/ that is the best solution because you must work hard to get a good grid with deep functionality like JQgrid

    Write a comment if you need help, remember to vote up and check the answer if its help byeee