Passing key-value pair jquery array into .NET MVC action - javascript

I have an jquery key-value pair array as following:
The array is filled when check-boxes are checked
If a checkbox is unchecked, item will be removed from there
The code for that part is:
$(document).on('click', '.chkItem', function () {
if ($(this).is(':checked')) {
product_ids[$(this).attr('id')] = "Checked";
} else {
delete product_ids[$(this).attr('id')];
}
});
This works fine, let's head onto the next part. Now I'm trying to send all these ID's from my view into a controller "Analyze" and action "Index", which looks as following:
$(".btnAnalyze").click(function () {
if (jQuery.isEmptyObject(product_ids) == true) {
alert("Array is empty");
}
else {
var postData = { values: product_ids };
$.ajax({
type: "POST",
url: "/Analyze/Index",
data: postData,
success: function (data) {
alert(data.Result);
},
dataType: "json",
traditional: true
});
}
});
And my action looks like following:
public ActionResult Index(List<string> values)
{
string id2= "";
foreach (var id in values)
{
id2= id;
}
// I'm trying to fetch the ID values here that I added into the array, but I'm not sure how...
}
With this current method the contents of List values is
"[object Object]"
which is not what I want.. I need all of the ID's sorted out nicely into the list as I send them to the Action Index...
Can someone help me out with this???

You're using an object, not an array, and it is thus saying that it's an object. You have two choices:
Use an actual array:
var product_ids = [];
$(document).on('click', '.chkItem', function () {
if ($(this).is(':checked')) {
product_ids.push($(this).attr('id'));
} else {
product_ids.splice(product_ids.indexOf($(this).attr('id')), 1);
}
});
Continue using an object and use Object.keys to get just the property names (which are the IDs in your code):
var postData = { values: Object.keys(product_ids) };
Personally, I like #1 because it's more explicit that you're capturing the ids of the checked checkboxes, and the values of the object's properties is always "Checked" rather than anything meaningful, but hey, JavaScripts' flexible like that :).

Use console.log(data.Result) to debug instead of alert(data.Result), because alert(data.Result) stringifies your variable to [object Object]. To open up console press F12

Related

Jquery each loop doesn't display JSON item's properties

