jQuery live edit table do ajax update and delete, focusout problem

#1
I want to use jQuery make a table live edit/update/delete , but now has two problems
  1. if click the pen by order #3 to #1 , total 3 clicks, but why click the pen by order #1 to #3 total 5 clicks ?
  2. click tick icon action won't fire because input box focusout
Full code see the demo here https://jsfiddle.net/hjxr7bvf/1/
html code, loop this block n times
Mã:
<tr>
  <th>1</th>
  <td>
    <div class="d-flex align-items-center">
      <div class="flex-grow-1 mr-3">
          <div data-value="1">php</div>
          <input type="text" value="php" data-input="1" style="display: none;">
      </div>
      <a href="#" data-update="1" style="display: none;">
          <i class="fas fa-check text-success"></i>
      </a>
      <a href="#" data-edit="1">
          <i class="fas fa-pen text-info"></i>
      </a>
      <a href="#" data-destroy="1">
          <i class="fas fa-trash-alt text-info"></i>
      </a>
    </div>
  </td>
</tr>
script code
Mã:
<script type="text/javascript">
  $(function() {
      function tableReset() {
          $('[data-update]').hide(); // hide tick icon
          $('[data-input]').hide();  // hide input box
          $('[data-value]').show();  // show tag name text
          $('[data-edit]').show();   // show pen icon     
      }

      // click pen icon
      $('[data-edit]').click(function(e) {
          e.preventDefault();
          var id = $(this).data('edit');
          tableReset();

          $('[data-update="' + id + '"]').show();        // show tick icon by id
          $('[data-input="' + id + '"]').show().focus(); // show input box by id
          $('[data-value="' + id + '"]').hide();         // hide tag name text by id
          $('[data-edit="' + id + '"]').hide();          // hide pen icon by id
      });

      // click tick icon won't fire because focusout here
      // and click pen icon has problem too
      $('[data-input]').focusout(function() {
          var id = $(this).data('input');
          var value = $('[data-value="' + id + '"]').text();
          $('[data-input="' + id + '"]').val(value);

          tableReset();
      });

      // click tick icon do Ajax update
      $('[data-update]').click(function(e) {
          e.preventDefault();
          var id = $(this).data('update');
          var input = $('[data-input="' + id + '"]').val();
          $('[data-value="' + id + '"]').text(input); // set text = input val

          // action for Ajax update
      });

      // Ajax destroy
      $('[data-destroy]').click(function(e) {
          e.preventDefault();
      });
  });
</script>
Edited: read the answer below, use live table instead modal
 

Admin

Administrator
Thành viên BQT
#2
Unfocus
The appropriate event for form controls that will fire when value has changed and gets unfocused is "change". "blur" event is for when it gets unfocused without an edit.

There are many changes with comments in the demo. Since there wasn't an AJAX function posted (not needed, don't worry), I adjusted for a live test server just for fun. All changes with the exception of the following code is optional:

Point of Interest
Mã:
input.on('change blur', function(e) {
    var id = $(this).data('input') - 1;
    saveData(id);
    done();
  });
Demo
Fiddle
Details are commented in demo
Note:
For some reason the form isn't submitting to the test server on SO but it is on the Fiddle

Mã:
$(function() {
      // All classes are stored in variables for easier use
      /*
      Instead of this:
      > $('[data-messy="' + id + '"]');
      we are using this:
      > clean.eq(id);
      */
      var update = $('.update');
      var input = $('.input');
      var value = $('.value');
      var edit = $('.edit');
      var destroy = $('.destroy');

      function done() {
        update.add(input).hide();
        value.add(edit).show();
      }

      function editData(id) {
        update.eq(id).show();
        input.eq(id).show().focus();
        value.eq(id).hide();
        edit.eq(id).hide();
      }

      function saveData(id) {
        var v = input.eq(id).val();
        value.eq(id).text(v);
      }

      function deleteData(id) {
        if (id === -1) {
          input.val('');
          value.text('');
        } else {
          input.eq(id).val('');
          value.eq(id).text('');
        }
      }

      edit.click(function(e) {
        done();
        var id = $(this).data('edit') - 1;
        editData(id);
      });
     
      /*
      The appropriate event for form controls that will fire when value has changed and gets unfocused is "change". "blur" event is for when it gets unfocused without an edit.
      */
      input.on('change blur', function(e) {
        var id = $(this).data('input') - 1;
        saveData(id);
        done();
      });

      update.on('click', function(e) {
        //e.preventDefault();
        var id = $(this).data('update') - 1;
        saveData(id);
        done();
      });

      destroy.click(function(e) {
        var id = $(this).data('destroy') - 1;
        deleteData(id);
        done();
      });
    });
Mã:
/* Added so there's no jumping heights on rows when a button is toggled */
td div {
  line-height: 2;
}

