I'm using jquery autocomplete plugin for a textbox:
$('#TargetArea').autocomplete({
source: '#Url.Action("GetTarget", "Ads", new { type = "Zip", term = target })'
});
It works fine. Now, I want to do is: when the textbox text changed, call an action to get data from database, then show the data in another div.
$('#TargetArea').change(function () {
var url = "/My/Test";
var target = $("#TargetArea").val();
$.post(url, { Target: target }, function (data) {
$("#resultId").html(data);
});
})
However, this change event never triggered. If I comment out the autocomplete part, then it works fine. Anyone knows what the problem is? or, How I should do this?
Thanks
I think you should use the change event of the autocomplete plugin.
See the documentation here: http://api.jqueryui.com/autocomplete/#event-change
Check it, I think it should works.
$( "#TargetArea" ).autocomplete({
source: '#Url.Action("GetTarget", "Ads", new { type = "Zip", term = target })',
change: function( event, ui ) {}
});
you can make this either
1 - Initialize the autocomplete with the change callback specified:
$( '#TargetArea' ).autocomplete({
source: '#Url.Action("GetTarget", "Ads", new { type = "Zip", term = target })',
change: function( event, ui ) {
var url = "/My/Test";
var target = $("#TargetArea").val();
$.post(url, { Target: target }, function (data) {
$("#resultId").html(data);
});
}
});
or
2- Bind an event listener to the autocompletechange event:
$('#TargetArea').autocomplete({
source: '#Url.Action("GetTarget", "Ads", new { type = "Zip", term = target })'
});
$( '#TargetArea' ).on( "autocompletechange", function( event, ui ) {
var url = "/My/Test";
var target = $("#TargetArea").val();
$.post(url, { Target: target }, function (data) {
$("#resultId").html(data);
});
});
This will be triggered when the field is blurred, if the value has changed.
Source : http://api.jqueryui.com/autocomplete/#event-change
Related
Updated code - working
(function($) {
$.fn.mbajaxform = function( mbopts ) {
var mb_form_items = $(this).find('input, submit, button'),
mb_form_type = mb_mbtheme_js[0],
mb_get_page_slug = mb_mbtheme_js[1],
mb_redirect = mb_mbtheme_js[2],
mb_redirect_time = mb_mbtheme_js[3],
mb_form_disable = mb_mbtheme_js[4];
// create the defaults
let mbdefaults = {
beforeSend: function( el, beforeSend ) {
},
success: function( el, success ) {
},
complete: function( el, complete ) {
},
error: function( el, error ) {
}
};
// extend the defaults
let mboptions = $.extend( {}, mbdefaults, mbopts );
return this.each( function() {
// the variable for this
var $this = $(this);
function beforesend_callback(e) {
mboptions.beforeSend( $this, e );
}
function success_callback(e) {
mboptions.success( $this, e );
}
function complete_callback(e) {
mboptions.complete( $this, e );
}
function error_callback(e) {
mboptions.error( $this, e );
}
// run the function
$this.on( mb_form_type, function(mb) {
// stop the default function of buttons
mb.preventDefault();
var mb_ajax_form_data = new FormData( $this[0] );
// do the ajax
$.ajax({
method: "POST",
data: mb_ajax_form_data,
contentType: false,
processData: false,
beforeSend: beforesend_callback,
success: success_callback,
complete: complete_callback,
error: error_callback
});
});
});
};
}( jQuery ));
$("#mbform").mbajaxform();
Original question
This is my first attempt at creating a plugin but was following a few tutorials hoping it would work first go - rookie!
I have an AJAX form that I noticed was being repeated (such as password resets, theme settings, user creation) across a few sub-sites within my network (using Wordpress Multisite), so I decided it could be more beneficial to create a function that was able to be extended (if changes needed) but otherwise apply the defaults.
see edit revisions for older code
At a glance looks like you might not be referencing the correct options variable.
You're setting it with the name mboptions
let mboptions = $.extend({}, mbdefaults, mbopts);
but then trying to access it using options
options.beforeSend($this, e);
And when you're trying to bind the submit event you're not accessing the event name from the options object. So instead of
$this[mb_form_type](function(mb) {...});
I think
$this.on(mboptions.mb_form_type, function(mb) {...}):
is a bit more readable (also you can later remove the binding with this.off(mboptions.mb_form_type) if you need to ;)
I have an MVC Control for a KendoUI ComboBox that does NOT setup the Change Event ahead of time. Upon rendering, a page controller sets-up & shims-in its' own Change Event.
Oddly, this event gets called TWICE:
When I change the Selected Item
When I click away from the control
Q: What am I doing wrong?
Q: Is this HOW we should over-write the change event on an existing Kendo ComboBox?
MVC CONTROL:
As you can see, I am NOT defining any client-side events here...
#(Html.Kendo().ComboBox()
.Name("ddlTechnician")
.Filter("contains")
.Placeholder("Select Technician...")
.DataTextField("Text")
.DataValueField("Value")
.BindTo(new List<SelectListItem>() {
new SelectListItem() { Text = "Frank", Value = "1" },
new SelectListItem() { Text = "Suzie", Value = "2" },
new SelectListItem() { Text = "Ralph", Value = "3" }
})
.Suggest(true)
.HtmlAttributes(new { style = "width:300px;" }))
PAGE CONTROLLER:
And, I am only defining the event ONCE here. I have also confirmed the event isn't already firing BEFORE setting it in the Page Controller
$(document).ready(function () {
var PageController = (function ($) {
function PageController(options) {
var that = this,
empty = {},
dictionary = {
elements: {
form: null
},
instances: {
ddlTechnician: null
},
selectors: {
form: 'form',
ddlTechnician: '#ddlTechnician'
}
};
var initialize = function (options) {
that.settings = $.extend(empty, $.isPlainObject(options) ? options : empty);
dictionary.elements.form = $(dictionary.selectors.form);
// Objects
dictionary.instances.ddlTechnician = $(dictionary.selectors.ddlTechnician, dictionary.elements.form).data('kendoComboBox');
// Events
dictionary.instances.ddlTechnician.setOptions({ change: that.on.change.kendoComboBox });
};
this.settings = null;
this.on = {
change: {
kendoComboBox: function (e) {
// This is getting called MULTIPLE TIMES
console.log('kendoComboBox RAN');
}
}
}
};
initialize(options);
}
return PageController;
})(jQuery);
var pageController = new PageController({});
});
I was able to reproduce your problem on a Kendo JQuery Combobox when I set the event handler through setOptions, which is not the recommended way after the widget has been rendered. Instead you should use the "bind" method as shown in the documentation's example for change events.
Try changing the line of code where you set your event handler to this:
dictionary.instances.ddlTechnician.bind("change", that.on.change.kendoComboBox);
Here's a dojo that shows the difference: http://dojo.telerik.com/iyEQe
Hope this helps.
My goal is to contruct an object with data of my form.
After doing some googling, people suggested me to use serialize()
Now, I got this from my form data
_method=PUT&_token=rs8iLxwoJHSCj3Cc47jaP5gp8pO5lhGghF1WeDJQ&max_down=256&max_up=256&cpe_mac=000D6766F2F6&device_mac=503275AE7A69
Is there a way to convert that long string into an object ?
Is there a any other way to achieve this ?
Any direction on this will mean a lot to me !
I've tried
$( "form#editRateLimitForm" ).on( "submit", function( event ) {
event.preventDefault();
var serialize = $( this ).serialize() ; // Nothing printing out
console.log(serialize); // _method=PUT&_token=rs8iLxwoJHSCj3Cc47jaP5gp8pO5lhGghF1WeDJQ&max_down=256&max_up=256&cpe_mac=000D6766F2F6&device_mac=503275AE7A69
});
I have used this approach many times.
$("form#editRateLimitForm").on("submit", function( event ) {
event.preventDefault();
var formObj = {},
formData = $(this).serializeArray(),
i;
for (i in formData) {
formObj [formData[i]['name']] = formData[i]['value'];
}
console.log(formObj);
});
console.log should show
{_method: 'PUT', token:'rs8iLxwoJHSCj3Cc47jaP5gp8pO5lhGghF1WeDJQ', max_down: '256',
max_up: '256', cpe_mac: '000D6766F2F6', device_mac: '503275AE7A69'}
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" }
});
Hi all,
In my application I am using autocomplete, I have list as
<p>
<input type="text" id="searchField" placeholder="Categories">
<ul id="suggestions" data-role="listview" data-inset="true"></ul>
</p>
I have one array name myArray and using autocomplete as:
$("#searchField").autocomplete(
{
target: $('#suggestions'),
source: myArray ,
link: 'target.html?term=',
minLength:0
});
Now I want to get the list item name on which I click and use that variable in target.html file. How to get that? Thanks in advance.
From their help docs.
Callback
When using the optional callback function autoComplete will only execute code found within the callback. The click event object is passed into the callback function for use in accessing the information contained in the selection. Here's one use case:
$("#searchField").autocomplete("update", {
source: [ "foo", "bar", "baz" ],
minLength: 3,
callback: function(e) {
var $a = $(e.currentTarget); // access the selected item
$('#searchField').val($a.text()); // place the value of the selection into the search box
$("#searchField").autocomplete('clear'); // clear the listview
}
});
OPTION 1
This section will allow you to access the text field
$('#searchField').val($a.text()); // or $a.value()
so do something like this inside the callback event
window.location.replace("http://stackoverflow.com?target=" + $a.text());
OPTION 2
It seems like they expect the result set to be in this format (text & value), so if you'd need other values, you'd need to resort to the jquery autocomplete (which this component is based on)
$('#some_id').autocomplete({
source: function (request, response) {
$.ajax({
url: 'some_url',
dataType: "json",
data: {
filter: request.term
},
success: function (data) {
response($.map(eval(data), function (item) {
return {
label: item.Text,
value: item.Value,
extra_value: item.Extra_Value
}
}));
}
})
},
maxLength: 2,
select: function (event, ui) {
$("#Some_id2").attr('value', ui.item.extra_value);
}
});
UPDATE aka OPTION 3
From their demo code, if you just want the text value, and don't need the ID (like in your case), just change your source format. Rather than returning a JSON result from the server return an array of strings, or convert the JSON result to a string array, which ever flavor you like
(code from the working sample on their demo page)
var availableTags = ['24', 'about me',... , 'XUIJS'];
$("#searchField").autocomplete({
target: $('#suggestions'),
source: availableTags,
link: 'target.html?term=',
minLength: 1,
matchFromStart: false
});
Use Callback .
$("#searchField").autocomplete(
{
target: $('#suggestions'),
source: myArray ,
link: 'javascript:void();',
minLength:0,
callback: function(e){
var name = $(e.target).attr('name');
//This function will be called when one of the suggestions is clicked according to documentation
window.location = 'target.html?term=' // This line might need some tweaking.
}
});
The code is not tested, you might need to debug this step by step.
If I use
$("#searchField").autocomplete(
{
icon: 'arrow-l',
target: $('#suggestions'),
source: stockArray,
link: 'target.html?term=',
minLength:0,
callback: function(e)
{
var nameq = $(e.currentTarget);
console.log("^^^^^^^^^^^^^^^^^^^^^"+nameq);
//This function will be called when one of the suggestions is clicked according to documentation
window.location = 'target.html?term='
}
});
I get value of nameq as
^^^^^^^^^^^^^^^^^^^^^[object Object] at file:///android_asset/www/index.html:115
and If I use
$("#searchField").autocomplete(
{
icon: 'arrow-l',
target: $('#suggestions'),
source: stockArray,
link: 'target.html?term=',
minLength:0,
callback: function(e){
var nameq = $(e.target).attr('name');
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^"+nameq);
//This function will be called when one of the suggestions is clicked according to documentation
window.location = 'target.html?term=' // This line might need some tweaking.
}
I get value of nameq as:
^^^^^^^^^^^^^^^^^^^^^^^^^^undefined at file:///android_asset/www/index.html:115
$("#searchField").autocomplete(
{
icon: 'arrow-l',
target: $('#suggestions'),
source: stockArray,
link: 'target.html?term=',
minLength:0,
callback: function(e)
{
var $a = $(e.currentTarget); // access the selected item
console.log("###################!!###"+$a.text());
$('#searchField').val($a.text()); // place the value of the selection into the search box
$("#searchField").autocomplete('clear'); // clear the listview
}
});
Now using $a.text() I get selected item value.