2021-09-28 10:59:57 +02:00
|
|
|
<select id="search-settings" class="d-block w-100 form-select" aria-describedby="<?= __('Search setting input') ?>"><option></option></select>
|
2021-07-26 11:16:52 +02:00
|
|
|
|
|
|
|
<script>
|
|
|
|
let selectData = []
|
|
|
|
for (const settingName in settingsFlattened) {
|
|
|
|
if (Object.hasOwnProperty.call(settingsFlattened, settingName)) {
|
|
|
|
const setting = settingsFlattened[settingName];
|
|
|
|
const selectID = settingName.replaceAll('.', '_')
|
|
|
|
selectData.push({
|
|
|
|
id: selectID,
|
|
|
|
text: setting.name,
|
|
|
|
setting: setting
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$(document).ready(function() {
|
|
|
|
$("#search-settings").select2({
|
|
|
|
data: selectData,
|
|
|
|
placeholder: '<?= __('Search setting by typing here...') ?>',
|
|
|
|
templateResult: formatSettingSearchResult,
|
|
|
|
templateSelection: formatSettingSearchSelection,
|
|
|
|
matcher: settingMatcher,
|
|
|
|
sorter: settingSorter,
|
|
|
|
})
|
|
|
|
.on('select2:select', function (e) {
|
|
|
|
const selected = e.params.data
|
|
|
|
const settingPath = selected.setting['setting-path']
|
2021-07-30 11:44:53 +02:00
|
|
|
const {tabName, IDtoFocus} = getTabAndSettingIDFromPath(settingPath)
|
|
|
|
showSetting(selected, tabName, IDtoFocus)
|
2021-07-26 11:16:52 +02:00
|
|
|
$("#search-settings").val(null).trigger('change.select2');
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-07-30 11:44:53 +02:00
|
|
|
function getTabAndSettingIDFromPath(settingPath) {
|
|
|
|
let settingPathTokenized = settingPath.split('.')
|
|
|
|
settingPathTokenized = settingPathTokenized.map((elem) => elem.replaceAll(/(\.|\W)/g, '_'))
|
|
|
|
const tabName = settingPathTokenized[0]
|
|
|
|
const IDtoFocus = 'sp-' + settingPathTokenized.slice(1).join('-')
|
|
|
|
return {tabName: tabName, IDtoFocus: IDtoFocus}
|
|
|
|
}
|
|
|
|
|
|
|
|
function showSetting(selected, tabName, IDtoFocus) {
|
|
|
|
const $navController = $('.settings-tabs').find('a.nav-link').filter(function() {
|
|
|
|
return $(this).text() == tabName
|
|
|
|
})
|
|
|
|
if ($navController.length == 1) {
|
|
|
|
$toFocus = $(`#${IDtoFocus}`).parent()
|
|
|
|
if ($navController.hasClass('active')) {
|
|
|
|
$toFocus[0].scrollIntoView()
|
|
|
|
$toFocus.find(`input#${selected.id}, textarea#${selected.id}`).focus()
|
|
|
|
} else {
|
|
|
|
$navController.on('shown.bs.tab.after-selection', () => {
|
|
|
|
$toFocus[0].scrollIntoView()
|
|
|
|
$toFocus.find(`input#${selected.id}, textarea#${selected.id}`).focus()
|
|
|
|
$navController.off('shown.bs.tab.after-selection')
|
|
|
|
}).tab('show')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-26 11:16:52 +02:00
|
|
|
function settingMatcher(params, data) {
|
|
|
|
if (params.term == null || params.term.trim() === '') {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
if (data.text === undefined || data.setting === undefined) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
let modifiedData = $.extend({}, data, true);
|
|
|
|
const loweredTerms = params.term.trim().toLowerCase().split(' ')
|
2021-07-30 09:41:43 +02:00
|
|
|
let matchNumber = 0
|
2021-07-26 11:16:52 +02:00
|
|
|
for (let i = 0; i < loweredTerms.length; i++) {
|
|
|
|
const loweredTerm = loweredTerms[i];
|
|
|
|
const settingNameMatch = data.setting['true-name'].toLowerCase().indexOf(loweredTerm) > -1 || data.text.toLowerCase().indexOf(loweredTerm) > -1
|
|
|
|
const settingGroupMatch = data.setting['setting-path'].toLowerCase().indexOf(loweredTerm) > -1
|
|
|
|
const settingDescMatch = data.setting.description.toLowerCase().indexOf(loweredTerm) > -1
|
|
|
|
if (settingNameMatch || settingGroupMatch || settingDescMatch) {
|
2021-07-30 09:41:43 +02:00
|
|
|
matchNumber += 1
|
2021-07-26 11:16:52 +02:00
|
|
|
modifiedData.matchPriority = (settingNameMatch ? 10 : 0) + (settingGroupMatch ? 5 : 0) + (settingDescMatch ? 1 : 0)
|
|
|
|
}
|
|
|
|
}
|
2021-07-30 09:41:43 +02:00
|
|
|
if (matchNumber == loweredTerms.length && modifiedData.matchPriority > 0) {
|
2021-07-26 11:16:52 +02:00
|
|
|
return modifiedData;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function settingSorter(data) {
|
|
|
|
let sortedData = data.slice(0)
|
|
|
|
sortedData = sortedData.sort((a, b) => {
|
|
|
|
return a.matchPriority == b.matchPriority ? 0 : (b.matchPriority - a.matchPriority)
|
|
|
|
})
|
|
|
|
return sortedData;
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatSettingSearchResult(state) {
|
|
|
|
if (!state.id) {
|
|
|
|
return state.text;
|
|
|
|
}
|
|
|
|
const $state = $('<div/>').append(
|
|
|
|
$('<div/>').addClass('d-flex justify-content-between')
|
|
|
|
.append(
|
2021-09-17 17:51:45 +02:00
|
|
|
$('<span/>').addClass('fw-bold').text(state.text),
|
|
|
|
$('<span/>').addClass('fw-light').text(state.setting['setting-path'].replaceAll('.', ' ▸ '))
|
2021-07-26 11:16:52 +02:00
|
|
|
),
|
2021-09-17 17:51:45 +02:00
|
|
|
$('<div/>').addClass('font-italic fw-light ms-3').text(state.setting['description'])
|
2021-07-26 11:16:52 +02:00
|
|
|
)
|
|
|
|
return $state
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatSettingSearchSelection(state) {
|
|
|
|
return state.text
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
.select2-container {
|
|
|
|
max-width: 100%;
|
|
|
|
min-width: 100%;
|
|
|
|
}
|
|
|
|
</style>
|