For the life of me I cannot figure out how to trigger a suggestion selection on a TypeAhead input
I've tried all kinds of things like
.trigger('suggestionClicked', $('.tt-dropdown-menu .tt-suggestion:nth-child(1)'))
I suppose there are really two parts to this problem.
1. Properly selecting the actual TypeAhead object.
I do this primarily by focusing (focus()) on the input field, and then using jQuery to find the element that is active ($(document.activeElement)). This might not be the best way. It's quite difficult to test in the browser web-inspector because every time I go to the console I lose focus and then the menu disappears (literally removing the results from the DOM)
2. Triggering the correct event.
I'm not sure exactly on which object or which event to trigger, but my best guess is either suggestionClicked on either the TypeAhead object or the TypeAhead.Dropdown object. Second best guess would be click.tt.
I might be overthinking this.
If you really care about the reason behind this, it's because I need to test the functionality via Capybara/Selenium.
I've been browsing the source code on github for some insight.
Here is a step in my Capybara attempt. I feel like I'm getting close but it's not there yet.
steps.rb
Then /^I select result number "([^\"]*)" from typeahead$/ do |num|
find('.tt-dropdown-menu')
#within('.tt-dropdown-menu') do
page.execute_script %Q{$(document.activeElement).dropdown().trigger('suggestionClicked', $('.tt-dropdown-menu .tt-suggestion:nth-child(#{num})'))}
#end
end
Related
I am using select2 version 4.0.2(rc1)
What I am seeing is that when using select2 with isMultple=true, opening the dropdown and then dynamically removing the select from the DOM, the menu sticks around.
You can see it happening in the select2 examples by focusing on control so you see the time zone options, then in the console typing $('.s2-example').remove(). The list of options sticks around.
Edit: Above is an example of what I am trying to work around. What is happening in my case is the dom is being manipulated to remove the select box by a framework in such a way that I can't hook into it before it happens. What I am trying to do is find a way to respond to the element being removed in the hopes that I can manually remove the options list if it exists.
I'm trying to figure out a clean approach to handling this. I've tried hooking into destroy like so:
$("#select-2-id").on("destroy", function(){...})
but destroy doesn't appear to be fired.
I have considered using a mutation observer but that feels kind of hacky to me. Could anyone suggest a better way to handle this? Any advice would be appreciated. Thanks!
Definitely buried in the documentation (under adapters), but you should be calling the destroy method on the select by passing "destroy" to the jQuery object's .select2() method
$(".js-example-basic-multiple").select2('destroy');
This destroys the instance. You can then safely call .remove()
$(".js-example-basic-multiple").select2('destroy').remove();
I am working with Prototype JS framework and I have a form with two select fields (each with three options). There is an observer that changes the text of another element whenever I select a value, which is what it is supposed to do.
However, how do I find out what code is observing that event (the selecting of an option in the form) and therefore making the changes to the element? I've spent the past few hours trying to work it out to no avail.
Am I correct in thinking there is a way to get a stack trace to find out what code is observing that change? Or is there an alternative method to debugging.
Thanks in advance for any advice :-)
The simplest fix was a matter of finding where Event.observe was written in the JavaScript and tracing back.
The documentation was helpful: http://prototypejs.org/doc/latest/dom/Event/observe/
I recently found and applied the changeTracker/dirtyFlag approach successfully in my code and everything was good. Very neat and useful. Though, today, I was trying to use it again and something weird was happening: the somethingHasChanged trigger was firing as soon as I opened the page.
I looked, searched and nothing. I was not doing any change to the observables after setting the tracker.
After a couple of hours of this, I found the root of the problem:
One of the observables is binded to a <select> element thus setting the currently selected <option>.
If I remove this binding, it no long triggers.
I don't know why this happens, since the value is only read (supposedly).
Any thoughts on this?
My guess would be that you are binding against numeric values and the selected one is being written back to your view model as a string, as KO reads it out of the DOM element.
I am trying to do all dom manipulations off screen and then make it visible. Which works, except now I have the situation where I am trying to do it with a form which I want to focus on the first input text upon rendering it on the browser.
Something like: myForm.prependTo(myDiv).show().find('input:first').focus();
Problem is that the focus is being called before the form has finished rendering which is causing the lovely error 'Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus'
How do other web developers handle the similiar situation of manipulating elements off screen and then making it visible? I wish jQuery had something like myForm.prependTo(myDiv, function() { /* on render code here */ })
I know one way of doing it is setting a timeout and when it fires I put focus on the input, but I feel like that's not really the cleanest way to do things. I know the iframe has an onload event, so I'm curious if people usually draw their elements in some hidden iframe and listen for its load event to know when the element has finished rendering? If so could you point me to an example of doing this?
myForm.prependTo(myDiv).show(function(e){
$(this).find('input:first').focus();
});
I know I'm 7 years late, but I had a similar problem, which I solved by putting the stuff I needed to happen after the render in a ready handler.
I had a restore function that worked, but there was zero or near zero visual feedback that the element had been restored.
I tried emptying the element first. It still worked, but still had zero visual feedback.
$("#someSelector").empty();
restore();
Then I discovered ready() happens after the rendering; so I changed it to something like....
$("#someSelector").empty().ready(function() {
restore();
});
Now the restore() doesn't happen until after the empty() action RENDERS. This means my element APPEARS to empty out and then refill (it always did, but now the user can see it happen).
I found this solution somehow a few days ago for a different problem with some vague search that I can't remember. Then I needed it again but couldn't exactly remember what I did. Now my searches included the word "jquery" and "render" and lead me here.
I ended up going thru my code to find out what I did, and I thought it might be a good idea to post it here in case other people stumble on this post and actually need to execute something AFTER rendering happens.
Cheers.
So I have looked through most of the facebook questions here and it has absolutely confirmed my thoughts. Facebook development may be among some of the worst I've ever used. I'll avoid my rant for now, but as a note to where I'm coming from: tried php sdk, worked decently out of the box, found out I need to put the functionality on a pages tab, can't iframe on pages tab, have to use FBML (which they are retiring in two months, yet I can't start testing the iframe approach yet)
Anyway, I run into FBJS at this point. It works "good enough" for most things, but for some reason I can't get an event registered to an object (a select box in particular interest) by adding a listener (as per FBJS documentation). I am able to add it directly to the html object and have it work, but this is not desirable and I would really like to know what I consider the proper way to do it, which involves seperation of logic and display.
What I want to happen: click on the select box, make a selection, display the text of the selection in an empty div (later on adding Ajax but one step at a time here)
Code:
<script>
var obj = document.getElementById('select-id');
obj.addEventListener('onchange',my_func);
function my_func(evt){
var inner = document.getElementById('div-id');
inner.setTextValue('hey'); // for testing purposes
}
</script>
The above code doesn't do anything when I make a change to the select box. However, this behaves as planned:
<select name="find_state" id="find_state" onchange="my_func();">
I will be grudgingly using this method as I develop, but would really love to know what I might be doing wrong or if anyone else has this issue? And if anyone has any opinions on the matter I would love to know of some form of facebook development recommendations as applications, pages, and tabs all appear to behave totally different from eachother, yet it seems that they all should be doing the same thing to me? Is there any unified way to develop across all three of these things, or am I missing something?
Thanks in advance, as well as for the past help!
I think it should be:
obj.addEventListener('change',my_func);
(instead of onchange)
Straight from Facebook documentation:
The third parameter [to addEventListener], boolean useCapture is required (it does not have a default value)
That means that you should have:
obj.addEventListener('change', my_func, false);
Use the following html and your events attached with .addEventListener() start to work. This seems to be undocumented "feature".
<select name="find_state" id="find_state" onmousedown="return true;">
This also enables the event to fire first time the user changes the value of select. Otherwise it would fire only on second onchange event.