How to simulate a click on a google place autocomplete result? - javascript

I am struggling to interact with my google place autocomplete results within my integration tests.
var placeSelector = '.pac-container .pac-item:first-child';
exports.runTest = function(test) {
casper.waitForSelector('input.street-address'); // wait for page to load
casper.sendKeys('input.street-address', 'fake address here', {keepFocus: true});
casper.waitUntilVisible(placeSelector);
casper.then(function() {
casper.click(placeSelector); // THIS DOES NOT DO ANYTHING
// if its possible to trigger the event in the context of the page, I
// could probably do so. However, I've scoured google's docs and cannot find the
// event that is fired when a place is clicked upon.
casper.evaluate(function() {
//google.maps.places.Autocomplete.event.trigger(???);
});
});
var formVal;
casper.then(function() {
formVal = casper.evaluate(function () {
return $('input.street-address').val();
});
});
};
With the previous code, there is no result and the input is not populated nor are the suggested results hidden.
How can I simulate the action of a user entering in an address to the autocomplete input and proceeding to click upon one of the suggested results?
A few resources that I have come across asking similar questions:
How to "simulate" a click on a Google Maps Marker?
https://developers.google.com/maps/documentation/javascript/events?csw=1#EventsOverview

I had this same question. After digging around in the Places Autocomplete source code, I came up with the following, which you can include in your CasperJS test, or modify as needed:
https://gist.github.com/jadell/8b9aeca9f1cc738843eca3b4af1e1d32
casper.then(function () {
casper.sendKeys('input.street-address', 'fake address here', { keepFocus: true });
casper.page.sendEvent('keydown', 0);
casper.page.sendEvent('keyup', 0);
});
casper.waitUntilVisible('.pac-container .pac-item', function () {
casper.page.sendEvent('keydown', casper.page.event.key.Down);
casper.page.sendEvent('keydown', casper.page.event.key.Enter);
});
Basically, don't try to simulate a mouse click on the result, use Down Arrow and Enter keys to select the first result.
The autocomplete listens for key down and up events before triggering, which the sendKeys method does not send, so we send some null key events with sendEvent. Then, wait until the resutls container appears, and send Down Arrow and Enter key events to select the first result.

The autocomplete input element does not have a click event attached, so sending it a click will have no effect.
Try a keydown event:
casper.page.sendEvent('keydown', someKey);

I was unable to simulate the actual clicking of an autocomplete result, however it was possible to accomplish the same result by utilizing the down arrow and enter keypresses.
After typing your text into the autocomplete input and being sure to keep the focus, simply include the following lines of code and your result will be properly set by the google places autocomplete API
casper.then(function() {
casper.page.sendEvent('keypress', casper.page.event.key.Down);
casper.page.sendEvent('keypress', casper.page.event.key.Enter);
});
casper.thenEvaluate(function() {
$(inputSelector).blur();
}, placeSelector, inputSelector);
That code will select the first autocomplete result.

Related

Search box not showing post list

I'm hoping you can help me with an issue that I can't solve.
When I updated wordpress to the latest version, select2 lost the functionality to show the latest posts.
The above image is the example of what is happening. Instead it should search and show a list of the last posts by default, without the need to write anything.
The javascript code that we built to circumvent the situation should correct this behaviour, but the trigger is not working properly and only works when a key is pressed inside the box.
Question: Has anyone ever had this problem?
$(document).ready(function () {
var select2_open;
// open select2 dropdown on focus
$(document).on('focus', '.select2-selection--single', function (e) {
select2_open = $(this).parent().parent().siblings('select');
$('.select2-search__field').val(' ');
// trigger keydown event, currently not working
$('.select2-search__field').trigger('keyup.search');
});
});

How to detect if item is selected in Google Maps API autocomplete list?

