how to dynamically push form input inside object literal with angular - javascript

I'm a beginner in angular programming and i'm looking for some examples onhow to interact with object literal using this language. unfortunately, i didn't find any examples that could answer my questions about this topic.So, if i have this HTML file :
<body ng-app="watch">
<div ng-controller="reely">
<form>
Name:
<input type="text" ng-model="place.name" ng-change='change()'>
<br/>
StreetAdress:
<input type="text" ng-model="place.streetAdress" ng-change='change()'>
<br/>
AddressLocality :
<input type="text" ng-model="place.addressLocality" ng-change='change()'>
<br/>
AddressRegion:
<input type="text" ng-model="place.addressRegion" ng-change='change()'>
<br/>
postalCode :
<input type="text" ng-model="place.postalCode" ng-change='change()'>
<br/>
AddressCountry:
<input type="text" ng-model="place.addressCountry" ng-change='change()'>
<br/>
Logo: <input type="text" ng-model="place.logo" ng-change='change()'><br/>
Url: <input type="text" ng-model="place.url" ng-change='change()'><br/>
Image:<input type="text" ng-model="place.image" ng-change='change()'><br/>
</form>
<h1>
Your JSON
</h1>
<p>
{{mtl}}
</p>
</div>
</body>
If the user enters something in the different forms, datas will be automatically added to the object literal which look like this for example :
{
"#context": {
"schema": "http://schema.org/"
},
"#graph": [
{
"#id": "place",
"#type": "schema:Person",
"schema:name": " office",
"schema:address": {
"#type": "schema.PostalAddress",
"streetAdress": "501 rue William",
"addressLocality": "Toronto",
"addressRegion": "ON",
"postalCode": "H3C 1P4",
"addressCountry": "CA"
}
"schema:logo": "http://active.com/images/logo.png",
"schema:url": "http://shop.active.com/products/ra-r436",
"schema:image": "http://active.com/images/ra-r4xx.jpg"
}
}
}
Notice that datas should be displayed in different places inside the literal object.i know that that my post is not very clear and hope i could get a demo if possible
and this is my controller code :
angular.module("watch", [])
.controller("reely", function($scope) {
$scope.mtl = {
"#context": {
"schema": "http://schema.org/"
},
"#graph": [
{
"#id": "place",
"#type": "schema:Place",
"schema:address": {
"#type": "schema.PostalAddress"
}
}
]
}
$scope.place = {};
$scope.adress= {};
$scope.adress["#type"]= "schema.PostalAddress";
function changeKeyValue() {
for (var key in $scope.place) {
if ($scope.place.hasOwnProperty(key)) {
$scope.mtl["#graph"][0]["schema:address"]["schema:" + key] = $scope.place[key];
}
}
}
$scope.change = function () {
changeKeyValue();
}
});

Actually you can do it without almost any effort :) you can use another notation like this:
var obj={
"#graph":[{
"#type":"anyValueHere"
}]
};
You can override values like this:
obj['#graph'][0]['streetAddress']="Toronto";
And as a result, you will get this new json object:
{
"#graph":[{
"#type":"anyValueHere",
"streetAddress":"Toronto"
}]
}
So based on this kind of notation, you can do that like this:
This is your html:
<div ng-controller="reely">
<form>
Name:
<input type="text" ng-model="mtl['#graph'][0]['schema:name']" >
<br/>
StreetAdress:
<input type="text" ng-model="mtl['#graph'][0]['schema:address'].streetAdress" >
<br/>
AddressLocality :
<input type="text" ng-model="mtl['#graph'][0]['schema:address'].addressLocality" >
<br/>
AddressRegion:
<input type="text" ng-model="mtl['#graph'][0]['schema:address'].addressRegion" >
<br/>
postalCode :
<input type="text" ng-model="mtl['#graph'][0]['schema:address'].postalCode" >
<br/>
AddressCountry:
<input type="text" ng-model="mtl['#graph'][0]['schema:address'].addressCountry" >
<br/>
Logo: <input type="text" ng-model="mtl['#graph'][0]['schema:logo']" ><br/>
Url: <input type="text" ng-model="mtl['#graph'][0]['schema:url']" ><br/>
Image:<input type="text" ng-model="mtl['#graph'][0]['schema:image']" ><br/>
</form>
<h1>
Your JSON
</h1>
<p>
{{mtl}}
</p>
</div>
This will be your modified controller:
angular.module("watch", [])
.controller("reely", function($scope) {
$scope.mtl = {
"#context": {
"schema": "http://schema.org/"
},
"#graph": [
{
"#id": "place",
"#type": "schema:Place",
"schema:address": {
"#type": "schema.PostalAddress"
}
}
]
};
})
As you can see, you use the "mtl" object directly from the html , just use the object["property"] notation.
So I hope it helps, and if it does, you can mark as the right answer :D

