Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature req: Trees with tristate checkboxes #195

Open
NoseyNick opened this issue Feb 12, 2017 · 1 comment
Open

Feature req: Trees with tristate checkboxes #195

NoseyNick opened this issue Feb 12, 2017 · 1 comment

Comments

@NoseyNick
Copy link

I've combined treetable with https://css-tricks.com/indeterminate-checkboxes/ for one of those trees where you can select/unselect nodes or entire tree branches.

However I did it "on the outside" of jquery-treetable. Would love to see it merged into jquery-treetable itself, with a setting to enable/disable. Will definitely need tidying (EG my remove/wrap/prepend could almost certainly be "done right" if it was inside the real _initialize, and I probably violate all naming conventions and indent styles etc)

Here's my PoC:

$("#tab").treetable({
  expandable: true,
  onNodeInitialized: function () {
    // Create a checkbox per tree node too:
    this.nn_cb = $('<input type="checkbox">').click(this, function(e) {
      $(this).prop('indeterminate', false); // we have set/unset, so no longer indeterminate
      tt_set_kids(e.data, $(this).is(':checked'));
      tt_check_parent(e.data.tree[e.data.parentId]);
    }).attr('id', this.id);

    // if I have a parent, which was checked, I should be checked too!
    if (this.parentId && this.tree[this.parentId]) {
      this.nn_cb.attr('checked', this.tree[this.parentId].nn_cb.is(':checked'));
    }

    // remove the indenter, wrap the label, add back indenter AND CHECKBOX
    this.treeCell
      .remove('span.indenter')
      .wrapInner($('<label>').attr('for', this.id))
      .prepend(this.indenter, this.nn_cb);
  }
});

function tt_set_kids(tt, checked) {
  // User has just set/unset a parent. All kids should be updated to match:
  if (!tt) { return }
  tt.children.forEach(function (kid) {
    if (! kid.nn_cb) { return } // has no checkbox, prob not init'd yet
    kid.nn_cb.prop('checked', checked);
    tt_set_kids(kid, checked);
  });
}

function tt_check_parent(tt) {
  // I have just changed a child. See if this makes parent (and 
  // grandparents etc) set/unset/indeterminate:
  if (! tt) { return }
  var ch = false, un = false;
  tt.children.forEach(function(kid) {
    if      (kid.nn_cb.is(':indeterminate')) { ch = un = true }
    else if (kid.nn_cb.is(':checked'))       { ch      = true }
    else                                     {      un = true }
  });
  // We should be checked if there are NO unchecked (all checked) kids
  // We should be indeterminate if there are checked+unchecked kids:
  tt.nn_cb.prop('checked', !un).prop('indeterminate', ch && un);
  tt_check_parent(tt.tree[tt.parentId]);
}

@Tinycocha
Copy link

it‘s good, thanks,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants