Submit array param with jQuery ajax/load - asp.net-mvc

public ActionResult DoSomething(string[] arr, bool someBool, int someInt) { }
trying to call the above method from jQuery:
var test = [];
test.push('dog');
test.push('cat');
$container.load('MyController/DoSomething',
{ 'arr[]': test, 'someBool': true, 'someInt': 1 },
function(response, status, xhr) {
// ...
});
the array paramater is null, other params are fine. What am I doing wrong?
Chrome developer tools shows form data being submitted as
arr%5B%5D%5B%5D:dog
arr%5B%5D%5B%5D:cat
someBool:true
someInt:1
not sure whats going on there but doesn't look right to me

If you are using jquery 1.4 you might need to set the traditional parameter to true in order to be compatible with the default model binder format in ASP.NET MVC:
var test = [];
test.push('dog');
test.push('cat');
$.ajax({
url: 'MyController/DoSomething',
type: 'GET',
traditional: true,
data: { arr: test, someBool: true, someInt: 1 },
success: function(result) {
$container.html(result);
}
});
or if you prefer the .load() method:
var data = { arr: test, someBool: true, someInt: 1 };
$container.load('MyController/DoSomething', $.param(data, true),
function(response, status, xhr) {
// ...
});

Just remove []
{ 'arr': test, 'someBool': true, 'someInt': 1 },
Posted values (checking with Firebug).
arr[] dog
arr[] cat
someBool true
someInt 1
Example on jsFiddle

can you see if this problem is similar to yours:
Passing an nested arrays to asp.net mvc using jQuery's $.ajax

Even i was facing error, in passing array from HTML page to aspx page.
my requirement was to load the aspx page in a DIV tag of the html page. on the page load i need to pass these JS array values to aspx page load.
i used below method.
$('#<divTagID>').load("Targetpage.aspx",{"Arr":JSArrValues});
In aspx page load event i can access this values as:
string results = Response["Arr[]"];
Thanks to JQuery API documentation enter link description here and stackoverflow

Related

Ajax not allowing View rendering

I have a couple of variations on the ajax depending on the flow of interactions on the page. But it's only the variables that changes. here is one of them:
$('#btn_skickaEnkel').bind('click', function () {
$.ajax({
type: 'POST',
url: '/Contact/IntresseAnmälan/',
dataType: 'json',
data: {
Namn: $('#namn').val(),
Mail: $('#mail').val(),
Info: $('#meddelande').val(),
Nivå: $('#nivå').find(":selected").text(),
IsEnkel: true,
Telefon: $('#nr').val(),
ID: function () {
var url = window.location.pathname;
var id = url.substring(url.lastIndexOf('/') + 1);
return id;
}
},
traditional: true
});
});
In my controller i am unable to redirect or return a different view. At this point the data from JSON is no longer relevant because it's already been saved to DB.
My Controller:
public ActionResult IntresseAnmälan(BokningContainer bokning)
{
db = new DbContext();
//Saving some data to database(removed)
//Just determening the state of container obj.
if (bokning.IsEnkel)
{
//Geting som information from db (removed)
//Creating a mail (removed)
email.Send(bokning.Namn, bokning.Mail, body);
}
else
{
}
//db.SaveChanges();
//This part is not working, I think it's beacuase of the Ajax
return View("IntresseAnmälan");
}
The view is not rendered and I think it's related to the ajax. The view is simply not rendered. Is there some way to force returning it and ignoring the ajax? As I said the data is no longer needed because the content is already saved to the DB.
You cannot render view on ajax call,simply you can use form post method or just redirect it to desired action on "succcess" of ajax call as below:
$('#btn_skickaEnkel').bind('click', function () {
$.ajax({
type: 'POST',
url: '/Contact/IntresseAnmälan/',
dataType: 'json',
data: {
Namn: $('#namn').val(),
Mail: $('#mail').val(),
Info: $('#meddelande').val(),
Nivå: $('#nivå').find(":selected").text(),
IsEnkel: true,
Telefon: $('#nr').val(),
ID: function () {
var url = window.location.pathname;
var id = url.substring(url.lastIndexOf('/') + 1);
return id;
}
},
traditional: true,
success: function(result) {
window.location.href = '#Url.Action("action", "Controller")';
}
});
});
I couldn't believe my eyes when I figured out this "Bugg". The problem was that I, at some point, changed the submit to a button. So the form was never submiting. Well, at least I learnt a bit about views and Ajax.
Sorry for taking your time.

