Posting form using javascript and json with nested objects - javascript

I have an html form that has the following structure:
<input type="text" name="title" />
<input type="text" name="persons[0].name" />
<input type="text" name="persons[0].color" />
<input type="text" name="persons[1].name" />
<input type="text" name="persons[1].color" />
I would like to serialize this into the following json:
{
"title": "titlecontent",
"persons": [{
"name": "person0name",
"color": "red"
},
{
"name": "person1name",
"color": "blue"
}
]
}
Notice that the number of persons can vary from case to case.
The structure of the html form can change, but the structure of the submitted json can't.
How is this done the easiest?

Dependencies:
locutus (npm install locutus)
jQuery
Code:
var parse_str = require('locutus/php/strings/parse_str');
parse_str($("#form ID").serialize(), var result = {});
console.log(result);

Hey man using jQuery and the
jQuery JSON plugin, I was able to do the following:
I had to change your html a bit:
<div id="Directory">
<input type="text" class="title" />
<span class="person 0">
<input type="text" class="name" />
<input type="text" class="color" />
</span>
<span class="person 1">
<input type="text" class="name" />
<input type="text" class="color" />
</span>
</div>
And then I was able to use the following code to create your JSON array:
var Directory = {};
Directory.title = $("div#Directory input.title").val();
Directory.persons = [];
$("div#Directory span.person").each(function() {
var index = $(this).attr("class").split(" ")[1];
Directory.persons.push({
name: "person" + index + $(this).children("input.name").val(),
color: $(this).children("input.color").val(),
});
});
alert($.toJSON(Directory));
This http ://stackoverflow.com/questions/492833/getting-correct-index-from-input-array-in-jquery is also somewhat helpful. Unfortunately I couldn't replicate their selection method with your particular set of attributes.
Hope I'm not doing your homework ;) There's a space in the URL above because I don't have enough reputation points to put more than one hyperlink.
This is your final JSON:
{
"title": "abc",
"persons": [{
"name": "person0englishman",
"color": "pink"
}, {
"name": "person1indian",
"color": "brown"
}]
}

Related

Vue.js - Dynamically generate v-model name

this is my first use of Vue.js so please bear with me. I have a section in my app where users can dynamically add (up to 5) entries and also remove entries. Each entry consists of four input tags that correspond to product id, description, quantity, and unit price. There is also an "X" icon at the end so that users can choose whether or not to remove that entry row before saving it. So visually, it would look something like this:
1 Tomatoes 40 $2.50 X
2 Pears 50 $1.39 X
3 Celery 12 $1.60 X
I am unsure how to dynamically generate v-model names that correspond to each piece of data that I want to save. In other words, I need four input tags and the X icon for each entry that a user wants to enter. Therefore, I'd want the Vue.js state to look something like:
data: {
numEntries: 2,
entries: [
{
productId: "",
description: "",
qty: "",
price: "",
},
{
productId: "",
description: "",
qty: "",
price: "",
},
// There will be 'n' of these objects depending on how many entries there are.
]
}
And I would like the v-model to be something like "productId1" to refer to entries[0].productId and "productId2" to refer to entries[1].productId, etc. My code is shown below:
HTML
<div id="app">
...
<div v-for="n in numEntries" class="inventory-section">
<input type="text" class="id-input" placeholder="Product Id" v-model="productId" />
<input type="text" class="description-input" placeholder="Description" v-model="description" />
<input type="text" class="qty-input" placeholder="Qty" v-model="qty" />
<input type="text" class="price-input" placeholder="Price" v-model="price" />
<span class="x-sign" v-on:click="removeEntry">X</span>
</div>
...
</div>
Vue JS
var app = new Vue({
el: '#app',
data: {
numEntries: 1,
entries: [
{
productId: "",
description: "",
qty: "",
price: "",
}
]
},
methods: {
addEntry: function () {
if (this.numEntries < 12)
this.numEntries += 1;
},
removeEntry: function () {
if (this.numEntries > 1)
this.numEntries -= 1;
}
}
})
In addition, when clicking the X on a row, how do I determine which row to remove? Currently my removeEntry function is very bare bones.
Any help would be greatly appreciated.
Vue loop code:
<div v-for="(itm,ind) in entries" class="inventory-section">
<input type="text" class="id-input" placeholder="Product Id" v-model="itm.productId" />
<input type="text" class="description-input" placeholder="Description" v-model="itm.description" />
<input type="text" class="qty-input" placeholder="Qty" v-model="itm.qty" />
<input type="text" class="price-input" placeholder="Price" v-model="itm.price" />
<span class="x-sign" #click="removeEntry(ind)">X</span>
</div>
And remove item from array
removeEntry: function (i) {
this.entries.splice(i,1)
}
Instead of using v-for="n in numEntries" use it as v-for="entry in entries".
in this way, "entry" will be your scoped object in that div. and you can use v-model="entry.productId"
you can loop through entries using v-for="(entry, index) in entries" and you can use v-model="entry.productId" and so on
<div id="app">
...
<div v-for="(entry, index) in entries" class="inventory-section">
<input type="text" class="id-input" placeholder="Product Id" v-model="entry.productId" />
<input type="text" class="description-input" placeholder="Description" v-model="entry.description" />
<input type="text" class="qty-input" placeholder="Qty" v-model="entry.qty" />
<input type="text" class="price-input" placeholder="Price" v-model="entry.price" />
<span class="x-sign" v-on:click="removeEntry(index)>X</span>
</div>
...
</div>

