Pass array of objects from JS to ASP.NET controller - javascript

I'm having problem with passing the array of objects as mentioned above.
The code generally works, but when I pass the data only 1st object goes further.
I'm a total noob at .js/JSON parsing and would be grateful for guidance.
Also if you have any data on approach towards dynamic forms/JSON parsing in asp.net mvc that would help. I've been scouting internet for a few days now and can't find solution that has all the things I require.
Thanks!
controller that takes json data:
public ActionResult JsonResult(object[] json)
{
TempData["json"] = json;
return View();
}
javascript taking input data from all elements (also those dynamiclly added):
<script>
$(document).on('submit', '.simple-form', function (e) {
getValues(this);
e.preventDefault();
})
var getValues = function (currForm) {
var formData = $(currForm).serializeArray();
//object Array - all values present, though
// each value from a row is stored in other object meaning
// that row having prop1,prop2,prop3 isnt stored in 1 object,
// 3 rows generate 9 objects (each has 3 properties)
console.log(formData);
//here I try to pass JSON to MVC controller
'#Url.Action("JsonResult", "Session", new { json = "formData" })';
</script>

Related

Parse JSON data, and then pass all its values to another function

I'm building this website: http://collections.design
The way it works is by reading all tools data from a JSON, using jQuery (I don't know much javascript). Then, you can click on an item and a side panels opens with further information. But there's a lot of repeated code, so I'm trying to optimise it a bit.
First I parse the JSON:
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
// And I'm storing all of its values in variables, to make them easier to read:
var name = val.availability.name;
var linux = val.os.linux;
// Then I'm using all that to render each item on screen
…
});
});
Each of the items has a button that calls another function to create and open the side panel. The side panel reuses that item's data from the JSON. This function to create the side panel is using the name variable as parameter, but then inside is parsing the JSON again to get the rest of the values it needs.
My question is:
How can I "encapsulate" all variables when I do the JSON parsing, then pass it as a parameter to the other function; and finally, individually read each of those values in the other function?
I tried working with arrays. But didn't manage it to work, also keeping in mind that I'm trying to simplify things, not repeat myself, and keep short names…
Maybe I'm asking too much, but any pointers or links to doc will be appreciated.
I see two ways of doing this.
1) Save the JSON data outside the scope so you can reuse it and pass the index of the data you want.
Something like this
// The data source
var data_source = "../data/tools/tools.json";
var all_data;
// Parsing the JSON
$.getJSON(data_source, function(data) {
all_data = data;
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(key) {
console.log(all_data[key]);
}
2) As Sam Axe said, pass the data directly to the function
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(val) {
console.log(val);
}
Here's a working fiddle.
The data is already "encapsulated" in the data object. Pass that object to the function that you want to use the data in.
You could always construct a new object - but what's the point - it's already in the data object.

How do I create a reuseable AJAX call function and extract different values from the returned object

I have a Nodejs application that displays randomly generated data on an html page. There are 8 fields each populated from the values of an object with a page load.
I'd like to allow the user to change just a single field with the click of a button to generate a new random result in that field only.
I am using an AJAX calling function but having trouble making the function reusable for each field without rewriting mostly the exact same code 8 times.
I realize the final function will need some error handling as well.
function ajaxCall() {
var http = new XMLHttpRequest();
var data;
http.open("GET", "/randomStuff", true);
http.onload = function() {
// response is an object of 8 different properties
data = JSON.parse(http.response);
// this .log yields the object to the console without any errors
// so I know it works and the correct data is there
console.log(data);
// This works of course but I want to simply call the function for each....
// ... section and put a single value in each.
// Without having to rewrite the entire ajaxCall function each time.
insertP(data.propOne, 'sectionOneID')
}
http.send();
};
// This is the function that puts the data on the page.
function insertP(str, id) {
var p = document.getElementById(id);
p.textContent = str;
};
Using insertP or another as a callback seems to be the solution but I am not sure where to put it. In that case I could simply call the desired object property in the html.

Object Compare in AngularJS

I have a form which when loaded sends GET request to server and recives data which will stored in 'master' and i copy that data to 'local' as below.
$scope.dirty = false;
init(data);
function init(data) {
$scope.master = angular.copy(data.data);
$scope.local = angular.copy($scope.master);
}
Now, I use local object as model for my form and I have to button submit and reset. I watch the local object as below.
$scope.$watchCollection('local', function (newLocal, oldLocal) {
$scope.dirty = !angular.equals(newLocal, $scope.master);
});
So, If dirty is true then i can know that data has been modified but since I am using Objects AngularJS adds $$hasKey to $scope.local and because of that $scope.dirty always sets to true.
So, is there any way to handle this problem? I am new to AngularJS so may be this can be funny question but I'm stuck.
You could convert your object to a JSON string before comparing:
function init(data) {
// store json data into $scope.master for later comparison
$scope.master = angular.toJson(data.data);
$scope.local = angular.copy(data.data);
}
$scope.$watchCollection('local', function (newLocal, oldLocal) {
var json = angular.toJson(newLocal); // new local without $$ key
$scope.status.dirty = !angular.equals(json, $scope.master);
// $scope.local is still a javascript object
});
I was sending data form PHP and PHP treats Number and string as seperate datatype.
So I converted those Number data to string and now It works as desired and also I leart that whenever I use <form name='newForm> angularJS creates a new scope named newForm so that I can you many properties of that scope like $dirty, $pristinem $submitted and many more. so Now I dont have to write this logic by myself

using razor form and model values instead of current js object

I'm following js snippet to grab value dynamic number of input elements. I then use that values as a property inside js object which I later sent to mvc controller.
Since I already using Model inside razor which already has necessary properties to send to the mvc controller I wonder how can I grab those dynamic input elements values without using javascript object.
var myArr= [];
for (var i = 1; true; i++) {
var pTxtBox = $('#PCaption' + i);
var nTxtBox = $('#PWinners' + i);
if ((pTxtBox).length) {
var myObj = {};
myObj.Name = pTxtBox.val();
myObj.NWinners = nTxtBox.val();
myArr.push(myObj);
} else {
break;
}
}
When you render a page in MVC, The model is populated with whatever you specifically pass into the view. As MVC isn't coupled with the server. The only time the model re-binds is when there is a post back, then it goes through the input fields with the correct 'name' attribute and binds them into the model expected into the HTTPPOST method in the controller.
You will not be able to dynamically get a textboxes value on the client side using razor, Youll have to get the element by id or class, just as you are doing here.

how to serialize a form without jQuery? [duplicate]

This question already has answers here:
form serialize javascript (no framework)
(25 answers)
Closed 8 years ago.
For a lot of reasons (first of all: learning javascript), I need to serialize a form without jQuery, and send the resulting serialized data-structure to a php page with ajax.
The serialized data must be in JSON format.
How can I do that?
--EDIT--
this is how my form looks like: http://jsfiddle.net/XGD4X/
I am working on a similar problem, and I agree that it is worthwhile to learn how to program first without using a framework. I am using a data object (BP.reading) to hold the information, in my case a blood pressure reading. Then the JSON.stringify(dataObj) dose the work for you.
Here is the handler for the 'save' button click, which is a method on the dataObj. Note I am using a form instead of a table to input data, but the same idea should apply.
update: function () {
var arr = document.getElementById("BP_input_form").firstChild.elements,
request = JDK.makeAjaxPost(); // simple cross-browser httpxmlrequest with post headings preset
// gather the data and store in this data obj
this.name = arr[0].value.trim();
...
this.systolic = arr[3].value;
this.diastolic = arr[4].value;
// still testing so just put server message on page
request.callback = function (text) {
msgDiv.innerHTML += 'server said ' + text;
};
//
request.call("BP_update_server.php", JSON.stringify(this));
}
I hope this is helpful
* edit to show generic version *
In my program, I am using objects to send, receive, display, and input the same kind of data, so I already have objects ready. For a quicker solution you can just use a empty object and add the data to it. If the data is a set of the same type of data then just use an array. However, with a object you have useful names on the server side. Here is a more generic version untested, but passed jslint.
function postUsingJSON() {
// collect elements that hold data on the page, here I have an array
var elms = document.getElementById('parent_id').elements,
// create a post request object
// JDK is a namespace I use for helper function I intend to use in other
// programs or that i use over and over
// makeAjaxPost returns a request object with post header prefilled
req = JDK.makeAjaxPost(),
// create object to hold the data, or use one you have already
dataObj = {}, // empty object or use array dataArray = []
n = elms.length - 1; // last field in form
// next add the data to the object, trim whitespace
// use meaningful names here to make it easy on the server side
dataObj.dataFromField0 = elms[0].value.trim(); // dataArray[0] =
// ....
dataObj.dataFromFieldn = elms[n].value;
// define a callback method on post to use the server response
req.callback = function (text) {
// ...
};
// JDK.makeAjaxPost.call(ULR, data)
req.call('handle_post_on_server.php', JSON.stringify(dataObj));
}
Good Luck.
CoffeeScript implementation returning a GET query string:
serialize = (form) ->
enabled = [].filter.call form.elements, (node) -> not node.disabled
pairs = [].map.call enabled, (node) ->
encoded = [node.name, node.value].map(encodeURIComponent)
encoded.join '='
pairs.join '&'
Or if you rather prefer a key-value map:
serialize = (form) ->
data = {}
for node in form.elements when not node.disabled and node.name
data[node.name] = node.value
data
I haven't looked at jQuery's implementation, so no 100% compatibility guaranteed.

Categories