Skip to content

Commit

Permalink
Convert select menus from bootstrap-select to tom-select
Browse files Browse the repository at this point in the history
Reuse the selectpicker class since tom-select allows you
to set the class to find select elements and we already
apply the selectpicker class.
  • Loading branch information
cbrandtbuffalo committed Nov 22, 2024
1 parent a12c435 commit 1a1ba98
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 17 deletions.
2 changes: 1 addition & 1 deletion lib/RT/Interface/Web.pm
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ sub JSFiles {
jquery-ui-patch-datepicker.js
selectize.min.js
bootstrap.bundle.min.js
bootstrap-select.min.js
bootstrap-combobox.js
i18n.js
util.js
Expand All @@ -152,6 +151,7 @@ sub JSFiles {
jquery.jgrowl.min.js
clipboard.min.js
pagelayout.js
tom-select.complete.min.js
}, RT->Config->Get('JSFiles');
}

Expand Down
1 change: 0 additions & 1 deletion share/html/Elements/Footer
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
% }
<script type="text/javascript">
RT.UserMessages = <% JSON( \%UserMessages ) |n%>;
updateSelectpickerLiveSearch();
</script>
</div>
</body>
Expand Down
3 changes: 2 additions & 1 deletion share/static/css/elevator/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
@import "tablesorter.css";
@import "farbtastic.css";
@import "bootstrap.css";
@import "bootstrap-select.css";
@import "bootstrap-combobox.css";
@import "dropzone.css";
@import "dropzone.customized.css";
@import "selectize.default.css";
@import "tom-select.bootstrap5.css";
@import "tom-select-rt.css";

@import "base.css";
@import "collection.css";
Expand Down
59 changes: 45 additions & 14 deletions share/static/js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,41 @@ function textToHTML(value) {
.replace(/\n/g, "\n<br />");
};

// Initialize the tom-select library
function initializeSelectElements(elt) {

// The selectpicker class was used by the bootstrap-select
// JS library as the default. We retained it because tom-select
// allows you to set any class value and all of the RT dropdowns
// already had 'selectpicker'.

elt.querySelectorAll('select.selectpicker').forEach((elt)=>{

/* We shouldn't initialize on parts of the page that have already
been initialized, so this check shouldn't be needed. Leave commented
out for now pending more testing.
if ( elt.tomselect ) {
// This can get called on elements already initialized.
return;
}
*/

let settings = {
allowEmptyOption: true,
};

if ( elt.options && elt.options.length < RT.Config.SelectLiveSearchLimit ) {
// Under the config limit, don't show the search input box,
// just a regular dropdown.
settings.controlInput = null;
}

new TomSelect(elt,settings);

});
}

function ReplaceAllTextareas(elt) {
window.CKEDITOR ||= { "instances": {} };

Expand Down Expand Up @@ -624,7 +659,7 @@ function refreshCollectionListRow(tr, table, success, error) {
// Get the new replaced tr
tr = table.find('tr[data-index=' + index + ']');
initDatePicker(tr);
tr.find('.selectpicker').selectpicker();
// tr.find('.selectpicker').selectpicker();
RT.Autocomplete.bind(tr);
if (success) { success(response) }
},
Expand Down Expand Up @@ -775,7 +810,7 @@ jQuery(function() {
elt.classList.remove('hasDatepicker');
});

jQuery(evt.detail.historyElt).find('.selectpicker').selectpicker('destroy').addClass('selectpicker');
// jQuery(evt.detail.historyElt).find('.selectpicker').selectpicker('destroy').addClass('selectpicker');
});

document.body.addEventListener('actionsChanged', function(evt) {
Expand Down Expand Up @@ -846,6 +881,7 @@ jQuery(function() {
});

htmx.onLoad(function(elt) {
initializeSelectElements(elt);
ReplaceAllTextareas(elt);
AddAttachmentWarning();
jQuery(elt).find('a.delete-attach').click( function() {
Expand Down Expand Up @@ -979,7 +1015,7 @@ htmx.onLoad(function(elt) {
var new_operator = form.find(':input[name="' + val + 'Op"]:first').clone();
row.children('div.operator').children().remove();
row.children('div.operator').append(new_operator);
row.children('div.operator').find('select.selectpicker').selectpicker();
// row.children('div.operator').find('select.selectpicker').selectpicker();

var new_value = form.find(':input[name="ValueOf' + val + '"]:first');
if ( new_value.hasClass('ui-autocomplete-input') ) {
Expand All @@ -994,7 +1030,7 @@ htmx.onLoad(function(elt) {
new_value.attr('id', null);
row.children('div.value').children().remove();
row.children('div.value').append(new_value);
row.children('div.value').find('select.selectpicker').selectpicker();
// row.children('div.value').find('select.selectpicker').selectpicker();
if ( new_value.hasClass('datepicker') ) {
new_value.removeClass('hasDatepicker');
initDatePicker(row);
Expand Down Expand Up @@ -1443,7 +1479,7 @@ jQuery(function () {

editor.find(':input:visible:enabled:first').focus();
setTimeout( function(){
editor.find('.selectpicker').selectpicker('toggle');
editor.find('select.selectpicker')[0].tomselect.open();
}, 100);

jQuery('body').addClass('inline-editing');
Expand Down Expand Up @@ -1788,17 +1824,12 @@ htmx.onLoad( function() {
RT.UserMessages = {};
} );

function updateSelectpickerLiveSearch (element) {
element ||= jQuery('.selectpicker');
element.filter(':not([data-live-search])').each(function() {
jQuery(this).attr('data-live-search', jQuery(this).find('option').length >= RT.Config.SelectLiveSearchLimit ? true : false );
});
}

function refreshSelectpicker (element) {
element ||= jQuery('.selectpicker');
updateSelectpickerLiveSearch(element);
element.selectpicker('refresh');
// Why would we call this on non-selectpicker elements?
if ( element.tomselect ) {
element.tomselect.refreshOptions();
}
}

function checkRefreshState(elt) {
Expand Down

0 comments on commit 1a1ba98

Please sign in to comment.