Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /*
  2.  * Copyright (c) 2013 ROMERO Christophe (chromero).  All rights reserved.
  3.  * jquery.table.js is a part of jquery.table library
  4.  * ====================================================================
  5.  *
  6.  * jquery.table library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public License as
  8.  * published by the Free Software Foundation, either version 3 of the License,
  9.  * or any later version.
  10.  *
  11.  * This is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14.  * See the GNU Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18.  */
  19.  
  20. /*
  21.  * voir http://chromero.blogspot.fr/search/label/jQueryTable
  22.  */
  23.  
  24. (function($) {
  25.  
  26.     $.widget("ui.table", {
  27.         options: {
  28.             name: "table",
  29.             default_controls: [{
  30.                     id: 'first',
  31.                     icon: 'ui-icon-arrowthickstop-1-w'
  32.                 }, {
  33.                     id: 'previous',
  34.                     icon: 'ui-icon-arrowthick-1-w'
  35.                 }, {
  36.                     id: 'next',
  37.                     icon: 'ui-icon-arrowthick-1-e'
  38.                 }, {
  39.                     id: 'last',
  40.                     icon: 'ui-icon-arrowthickstop-1-e'
  41.                 }, {
  42.                     id: 'reset_filter',
  43.                     icon: 'ui-icon-circle-close'
  44.                 }/*, {
  45.                  id : 'filter',
  46.                  icon : 'ui-icon-search'
  47.                  } */],
  48.             controls: [],
  49.             page_size: 30,
  50.             page: 1,
  51.             page_count: 1,
  52.             filter: null, // filter [{}, ..]
  53.             oddclass: 'table_odd',
  54.             evenclass: 'table_even',
  55.             sort: null, // tri
  56.             columns: null, // liste des colonnes
  57.             ajaxLoading: 0          // pour l'icone
  58.         },
  59.         _init: function() {
  60.         },
  61.         /**
  62.          *
  63.          * _create
  64.          *
  65.          **/
  66.         _create: function() {
  67.             // sauvegarde du contenu précédent de l'élément'
  68.             $(this).data('old_content', this.element.html());
  69.             // Liste des controles de la barre de navigation
  70.             this.options.controls = this.options.default_controls.concat(this.options.controls);
  71.             // creation de la barre de navigation
  72.             // ajout du spinner, puis des controles
  73.             var chaine = "<table id='" + this._getId("table") + "'>";
  74.             chaine += "<tr id='" + this._getId('controlBar') + "'><td><ul id='" + this._getId("navBar") + "' style='list-style:none;margin: 0;'>";
  75.             chaine += "<li class='ui-state-default' id='" + this._getId("spinner")
  76.                     + "' style='float:left;margin-right:2px;text-decoration: none;'>"
  77.                     + "<span class='ui-widget ui-corner-all ui-icon ui-button' style='background-image: url(\"lib/jquery.table/ajax-loader.gif\");'></span></li>";
  78.  
  79.             for (var i = 0; i < this.options.controls.length; i++) {
  80.                 chaine += this._getControl(this.options.controls[i]['id'], this.options.controls[i]['icon']);
  81.             }
  82.             chaine += "<li id='" + this._getId('info') + "'></li>";
  83.             chaine += "</ul></td></tr>";
  84.             chaine += "<tr id='" + this._getId('header') + "'></tr>";
  85.             chaine += "</table>";
  86.             // on met à jour l'élément pour l'afficher
  87.             this.element.html(chaine);
  88.             // on récupère le nombre d'enregistrement
  89.             this.options.provider.getCount(this);
  90.             // ainsi que la liste des colonnes
  91.             this.options.provider.getColumns(this);
  92.             // récupérer les données
  93.             this.getValues();
  94.             var self = this;
  95.             var classe = this._getId('controls');
  96.             // tous les controles ont la classe <nom>_controls
  97.             // on leur rajoute l'appel de la methode correspondante
  98.             $('.' + classe).click(
  99.                     function() {
  100.                         var methode = $(this).attr('id').replace(new RegExp('^' + self.options.name + '_'), '');
  101.                         self[methode]();
  102.                     });
  103.         },
  104.         destroy: function() {
  105.             this.element.html($(this).data('old_content'));
  106.             // call the original destroy method since we overwrote it
  107.             $.Widget.prototype.destroy.call(this);
  108.         },
  109.         // méthodes correspondantes aux boutons de navigation
  110.         first: function() {
  111.             this._setOption('page', 1);
  112.         },
  113.         next: function() {
  114.             this._setOption('page', Math.min(this.options.page + 1, this.options.page_count));
  115.         },
  116.         previous: function() {
  117.             this._setOption('page', Math.max(this.options.page - 1, 1));
  118.         },
  119.         last: function() {
  120.             this._setOption('page', this.options.page_count);
  121.         },
  122.         reset_filter: function() {
  123.             this._setOption('filter',null);
  124.         },
  125.         /* filter : function() {
  126.          $('#test').filterbuilder({
  127.          name : 'filter',
  128.          owner: this,
  129.          columns: this.options.columns,
  130.          current_filter: this.options.filter
  131.          });
  132.          },
  133.          */
  134.         _setOption: function(key, value) {
  135.             this.options[key] = value;
  136.             switch (key) {
  137.                 case 'page':
  138.                     this.getValues();
  139.                     this._updateInfo();
  140.                     break;
  141.                 case 'columns':
  142.                     this._createHeader();
  143.                     break;
  144.                 case 'count':
  145.                     this.options.page_count = Math.max(1, Math.ceil(value / this.options.page_size));
  146.                     this._updateInfo();
  147.                     break;
  148.                 case 'values':
  149.                     this._setValues(value);
  150.                     break;
  151.                 case 'sort':
  152.                     this._setSort(value);
  153.                     break;
  154.                 case 'filter':
  155.                     this._setFilter();
  156.                     break;
  157.             }
  158.         },
  159.         // renvoie un controle sous forme de <li>
  160.         _getControl: function(id, icon) {
  161.             var classe = this._getId('controls');
  162.             var chaine = "<li class='" + classe + " ui-state-default ui-corner-all' id='" + this._getId(id)
  163.                     + "' style='float:left;margin-right:2px;text-decoration: none;'>"
  164.                     + "<span class='ui-widget ui-corner-all ui-icon ui-button " + icon + "' title='" + id
  165.                     + "'></span></li>";
  166.  
  167.             return chaine;
  168.         },
  169.         _createHeader: function() {
  170.             // on supprime l'ancien si besoin
  171.             $('#' + this._getId('header')).empty();
  172.             var chaine = ""; //"<tr id='"+this._getId('header')+"'>";
  173.             var cols = this.options.columns;
  174.             var self = this;
  175.             var sort;
  176.             var filter;
  177.  
  178.             filter = "<div class='filter ui-icon ui-icon-search'></div>";
  179.             sort = "<div class='sort ui-icon ui-icon-triangle-2-n-s'></div>";
  180.             for (var i = 0; i < cols.length; i++) {
  181.                 chaine += "<th field='" + cols[i]['id'] + "'><div class='title_div'>" + cols[i]['label'] + "</div>" + filter + sort + '</th>';
  182.             }
  183.             $('#' + this._getId('controlBar') + ' td').attr('colspan', cols.length);
  184.             var ctrl_id = '#' + this._getId('header')
  185.  
  186.             $(ctrl_id).append(chaine);
  187.             // click sur le titre pour tri
  188.             $(ctrl_id + ' .title_div').click(function() {
  189.                 var current_sort = '';
  190.                 if (self.options.sort != null) {
  191.                     current_sort = self.options.sort.split(' ');
  192.                     $(this).parent().parent().children().children('div.sort').removeClass('ui-icon-triangle-1-s').removeClass('ui-icon-triangle-1-n').addClass('ui-icon-triangle-2-n-s');
  193.                 }
  194.                 var champ = $(this).parent().attr('field');
  195.                 var sens = 'asc';
  196.                 var classe = 'ui-icon-triangle-1-n';
  197.                 if (current_sort[0] == champ) {
  198.  
  199.                     if (current_sort[1] == 'desc') {
  200.                         sens = 'asc';
  201.                     } else {
  202.                         sens = 'desc';
  203.                     }
  204.  
  205.                 }
  206.                 classe = (sens == 'desc') ? 'ui-icon-triangle-1-s' : 'ui-icon-triangle-1-n';
  207.                 $(this).parent().children('.sort').removeClass('ui-icon-triangle-2-n-s').addClass(classe);
  208.                 self._setOption('sort', (champ + ' ' + sens));
  209.             });
  210.             // click sur filtrer = appel de showFilter
  211.             $('.filter').click(function() {
  212.                 self.showFilter($(this));
  213.             });
  214.         },
  215.         // affiche un input sur le header correspondant
  216.         showFilter: function(element) {
  217.             var self = this;
  218.             var field = element.parent().attr('field');
  219.             var html = '<INPUT id="' + this._getId('input') + '" class="filter_input" type="text" />';
  220.             $('#' + this._getId('header')).append(html);
  221.             $('#' + this._getId('input')).width(element.parent().width()-4).height(element.parent().children(':first').height()-4).position({
  222.                 my: 'center',
  223.                 at: 'center',
  224.                 of: element.parent()
  225.             }).focus();
  226.             $('#' + this._getId('input')).keydown(function(event) {
  227.                 switch (event.which) {
  228.                     case 13:
  229.                         // appliquer le fitre
  230.                         var fd = new FilterDescriptor('AND');
  231.                         fd.add(field, element.html(), 'like', $('#' + self._getId('input')).val());
  232.                         self._setOption('filter', fd);
  233.                     case 27:
  234.                         $('#' + self._getId('input')).remove();
  235.                         break;
  236.                 }
  237.  
  238.                 //event.preventDefault();
  239.             }).blur(function() {
  240.                 //$('#' + self._getId('input')).remove();
  241.             });
  242.         },
  243.         // récupère les données correspondantes à la page courante au tri et au filtre en cours
  244.         getValues: function() {
  245.             var min = (this.options.page - 1) * this.options.page_size;
  246.             // TODO passer uniquement this et récupérer les infos
  247.             this.options.provider.getData(this, min, this.options.page_size, this.options.sort, this.options.filter);
  248.         },
  249.         // début ajax (affiche le spinner)
  250.         beginAjax: function() {
  251.             this.options.ajaxLoading++;
  252.             if (this.options.ajaxLoading > 0) {
  253.                 $('#' + this._getId('spinner')).css('visibility', 'visible');
  254.             }
  255.         },
  256.         // fin ajax (cache le spinner)
  257.         endAjax: function() {
  258.             this.options.ajaxLoading--;
  259.             if (this.options.ajaxLoading <= 0) {
  260.                 $('#' + this._getId('spinner')).css('visibility', 'hidden');
  261.             }
  262.         },
  263.         // on a récupéré les valeurs (donnée en ajax)
  264.         // on met à jour l'écran
  265.         _setValues: function(values) {
  266.             var chaine = '';
  267.             $('.' + this._getId("values")).remove();
  268.             for (var i = 0; i < values.length; i++) {
  269.                 chaine += "<tr class='" + this._getId("values") + "'>";
  270.                 for (var j = 0; j < values[i].length; j++) {
  271.                     chaine += '<td>' + values[i][j] + '</td>';
  272.                 }
  273.                 chaine += '</tr>';
  274.             }
  275.             $('#' + this._getId("table")).append(chaine);
  276.             $('.' + this._getId("values") + ':odd').addClass(this.options.oddclass);
  277.             $('.' + this._getId("values") + ':even').addClass(this.options.evenclass);
  278.         },
  279.         _setSort: function(value) {
  280.             // on a mis à jour le tri, on récupère les données
  281.             this.getValues();
  282.         },
  283.         _setFilter: function() {
  284.             // on a mis à jour le filtre, on récupère les données ainsi que le count
  285.             this.options.page = 1;
  286.             this.options.provider.getCount(this);
  287.             this.getValues();
  288.         },
  289.         // met à jour les infos supplémentaires
  290.         _updateInfo: function() {
  291.             var texte = 'page ' + this.options.page + ' / ' + this.options.page_count + ' - ' +
  292.                     this.options.count + ' enregistrements';
  293.             $('#' + this._getId('info')).html(texte);
  294.  
  295.         },
  296.         // renvoie un id avec comme préfixe le nom de la table
  297.         _getId: function(id) {
  298.             return this.options.name + '_' + id;
  299.         }
  300.  
  301.     });
  302.  
  303.     $.extend($.ui.table, {});
  304.  
  305. })(jQuery);
  306.  
  307. function DataProvider(baseurl) {
  308.     this.baseurl = baseurl;
  309. }
  310.  
  311. DataProvider.prototype.getColumns = function(table) {
  312.     table.beginAjax();
  313.     $.getJSON(this.baseurl + '?action=columns&token=' + token, function(res) {
  314.         table._setOption('columns', res);
  315.         table.endAjax();
  316.     });
  317. }
  318.  
  319. DataProvider.prototype.getData = function(table, start, size, sort, filter) {
  320.     table.beginAjax();
  321.     var sortString = (sort == null) ? '' : '&sort=' + sort;
  322.     var filterString = (filter == null) ? '' : '&filter=' + JSON.stringify(filter);
  323.  
  324.     $.ajax({
  325.         url: this.baseurl + '?action=list&limit=' + start + ',' + size + sortString + filterString + '&token=' + token,
  326.         success: function(texte) {
  327.             try {
  328.                 var regexp = /(\[.*\]).*/;
  329.                 var match = regexp.exec(texte);
  330.                 var json = $.parseJSON(match[1]);
  331.                 table._setOption('values', json);
  332.             } catch (err) {
  333.  
  334.             }
  335.             table.endAjax();
  336.         }
  337.     });
  338.  
  339.  
  340. //});
  341. }
  342. DataProvider.prototype.getCount = function(table) {
  343.     table.beginAjax();
  344.     var filter = table.options.filter;
  345.     var filterString = (filter == null) ? '' : '&filter=' + JSON.stringify(filter);
  346.     $.getJSON(this.baseurl + '?action=count' + filterString + '&token=' + token, function(res) {
  347.         table._setOption('count', res);
  348.         table.endAjax();
  349.     });
  350. }