jQuery autocomplete programmatically search and SELECT first choice (if any) - jquery-ui

This should have been pretty straight-forward, but none of the solutions in StackOverflow doesn't seem to work for me...
Using jQuery 2.1.0, I've set up an autocomplete using an Ajax source, autoFocus: true, and a select: function (event, ui) { ... } to provide me with key/value pair combinations.
As soon as I start typing in the input field, I get the correct options as a DDL, which I can then select using the mouse.
However, I would now like to programmatically trigger the autocomplete search, and then SELECT the first option (if available).
I trigger the search like this:
Preparer.autocomplete('search', LoginName);
The available choices show up correctly, but I can't seem to be able to select the first one programmatically!
I tried calling .select(), I've tried triggering keypress 13 and 9 within the control, and even tried performing the actions within a setTimeout function to make sure that the dialog was rendered correctly!
I even tried setting the option { selectFirst: true }, but still nothing...
Is there something else I could try??

As in the comment above:
You can trigger a click on the first menu item:
$("#autocomplete-id").data("ui-autocomplete").menu.element.c‌​hildren().first().cl‌​ick()
Keep in mind: Triggering a select will also close the menu, which seems counterintuitive. It'd be better to intercept the data in source and trigger your custom callback there, and not bother with select at all.

Search
$('#autocomplete-id').data("uiAutocomplete").search($("#autocomplete-id").val());
&
Select
var results = $("#autocomplete-id").data("ui-autocomplete").menu.element.c‌​hildren()
.first().cl‌​ick()

Related

how to change select2 value programmatically

I have a select2 box in bootstrap modal, I want to change the value of the select2 box but it didn't work.
I tried every single solution in previous posts and results but none of them got it work.
I use select2 4.0.2, I tested:
$('#select_id').val('val').trigger('change.select2');
$('#select_id').val('val').trigger('change');
$('#select_id').val('val').change()
It works one or two times then it stops working (randomly)
It works fine only when I change the select2 back to 3.x.x
$('#select_id').val('val').trigger('change');
is the right way, see here
$('#select_id').select2('val', selectedValue);
For Select2 with Ajax call, I struggled with lot of options, but none worked. Then i came to following solution, which works like charm
$("#select_id").html($("").val('val').text('text')).trigger("change");
To programmatically select an option/item for a Select2 control, use the jQuery
$('#mySelect2').val('1'); // Select the option with a value of '1'
$('#mySelect2').trigger('change'); // Notify any JS components that the value changed
You can also pass an array to val make multiple selections:
$('#mySelect2').val(['1', '2']);
$('#mySelect2').trigger('change'); // Notify any JS components that the value changed
I have used the following code in 4.x.xx version and it is working
$('#select_id').val('val').select2();
If you, like me, have added a custom handler for the select2:selecting event the correct complete answer to changing a value and triggering the custom select2 event would be:
$('#select_id').val('val').trigger('change').trigger({
type: 'select2:event_name', // It worked for me with select2:selecting and select2:select
params: {
args: { // Only use 'args' if using select2:selecting, select2:select does not use it
data: varWithEventData
}
}
});
For those who facing an issue like this:
If you're using multiple select elements and have a common event handler (like $(".mySelect2Inputs").click(...) ) when you do $('#mySelect2').trigger('change') the click event handler is gonna trigger multiple times ($(".mySelect2Inputs").length times).
To prevent this situation, you must use $('#mySelect2').trigger('change.select2') (attention to .select2 namespace!).
From the select2 docs:
https://select2.org/programmatic-control/events#limiting-the-scope-of-the-change-event
It's common for other components to be listening to the change event, or for custom event handlers to be attached that may have side effects. To limit the scope to only notify Select2 of the change, use the .select2 event namespace:
$('#mySelect2').val('US'); // Change the value or make some change to the internal state $('#mySelect2').trigger('change.select2'); // Notify only Select2 of changes

How to get select2 dropdown to scroll to selection when initially opened

When I attach jquery select2 to a <select> that already has an option selected, the dropdown does not show the selected option. If I choose a new option, close the dropdown, then re-open it, the dropdown does show the option.
Example fiddle here: https://jsfiddle.net/9tf2nx8L/1/
Steps to reproduce:
Notice "5" is selected in the markup
Click the select2 box
Notice how the list of options starts at the top
Click another option.
Click outside the dropdown, causing it to disappear
Click the select2 box again
Notice how the list of options has scrolled to have your newly selected option visible
I'm thinking this is a bug report, but wanted to sanity-check it with SO first.
There you go:
function dropscroll(){
document.getElementById($(".select2-results__options").attr("id")).scrollTop = $(".select2-results__option[aria-selected=true]").outerHeight() * $(".select2-results__option[aria-selected=true]").index() - 100;
}
$(document).on("click",".select2-container", function(){
setTimeout("dropscroll()",1);
})
You may have to do some overriding of some select2 core. The method that is invoked that scrolls to the currently selected item is the
ensureHighlightVisible()
It's located inside of the results module of select2. If you go down the route of overriding the core, you can hook into the 'results:all' event from select2 when you bind to the results module. Your code would look something like so:
[omitted code here]
YourClassThatOverridesResults.prototype.bind = function (decorated, container, $container) {
var self = this;
decorated.call(this, container, $container);
container.on('results:all', function (params) {
if (container.isOpen())
{
self.setClasses(params);
self.ensureHighlightVisible();
}
});
}
[omitted code here]
If this seems like a roundabout answer - it is. I don't know how deep down the rabbit hole you want to go, but I hope it can lead you in the right direction.