I'm trying to achieve the following behavior.
When using Google Maps API's autocomplete, clicking with the mouse on an element in the list or pressing enter will select the desired element and fill in the input with necessary values. However, if you press enter while focus is still in the input element itself, nothing happens, so it's necessary to somehow solve that.
I have decided to solve that problem by selecting the first item from the autocomplete list:
$("#autocomplete").keypress(function(e){
if(e.which == 13) {
select-first-item();
}
});
It works well, but the problem is that it will select the first item even if you use the down arrow on the keyboard, browse the autocomplete list and then press enter while e. g. 4th result is selected.
How to solve this? I have tried with :focus, but it doesn't seem very reliable. Sometimes it selected the first result, sometimes it selected the focused item from the list.
Google Maps adds class pac-item-selected to the item selected in the list, so my last try was based on checking for length.
$("#autocomplete").keypress(function(e){
if ( $( ".pac-item-selected" ).length ) {
if(e.which == 13) {
select-first-item();
}
}
}
However, as soon as you press anything, the class goes away and checking for length doesn't work. If I use event.preventDefault, the whole functionalitiy doesn't work, since autocomplete is obviously based on keypress/keydown/... events.
I couldn't make Maps work in my fiddle properly, so I have adapted an old fiddle: http://jsfiddle.net/pbbhH/1222/
Is there any solution for this?
using place_changed event of autocomplete you can check place has been changed:
var input_source = document.getElementById('input_source');
var autocomplete = new google.maps.places.Autocomplete(input_source);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
// process
});
In addition to #dhara-paramar solution:
Just wanted to add new shorter version according to Google Maps Api Documantation:
var input_source = document.getElementById('input_source');
var autocomplete = new google.maps.places.Autocomplete(input_source);
autocomplete.addListener('place_changed', fillInAddress);
function fillInAddress() {
//your process here
};

jQuery Searchbox IE9 issue

I'm working on an issue here that only occurs in IE8/9
We have 2 search boxes. One in the header that uses jQuery's Autocomplete, and the other which is specifically for an archiving feature we have on certain pages. What should happen is if the Autocomplete searchbox is in focus and we hit Enter after typing something in, it searches with that value. Easy enough.
However, in IE8/9, no matter which text box has focus, the Enter key will trigger that event.
Here's what we've got:
jQuery(".autocomplete").keydown(function(event) {
if (jQuery(".autocomplete").is(":focus")){
var query;
if (event.which === 13) {
event.preventDefault();
query = this.value;
return window.location.href = "/search?q=" + query;
}
}
});
I've also tried .keypress() and it yields the same result. We're using jQuery 2.0.0
Our team is relatively new to jQuery, so we're probably just doing this wrong.
It should only be firing on searchboxes with the .autocomplete class, and only if that particular box has focus.
Thanks!
I apologize, apparently a different team had added a .js file that was interfering with the operation of this jquery script in our file.

How to deslect highlighted text in textbox if already highlighted?

So I have this very simple JS function that selects all the text in the ASP.NET texbox (input):
function selectAllText(textbox) {
textbox.focus();
textbox.select();
}
..and it gets called like this on the click event:
$("#<%=Textbox1.ClientID %>").click(function () { selectAllText(jQuery(this)) });
The problem is no matter how many times a user clicks in the text box all of the text is always selected. I understand why this is occuring (based on the way my code above is), but it doesn't work well when the user tries to click in the middle of a word to get the cursor back to make a modification to the text.
How do I modify this JS to tell if the text is already highlighted and then deselect the text? This was on subsiquient click, the user can get the single cursor on a precise clicked location to make a modification.
I am trying to get the documentation on the .select() method to see if I could do if(!textbox.select()), but I am having a hard time finding it, so post any doc links as well if you have them.
EDIT: This problem and need for a workaround seems to be for IE (I am using IE9). In Chrome the behavior by default is what I need, but this is for an intranet application that runs on IE, so it appears I need an explicit workaround.
Thanks!
Is it necessary to do the .focus() in this function? You could instead attach a simple .select(); to the onfocus event (.bind('focus', function(){..})): http://jsfiddle.net/EGHzj/
Try this
$(document).ready(function(){
$('input').bind('click',function(){
if($(this).hasClass('selected')){
$(this).toggleClass('selected');
}else{
this.focus();
this.select();
$(this).toggleClass('selected');
}
});
});
This should work in IE also,
http://jsfiddle.net/rAqgw/7/
function selectAllText(textbox) {
// if there isn't selected text.
if (textbox[0].selectionEnd) {
textbox.focus();
textbox.select();
}
}
$('#txt').click(function() {
selectAllText($(this));
});
Live DEMO
​

Any event triggered on autocomplete?

