inherit
133146
0
Jan 7, 2024 2:07:03 GMT -8
Alanna 🥀🖤
3,564
November 2008
alannab
|
Post by Alanna 🥀🖤 on Jan 7, 2024 0:59:20 GMT -8
Would be amazing if a plugin that added a filter drop down menu next to the select and actions drop downs on thread lists for labels was made!
|
|
inherit
Official Code Helper
65613
0
1
Apr 15, 2024 17:01:41 GMT -8
Chris
"'Oops' is the sound we make when we improve"
8,864
December 2005
horace
|
Post by Chris on Jan 7, 2024 21:57:23 GMT -8
I wrote something about a year ago, this isn't exactly what you're requesting since it doesn't use a dropdown. Multi-select on a dropdown can be cumbersome I ran into a treasure trove of labels on the help guide boards I may need to put more time into working out the logistics and UX of the script /* Adds a general method to return label markup using passed in string template (returns jQuery collection) */ (function () { /* Returns a jQuery array of DOM elements created using item_template */ pb.board.getLabels = function getBoardLabels( item_template = '<li class="item label label-${id} board-${board_id}" data-label-is="${id}"><label for="label-${id}" data-label-is="${id}" style="color:#${color};" class="ui-label">${name}</label></li>', labels_viewable = 'labels_viewable') { let $labels = $(); if (pb.data('proboards.thread') && (labels_viewable = pb.data(labels_viewable))) { for (const label of labels_viewable) { $labels = $labels.add(literal_JIT(item_template, label)) } } return $labels } function literal_JIT(S = '', V = {}) { const fillTemplate = function (S, V) { return new Function("return `" + S.replace(/\$\{/g, '${this.') + "`;").call(V); } return fillTemplate(S, V); } })();
/* Build Labels UI */ $(function () { const board_id = pb.data('board_id') let filters = (localStorage['autosearch-labels-board-' + board_id] || (localStorage['autosearch-labels-board-' + board_id] = '')).split(',');
if (pb.data('proboards.thread') && pb.data('labels_viewable') && pb.data('labels_viewable').length) {
/* Build Labels Container */ $('<div class="list">').css({ display: 'grid', 'grid-template-columns': 'repeat(4,1fr)', padding: '.3em', gap: '.2em' }).prependTo('#content').append(pb.board.getLabels()).wrap('<div class="container labels"><div class="content cap-bottom"><ul></ul></div></div>').parent().parent().before('<div class="title-bar"><h2>Labels</h2></div>')
/* checkbox handler */ .on('click', 'input,label', click_checkbox)
/* Labels titlebar */ .prev('.title-bar') .prepend('<ul class="controls"><li><a role="button" class="clear-filters">Clear Search</a> <a role="button" class="apply-filters">Search Labels</a></li></ul>') .find('li>a')
/* Titlebar Buttons Handler */ .on('click', click_titlebar_button)
/* Add Checkboxes */ $('.container.labels li.label') .each(function (i, e) { $('label', e).prepend('<input type="checkbox" id="label-' + $(e).idFromClass('label') + '">') }) .css({ background: 'transparent' })
/* Set checkbox states using on saved localStorage values */ for (let x of filters) { $('.container.labels li.label-' + x) .find('input').prop('checked', true) }
/* Make sure array has no duplicates nor zeroes nor empty strings */ function clean_array(e) { for (var t = {}, i = [], n = 0, o = e.length; n < o; ++n) (!parseInt(e[n]) || (e[n]in t)) || (i.push(e[n]), t[e[n]] = 1); return i } /* checkbox handler */ function click_checkbox(ev) { const $target = $(ev.currentTarget) const filter_id = $target.closest('li').idFromClass('label'); const filter = 'label_id:only:' + filter_id; /*label click (as opposed to INPUT[type=checkbox] click) */ if(ev.currentTarget.nodeName === 'LABEL'){ //debugger; /* ensure direct label click and not a bubble up event */ /* label click fires before input click so checkbox is still in unchanged state */ if(ev.currentTarget === ev.target && !ev.currentTarget.control.checked){ $('.ui-autosearch').autosearch('setData', 'filters', [filter]); //ev.preventDefault(); $('.container.labels :checked').prop('indeterminate',true); setTimeout(m=>{$target[0].control.checked=true;},400); filters.push(filter_id) }else if($('.container.labels :checked').not(ev.currentTarget.control).length==0 && /filters\[\]\=label_id/.test(location.href) ){ $('.ui-autosearch').autosearch('setData', 'filters', []); setTimeout(m=>{$target[0].control.checked=false;},400); filters.splice(filters.indexOf(filter_id), 1); } ev.preventDefault(); }else if(ev.currentTarget.nodeName === 'INPUT'){ if($target[0].checked) { filters.push(filter_id); } else { filters.splice(filters.indexOf(filter_id), 1); if($('.container.labels :checked').length==0 && /filters\[\]\=label_id/.test(location.href) ){ $('.ui-autosearch').autosearch('setData', 'filters', []); } } ev.stopPropagation() $('.container.labels :indeterminate').prop('indeterminate',false); }
filters = clean_array(filters); localStorage['autosearch-labels-board-' + board_id] = filters; } /* Titlebar Buttons Handler */ function click_titlebar_button(ev) { ev.preventDefault(); ev.stopImmediatePropagation();
if ($(ev.currentTarget).hasClass('clear-filters')) { $('.container.labels input').prop('checked', false).prop('indeterminate',false) filters = []; if(/filters\[\]\=label_id/.test(location.href) ){ $('.ui-autosearch').autosearch('setData', 'filters', filters); } localStorage.removeItem('autosearch-labels-board-' + board_id); return } const filter = 'label_id:only:' + '' + filters; $('.container.labels :indeterminate').prop('indeterminate',false); if (filters.length) { $('.ui-autosearch').autosearch('setData', 'filters', [filter]) } } }
})
It can easily be dropped into the JS Component of a plugin. A rewrite of the UI builder could get you to a dropdown
|
|