Related

Make diffrent V-MODEL on every index that i generate

How can I have different V-MODEL on every object that i generate
I am trying to make an sample cupcake website that can generate multiple forms in one submit.
But when I generate 2 field, the inputs of the 2 generated field bound by each other inputs.
This is the code I am trying to generate:
<template>
<div>
<button #click="cupcakes.push(def)">Add Cup Cake</button>
<div v-for="(cupcake, index) in cupcakes" :key="index">
<input type="text" v-model="cupcakes[index].name">
<input type="text" v-model="cupcakes[index].description">
<input type="text" v-model="cupcakes[index].type">
<input type="text" v-model="cupcakes[index].prize">
<input type="text" v-model="cupcakes[index].color">
</div>
<button #click="onSubmit">Create Cupcate</button>
</div>
</template>
<script>
export default {
data() {
return {
cupcakes: [],
def: {
name: '',
description: 'Originals',
type: 'small',
prize: 500,
color: 'color'
}
}
},
methods: {
onSubmit() {
console.log(this.cupcakes);
}
}
}
</script>
I tried to do other things but it doesn't work.
How can I dis bind the 2 field and when I submit it will take the inputs that I type or input.
You are pushing n times the same objet (def) into your cupcakes Array. def is a reference to an object. So when you update cupcakes[n], you are just updating the def values.
What you need to do is send a copy of that object into the cupcakes object:
<button #click="cupcakes.push(JSON.parse(JSON.stringify(def)))">Add Cup Cake</button>
I think a better pattern would be to make a method that returns you a new cupcake:
<template>
<div>
<button #click="cupcakes.push(getNewCupcake())">Add Cup Cake</button>
<div v-for="(cupcake, index) in cupcakes" :key="index">
<input type="text" v-model="cupcakes[index].name">
<input type="text" v-model="cupcakes[index].description">
<input type="text" v-model="cupcakes[index].type">
<input type="text" v-model="cupcakes[index].prize">
<input type="text" v-model="cupcakes[index].color">
</div>
<button #click="onSubmit">Create Cupcate</button>
</div>
</template>
<script>
export default {
data() {
return {
cupcakes: []
};
},
methods: {
onSubmit() {
console.log(this.cupcakes);
},
getNewCupcake() {
return {
name: "",
description: "Originals",
type: "small",
prize: 500,
color: "color"
}
}
}
};
</script>

Is there a way to change the key of object dynamically using ng-repeat

My json object looks like this,
$scope.myObject = {
"mainKey1":{
"name": "x",
"age": "20"
},
"mainKey2":{
"name":"y",
"age":"25"
},
"mainKey3":{
name:"z",
"age":"30"
}
};
and i want to change keys for example ,
i want to change "mainKey1" to "newKey1" in ng-repeat
my html looks like this
<div ng-repeat="(key,obj) in myObject">
<label>Name</label>
<input type="text" name="name" ng-model="obj.name"
placeholder="enetr name"/><br/>
<label>Age</label>
<input type="text" name="age" ng-model="obj.age" placeholedr="enter age" /><br/>
<label>Key </label>
<select ng-options="k for k in keyCollection" ng-model="key" >
</select>
</div>
But looks like using key in ng-model directly doesn't work , can anyone please help to achieve expected result, Thanks in advance
angular.module('app', []).controller('ctrl', function($scope) {
$scope.myObject = {
"mainKey1": {
"name": "x",
"age": "20"
},
"mainKey2": {
"name": "y",
"age": "25"
},
"mainKey3": {
"name": "z",
"age": "30"
}
};
$scope.keyCollection = ['newKey1', 'newKey2', 'newKey3'];
for (var key in $scope.myObject)
$scope.keyCollection.push(key);
$scope.changeKey = function(next, ex) {
if (Object.keys($scope.myObject).indexOf(next) == -1) {
var temp = $scope.myObject[ex];
delete $scope.myObject[ex];
$scope.myObject[next] = temp;
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='ctrl'>
<div ng-repeat="(key,obj) in myObject">
<label>Name</label>
<input type="text" name="name" ng-model="obj.name" placeholder="enter name" /><br/>
<label>Age</label>
<input type="text" name="age" ng-model="obj.age" placeholedr="enter age" /><br/>
<label>{{key}}</label>
<select ng-options="k for k in keyCollection" ng-change='changeKey(temp, key)' ng-model='temp' ng-init='temp=key'></select>
<br>
<br>
</div>
</div>

How show diff. HTML based on property in angularjs?

I have a collection of objects that are of types: text, selectoptions and multiselectoptions. I need to display them as editable inputs based on their type.
For example, a text object:
<input type="text" name="caption" value="{{option.value}}" />
A selectoption/multiselectoptions:
<div ng-repeat="value in option.values">
<input type="text" name="{{option.id}}[value][{{value.id}}]" value="{{value.value}}" />
<input type="text" name="{{option.id}}[caption][{{value.id}}]" value="{{value.caption}}" />
</div>
Is this the correct way to do this? Is there a better way to represent it?
Example of the JSON objects:
FORM: {
options: [
{
type: "select",
values: [
{
value: 0,
caption: "Some option"
},
{
value: 1,
caption: "Some other option"
}
]
},
{
type: "text",
caption: "Some text item"
}
]
}
You could use ng-if to display the correct form element based on your model. Here is an example in plunker based on your code.
<form novalidate class="simple-form">
<div ng-repeat="field in FORM.options">
<input type="text" ng-model='field.caption' ng-if="field.type == 'text'" /><br />
<div ng-if="field.type != 'text'">
<div ng-repeat="value in field.values">
Option: <input type="text" name="{{option.id}}[value][{{value.id}}]" value="{{value.value}}" /><br/>
Caption: <input type="text" name="{{option.id}}[caption][{{value.id}}]" value="{{value.caption}}" /><br/>
</div>
</div>
</div>
<button ng-click="submit()">Save</button>
</form>
I check the type field.type and display different HTML in the main ng-repeat.
The app assign your model to FORM:
$scope.FORM = {
options: [
{
type: "select",
values: [
{
value: 0,
caption: "Some option"
},
{
value: 1,
caption: "Some other option"
}
]
},
{
type: "text",
caption: "Some text item"
}
]
};
I also added a submit button that display the model in the Javascript console, so you can see that the data is being updated when you change the values:
<button ng-click="submit()">Save</button>
Try ng-switch which will switch to corresponding HTML based on the type from the JSON.
<div ng-repeat="opt in FORM.options" ng-switch on="opt.type">
<select ng-switch-when="select">
<option ng-repeat="val in opt.values" value='{{val.value}}'>{{val.caption}}</option>
</select>
<input type="text" ng-model="opt.caption" ng-switch-when="text"/>
</div>
Add more MultiSelect types with ng-switch-when = "multiselect". If the type is not specified, set a ng-switch-default to default html.
Working Plunker

Assign each element’s value with a class from an object based on ID

If I have this object:
const person = {
"name": "john",
"address": "john’s home"
};
and this part of a form:
<input class="form-control john" id="name">
<input class="form-control john" id="address">
then how do I assign the value of each id with its associated value from the object?
Something like:
$(".john").each(function(){
$(id).val(person.id)
});
You can do something like this:
Set value of input using $(this).val(value) or this.value = value.
Get object value using its id. You can get the ID using this.id.
Code:
var person = {
"name": "john",
"address": "john's home"
};
$('.john').each(function() {
$(this).val(person[this.id]);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input class="form-control john" id="name">
<input class="form-control john" id="address">
Also you can iterate over them using .val with a callback:
var person = {
"name": "john",
"address": "john's home"
};
$('.john').val(function() {
return person[this.id];
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input class="form-control john" id="name">
<input class="form-control john" id="address">
Reference: Accessing object property

how to validate element is angular js?

I make a view from json object. I am able to make take now I need to valid element on keyup event and blur event. So I googled it and find this tutorial
http://scotch.io/tutorials/javascript/angularjs-form-validation
I try to implement this in my demo, but when I used this:
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine"
class="help-block">`Your name is required.</p>
This break my view can you please tell me how to validate thing in angular if there is no form?
Here is my plunker: http://plnkr.co/edit/we1QHuDuCOOR4tDAk6yv?p=preview
<script>
function Controller($scope) {
$scope.outputs = {};
$scope.inputs = [{
type: "email",
name: "email",
required:true
}, {
type: "text",
name: "name",
}, {
type: "number",
name: "phonenumber",
}, {
type: "checkbox",
name: "whant to check",
},
{
type: "url",
name: "server Url",
}];
}
</script>
A solution is to use ng-form like
<div ng-switch="input.type" ng-form="myfrm">
<div ng-switch-when="text">
<input type="text" ng-model="outputs[input.name]"/>
</div>
<div ng-switch-when="email">
<input type="email" ng-model="outputs[input.name]" name="input" ng-required="input.required">
<span ng-if="myfrm.input.$invalid">Please enter a valid email</span>
</div>
<div ng-switch-when="number">
<input type="number" ng-model="outputs[input.name]"/>
</div>
<div ng-switch-when="url">
<input type="number" ng-model="outputs[input.name]"/>
</div>
<div ng-switch-when="checkbox">
<input type="checkbox" ng-model="outputs[input.name]" ng-checked="outputs[input.name]" value="outputs[input.name]"/>
</div>
</div>
Demo: Plunker

Categories