Javascript: pass var to object literal - javascript

I'm having a problem with this code:
$(function () {
$('#city_input').autocomplete({
onSelect: function (suggestion) {
alert(suggestion.data);
window.latlng = suggestion.data;
}
});
$('#fs_input').autocomplete({
params: { "latlng" : window.latlng, "latlng2" : '99.9999,-99.9999' },
onSelect: function (suggestion) {
alert(window.latlng);
}
});
});
This is an autocomplete script. First the user selects a suggestion on #city_input. Doing that, it sets the value for window.latlng.
Then next, the user needs to select a suggestion on #fs_input. The problem I'm having is that, in the "params" property, the "latlng" : window.latlng property is not being set. Just for tests, I also created another property, seen in the code, latlng2 which is working fine. Also, a little below, I'm doing an alert(window.latlng) to check the value and it alerts the expected value.
So the question is, why "latlng" : window.latlng is not being set? Maybe I'm not supposed to pass a variable to an object liberal property?

It is being set. It's simply that it has no value at the point when you're setting it.
The value isn't computed dynamically after #city_input's onSelect callback fires, it's being computed once when the script first loads, long before you ever assign to it.
$('#city_input').autocomplete({
onSelect: function (suggestion) {
alert(suggestion.data);
# you assign here, in a callback that executes some time after the page loads
window.latlng = suggestion.data;
}
});
$('#fs_input').autocomplete({
# however, you *read* the value here, immediately on page load, long before `onSelect` ever runs
# window.latlng is "undefined" at the point `params` is created.
params: { "latlng" : window.latlng, "latlng2" : '99.9999,-99.9999' },
onSelect: function (suggestion) {
alert(window.latlng);
}
});
If you want a value selected in the onSelect callback to be used in the autocomplete for a different element, you need to wait to initialize the autocomplete until after a value is selected and actually available:
$('#city_input').autocomplete({
onSelect: function (suggestion) {
alert(suggestion.data);
window.latlng = suggestion.data;
$('#fs_input').autocomplete({
params: { "latlng" : window.latlng, "latlng2" : '99.9999,-99.9999' },
onSelect: function (suggestion) {
alert(window.latlng);
}
});
}
});

In your code, I'm guessing that the onSelect function doesn't execute until a user has selected an item. However, the 'params' object is created when the autocomplete function is invoked, which is immediate (before a value has been assigned).
You need to initialise autocomplete on #fs_input only when you know the value of window.latlng (i.e. after the user has selected it):
$(function () {
$('#city_input').autocomplete({
onSelect: function (suggestion) {
alert(suggestion.data);
window.latlng = suggestion.data;
$('#fs_input').autocomplete({
params: { "latlng" : window.latlng, "latlng2" : '99.9999,-99.9999' },
onSelect: function (suggestion) {
alert(window.latlng);
}
});
}
});
});

Related

Getting the selected value on autocomplete in Jquery

I added an Autocomplete feature to a form on a HTML template, i would like to perform some actions when an hint is selected, is there any way to do it? I'm using Jquery-Typeahead. Here is my actual code:
$(document).ready(function(){
// Defining the local dataset
$.getJSON('http://127.0.0.1:8000/myapi', function(data) {
console.log(data)
var dt = data
$(() => {
$('#myform').typeahead({
source: {
data: dt.results.map(record => record.item)
},
callback: {
onInit: function($el) {
console.log(`Typeahead initiated on: ${$el.prop('tagName')}#${$el.attr('id')}`);
},
onClick: function() {
console.log(); //How can i console.log() the selected value here, for example?
}
}
});
});
});
});
Try defining an onClickAfter callback, it's called right after user clicks on an item. Something like this:
onClickAfter: function(node, a, item, event) {
// item will be the item you selected
console.log(item);
}
You can also define the onClickBefore callback the same way, and it will be called immediately before "normal" typeahead behaviour kicks in

Where are the arguments to the jQueryUI Dialog submit handler coming from?

Take a look at the following code:
this.dialog({
width: 500,
height: 260,
title: "Setup database",
content: $("<form>").append(table),
buttons: {
submit: function(_alert, dialog) {
dialog.find("form").each(function() {
var arr = $(this).serializeArray();
var data = {
mysql: true
};
var empty = false;
$(this).find("input").removeClass("error");
for (var k in arr) {
if ($.trim(arr[k].value) !== "") {
data[arr[k].name] = arr[k].value;
} else {
empty = true;
$(this).find("input[name='" + arr[k].name + "']").each(function() {
$(this).addClass("error");
});
break;
}
}
if (!empty) {
self.ajax({
url: url,
data: data
}, function(result) {
callback(result);
}, function() {
self.mysql(url, callback, _db_name, _db_user, _db_pass, is_dialog);
});
}
_alert.remove();
if($.isFunction(callback_submit)) {
callback_submit();
}
});
}
}
});
There are two parameters passed into the anonymous function that is supposed to trigger when the button "submit" is clicked. But I have no idea where these parameters are supposed to come from. Can someone explain? Is this related to passing parameters to an anonymous function in Javascript in general?
I don't think you get any argument passed to you when a button event callback is fired on jquery-ui dialog box
http://jsfiddle.net/3d7QC/1577/
buttons: {
"I've read and understand this": function() {
console.log(arguments);
// look at your console
$(this).dialog("close");
}
Only argument you get passed through to you is the customary jQuery event object.
There should only be one parameter passed to submit, which is the event object of the button itself, when clicked. So the context set is the submit button, if you need to access the dialog and modify it, you can do so by accessing the event.target property.
this.dialog({
buttons: {
submit: function(event) {
$(event).dialog('close'); //is the same as...
$(this).dialog('close');
}
});
The first argument _alert is the JS event object that is passed to every event handler in JavaScript. This is not specific to jQuery. javascript.info explains this as follows:
W3C way
Browsers which follow W3C standards always pass the event object as
the first argument for the handler.
For instance:
element.onclick = function(event) {
// process data from event
}
In the jQueryUI API reference they confirm that i
Specifies which buttons should be displayed on the dialog. The context
of the callback is the dialog element; if you need access to the
button, it is available as the target of the event object.
I illustrated this in a fiddle. Not sure what the second argument (dialog in your case) does, though. It's not passed in my example code.

How to wait for a function to complete before executing another function

I'm using selecter jquery. I initialize it by typing the code
$("select").selecter();
I need to make sure that the formstone selecter jquery library has completed before i start appending elements. So what i did is to is use the $.when function
initialize: function(){
$.when($("select").selecter()).then(this.initOptions());
},
initOptions: function(){
this.$el.find('.selecter').addClass('something');
}
But this does not work. How can i wait while formstone selecter is doing its thing before i execute another function?
Thanks,
UPDATE
Here's the update of what i did but it does not work.
initialize: function(){
$("select").selecter({callback: this.initOptions });
},
initOptions: function(){
this.$el.find('.selecter').addClass('something');
}
There is a callback option.
The function passed as a callback will receive the newly selected value as the first parameter
Should be $("select").selecter(callback: function() { alert('callback fired.') });
or as shown
$("select").selecter({
callback: selectCallback
});
function selectCallback(value, index) {
alert("VALUE: " + value + ", INDEX: " + index);
}
The problem which I think regarding the callback edited code is that this can refer to anything. Try the following code
var selectorObj = {
initialize: function(){
$("select").selecter({callback: selectorObj.initOptions });
},
initOptions: function(){
this.$el.find('.selecter').addClass('something');
}
};
Created a working fiddler for you http://jsfiddle.net/6Bj6j/
The css is out of shape. Just select what is poping up when you click on the dropdown. You will get an alert which is written in the callback.
The problem with the provided snippet is the scope of the callback:
var selectorObj = {
initialize: function(){
$("select").selecter({ callback: selectorObj.initOptions });
},
initOptions: function(){
// 'this' refers to the "$('.selecter')" jQuery element
this.addClass('something');
}
};
However if you just need to add a class to the rendered element, you should use the 'customClass' option:
$("select").selecter({
customClass: "something"
});
If you need to do more, you can always access the Selecter element directly:
var $selecter = $("select").selecter().next(".selecter");
$selecter.addClass("something").find(".selecter-selected").trigger("click");
Sidenote: I'm the main developer of Formstone. If you have any suggestions for new features or better implementation, just open a new issue on GitHub.

How to pass in event data for jQuery datepicker events

I am trying to pass event data to a jQuery datepicker event handler, for 'dataID':
input.datepicker({
onClose: function() {
var datePicker = jQuery(this);
customFunction(datePicker, dataID);
}
});
Does anyone know how to do that?
Pass the current object as:-
input.datepicker({
onClose: function(txt, obj) {
var datePicker = obj;
customFunction(datePicker, datagridId);
}
});
onClose method gives two arguments. The text entered and the this instance where the event occurs.
Check the reference here
http://api.jqueryui.com/datepicker/#option-onClose

Replacing jQuery.bind with jQuery.on

I've written a program that includes a form that the user interacts with. Because there are lots of events bound to different buttons I have written a loop that parses some JS that contains the form input information. Here is some example data:
var value = 0,
forms = {
place_controls : {
attrs : {
'class' : 'place-form'
},
input : {
place_x : {
attrs : {
type : 'text',
},
events : {
change : function () {
value = 10;
}
}
},
place_y : {
attrs : {
type : 'text',
},
events : {
change : function () {
value = 50
}
}
}
}
}
}
The data is then parsed by this:
$.each(forms, function (form_index, form) {
var $form_markup = $('<form>').attr(form.attrs);
// Next: loop through each input element of the form we've reached
$.each(form.input, function (element_index, element) {
var $elem = $('<input>').attr(element.attrs);
$elem.appendTo($form_markup);
if (element.events !== undefined) {
$.each(element.events, function (event_index, event) {
$elem.bind(event_index, event);
//$form_markup.on(event_index, $elem, event);
});
}
});
$form_markup.appendTo($form_goes_here);
});
As you can see, I'm using .bind() at the moment, however I want to use .on(). Unfortunately, when I do this all of the items within a form are bound to the last event parsed by the function. When I use .bind() everything works as planned - i.e. Clicking on 'place_x' sets value to 10, clicking 'place_y' sets value to 50.
When using .on(), whichever I change sets value to 50, which I am assuming is because the last function is becoming bound to each event.
Can anybody see what I have done wrong?
Update: There are many different ways to do this, and I have subsequently changed how my code works, however this question is related to why .bind() is working and why .on() is not.
//$elem.bind(event_index, event);
//It looks like you should just be using .on() like this
$elem.on(event_index, event);
The way it looks like you are trying to use .on() is in the live -bubbling- event sort of way, it looks like only the last event you are created is sticking, why each value just gets set to 50.
//$form_markup.on(event_index, $elem, event);
You can create elements with property maps that include handler functions in one simple call:
var $elem = $('<input/>', properties);
The "properties" object can contain event handlers:
var $elem = $('<input/>', {
type: 'text',
name: 'somethingUseful',
click: function(ev) { /* click handler */ },
change: function(ev) { /* change handler */ },
css: { color: "red" }
});

Categories

Resources