Select2 dropdown but allow new values by user?

I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.
I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?
The excellent answer provided by #fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.
Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.
$("select").select2({
tags: true
});
By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
For version 4+ check this answer below by Kevin Brown
In Select2 3.5.2 and below, you can use something like:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(taken from an answer on the select2 mailing list, but cannot find the link now)
Just for the sake of keep the code alive, I'm posting #rrauenza Fiddle's code from his comment.
HTML
<input type='hidden' id='tags' style='width:300px'/>
jQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:
User searches for value (which makes ajax request to server)
If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
When the form is submitted just check to see if that option is in the db and if not create it before saving.
There is a better solution I think now
simply set tagging to true on the select options ?
tags: true
from https://select2.org/tagging
Improvent on #fmpwizard answer:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
I just stumbled upon this from Kevin Brown.
https://stackoverflow.com/a/30019966/112680
All you have to do for v4.0.6 is use tags: true parameter.
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;
return this.text.localeCompare(term)===0;
will better replace to
return this.text.toLowerCase() === term.toLowerCase();

Prevent $.ajaxStart() from being executed during jquery-ui autocomplete

I'm using jquery-ui autocomplete on a page I'm creating. On the same page I have some ajax events going on. During the other ajax events I'm adding an overlay to my page, so that all the links on the website aren't clickable anymore for the user. I don't want that to happen during the autocomplete.
autocomplete:
$(function() {
$( "#search_input" ).autocomplete({
source: '/search_autocomplete/',});
});
ajax:
$.ajax({
url: "/ajax_login/",
login_user: $("#login_user").val(),
password: $("#login_password").val(),
});
ajaxStart:
$("#loading_gif").ajaxStart(function() {
$("#overlay").show();
$(this).show();
});
To prevent the ajaxstart function from being executed during the ajax events where it's not necessary. I add
global:false,
to the corresponding ajaxfunctions. How can I do something similar during the autocomplete without changing the jquery-ui source?
For this you have to omit the shorthand call with source and change the call like this.
$('#search_input').autocomplete({
source: function (request, response) {
var DTO = { "term": request.term };
//var DTO = { "term": $('#search_input').val() };
$.ajax({
data: DTO,
global: false,
type: 'GET',
url: '/search_autocomplete/',
success: function (jobNumbers) {
//var formattedNumbers = $.map(jobNumbersObject, function (item) {
// return {
// label: item.JobName,
// value: item.JobID
// }
//});
return response(jobNumbers);
}
});
}
//source: '/search_autocomplete/'
});
The advantage of this long-hand method is
You can pass more than one parameter. Also the parameter name should not have to be term.
The short-hand notation expects an array of strings. Here you could return an array of objects also.
If you want $.ajax() to work a certain way most of the time but now all the time, then you probably shouldn't change its default behavior.
I recommend creating a function that wraps an ajax request in a function that enables and disables the overlay at the appropriate times. Call this function where you want the overlay to be used, and use plain $.ajax() for your autocomplete.
I would agree that naveen's answer is the best solution. In my case the vast amount of code that would require changing wasn't cost effective as we're in the process of doing a re-write and we needed a short term solution.
You can override the ajax call in jQuery UI, I copied the source for the _initSource function call that handles the AJAX request. Then simply added the global: false to the $.ajax options. The code here is based on jquery-ui 1.9.2, you may have to find the correct source for your version.
$.ui.autocomplete.prototype._initSource = function () {
var array, url,
that = this;
if ( $.isArray(this.options.source) ) {
array = this.options.source;
this.source = function( request, response ) {
response( $.ui.autocomplete.filter( array, request.term ) );
};
} else if ( typeof this.options.source === "string" ) {
url = this.options.source;
this.source = function( request, response ) {
if ( that.xhr ) {
that.xhr.abort();
}
that.xhr = $.ajax({
url: url,
data: request,
dataType: "json",
global: false,
success: function( data ) {
response( data );
},
error: function() {
response( [] );
}
});
};
} else {
this.source = this.options.source;
}
};

Why won't this JqueryUI autocomplete hit its URL?

