Criando widget usando jQuery

Ítalo Queiroz,JavascriptjQuery

Atualmente a moda é namorar pelado Widget’s, que são componentes de interface que fornecem uma funcionalidade específica. Acessando o site da jQueryUI encontrei este link Widget Factory (opens in a new tab).

Montei o exemplo a seguir tentando repassa o que consegui abstrair dos conceitos informados pela jQueryUI.

Primeiro iremos criar 2 arquivos index.html e jquery.custom.list.js

No index.html montaremos uma estrutura simples de html adicionando algumas chamadas para as libs da jQuery (v 1.8) e jQueryUI (v 1.9).

index.html
<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <title></title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
  <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
  <script type="text/javascript" src="jquery.custom.list.js"></script>
  <style type="text/css">
      table td, table th {
          padding:5px;
      }
  </style>
</head>
<body>
  <div id="demo"></div>
</body>
</html>

O jquery.custom.list.js será o arquivo onde criaremos nosso widget.

jquery.custom.list.js
$(function() {
  $.widget("custom.list", {
    // default options
    options: {
      data: [],
      columns: ['nome', 'idade']
    },
 
    htmlTable: null,
 
    //Construtor
    _create: function() {
      console.log('construtor');
      this.element.addClass('custom-list');
      this._refresh();
    },
 
    //Este método é chamada assim que for criado e quando for alterada as opções.
    _refresh: function() {
      //verifica se foi informado os dados.
      if (this.options.data.length) {
        this._createTable();
        this._createHeaderTable();
        this._createBodyTable();
      } else {
        $('<div>', {id:"custon-list-alert", text:"Não existem registros"})
          .appendTo(this.element);
      }
    },
 
    //Método privado que cria a tabela
    _createTable: function () {
      this.element.html('<table>');
    },
 
    //Método privado que cria o cabeçalho
    _createHeaderTable: function () {
      var headerTable = $('<thead>');
 
      $('<tr>').appendTo(headerTable);
      $.each(this.options.columns, function(key, column){
        $('<th>', {text:column, class:'ui-widget-header'}).appendTo(headerTable.find('tr'));
      });
 
      this.element.find('table').html(headerTable);
    },
 
    //Método privado que monta o corpo da tabela com os dados passados.
    _createBodyTable: function () {
      var bodyTable = $('<tbody>'),
      self = this;
 
      $.each(self.options.data, function(key, data){
        $('<tr>').appendTo(bodyTable);
        $.each(self.options.columns, function(i, column){
          $('<td>', {text: (data[column]?data[column]:'') , class:'ui-state-default'}).appendTo(bodyTable.find('tr:last-child'));
        });
      });
 
      this.element.find('table').append(bodyTable);
    },
 
    //Responsável por remover o plugin e fazer as limpezas necessárias.
    _destroy: function() {
      this.element.find('table').remove();
      this.element.removeClass('custom-list');
    },
 
    // Este método é chamado sempre que uma opção é alterada
    // e toda vez que uma opção é alterada atualizamos nosso widget.
    _setOptions: function() {
      // _super and _superApply continuam a manipulação correta dos argumentos passados.
      this._superApply( arguments );
      this._refresh();
    }
  });
});

No início do arquivo temos a chamada do $.widget que tem como primeiro parâmetro o namespace (custom) e nome (list) do seu plugin, caso o namespace não exista a jQuery já criara a instância. O segundo parâmetro é o objeto widget de onde você deseja herdar, podendo este também ser um novo objeto. Terceiro parâmetro são as configurações que você deseja adicionar ou sobrescrever no widget herdado.

Como você pode perceber temos alguns métodos que iniciam com “_” (underscore), este são métodos privados (por convenção) não podem ser acessados Ex: $('#demo').list('_create')

São necessários a princípio as seguintes implementações:

Adicionei meus métodos privados: _refresh, _createTable, _createHeaderTable, _createBodyTable.

E sobrescrevi o setOptions, pois sempre que for alterado meus options o widget será atualizado (_refresh).

Abra o console do seu navegador e tente as seguintes instruções, uma por vez:

$('#demo').list('option', 'columns', ['nome']);
$('#demo').list('option', 'data', [{nome:'Nome de alguém', idade:43}]);
$('#demo').data('list')._refresh;
$('#demo').list('destroy');

Link do código no GitHub (opens in a new tab)

RSS