/* Multiple repeats of class selector will override Bootstrap styles */
button.update.update.update {
  border-color: transparent;
  background: none;
  padding: 0;
  line-height: 1
}
Mã:
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/solid.js" integrity="sha384-GJiigN/ef2B3HMj0haY+eMmG4EIIrhWgGJ2Rv0IaWnNdWdbWPr1sRLkGz7xfjOFw" crossorigin="anonymous"></script>
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/fontawesome.js" integrity="sha384-2OfHGv4zQZxcNK+oL8TR9pA+ADXtUODqGpIRy1zOgioC4X3+2vbOAp5Qv7uHM4Z8" crossorigin="anonymous"></script>
  </head>

  <body>
  <!--All buttons have a class added form easier use-->
<!--All button anchor [href] attribute values are changed to href="#/" -- this prevents jumping to locations, so e.preventDefault() is no longer needed-->

    <div class="container-fluid">
      <div class="row">
        <div class="col">
          <h4>
            click pen edit, click tick update
          </h4>
          <!--This form was added just to send to a live test server. The response is sent to the iframe located below the form-->
          <form id="tags" action='https://httpbin.org/post' method='post' target='response'>

            <table class="table table-bordered">
              <thead>
                <tr>
                <!--This column never needs to expand more than its content-->
                  <th width='24px' scope="col">#</th>
                  <th class="col-sm-10" scope="col">Tag Name

                    <!--Destroy all button-->
                    <a href="#/" class='destroy float-right float-right' data-destroy="0">
                          <i class="fas fa-trash-alt text-info"></i>
                      </a>
                  </th>

                </tr>
              </thead>
              <tbody>

                <tr>
                <!--1st column has a hidden input-->
                  <th scope="row">1<input name="#" value="1" type="hidden"></th>
                  <td>
                    <div class="group d-flex align-items-center">
                      <i class="fas fa-tag fa-fw text-success mr-3"></i>
                      <div class="flex-grow-1 mr-3">
                        <div class='value' data-value="1">php</div>
                       <!--Added [name="Tag Name"]-->
                        <input type="text" class="input form-control form-control-sm" name="Tag Name" value="php" data-input="1" style="display: none;">
                      </div>
                      <!--All update buttons are real buttons so they submit automatically-->
                      <button class="update mr-3" data-update="1" style="display: none;">
                          <i class="fas fa-check text-success"></i>
                      </button>
                      <a href="#/" class="edit mr-3" data-edit="1">
                          <i class="fas fa-pen text-info"></i>
                      </a>
                      <a href="#/" class='destroy' data-destroy="1">
                          <i class="fas fa-trash-alt text-info"></i>
                      </a>
                    </div>
                  </td>
                </tr>

                <tr>
                  <th scope="row">2<input name="#" value="2" type="hidden"></th>
                  <td>
                    <div class="d-flex align-items-center">
                      <i class="fas fa-tag fa-fw text-success mr-3"></i>
                      <div class="flex-grow-1 mr-3">
                        <div class='value' data-value="2">javascript</div>
                        <input type="text" class="input form-control form-control-sm" name="Tag Name" value="javascript" data-input="2" style="display: none;">
                      </div>
                      <button class="update mr-3" data-update="2" style="display: none;">
                          <i class="fas fa-check text-success"></i>
                      </button>
                      <a href='#/' class="edit mr-3" data-edit="2">
                          <i class="fas fa-pen text-info"></i>
                      </a>
                      <a href="#/" class='destroy' data-destroy="2">
                          <i class="fas fa-trash-alt text-info"></i>
                      </a>
                    </div>
                  </td>
                </tr>

                <tr>
                  <th scope="row">3<input name="#" value="3" type="hidden"></th>
                  <td>
                    <div class="group d-flex align-items-center">
                      <i class="fas fa-tag fa-fw text-success mr-3"></i>
                      <div class="flex-grow-1 mr-3">
                        <div class='value' data-value="3">css</div>
                        <input type="text" class="input form-control form-control-sm" name="Tag Name" value="css" data-input="3" style="display: none;">
                      </div>
                      <button class="update mr-3" data-update="3" style="display: none;">
                          <i class="fas fa-check text-success"></i>
                      </button>
                      <a href="#/" class="edit mr-3" data-edit="3">
                          <i class="fas fa-pen text-info"></i>
                      </a>
                      <a href="#/" class='destroy' data-destroy="3">
                          <i class="fas fa-trash-alt text-info"></i>
                      </a>
                    </div>
                  </td>
                </tr>

              </tbody>
            </table>
          </form>
          <h5>
            Test Server Response
          </h5>
          <iframe name='response'></iframe>
        </div>
      </div>
    </div>




    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

  </body>

</html>
References
.eq()
.change()
.blur()
.on()
 
OP
OP
K

kenken9999

New Member
#3
OMG OMG you rock, your code is very beautiful, so after ajax response success, just renew the ('.value').text and ('.input').val() ?
 

Admin

Administrator
Thành viên BQT
#4
You're very welcome! Thank you, my C++ professor said the same thing about my code. Yeah on the update.on('click',...` try using the first 2 statements in function destroyData() { if (id === -1) { this part } ...
 
OP
OP
K

kenken9999

New Member
#5
i will upvote this x 10000 if i can, thankyou very very much, i going to try add the ajax part, thx again
 

Từ khóa phổ biến

You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an alternative browser.

Top