Checkbox Table

Késako ?

Text

Text

Text

Text

Comment
ça marche ?

Text

Text

Types de checkbox

Chaque cellule peut avoir : une "value" et/ou un "state"

API

  • Y.Widget methods
    • renderUI(), bindUI(), render()
  • Builder methods
  • Abstract methods
  • Runtime methods
  • Y.CheckboxTable.SelectableQueue mixin
    • clearQueue()
    • eachOfQueue()
    • this._queue

API

API

  • setBatchCells(position, headers, css_classes=[])
  • setTextCells(position, texts, css_classes=[])
  • setValueCells(matrix)
  • insertSpecialCells(position, type, cells, css_classes=[])
  • build()

Builder methods

API

Abstracts methods

  • selectionChange(virtual_cell, state)
  • save()
  • load()

Implémentés par les "classes filles"

API

Runtime methods

  • at(row, col, with_offset=false)
  • getValue(row, col, with_offset=false)
  • getState(row, col , with_offset=false)
  • setValue(row, col, value, with_offset=false)
  • setState(row, col, state, fireUpdateEvent=true, with_offset=false)
  • each(callback, exclude_batch_cell=false)
  • eachOfRow(row, callback, exclude_batch_cell=false)
  • eachOfColumn(col, callback, exclude_batch_cell=false)

"High level", deals with coordinates

API

Runtime methods

  • _getValue(virtual_cell)
  • _getState(virtual_cell)
  • _setValue(virtual_cell, value, with_offset=false)
  • _setState(virtual_cell, state, fireUpdateEvent=true, with_offset=false)
  • _isCellSelectable(virtual_cell)
  • _isBatchCell(virtual_cell)
  • _cellHasState(virtual_cell)
  • _cellHasValue(virtual_cell)

"Low level", deals with 'virtual_cell' references

Mode debug

Example with

Opening-checkboxtable

let's watch some code.

OpeningsCheckboxTable = Y.Base.create("openingsCheckboxTable", Y.CheckboxTable, [Y.CheckboxTable.SelectableQueue], {

  // ...

  load : function () { /* ... load data and call render() */ },

  save : function () { /* ... collect data using runtime API */ },

  selectionChange : function (virtual_cell, state) { /* ... */ },

  // ...

});
load : function() {
  // ...

  // top headers (with no checkboxes)
  this.setTextCells('top', ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', "samedi", "dimanche"]);
  // left headers (with checkboxes)
  this.setBatchCells('left', [
     "Déjeuner premier service",
     "Déjeuner dernier service",
     "Dîner premier service",
     "Dîner dernier service"
  ], ['left_selectors']);

  // ...

  // convert data in matrice
  // Example data format for openinghours (with closed on sunday)
      /**
       * [
       *    [],
       *    [{"start":"09:00","stop":"19:00"}, {"start":"09:00","stop":"19:00"}],
       *    [{"start":"09:00","stop":"19:00"}, {"start":"09:00","stop":"19:00"}],
       *    [{"start":"09:00","stop":"19:00"}, {"start":"09:00","stop":"19:00"}],
       *    [{"start":"09:00","stop":"19:00"}, {"start":"09:00","stop":"19:00"}],
       *    [{"start":"09:00","stop":"19:00"}, {"start":"09:00","stop":"19:00"}],
       *    [{"start":"09:00","stop":"19:00"}, {"start":"09:00","stop":"19:00"}]
       * ]
       */
  var openinghours = Y.config.locals.openinghours,
  values  = [ [], [], [], []  ],
  sunday = null;
  for (var i = 0; i < 7; i++) {
    // ...
  }

  // ...

  // set values
  this.setValueCells(values);

  this._render(); // custom renderer that will call render()
  // ...
}
selectionChange : function(virtual_cell, state) {

    var boundingBox = this.get('boundingBox'), allEqual = false, firstSelectedValue = null;

    if (this._queue.length) {
       // if all selected value are equal, <select> will take this common value, otherwise "-" value
      firstSelectedValue = this._getValue(this._queue[0]);

       // compute <select> value
       allEqual = Y.Array.every(this._queue, Y.rbind(function(virtual_cell) {
         return this._getValue(virtual_cell) === firstSelectedValue;
       }, this));

       if (allEqual) {
         this.hoursSelect.setValue(firstSelectedValue);
       } else {
         this.hoursSelect.setValue('choisissez dans la liste');
       }

       // show edit panel if not hidden
       boundingBox.one('.time_editor').show();
    } else {
       // hide edit panel
       boundingBox.one('.time_editor').hide();
    }

 },
save : function() {
  // ...

  // format openings from this._table
  for (; i < 7; i++) {
    //we have 4 rows
     values[0] = this.getValue(0, col, true);
     values[1] = this.getValue(1, col, true);
     values[2] = this.getValue(2, col, true);
     values[3] = this.getValue(3, col, true);

     openings[i] = [];

     // an close day have [] as value
     if (values[0] === i18n.closed && values[1] === i18n.closed) {
        openings[i].push({});
     } else {
        openings[i].push({
          start : values[0],
          stop : values[1]
        });
     }

     if (values[2] === i18n.closed && values[3] === i18n.closed) {
        openings[i].push({});
     } else {
        openings[i].push({
          start : values[2],
          stop : values[3]
        });
     }

  }

  validation = this._validateOpenings(openings);

  // ...

  Y.io('/admin/restaurant/openings?group_id=' + Y.config.locals.group_id, { /* ... */ });
},

Améliorations possibles

Drop inputEx +
use events delegation

Dynamically change table structure without builder 

Use double LinkedList

React + Flux

Utiliser React et la puissance de Flux

Open source ?

Pitié, ne la "droppez" pas.

Merci de votre attention !

Made with Slides.com