Why is my form not populating the data using ngModelGroup?

I have a below form, where i am using ngModelGroup to group the inputs.
<form #form="ngForm" (ngSubmit)="submit(form.value)">
<fieldset ngModelGroup="user">
<div>
<label>Firstname:</label>
<input type="text" name="firstname" [(ngModel)]="firstname">
</div>
<div>
<label>Lastname:</label>
<input type="text" name="lastname" [(ngModel)]="lastname">
</div>
</fieldset>
<fieldset ngModelGroup="address">
<div>
<label>Street:</label>
<input type="text" name="street" [(ngModel)]="street">
</div>
<div>
<label>Zip:</label>
<input type="text" name="zip" [(ngModel)]="zip">
</div>
<div>
<label>City:</label>
<input type="text" name="city" [(ngModel)]="city">
</div>
</fieldset>
<button type="submit">Submit</button>
</form>
When i map my [(ngModel)] = "user.firstname" or "user.lastname" or "user.address.street" it works? If i do in the above way, i don't see a reason why i need ngModelGroup in total.
I am not sure how to properly use ngModelGroup for nested objects.
Below is the plunkr:
https://plnkr.co/edit/Y4bjFh6sjtvdzkUWciid?p=preview
ngModelGroup lets you shape the data received from the form by introducing "subproperties".
With ngModelGroup="user" in your template, here's what form.value will look like:
{
"user": {
"firstname": "foo",
"lastname": "bar"
},
// ...
}
Without ngModelGroup="user" in your template, form.value will be:
{
"firstname": "foo",
"lastname": "bar",
// ...
}
ngModelGroup can be useful to give the form data the same shape as your data models. But it has no impact on the properties that you bind [(ngModel)] to (these properties can be whatever you want).

Convert form with form arrays into a vaild json object

My form looks like this.
<form>
<input type="text" name="pic" value="test" />
<input type="text" name="person[0].name" value="Bob" />
<input type="text" name="person[0].age" value="25" />
<input type="text" name="person[1].name" value="Jim"/>
<input type="text" name="person[1].age" value="30" />
</form>
Is their a method that can take in any form and if the name of several form elements is the same then make them into an array under the initial name in json.
The json object would ideally look like
{
"pic" : "test",
"person":[
{"name":"Bob", "age":"25"},
{"name":"Jim", "age":"30"}
]
}
I found a library that handles this
form2js

How to dynamically create a form using angularjs

I am trying to figure out how to dynamically create a form based on an array of fields returned from the server.
Something like this
[{
id: "title",
type: "text", /* Map to Input type=text */
regex: "/^[a-zA-Z]+/"
},{
id: "summary",
type: "memo", /* Map to Textarea */
regex: "/^[a-zA-Z]+/"
},{
id: "priority",
type: "list", /* Map to Select */
options: [1,2,3,4,5]
}]
I cant figure out a nice way of doing this, even with ng-repeat. Once the form has about 30 fields, and 15+ different input types, it gets very ugly.
Whats the 'Angular' way to do this, or should i generate the controller.js and template.html dynamically on the server?
Try this. It is not the answer, just an approach.Hope It may help You.
HTML:
<div ng-repeat="person in person">
<form class="form-group" name="signinForm">
<label>Name:
<input class="form-control" ng-model="person.name" type="text">
</label>
<label>Male:
<input class="form-control" ng-model="person.gender" name="gender{{$index}}" type="radio" value="male">
</label>
<label>Female:
<input class="form-control" ng-model="person.gender" name="gender{{$index}}" type="radio" value="female">
</label><br>
<label>Age
<input class="form-control" ng-model="person.age" type="number">
</label>
</form>
<button type="button" ng-click="addPerson()">Add More</button>
</div>
JS:
$scope.initialize = [{}];
$scope.person = {};
$scope.addPerson = function(){
$scope.initialize.push({});// adding more similar fields.
}

Serialize form to a specific json format

When I use .serializeArray(), my data looks like:
[ Object { Name="Name", Value="MyName" }, Object { Name="Age", Value="15"} ]
But I want it to look like:
{ Name: "MyName", Age: 15 }
What do I need to do?
My form:
<form id="newUser">
<input id="Name" name="Name" />
<input id="Age" name="Age" />
<input type="submit" />
</form>
You could write a bit of code which takes the first format and then converts it into the other. Just have it loop over the array and take Name as a key in the object, and Value as the value for the key and assign each pair into a single object.

Categories

Resources