Dynamically bind objects to inputs in angular - javascript

I have these objects right here that I will use to save data from a form, and later send it to an api as JSON :
$scope.price = {}
$scope.item = {"price":$scope.price, };
I also have these field which will be used to dynamically generate inputs on a html page:
$scope.fields = [
{
name: $scope.item.title,
title: 'Title',
type: {
view: 'input'
}
},
{
name: $scope.price.regular,
title: 'Regualar Price',
type: {
view: 'input'
}
}
];
Now in order to generate the form I use this code:
<div class="form-group" ng-repeat="field in fields">
<label>{{ field.title }}:</label>
<span ng-switch on="field.type.view">
<span ng-switch-when="input">
<input
ng-model=field.name
type="text"
/>
</span>
</span>
</div>
And with this code, it is not assigning the values in the input to the objects. Is there a way to do it? I know I can do it this way:
ng-model="item[field.name]"
But that limits me to only one level of the object. I want to be able to bind nested objects. And I just can't seem to figure it out. Thank You!

Related

bind list item array vue data to input value in a form

Hi I have a form and I have a input field in which I have a vue event which allows to take some values and add it to a data a object in the vue js, but I am not able to bind this vue data property to the input value so I would get back when the form is submitted.
My input
<div class="col-md-4">
<ul>
<li v-for="item in filterListValueEnArray">
#{{ item }}
<button #click.prevent="removeFilterEn(filterListValueEn)">remove</button>
</li>
</ul>
<input type="text" v-model="filterListValueEn" #keydown.enter.prevent="addFilterValEn(filterListValueEn)" name="array" v-bind:value="filterListValueEnArray" class="form-control">
</div>
vue js code
new Vue({
el: '#advFilter',
data: {
selectFilterType: '',
filterListValueEn: '',
filterListValueEnArray: [],
filterListValueAr: '',
filterListValueArArray: [],
},
methods: {
addFilterValEn: function(filterListValueEn) {
this.filterListValueEnArray.push(filterListValueEn);
this.filterListValueEn = '';
},
addFilterValAr: function(filterListValueAr) {
this.filterListValueArArray.push(filterListValueAr);
this.filterListValueAr = '';
},
removeFilterAr: function(filterListValueAr) {
this.filterListValueArArray.pop(filterListValueAr)
},
removeFilterEn: function(filterListValueEn) {
this.filterListValueEnArray.pop(filterListValueEn)
}
}
});
I want to bind the filterListValueEnArray in the value of the text field but I dont get back anything when I do in laravel.
$request->all();
Please assist

concatenate an ng repeat item as an object inside ng-model

I'm trying to concatenate an ng-repeat item to ng-model object. I was wondering if this possible.
so for example:
//array
$scope.array = [
{
param: 'color',
....
},
{
param: 'weight',
.....
}
]
html
<div ng-repeat="item in array">
{{ item.param }}
<input type="text" ng-model="form.name.{{ item.param }}" >
</div>
so lets say {{ item.param }} is color, the ng-model will be form.name.color.
form object will be something like this:
{
name: {
color: 'value of input',
weight: 'value of input'
}
}
How can I concatenate the item.param to the object form.name? I've been trying so many ways but no results. I trying to use $index, but don't know where to begin.
Your help will be appreciated!
Check out this fiddle.
Your ng-model should look like this:
ng-model="form.name[item.param]"

AngularJS: View is updated properly but not the model

I have a problem when implementing a nested list in Angular: the view gets updated properly but, on the other side, the code is not updated on change.
I think it will be much clearer with the code:
_this.categories = injections.map(function (category) {
return {
title: category.get('title'),
object: category,
criteria: category._criteria.map(function (oneCriteria) {
return {
object: oneCriteria,
type: oneCriteria.get("type"),
min: _this.range(oneCriteria.get("range")).min,
max: _this.range(oneCriteria.get("range")).max,
key: oneCriteria.get("key"),
value: _this.range(oneCriteria.get("range")).min,
defaultValue: _this.range(oneCriteria.get("range")).min,
selected: false
}
})
}
});
_this.category = _this.categories[0];
_this.job = {
title: '',
description: '',
salaryAmount: 0,
salaryTimeUnit: _this.salaryTimeUnits[0],
category: _this.category.object,
criteria: _this.category.criteria,
location: {latitude: 48.137004, longitude: 11.575928}
};
So and, very quick here is my HTML:
<div ng-repeat="category in controller.categories">
<input type="radio" name="group" ng-value="category.object.get('title')" id="{{category.object.get('title')}}"
ng-checked="controller.category == category" ng-click="controller.category = category">
{{category.title}}
</div>
<br>
Criteria:
<div ng-repeat="criterium in controller.category.criteria">
<div class="row vertical-align">
<div class="col-xs-9">
<span ng-click="criterium.selected = !criterium.selected"
ng-class="['list-group-item', {active:criterium.selected == true}]">{{criterium.key}}</span>
</div>
</div>
</div>
The problem is the following: the value are getting updated in the view (when you click on a radio button on the category, you see the corresponding criteria(s)). But the job is for one reason that I ignore not updated although it has the same reference as the HTML (a reference to this category.criteria).
Did I miss something?
controller.job.criteria is still just a reference to controller.categories[0]. Your code should successfully update controller.category to point at whichever category you clicked on, but that does not also update the reference in your job data structure.
What you want to do is make your ngClick event a bit more robust, i.e.:
<input type="radio" ng-click="controller.updateCategory(category)" />
and then in your js:
_this.updateCategory = function (category) {
_this.category = category;
_this.updateJob(category);
};
_this.updateJob = function (category) {
_this.job.category = category.object;
_this.job.criteria = category.criteria;
};
This will update the references in your job to match the new jazz.
I would, however, recommend leveraging ngModel and ngChange in your radios instead. Like:
<input type="radio" ng-model="controller.category" ng-value="category" ng-change="updateJob(category)" /> {{category.title}}