JQuery mobile hiding a dynamically generated button

I have written some code that generates a set of buttons when the page loads using a loop, each iteration of the loop increments an ID value to assign to the new button.
I originally wrote it using standard JQuery but because of the way JQuery Mobile works, I am having to rewrite it.
<a id = "<?php echo $button_id_add_to_cookbook ?>"onclick="update_button('<?php echo $button_id_add_to_cookbook ?>')" data-role="button">Send</a>
the function update button is below, at least the test trial version.
function update_button(id)
{
$(id).click(function(){
$(id).toggle();
});
}
I'm having a hard time finding 2 accounts that say how to do this the same way so don't think this is correct.
The goal it to dynamically generate a set of buttons and when a button is clicked, it will call some code to alter a mysql database and on success hide the button that called the function. For this example I just want to hide the button when t was clicked.
Can anyone help me with the correct way to do this, the page should not refresh, just update the button element.
I think it was a spacing issue causing problems, for dynamic id content this seemed to work as a replacement function.
function update_button(id)
{
$('#' + id).closest('.ui-btn').hide();
}
if this will lead to any issues in the long term please let me know!

jquery ui tabs multiple calls to tabs()

I have a page where I put my tab content into a div.
This work fine and I can see the tabs.
Later, an event occurs (like selecting a combo box value) and I want to change to another set of tab.
I basically did:
('#divId').empty();
someData.appendTo("#divId");
$("#divId").tabs();
Here is the problem, this 2nd call show me a list:
. tabName1
. tabName2
..... etc
Any idea what's going on, seems like the call to .tabs() work only once when I first load the page.
Thanks.
Check the value of someData, it might contain invalid html that cannot handled when you call the jquery tabs() method again.
One way to do it is:
console.log(someData);
Then if you're using chrome, hit F12 then click on "Console".
$("#detailUL").append("<li><a href='#tabs3-"+id+"'>Desc No "+m+"</a></li>"); // desc
$("#details").append("<div id='tabs3-"+id+"' class='it_detail'>"+copy+"</div>"); // detail
$("#detailPanel").tabs("refresh");

Changing the hash but not moving the page using jquery ui tabs

I added the following code to change the hash to the tab name:
$("#tabs > ul").tabs({
select: function(event, ui){
window.location.hash = ui.tab.hash;
}
} );
This works fine in FF3 but in IE7 it moves down the page (depending on the tab selected anywhere from somewhere near the top of the page all the way down to the very end of the page).
I tried changing it to:
$("#tabs > ul").tabs();
$("#tabs > ul").bind("tabsshow", function(event, ui) {
window.location = ui.tab.hash;
})
This leads to identical behavior in both IE7 and FF3, which moves the page down to the top of the selected tab.
I would like the tab to be changed, the hash to be updated, but the page not moved at all, which is how it works in FF3 in my first example, but not in IE7.
Thanks.
Notes: JQuery 1.3.1 / JQuery-UI 1.6rc6
If there's an element on the page that has the same id as what you're setting the hash to, for instance you're trying to set the browser hash to #cars and there's already a div#cars on the page, the browser will scroll you down to where that div is.
To my knowledge, there are 3 possible workarounds
1) Change the browser hash to something else such as #thecars.
2) Change your existing markup in some similar manner.
3) On some event, changing the id of your similarly named markup, then changing the browser hash, then rechanging the name of markup back to it's original value should also theoretically work. This is obviously a bad and slow workaround, just thought I'd mention it.
You could try having a "return false;" after you set the window location but I can't be sure.
Unfortunately, your problems won't end there. There are other issues with navigating back and forth across multiple browsers--nothing may change, page may reload, page state might be mangled, javascript may get reinitialized etc.
You may want to have a look at Tabs v2 which uses the History/Remote plugin though it has not been updated for jQuery 1.3+.
This demo is easier to understand. If you look at the javascript source, you'll notice the use of iframes to handle states.
There is also the History Event plugin and the jHistory plugin to achieve what you want.
Would like to hear back how things turns out and what solution you went with.
What Chris suggested worked for me, had no clue even a div could link via the #. So my solution is quite simple, in the show: event handler, I do the following, it's not perfect in that back button won't be in history, but that's another job for BBQ history plugin. All my divs simply have id="tab-cars", id="tab-trucks"... strip out the 'tab-' part and put it into the url hash.
var name = ui.panel.id.substr(4);
location.hash = '#'+name;

Resources