I am using a barcode scanner in a drop down connected field that has over 1000 entries.
I need to be able to auto-select the code without human intervention (tab, enter, arrows, etc).
There is no problem when the drop down has less than 500 entries but above that, it turns into a searchable drop down and behaves very differently and refuses to select the found item. I want the list to close while keeping its selection. But calling trigger("liszt:updated") always erases the selection. If I don't use the call, then I end up with an opened list and the operator needs to manually select the found item to close the list.
To troubleshoot this, I've created a tiny app that demonstrates that.
You can see it here: https://morbern.knack.com/sandbox1#drop-down-list/
Login is guest@ctrnd.com, and pw = 123
Here's my Javascript code:
$(document).on(
'knack-scene-render.scene_16',
function (event, scene) {
//****** Login: un = guest@ctrnd.com, pw = 123
//Small Drop down, with 40 items - works ok.
$("#view_36-field_71").val("5d65980eed26072f431c7d8b"); //1029
$("#view_36-field_71").trigger("liszt:updated");
//Large Drop down, with 999 items - can't set value.
$("#view_36-field_69").val("5d6595f8c4cf503a51d974b7"); //1424
$("#view_36-field_69").trigger("liszt:updated");
// !!!! Trying just about anything to see that drop down show me something upon a page render !!!!!!!!
var myinput = $('#view_36_field_69_chzn').find('input').first();
var curclass = myinput.attr('class');
console.log('class = ' + curclass); //class = ui-autocomplete-input
//Ok, this works! I can search what I want.
myinput.autocomplete("search", "1424");
//Now, I need to be able to auto-select the result without any human intervention, i.e. mouse or keyboard action.
setTimeout(function () {
$("#view_36-field_69").selectedIndex = 0;
$("#view_36-field_69").trigger('liszt:updated'); //Why does this line always closes but without selection ??!!!
}, 2000); //Just a dummy timer to wait for search to find.
}
);
Any help will be greatly appreciated.
Norm
Thanks for sharing your hard work. I really appreciate it Norm.
Chris.
Remember, you can see it in action here:
https://morbern.knack.com/sandbox1#drop-down-list/
Login is guest@ctrnd.com, and pw = 123
Hi Chris,
Yes, I wrote some code to address the issue. I works really well.
Also, it uses Javascript promises to speed up the search and return as soon as possible when it found something. Before, I used a blind delay of 2 seconds, but this is not optimal because it needs to be adapted when the list eventually grows bigger. This always work regardless of size.
Here, I will share it with you.
//////////////////////////////////////////////////////////////////
$(document).on(
'knack-scene-render.scene_16',
function (event, scene) {
//Two seconds after loading the scene, search for 1424 in the single selection dropdown.
var textToSearch = '1424';
//var textToSearch = '9999'; //Use this to see what happens when a search fails.
var dropDownFieldId = 'field_69'; //Single
setTimeout(function () {
console.log('============================================');
searchDropDownforText(textToSearch, dropDownFieldId);
//Then two seconds later, search for 1425 in the multi selection dropdown.
setTimeout(function () {
textToSearch = '1425';
//var textToSearch = '9999'; //Use this to see what happens when a search fails.
dropDownFieldId = 'field_77'; //Multi
console.log('============================================');
searchDropDownforText(textToSearch, dropDownFieldId);
}, 2000)
}, 2000)
}
);
//////////////////////////////////////////////////////////////////
function searchDropDownforText(textToSearch, dropDownFieldId) {
var currentFormView = $('div.kn-form').attr('id');;
console.log('currentFormView = ' + currentFormView);
var dropDownFieldSel = $('#' + currentFormView + '-' + dropDownFieldId);
console.log(dropDownFieldSel);
var dropdownChznSel = $('#' + currentFormView + '_' + dropDownFieldId + '_chzn');
console.log(dropdownChznSel);
if (dropdownChznSel && dropdownChznSel.length > 0)
dropDownSearchField = dropdownChznSel.find('input').first();
if (dropDownFieldSel && dropDownFieldSel.length > 0 && textToSearch !== '') {
dropDownSearchField.focus(); //Send requested text to dropdown search box.
dropDownSearchField.autocomplete("search", textToSearch);
Knack.showSpinner();
//Check if single of multi selection dropdown
if (dropdownChznSel.hasClass('chzn-container-single')) {
console.log('Single');
searchSingleSelectionDropdown(dropDownFieldSel, dropdownChznSel).then(function (foundText) {
if (foundText === textToSearch) {
console.log('Found :)');
}
else {
console.log('Not Found :(');
//Erase previous drop down selection to prevent erroneously submitting a previous selection.
dropDownSearchField.focus();
dropDownSearchField.autocomplete("search", '');
dropDownFieldSel.val([]).trigger('liszt:updated');
}
$("button").trigger("focus");
});
} else {
console.log('multi');
searchMultiSelectionDropdown(currentFormView + '-' + dropDownFieldId, dropdownChznSel, textToSearch);
}
Knack.hideSpinner();
} else {
console.log('ERROR - currentField is null');
}
}
//////////////////////////////////////////////////////////////////
function searchSingleSelectionDropdown(currentField, dropdownChznSel) {
return new Promise(function (resolve, reject) {
//Check every 100ms until found.
var intervalId = setInterval(function () {
if (!$(".ui-autocomplete-loading").is(":visible")) {
clearInterval(intervalId);
var obj = currentField.find("option");
var id = $(obj[1]).val();
currentField.val(id);// = 1;
currentField.trigger('liszt:updated');
var querySel = '#' + dropdownChznSel.attr('id') + ' > a > span';
console.log($(querySel));
if ($(querySel) && $(querySel).length !== 0) {
var foundText = document.querySelector(querySel).innerText;
console.log('foundText = ' + foundText);
resolve(foundText);
}
}
}, 100)
});
}
//////////////////////////////////////////////////////////////////
function searchMultiSelectionDropdown(multiDropdownId, dropdownChznSel, textToSearch) {
var intervalId = setInterval(function () {
if (!$(".ui-autocomplete-loading").is(":visible")) {
clearInterval(intervalId);
var obj1 = $("#" + multiDropdownId).find("option");
var id = $(obj1[0]).val();
$("#" + multiDropdownId + " option[value='" + id + "']").attr("selected", 1);
$("#" + multiDropdownId).trigger('liszt:updated');
var querySel = '#' + dropdownChznSel.attr('id') + '_c_0 > span';
console.log($(querySel));
if ($(querySel) && $(querySel).length !== 0) {
var foundText = document.querySelector(querySel).innerText;
console.log('foundText = ' + foundText);
if (foundText === textToSearch) {
console.log('Found :)');
$("button").trigger("focus");
return;
}
}
console.log('Not Found :(');
$("button").trigger("focus");
}
}, 100);
}
Enjoy!
Cortex R&D Inc.
ctrnd.com
Norm,
I am battling the exact same problem. Don't know if you found a solution yet, but if I figure it out I will be sure to update this question.
Chris.