I have a pretty simple form. When the user types in an input field, I want to update what they've typed somewhere else on the page. This all works fine. I've bound the update to the keyup, change and click events.
The only problem is if you select an input from the browser's autocomplete box, it does not update. Is there any event that triggers when you select from autocomplete (it's apparently neither change nor click). Note that if you select from the autocomplete box and the blur the input field, the update will be triggered. I would like for it to be triggered as soon as the autocomplete .
See: http://jsfiddle.net/pYKKp/ (hopefully you have filled out a lot of forms in the past with an input named "email").
HTML:
<input name="email" />
<div id="whatever"><whatever></div>
CSS:
div {
float: right;
}
Script:
$("input").on('keyup change click', function () {
var v = $(this).val();
if (v) {
$("#whatever").text(v);
}
else {
$("#whatever").text('<whatever>');
}
});
I recommending using monitorEvents. It's a function provide by the javascript console in both web inspector and firebug that prints out all events that are generated by an element. Here's an example of how you'd use it:
monitorEvents($("input")[0]);
In your case, both Firefox and Opera generate an input event when the user selects an item from the autocomplete drop down. In IE7-8 a change event is produced after the user changes focus. The latest Chrome does generate a similar event.
A detailed browser compatibility chart can be found here:
https://developer.mozilla.org/en-US/docs/Web/Events/input
Here is an awesome solution.
$('html').bind('input', function() {
alert('test');
});
I tested with Chrome and Firefox and it will also work for other browsers.
I have tried a lot of events with many elements but only this is triggered when you select from autocomplete.
Hope it will save some one's time.
Add "blur". works in all browsers!
$("input").on('blur keyup change click', function () {
As Xavi explained, there's no a solution 100% cross-browser for that, so I created a trick on my own for that (5 steps to go on):
1. I need a couple of new arrays:
window.timeouts = new Array();
window.memo_values = new Array();
2. on focus on the input text I want to trigger (in your case "email", in my example "name") I set an Interval, for example using jQuery (not needed thought):
jQuery('#name').focus(function ()
{
var id = jQuery(this).attr('id');
window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});
3. on blur I remove the interval: (always using jQuery not needed thought), and I verify if the value changed
jQuery('#name').blur(function ()
{
var id = jQuery(this).attr('id');
onChangeValue.call(document.getElementById(id), doSomething);
clearInterval(window.timeouts[id]);
delete window.timeouts[id];
});
4. Now, the main function which check changes is the following
function onChangeValue(callback)
{
if (window.memo_values[this.id] != this.value)
{
window.memo_values[this.id] = this.value;
if (callback instanceof Function)
{
callback.call(this);
}
else
{
eval( callback );
}
}
}
Important note: you can use "this" inside the above function, referring to your triggered input HTML element. An id must be specified in order to that function to work, and you can pass a function, or a function name or a string of command as a callback.
5. Finally you can do something when the input value is changed, even when a value is selected from a autocomplete dropdown list
function doSomething()
{
alert('got you! '+this.value);
}
Important note: again you use "this" inside the above function referring to the your triggered input HTML element.
WORKING FIDDLE!!!
I know it sounds complicated, but it isn't.
I prepared a working fiddle for you, the input to change is named "name" so if you ever entered your name in an online form you might have an autocomplete dropdown list of your browser to test.
Detecting autocomplete on form input with jQuery OR JAVASCRIPT
Using: Event input. To select (input or textarea) value suggestions
FOR EXAMPLE FOR JQUERY:
$(input).on('input', function() {
alert("Number selected ");
});
FOR EXAMPLE FOR JAVASCRIPT:
<input type="text" onInput="affiche(document.getElementById('something').text)" name="Somthing" />
This start ajax query ...
The only sure way is to use an interval.
Luca's answer is too complicated for me, so I created my own short version which hopefully will help someone (maybe even me from the future):
$input.on( 'focus', function(){
var intervalDuration = 1000, // ms
interval = setInterval( function(){
// do your tests here
// ..................
// when element loses focus, we stop checking:
if( ! $input.is( ':focus' ) ) clearInterval( interval );
}, intervalDuration );
} );
Tested on Chrome, Mozilla and even IE.
I've realised via monitorEvents that at least in Chrome the keyup event is fired before the autocomplete input event. On a normal keyboard input the sequence is keydown input keyup, so after the input.
What i did is then:
let myFun = ()=>{ ..do Something };
input.addEventListener('change', myFun );
//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})
Needs to be checked with other browser, but that might be a way without intervals.
I don't think you need an event for this: this happens only once, and there is no good browser-wide support for this, as shown by #xavi 's answer.
Just add a function after loading the body that checks the fields once for any changes in the default value, or if it's just a matter of copying a certain value to another place, just copy it to make sure it is initialized properly.

Categories