Edited2: Here is a pic of how one object looks like. All fields for all objects are filled.
Edited: So the problem appears to be the each loop. I console.logged data and it showed it in an array style. But for some reason, when i try to print the object's age, f.ex., it shows up as undefined.
I am doing a small script for displaying information from a json-file with jquery and ajax. I got the ajax part working (I think) but I can't get my function to print the JSON object data.
So I am trying to display JSON object's with Jquery but it doesn't do anything. The ready function prints out done and complete.
$(document).ready(function(){
$.ajax({
url: "file.json",
cache: false
}).done(function(data) {
console.log("done");
showData(data);
}).fail(function() {
console.log("error");
}).always(function() {
console.log("complete");
});
});
function showData(data) {
$.each(data.cats, function(index, kitty) {
var div = $("<div></div>");
div.addClass("catContainer");
var image = $("<img></img>");
image.addClass("catImage");
image.src="kitty.image";
var header = $("<p></p>").text(kitty.color);
header.addClass("header");
var age = $("<p></p>").text(kitty.age);
var text = $("<p></p>").text(kitty.text);
text.addClass("text");
var price = $("<p></p>").text(kitty.price);
div.append(image,header,size,text,price);
$("div#cats").append(div);
});
}
I also tried this loop but it prints 'undefined' to the div:
$(data).each(function(i, kitty) {
$('#cats').append(kitty.price);
// I am sorry, I am noob. Hope this post is according to the instructions.
One issue is with your image.src. When you set it to "kitty.image", this would literally assign that string. So instead of:
image.src = "kitty.image",
Use:
image.attr("src", kitty.image);
Or:
image[0].src = kitty.image
The latter here, since image is a jQuery Object, would not have src as an index. So we can call image[0] to get the HTML Element, that we can then assign the src.
Consider the following.
$(function() {
function showData(d, o) {
$.each(d, function(index, kitty) {
console.log("Adding Kitty", kitty);
var div = $("<div>", {
class: "catContainer"
}).appendTo(o);
$("<img>", {
class: "catImage",
src: kitty.image
}).appendTo(div);
$("<p>", {
class: "header"
}).html(kitty.color).appendTo(div);
$("<p>").html(kitty.age).appendTo(div);
$("<p>", {
class: "text"
}).html(kitty.text).appendTo(div);
$("<p>").html(kitty.price).appendTo(div);
});
}
$.ajax({
url: "file.json",
cache: false,
success: function(data) {
showData(data.cats, "#cats");
console.log("Success");
},
error: function(x, e, n) {
console.log("Error", x, e, n);
}
});
});
Based on your post, data is an Object. data.cats is an Array of Objects. So we will iterate the Array with $.each() using data.cats. I also pass in the target object ID. .appendTo() accepts a few items:
A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the end of the element(s) specified by this parameter.
See More: https://api.jquery.com/appendto/
It is then just a matter of creating each of the elements. With the $("<div>"), jQuery will handle wrapping the element for us. We can also pass in an Object with the attributes, like class. We can chain to the jQuery Object that is the result and would advise using .html() versus .text(), yet there is nothing wrong with doing either.

How can I populate <select> with JSON data and display values when clicked?

I've been trying to do this, but I was only able to get the data populated inside the select of HTML.
2 Questions.
Q1.
I was able to get the JSON data using AJAX from an API. (using AJAX because I learned that it doesn't need the browser to refresh to fetch new data):
$(document).ready(function() {
getDataJson();
});
function getDataJson(ajaxurl) {
$.ajax({
method: "GET",
url: "https://corona.lmao.ninja/v2/jhucsse",
datatype: "json",
success: onSuccess,
error: onError
});
}
Next I tried to populate the select in my HTML on OnSuccess:
function onSuccess(jsonReturn) {
$("#dropdown").empty();
//console.log(jsonReturn);
let dropdown = $('#dropdown');
dropdown.empty();
dropdown.append('<option selected="true" disabled>Choose Country</option>');
dropdown.prop('selectedIndex', 0);
// Populate dropdown with list of countries
$.each(jsonReturn, function (key, entry) {
dropdown.append($('<option></option>').attr('value', entry.data).text(entry.data));
});
var $dropdown = $('#dropdown'),
$objView = $('#objView'),
$docFragment = $(document.createDocumentFragment());
for (var prop in jsonReturn) {
$('<option/>', {
val: prop,
text: prop
}).appendTo($docFragment);
}
$dropdown.append($docFragment);
$dropdown.on('change', function() {
var objString = JSON.stringify(jsonReturn[$dropdown.val()]);
objString = objString.replace(/[\{\}\[\]\"]*/ig, ''); // Remove unwanted chars
objString = objString.replace(/\,/ig, '<br/>'); // Replace commas with new lines (i.e. br tags)
$objView.html(objString);
});
$dropdown.trigger('change');
}
//if JSON fails
function onError() {
$("#dropdown").html("i failed.");
}
And It worked. But then I tried to do the next step I wanted to do which is to when I click on the name of a country it should display the rest of its JSON data with names and their values.
How to display JSON data on click with JavaScript
this isn't the exact, but close enough but it's a very different(difficult?for me) solution that I couldn't understand.
Currently my dropdown looks like this:
JSFIDDLE
Now I'm intended to do this Populate HTML Table with Certain Items from a JSON Array
but with all the other JSON data like this for each country How to display JSON data on click with JavaScript
How can I resolve the rest of the scripting?
Q2. How to reduce the AJAX fetching lag?
There's a little bit of a lag/slow that I've noticed even with fewer data. Or is it just normal?
Answer for Q1
First of all, I prepare these 3 variables to make it simpler.
let jsonResponseContainer = []
let dropdown = $("#dropdown")
let objView = $("#objView")
Then prepare this when the document is ready
$(document).ready(function() {
// Initiate everything
getDataJson();
// Move dropdown change to standalone
dropdown.on('change', function() {
let chosenResponse = JSON.stringify(jsonResponseContainer[$("#dropdown").val()])
// Remove unwanted chars
chosenResponse = chosenResponse.replace(/[\{\}\[\]\"]*/ig, '');
chosenResponse = chosenResponse.replace(/\,/ig, '<br/>');
// Change objView
objView.html(chosenResponse)
})
});
Your ajax is
function getDataJson(ajaxurl) {
$.ajax({
method: "GET",
url: "https://corona.lmao.ninja/v2/jhucsse",
datatype: "json",
success: onSuccess,
error: onError
});
}
I made a function just to populate the dropdown
function populateDropdown(index, data){
let newOption = "<option value=\"" + index + "\">" + data + "</option>"
dropdown.append(newOption)
}
Major changes I made
function onSuccess(jsonReturn) {
// Populate container with ajax return directly
jsonResponseContainer = jsonReturn
// Do what you need to do
dropdown.empty();
dropdown.append('<option selected="true" disabled>Choose Country</option>');
dropdown.prop('selectedIndex', 0);
// Populate dropdown with list of countries
$.each(jsonReturn, function (key, entry) {
populateDropdown(key, entry.country);
});
}
//if JSON fails
function onError() {
$("#objView").html("i failed.");
}
Notice that I copy jsonReturn to another variable just to make sure the data now can be accessed everywhere. Next is your on-change listener was put on a loop, I moved it out of the loop. Now, I make <option> with string (you may change it with fragment if you want). Pay attention I make the value with key (array key for jsonReturn which is the same for jsonResponseContainer). When the on-change listener is evoked, it just needs to retrieve from the array to <pre>.
Answer for Q2
I don't understand about it, I suppose it is not your fault.
note: I apologize if I was using the wrong grammar.

How do I add returned JavaScript array items to specific textboxes

I called a URL using AJAX using the following code below and it returned 2 items in an array in this format ["item1", "item2"]
function getbook()
{
$.ajax({
type: "POST",
url: "/Home/getBooked",
data: { "bookNumber": mobile },
success: function(succ) { // I need to add the items in succ to some text boxes as shown below
$.each(succ, function (index, element) {
$('#tb1').val(element);
$('#tb2').val(element);
});
},
error: function(err) {
alert("An error is thrown");
}
});
}
But the issue is that only the last item in the succ array is shown in both the textboxes. When I used the alert function to display the contents of succ, it displayed both the items. Clearly i'm missing something. I'll be glad if anyone could help.
The problem is you are setting the value in each iteration. Try like following.
success: function (succ) {
$('#tb1').val(succ[0]);
$('#tb2').val(succ[1]);
}
if the IDs of textbox is kind of sequence then we can resolve like bellow:
$.each(succ, function (index, element) {
$('#tb'+ (index + 1)).val(element);
});

dynamically creating text boxes after loop through javascript object

I have a javascript that sends some info to through an ajax request to the server and receives some data as Questions and their's ID's as a json array.
This is what the response json array i receive from the server looks like:
[
{
"ID":"1",
"question":"Write a function called addNum. "
},
{
"ID":"3",
"question":"Write a function called sumDouble "
}
]
And this is javascript:
$(document).ready(function(){
$("form#input_qnumber").submit(function() {
var questions = $('#questions').attr('value'); // written question
var quizname = $('#quizname').attr('value');
if (questions) { // values are not empty
$.ajax({
type: "POST",
url: "https://xxxx",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "application/json",
data: 'questions='+questions+'&quizname='+quizname,
success: function (data)
{
var JSONObject = JSON.parse(data);
for (var key in JSONObject) {
if (JSONObject.hasOwnProperty(key)) {
console.log(JSONObject[key]["ID"] + ", " + JSONObject[key]["question"]);
}
}
}
});
}
else {
$('div#createquizresp').text("Enter question ID's separated by a comma to be included in the quiz");
$('div#createquizresp').addClass("error");
} // else
$('div#createquizresp').fadeIn();
return false;
});
});
As you see, I can parse the response json into a javascript object array, loop through it and dump the contents in console. What I would like though would be to create textarea element, give its id attribute the 'ID' key from my array and label it with the corresponding question key from the array. After this I can just append the element to a div inside my html. But I am not really sure how to do it or if its even possible. Please HALP.
if you want also a label element;
for (var key in JSONObject) {
if (JSONObject.hasOwnProperty(key)) {
$('<label>')
.attr('for', JSONObject[key]["ID"])
.html(JSONObject[key]["question"])
.appendTo('wherever_you_want');
$('<textarea>')
.attr('id', JSONObject[key]["ID"])
.appendTo('wherever_you_want');
}
}
create dynamic elements input and label and then append these elements to the parent div or to the body what ever suits your requirement.
DEMO :https://jsfiddle.net/ew4mqhow/3/
<div id ="display"></div>
<script>
var textbox = document.createElement('input');
textbox.setAttribute("id", JSONObject[key]["ID"]);
var labell = document.createElement('label');
labell.setAttribute("for",JSONObject[key]["question"]);
labell.innerHTML = JSONObject[key]["question"];
document.getElementById('display').appendChild(textbox);
document.getElementById('display').appendChild(labell);
</script>
Answer by keune is perfect. One suggestion, tho - do add a prefix to foreign ID's. Just to be on safe side on case You'll assign ID's to other types of elements (ie. answers), too.
for (var key in JSONObject) {
if (JSONObject.hasOwnProperty(key)) {
$('#quizquestions')
.append($('<label>')
.attr('for', 'Q' + JSONObject[key]["ID"])
.html(JSONObject[key]["question"]))
.append($('<textarea>')
.attr('id', 'Q' + JSONObject[key]["ID"]))
}
}

How to format jquery ui autocomplete with function that returns json?

I have a function that makes an AJAX call and returns the data as JSON.
Donor.prototype.GetFriends = function(callback)
{
$.post(apiUrl + "getfriends",
{
"authentication_code" : this.authcode
},
function(response)
{
if (response)
{
callback(response.result);
}
}, "json");
}
Now in my UI I have the following:
var donor = new Donor();
$("#msg-to").autocomplete({source: function()
{
donor.GetFriends(function(response){response.friends.candidates})
}
});
But this is not working...The json is being returned in firebug, but not displaying in the autocomplte field.
result
Object { error_state=0, friends={...}, error_msg=""}
error_msg
""
error_state
0
friends
Object { candidates="[{"follow_id":"3","0":"...","6":"227.jpg"},false]", donors="[{"follow_id":"4","0":"...","6":"224.jpg"},false]"}
candidates
"[{"follow_id":"3","0":"3","user_id":"227","1":"227","following":"222","2":"222","candidate_id":"61","3":"61","firstname":"Helen","4":"Helen","lastname":"Hunt","5":"Hunt","image":"227.jpg","6":"227.jpg"},{"follow_id":"5","0":"5","user_id":"225","1":"225","following":"222","2":"222","candidate_id":"55","3":"55","firstname":"Test","4":"Test","lastname":"Candidate","5":"Candidate","image":"225.jpg","6":"225.jpg"},{"follow_id":"1","0":"1","user_id":"222","1":"222","following":"226","2":"226","candidate_id":"59","3":"59","firstname":"New","4":"New","lastname":"Candidate","5":"Candidate","image":"226.jpg","6":"226.jpg"},{"follow_id":"6","0":"6","user_id":"222","1":"222","following":"227","2":"227","candidate_id":"61","3":"61","firstname":"Helen","4":"Helen","lastname":"Hunt","5":"Hunt","image":"227.jpg","6":"227.jpg"},false]"
donors
"[{"follow_id":"4","0":"4","user_id":"224","1":"224","following":"222","2":"222","donor_id":"124","3":"124","firstname":"Just","4":"Just","lastname":"A Donor","5":"A Donor","image":"224.jpg","6":"224.jpg"},{"follow_id":"2","0":"2","user_id":"222","1":"222","following":"224","2":"224","donor_id":"124","3":"124","firstname":"Just","4":"Just","lastname":"A Donor","5":"A Donor","image":"224.jpg","6":"224.jpg"},false]"
Also the json that is returned has a candidate_id, firstname, lastname and imageUrl returned, how can I have these displayed in the results, with the friend_id being the value and the others for display?
Thanks in advance...
Couple of things:
You might need to return the array you're creating in order for the autocomplete to use it
You also need to make sure the array of objects has the correct keys for the autocomplete to use
The minimum required keys that need to available for the autocomplete to work correctly are 'label' and 'value'. Other keys can be included, and can be fetched during an event like select or change.
As an example, I might try something like the following. Adjust your GetFriends function to use the request and response callback functions provided by jQuery automatically, and then feed the formatted data that the autocomplete needs back to them:
Donor.prototype.GetFriends = function(request, response){
// this is where you can grab your search term, if need be...
var search_term = request.term;
$.post(
apiUrl + "getfriends",
{"authentication_code" : this.authcode},
function(data)
{
// process your data here into an array that the autocomplete
// will appreciate...
var autocomplete_array = [];
$.each(data.friends.candidates, function(index, candidate)
{
autocomplete_array.push(
{
label: candidate.firstname + " " + candidate.lastname,
value: candidate.user_id,
another_key: candidate.follow_id,
and_another: candidate.image
});
});
// now send the array back to the response parameter...
response(autocomplete_array);
},
"json"
);
};
Then, I'd simplify the autocomplete initializer parameters to include your function:
$("#msg-to").autocomplete({source: donor.GetFriends});
As an additional note, to get to the keys of the items, you could modify your autocomplete field to include the select or change event handlers I mentioned earlier:
$("#msg-to").autocomplete(
{
source: donor.GetFriends
select: function(event, ui){
alert("You selected: " + ui.item.label);
// or...
alert("You selected: " + ui.item.another_key);
}
});
Hope this helps, and that I didn't have a type-o's! :)
The problem is that $.post method works asynchronously. So when autocomplete tries to get data, your function makes POST call and returns empty result. To solve this try adding "async:false" option to .post call or:
Donor.prototype.GetFriends = function(callback) {
$.ajaxSetup({async:false});
$.post(apiUrl + "getfriends",
{
"authentication_code" : this.authcode
},
function(response)
{
if (response)
{
callback(response.result);
}
}, "json");
}​
You have to use the setter in the callback (see the 2nd source parameter in my examples) to add the list. If you use arrays to fill the autocomplete, the array needs objects with a label property. If this works you can add the value property too.
1.) If you can update the result of the ajax-result on server-side, change the result to:
friends
Object { candidates=Array { Object { "label": "Helen Hunt" }, ... }, donors=... }
Then your javascript can be:
var donor = new Donor();
$("#msg-to").autocomplete({
source: function(request, setter) {
donor.GetFriends(function(response) {
// set list
setter(response.friends.candidates);
});
}
});
2.) If you can't make changes at the ajax result and candidates is already an array:
var donor = new Donor();
$("#msg-to").autocomplete({
source: function(request, setter) {
donor.GetFriends(function(response) {
// create autocomplete list
var list = response.map(function(element) {
return {
label: element.firstname + ' ' + element.lastname
};
});
// set list
setter(list);
});
}
});
3.) Otherwise (if candidates is a string) [try this first]:
var donor = new Donor();
$("#msg-to").autocomplete({
source: function(request, setter) {
donor.GetFriends(function(response) {
// parse json string
var jsonresult = $.parseJSON(response);
// create autocomplete list
var list = jsonresult.map(function(element) {
return {
label: element.firstname + ' ' + element.lastname
};
});
// set list
setter(list);
});
}
});

Categories