Nested ng-repeat with model binding

HTML:
<div class="panel panel-default" ng-repeat="(section, sectionData) in report">
<div class="panel-heading">{{sectionData.text}}</div>
<div class="panel-body">
<div class="row" ng-repeat="(part, partData) in sectionData.attr">
<div class="col-md-2">
<label>{{partData.text}}</label>
</div>
<div class="col-md-10">
<div class="form-group">
<div class="radio-inline" ng-repeat="condition in radioValues">
<label class="radio-inline">
<input type="radio" name="{{section}}-{{part}}" ng-value="{{condition.value}}" ng-model="partData[model]">
{{condition.text}}
</label>
</div>
</div>
</div>
</div>
</div>
</div>
JS model:
$scope.radioValues = [{
text: 'Good',
value: '1'
}, {
text: 'Average',
value: '2'
}, {
text: 'Needs Improvement',
value: '3'
}];
$scope.report = {
card: {
text: 'Card',
attr: {
front: {
text: 'Front',
model: 'detail.report.card.front',
},
rear: {
text: 'Rear',
model: 'detail.report.card.front.rear'
},
assembly: {
text: 'Assembly',
model: 'detail.report.card.front.assembly'
}
}
} //, and a lot of others like card
};
// Instantiate the model so that values are preselected
for (var section in $scope.report) {
for (var part in $scope.report[section].attr) {
initModel($scope.report[section].attr[part]); // basically sets the model values defined in $scope.report to 1
}
}
The $scope.report object is used to create the html and I'm trying to set the value of ng-model in the html to strings defined in the $scope.report. Along with that, I'm also trying to set the default values of each set of radios.
Is the ng-model="partData[model]" part correct? After setting the model values in the controller, the radios aren't preselected when the page loads. The model defined in the $scope.report should bind to the $scope directly. E.g. detail.report.card.front.assembly should actually become $scope.detail.report...
How do I make this work? Is it the right use of angular? Better alternatives?
I was able to get this done using a directive with isolated scope.
Basically, I shifted the html to a template called report. I changed the template html a little bit. Here's the changed code:
<div class="radio-inline" ng-repeat="condition in radioValues">
<label class="radio-inline">
<input type="radio" name="{{section}}-{{part}}" ng-value="{{condition.value}}" ng-model="detail.report[section][part]">
{{condition.text}}
</label>
</div>
Then created a directive like so:
app.module('').directive('rating', function(){
return {
scope : {
report: "=",
detail: "=",
radios: "="
},
restrict : 'E',
templateUrl : '../view/rating.html',
link : function($scope, iElm, iAttrs, controller) {}
};
});
And in the html I simply call:
<rating report="report" radios="radios" detail="detail"></rating>
So I was able to access the detail object in the parent scope by passing it to the template. This allowed me to modify the parent scope's model directly.

AngularJS - Binding radio button selection to model inside ng-repeat

I have a data model persons which takes the following form:
personsInfo = {
name: Adam
dob: 31-FEB-1985
docs: [
{
docType: Drivers License,
number: 121212,
selected: false
id: 1
},
{
selected: true,
docType: None
},
{
docType: State ID,
number: 132345,
selected: false,
id: 2
}
]
}
In my markup I have defined the following to dynamically generate radio buttons.
<div ng-repeat="personDoc in personsInfo.docs">
<input type="radio" name="personDocs" ng-model="personDoc.selected" value=""/>
{{personDoc.docType}} <span ng-hide="personDoc.docType === 'None'">Number: {{personDoc.number}}</span>
</div>
I want to be able to check the documents which have selected as true on page load, and then depending on what the user selects save the selected flag in my personsInfo model.
My intent here is to send the personsInfo model back to another page.
If somebody could point me to a working fiddle it would be greatly appreciated!
Thanks!
You're almost there just missing the binding to show which document is selected. We'll add an object to the scope to represent the selected item, then bind the forms to that model.
JS
app.controller('...', function($scope) {
$scope.personInfo = { ... };
$scope.selectedDoc = {};
$scope.$watch('personInfo',function() {
$scope.selectedDoc = $scope.personInfo.docs[0];
});
});
HTML
<div ng-repeat='doc in personInfo.docs'>
<input type='radio' ng-model='selectedDoc' value='doc' /> {{doc.docType}}
</div>
<form>
<input type='text' ng-model='selectedDoc.number' />
...
</form>

Categories

Resources