Skip to content

Instantly share code, notes, and snippets.

@L5eoneill
Last active November 27, 2017 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save L5eoneill/87713d511dc0cc13704f0a512e18befb to your computer and use it in GitHub Desktop.
Save L5eoneill/87713d511dc0cc13704f0a512e18befb to your computer and use it in GitHub Desktop.
jQuery(function() {
var $ = jQuery;
var bossTypeId = $('.theBoss').attr('id');
$('body')
.on('change', '.checkbox.item', function(e) {
updateSelectedText(e.target);
})
.on('click', '.theBoss li, .theBoss li span', function(e) {
var el = $(e.target).closest('li.tree-parent');
if ($(el).find('ul').length === 0) {
getChildren(e.target, null, false);
}
})
.on('click change', '.checkbox.js-selectall', function(e) {
e.stopPropagation();
if (e.type === 'change') {
var el = $(e.target).closest('li.tree-parent');
if ($(el).find('ul').length === 0) {
getChildren(e.target, false, true);
} else {
el.find('li input').prop('checked', $(this).is(':checked'));
}
updateSelectedText(e.target);
}
});
var getChildren = function(target, doExpand, doKids) {
var el = $(target).closest('.js-toggle__parent');
$.ajax({
url: "get_theBoss_data",
data: {
"the_boss_code": $(el).attr('id'),
"the_boss_type_id": bossTypeId
},
dataType: 'json',
success: function(data) {
updateParent(el, data, doExpand);
},
complete: function() {
if (doKids) {
updateChildren(el, $(el).find('.checkbox.js-selectall').is(':checked'));
}
}
});
}
var updateParent = function(el, data, doExpand) {
var inputEl = '<input type="checkbox" class="checkbox" name="categoryCode" value="" />';
$(el).append('<ul class="js-toggle__target" aria-expanded="' + doExpand + '"></ul>');
var sublist = $(el).find('ul');
$.each(data.childlist, function(index, item) {
var listEl = $('<li id="item-' + item.categoryCode + '"></li>');
sublist.append(listEl);
$(listEl).append(inputEl);
$(listEl).find('input')
.attr('value', item.categoryCode)
.prop('checked', item.checked === 'true')
.attr('id', item.categoryCode)
.addClass('item')
.end()
.append(' <label for="' + item.categoryCode + '">' + item.categoryCode + ' : ' + item.description + '</label>');
});
}
var updateSelectedText = function(target) {
var t = $(target);
var ul = t.closest('ul');
if (t.hasClass('js-selectall')) {
ul = t.closest('.js-toggle__trigger').next('ul');
}
var top = ul.prev('.js-toggle__trigger'); // span above toggle__target
var count = ul.find('input:checked').length;
var selectedEl = top.find('.selectedCount');
if (count > 0) {
var txt = '';
if (selectedEl.length === 0) {
top.append('<span class="selectedCount"></span>');
}
if (count < ul.find('input').length) {
txt = ' - ' + count + ' item' + (count > 1 ? 's' : '') + ' selected';
} else {
txt = ' - all items selected';
}
top.find('.selectedCount').text(txt);
} else {
top.find('.selectedCount').empty();
}
}
var updateChildren = function(el, checked) {
$(el).find('li input').prop('checked', checked);
}
});
@L5eoneill
Copy link
Author

L5eoneill commented Nov 27, 2017

Problem: One has a long list of categories. Each category may have many sub-categories which can be selected
Desired UI interactions:

  • The user will not want to see all the sub-categories to start with
  • The user will select a category to drill down in to and the server will return that group as JSON data
  • The user may select all of the subcategories at once, or deselect them all
  • The user may select or deselect any subcategory under the category
  • The user should see an indicator of how many subcategories have been selected in each category
  • The user may collapse or expand any category, but clicking the Select All checkbox will not cause expand/collapse

This doesn't include adding expandable/collapsible capability; it's for handling checkboxes in elements that have expand/collapse already working.

The given DOM structure is as follows:

<ul>
  <li class="js-toggle__parent tree-parent" id="catId">
    <span class="js-toggle__trigger js-toggle-state--collapsed">
      <input type="checkbox" name="parent" value="catId" class="checkbox js-selectall" />
      Category Group Name
   </span>
 </li>
    ...
</ul>

To each of which will be appended another <ul> with <li> elements having their own <input type="checkbox" name="subcategoryId"> and <label>Subcategory Name</label>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment