Delete the selected row from a Material Design Lite dialog

1

I have this example table made with material design lite . The last column of the table has a CLEAR button that when pressed must show a dialog box where the option to delete the selected row is given.

Right now this is my code. It seems to be working, however, I am using a global variable fila that I do not like too much. What recommendations can you give me to improve this code?

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://code.getmdl.io/1.1.1/material.indigo-pink.min.css">
  </head>
  <body>

    <dialog class="mdl-dialog">
      <h4 class="mdl-dialog__title">Borrado filas</h4>
      <div class="mdl-dialog__content">
        <p>
          Desea eliminar la fila seleccionada?
        <p>
      </div>
      <div class="mdl-dialog__actions">
        <button type="button" class="mdl-button aceptar">Aceptar</button>
        <button type="button" class="mdl-button close">Cancelar</button>
      </div>
    </dialog>

    <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
      <thead>
        <tr>
          <th class="mdl-data-table__cell--non-numeric">Material</th>
          <th>Cantidad</th>
          <th>Borrar</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
          <td>25</td>
          <td><button id="show-dialog" type="button" class="mdl-button borrar">Borrar</button></td>
        </tr>
        <tr>
          <td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
          <td>50</td>
          <td><button id="show-dialog" type="button" class="mdl-button borrar">Borrar</button></td>
        </tr>
        <tr>
          <td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
          <td>10</td>
          <td><button id="show-dialog" type="button" class="mdl-button borrar">Borrar</button></td>
        </tr>
      </tbody>
    </table>

    <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
    <script defer src="https://code.getmdl.io/1.1.1/material.min.js"></script>
    <script>
      var dialog = document.querySelector('dialog');
      var showDialogButton = document.querySelector('#show-dialog');
      var fila; //variable global
      if (! dialog.showModal) {
        dialogPolyfill.registerDialog(dialog);
      }
      $('body').on('click', '.borrar', function(e) {
        fila = $(this).parent().parent();
        dialog.showModal();
      });
      dialog.querySelector('.close').addEventListener('click', function() {
        dialog.close();
      });
      dialog.querySelector('.aceptar').addEventListener('click', function() {
        fila.remove();
        dialog.close();
      });
    </script>

  </body>
</html>
    
asked by Javier Cárdenas 09.02.2016 в 17:55
source

2 answers

2

If you want to avoid the global variable, one option would be to add a class (or a data-* attribute) to the row you are operating with. Then: if the user clicks on "Cancel", the class is removed from the row; or if the user clicks "Accept" the element that has that class is deleted.

Although not directly related to the global variable, something else that would change in the code is this: $(this).parent().parent() . That works well with the current structure, but if you change the structure in the future, you will have to change that line as well. However if you replace it with $(this).closest("tr") , you no longer have to worry about whether the button changes its relative position within the row.

So the code would look like this:

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://code.getmdl.io/1.1.1/material.indigo-pink.min.css">
  </head>
  <body>

    <dialog class="mdl-dialog">
      <h4 class="mdl-dialog__title">Borrado filas</h4>
      <div class="mdl-dialog__content">
        <p>
          Desea eliminar la fila seleccionada?
        <p>
      </div>
      <div class="mdl-dialog__actions">
        <button type="button" class="mdl-button aceptar">Aceptar</button>
        <button type="button" class="mdl-button close">Cancelar</button>
      </div>
    </dialog>

    <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
      <thead>
        <tr>
          <th class="mdl-data-table__cell--non-numeric">Material</th>
          <th>Cantidad</th>
          <th>Borrar</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
          <td>25</td>
          <td><button id="show-dialog" type="button" class="mdl-button borrar">Borrar</button></td>
        </tr>
        <tr>
          <td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
          <td>50</td>
          <td><button id="show-dialog" type="button" class="mdl-button borrar">Borrar</button></td>
        </tr>
        <tr>
          <td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
          <td>10</td>
          <td><button id="show-dialog" type="button" class="mdl-button borrar">Borrar</button></td>
        </tr>
      </tbody>
    </table>

    <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
    <script defer src="https://code.getmdl.io/1.1.1/material.min.js"></script>
    <script>
      var dialog = document.querySelector('dialog');
      var showDialogButton = document.querySelector('#show-dialog');
      if (! dialog.showModal) {
        dialogPolyfill.registerDialog(dialog);
      }
      $('body').on('click', '.borrar', function(e) {
        $(this).closest("tr").addClass("active-row");
        dialog.showModal();
      });
      dialog.querySelector('.close').addEventListener('click', function() {
        $("tr.active-row").removeClass("active-row");
        dialog.close();
      });
      dialog.querySelector('.aceptar').addEventListener('click', function() {
        $("tr.active-row").remove();
        dialog.close();
      });
    </script>

  </body>
</html>
    
answered by 09.02.2016 / 18:42
source
1

The first solution to eliminate the use of global variables is to use a IIFE , in this way all the variables that you declare are local and there is no contamination of global scope .

(function() {
  'use strict';

  var dialog = document.querySelector('dialog');
  var showDialogButton = document.querySelector('#show-dialog');
  var fila; //ya no es global sino una variable local limitada al ámbito del IIFE
  if (!dialog.showModal) {
    dialogPolyfill.registerDialog(dialog);
  }
  $('body').on('click', '.borrar', function(e) {
    fila = $(this).parent().parent();
    dialog.showModal();
  });
  dialog.querySelector('.close').addEventListener('click', function() {
    dialog.close();
  });
  dialog.querySelector('.aceptar').addEventListener('click', function() {
    fila.remove();
    dialog.close();
  });

}());

The IIFE can be found in these two formats. The only thing that changes is the position of the invoking parentheses.

// Pasa jslint y jshint
(function() {

} ());

// No pasa jslint pero si jshint
(function() {

})();

The option that I recommend and second variant is that you wrap all your code in a function ready from jQuery since > the IIFEs are not a replacement for these events . These will run immediately and in your code there is a script with attribute defer which means that it will be executed after the document is loaded which can leave your function dialogPolyfill as undefined for example.

$(function() {
   'use strict';

   var dialog = document.querySelector('dialog');
   var showDialogButton = document.querySelector('#show-dialog');
   var fila; //ya no es global sino una variable local limitada al ámbito del la función anónima que le pasas a jQuery

   if (!dialog.showModal) {
       dialogPolyfill.registerDialog(dialog);
   }
   $('body').on('click', '.borrar', function(e) {
       fila = $(this).parent().parent();
       dialog.showModal();
   });
   dialog.querySelector('.close').addEventListener('click', function() {
       dialog.close();
   });
   dialog.querySelector('.aceptar').addEventListener('click', function() {
       fila.remove();
       dialog.close();
   });
 });  

Either of these two formats is recommended

$( document ).ready( handler )
$( handler )

Finally, as a personal note, I see that in some places you use jQuery and other pure javascript for selectors. I recommend consistency, if you decide to use jQuery jQuery because the browsers have inconsistencies with each other and jQuery is responsible for dealing with these in your place, otherwise you would have to deal with them to have a uniform experience. This is a general advice, it does not necessarily apply to your code snippet.

    
answered by 09.02.2016 в 18:51