I'm wiring the following method to my document.ready function. However, the "myAutoCompleteURL.aspx" URL is never being accessed (I have a breakpoint on the page, and it's never being hit).
Anybody know why this isn't working? I'm new to the UI version of AutoComplete; I had previously only used the jquery-based (deprecated) version.
function myAutoComplete(myTextBox, myLabel, myHidden) {
var myType = $(myLabel).html();
$(myTextBox).autocomplete({
source: function (request, response) {
$.ajax({
type: 'POST',
dataType: 'json',
url: "../myAutoCompleteURL.aspx",
data: { q: request.term, type: myType },
success: function (myData) {
response($.map(myData, function (myItem) {
return { label: myItem.name, value: myItem.name, id: myItem.id }
}));
}
});
},
select: function (event, ui) {
$(myTextBox).val(ui.myItem.name);
$(myHidden).val(ui.myItem.id);
return false;
}
});
}
You can remove the ../ in your url. I used to have the same issue sometime ago.
Secondly have an error function in your ajax call. If it hits the error function, then there is some problem in your data and you need to correct that.
As #GregL mentioned in his comment, that you are using JSON and not application/json :)
Use Firebug and look for what URL is being hit instead. If nothing shows up in the console, then the javascript code is not working at all.

JQuery Autocomplete source is a function

I'm using JQuery UI autocomplete, for different fields. To get the data i'm using a function as the source. It work great!
I was wondering if there were a way of not using the anonym function in the source, but to declare a generic one which will have a parameter to redirect to the right URL.
I'm quite new in JS and JQuery and so I have no idea of what the parameters request and response are comming from in the anonym function.
Here is what I'm trying to do:
$ac.autocomplete({
//Call the function here, but what are the parameter request and response???
source: autocomplete(),
minLength: 1
});
Here is the function I'd like to call
function autoComplete(request, response, url) {
$.ajax({
url: '/Comp/'+url,
dataType: "json",
type: "POST",
success: function (data) {
response($.map(data, function(item) {
return { label: item, value: item, id: item };
}));
}
});
}
Thanks a lot for your help.
You should use
source: autoComplete
instead of
source: autocomplete()
One more remark. The default implementation of jQuery UI Autocomplete use only value and label and not use id.
Reformatting ur question will pose as solution to the problem .:)
$ac.autocomplete({
minLength: 1 ,
source: function(request, response, url){
var searchParam = request.term;
$.ajax({
url: '/Comp/'+url,
data : searchParam,
dataType: "json",
type: "POST",
success: function (data) {
response($.map(data, function(item) {
return {
label: item.Firstname,
value: item.FirstName
};
});
}
});//ajax ends
}
}); //autocomplete ends
The request and response objects are expected by jQuery UI . The request.term will give u the text that the user types and the response method will return the label and value items to the widget factory for displaying the suggestion dropdown
P.S : assuming ur JSON string contains a FirstName key !
I will give an example of a situation that happened to me, might serve as an example:
Situation: After the user selects a keyword with Jquery Autocomplete not allow it to be listed. Taking into account that the query is executed the same, ie the unamended cat. server-side.
The code looked like this:
$( "#keyword-search" ).autocomplete({
minLength: 3 ,
source: function( request , response ) {
var param = { keyword_type: type , keyword_search: request.term } ;
$.ajax({
url: URI + 'search-to-json',
data : param,
dataType: "json",
type: "GET",
success: function (data) {
response($.map(data, function( item ) {
/* At this point I call a function, I use to decide whether to add on the list to be selected by the user. */
if ( ! is_record_selected( item ) ) {
return item;
}
}));
}
});
} ,
select: function( event , ui ) {
/* Before you add, looking if there is any cell */
/* If it exists, compare the id of each cell not to add an existing */
if ( validate_new_keyword( ui ) ) {
add_cell( ui ) ;
}
} ,
});
/* Any validation... */
function validate_new_keyword( ui ) {
var keyword_id = $.trim(ui.item.id) ;
Any condition...
if (keyword_id > 0) {
return true ;
}
return false ;
}
/* This function checks if a keyword has not been selected by the user, it checks for the keyword_array. */
function is_record_selected( item ) {
var index = jQuery.inArray( item.id , keyword_array ) ;
return index == -1 ? false : true;
}
Obs: Thus it is possible to use a function inside "source" and "select". =p

Resources