AngularJS - dynamic generated ng-model-name - javascript

I try and try but I cant get it working.. I do a ng-repeat creates me some DIVs out of a $scope-object:
<div class="col-2 currBit" ng-repeat="one in crypto">
<div class="currBitTitle">{{one.shortName}}</div>
<div class="currBitTitleSub">
<div class="currLogo currLogo_{{one.shortName}}"></div><br/>
{{one.longName}}<br/>
</div>
<div class="currBitInput">
<input type="number" placeholder="Your amount of {{one.shortName}}" ng-model="one.shortName" >
</div>
</div>
now, in the inputfield of each created DIV I need to set a ng-model, so my app can use the input-vlaues of the dynamicly generated input-fields
in this code posted, when the data is bound to the <div class="currBitTitle">{{one.shortName}}</div> ?? .. why is that? How can I get this managed?
it would be nice to have a individual prefix like ng-model="myfoobar_{one.shortName}"
is that even possible?

You can try to use like below code also check this fiddler link for your example scenario.
Template:
<input type="number" ng-model="myfoobar_[one.shortName]">
Controller:
$scope.myfoobar_ = {};
$scope.crypto = [{
"shortName": "Name1",
"longName": "Name One"
}, {
"shortName": "Name2",
"longName": "Name Two"
}];

Related

ngModel in input radio?

I'm developing an application using Angular 6. I have a big problem.
Using a template-driven form I would like that the item selected in a radio button can be sent when I press the submit button.
It's all right when I work with <input type="text" [(ngModel)] = "value" /> (value is a data field of my component), but if I try with this:
<div class="form-group">
<div *ngFor = "let option of options">
<div class="radio">
<input type = "radio"
name = "radio"
[(ngModel)] = "value"
/>
<label for="{{option.id}}">{{option.id}}</div>
</label>
</div>
</div>
</div>
The result is a bug! I can't even click the multiple buttons by moving the selector! Everything is stuck! Obviously it does not work with the form.
If I remove [(ngModel)] = "value" graphically it works, but without ngModel directive if I enter this code inside a template-driven form that uses (ngSubmit) it does not work.
Thanks a lot.
You are missing a value for each of the radio buttons so the binding does not work correctly. It is unable to determine which input should be checked so none of them get checked. Update the template to be something like:
<div *ngFor="let option of options">
<div class="radio">
<input type="radio"
name="radio"
id="radio-{{option.id}}"
[(ngModel)]="value"
[value]="option.value"
/>
<label for="radio-{{option.id}}">{{option.id}}
</label>
</div>
Stackblitz Demo
Radio buttons work different. To need to add a value to make it work. If you want to assign a value from angular use [value].
I have make it running in an example of stackblitz:
<div class="form-group">
<div *ngFor="let option of options; let i=index">
<div class="radio">
<input type="radio" id="{{option.id}}" name="radio{{i}}" [(ngModel)]="option.value" [value]="option.id" />
<label for="{{option.id}}">{{option.id}}</label>
</div>
</div>
</div>
<hr>
<h2>Values for options</h2>
<ul>
<ng-container *ngFor="let option of options; let i=index">
<li *ngIf="option.value !== ''">Value for {{option.id}}: {{option.value}}</li>
</ng-container>
</ul>
Component
value: any;
options = [
{
id: "test1",
value: ''
},
{
id: "test2",
value: ''
},
{
id: "test3",
value: ''
}];
Extension/Hints:
You can even use [(ngModel)] = "value" to assign the last selected value to value.
Give these radio buttons the same name name="radio" to ensure that only one of this group can be selected.
Inside the ts file :
radio_button_value = null;
box_options = [
{
"name": "Word",
"value": "word",
},
{
"name": "Line",
"value": "line"
},
]
Inside the html file:
Do notice of the tag 'name', it would we a great concern inside another for loop.
<div *ngFor="let box_opt of box_options; let i=index">
<input name="option-{{i}}" type="radio" [value]="box_opt.value" [(ngModel)]="radio_button_value">
{{box_opt.name}}
<br>
</div>

Angular.js Bind ng-model with ng-repeat in input:checkbox

I have an App using Angularjs v1.69
I Get a Json Response of Time Slot
The below is the Current Code:
$scope.TimeSlotList = JSON.parse(localStorage.getItem("TimeSlots"));
Console.log($scope.TimeSlotList);
Output:
[
{
"id": 1,
"time": "7am - 10am"
},
{
"id": 2,
"time": "10am - 1pm"
},
{
"id": 3,
"time": "1pm - 4pm"
},
{
"id": 4,
"time": "4pm - 7pm"
},
{
"id": 5,
"time": "7pm - 10pm"
}
]
and this is done in the partial
<div class="col-md-6">
<div class="form_pad20">
<label>Prefered Time</label>
<div class="clearfix">
<div class="form-field field-destination">
<div class="radio-checkbox display_inline" ng-repeat="x in TimeSlotList">
<input id="check-{{x.id+9}}" type="checkbox" class="checkbox" ng-model="TimeSlotList[$index]">
<label for="check-{{x.id+9}}">{{x.time}}</label>
</div>
</div>
</div>
</div>
</div>
The Required output is Whichever Checkbox is selected i want that value
For Ex: if the user select time slot 2 and 3
i want to send 23 to the backend
i.e Timeslot-2 and Timeslot-3 should return true
or something else i want output as
var FinalTime="23";
Trying to figure out from last 2 days
But After Few Atempts basically th best solution was
ng-model="TimeSlot-{{x.id}}"
but this throughs error
Error: [ngModel:nonassign] Expression 'ScdItem.TSlot(x.id)' is non-assignable.
please can anybody help me ?
Change the TimeSlotList so that it contains a selected field. The initial value can be set to false.
$scope.TimeSlotList = JSON.parse(localStorage.getItem("TimeSlots"));
$scope.TimeSlotList.forEach(item => item.selected = false);
Then bind the selected field to the corresponding checkboxes using ng-model:
<input id="check-{{x.id+9}}" type="checkbox" class="checkbox" ng-model="x.selected">
This will change the selected's value based on checkbox is checked/not checked. When you send the data to the server, you can extract the IDs of the slots based on the value of selected field, like this:
var selectedSlots = $scope.TimeSlotList
.filter(slot => slot.selected) // Get all the selected slots
.map(slot => slot.id) // Extract IDs of the slots
.join(''); // Join the IDs to form a string
This way selectedSlots will contain the IDs of the slots selected.
<div class="col-md-6">
<div class="form_pad20">
<label>Prefered Time</label>
<div class="clearfix">
<div class="form-field field-destination">
<div class="radio-checkbox display_inline" ng-repeat="x in TimeSlotList">
<input id="check-{{x.id+9}}" type="checkbox" class="checkbox" ng-model="x.id" ng-change="checkTimeslot(x.id)">
<label for="check-{{x.id+9}}">{{x.time}}</label>
</div>
</div>
</div>
</div>

using ng-options within ng-repeat

I am new to angular and I'm confused over this thing. I'm trying to populate a select box based on object inside an array. I want selectbox by using ng-repeat for that array... but initially i need to show only one selectbox after clicking add() next selectbox has to come. for ref:[initially one selectbox has to come]
HTML
<div class="col-lg-12" id="variant1" style="margin-top:10px" ng-repeat="variant in variants">
<div class="col-lg-4" style="text-align:right;padding-top:2px;padding-right: 20px" >
<label for="variant1name">Variant Name</label>
</div>
<div class="col-lg-6" >
<div >
<select class="form-control" ng-model="filterFormInputs.apps" ng-options="app.Application for app in variants" >
<option value="" disabled selected>Select an Application</option>
</select>
<label ng-repeat="checkbox in filterFormInputs.apps.details">
<input class="ecomtexttype1" type="checkbox" ng-model="checkbox.checked"> {{checkbox.name}}
</label>
</div>
</div>
</div>
Controller:
$scope.variants =
[
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]}
]
I think that you can just have your add() function update the array... if things are configured correctly the new row should render due to the binding on the array.
As mentioned in comments you did not provide enough source code, so here is the assumed pseudo-code:
in html you might have
<button ng-click="$scope.add()">Add</button>
so in the controller
$scope.variants = [
// array of whatever you are displaying
{"foo":"bar1"},
{"foo":"bar2"}
];
$scope.add = function() {
variants.push({"foo":"bar_new"});
}
Have you considered using a Directive for this? That may work better, depending on your situation. Look into this: https://docs.angularjs.org/guide/directive

Draw open closing tag if value is true in angularjs

Let's say I have a form, which iterates over some fields.
I want to wrap some fields in a container, so that I can split the form into sections.
I have tried to put field_open = true under the item I want to start opening the div, and then field_close = true under the last field in that container and then I repeat this process.
<form name="{{form.form_name}}" id="{{form.form_id}}">
<div ng-if="field.field_open == true" class="halfCol">
<div ng-repeat="field in form.form_fields">
<div class="{{field.field_class}}">
<field-directive field="field"></field-directive>
</div>
</div>
</div ng-if="field.field_close == true">
</form>
Obviously this doesn't work, but I'm wondering how I can achieve this?
The below HTML is how it should be rendered:
<form name="test" id="test">
<div class="halfCol">
<label for="apple">Apple</label>
<input type="text" name="apple" id="apple" />
<label for="fruit">Fruit</label>
<input type="text" name="fruit" id="fruit" />
</div>
<div class="halfCol">
<label for="dog">Dog</label>
<input type="text" name="dog" id="dog" />
</div>
</form>
The above html should be drawn from the following data.
var data = {
"form_name": "test",
"form_fields": [
{
"field_title": "Apple",
"field_open" : false
"field_open" : true
}{
"field_title": "Fruit",
},{
"field_title": "Dog",
"field_close" : true
"field_open" : true
}
]}
I'm more or less looking for a way to wrap certain elements in the same field scope.
What will the decision to separete the fields in sections depend on?
If the decision depends on some aspect of presentation, I think you don't need to use model data as you do. I mean you could write simple html without ng-repeat directives.
If you insist to use model data, your model structure will be like below.
var data = {
"form_name": "test",
"form_sectinons": [
{
"section_title": "section 1",
"fields": [
{"field_title": "Apple"},
{"field_title": "Fruit"},
]
},
{
"section_title": "section 2",
"fields": [
{"field_title": "Dog"},
]
}
]
}
And Html will be like below.
<form>
<div ng-repeat="section in data.form_sections">
<div ng-repeat="field in section.fields" class="halfCol">
<field-directive field="field"></field-directive>
</div>
</div>
</form>
I'm not sure quite what you are trying to do but you should do like this:
<form name="{{form.form_name}}" id="{{form.form_id}}">
<div ng-if="field.field_open == true && field.field_close == true" class="halfCol">
<div ng-repeat="field in form.form_fields">
<div class="{{field.field_class}}">
<field-directive field="field"></field-directive>
</div>
</div>
</div>
</form>

Get the value of an element inside ng-repeat

Here is my html snippet:
<tr ng-repeat="row in rowCollection">
<td><h6 id="{{$index}}">{{row.inventory_serialno}}</h6></td>
</tr>
<div class="form-group">
<label for="inventory_serialno">SL No:</label>
<input class="form-control" value="//I need the value of h6 here//" id="inventory_serialno" placeholder="Enter serial number">
</div>
Goal:
Get the value of an element inside ng-repeat (In this case the 'h6' tag value of each row)
Use that corresponding value to autofill the value of respective text box input present in each row.
The input text box is out of the ng-repeat scope.
For some reason i cant access the value of the h6 tag if i do this (gives a value null)
document.getElementById("1").innerHTML; //or even text()
Weirdly i noticed the above JavaScript code runs fine on the browser console but not on my script (which means its something to do with the angular element generation time.. May be i'm accessing it before it even got generated).
Nonetheless can someone please shed some light on the solution. Thanks in advance.
******** Updated with controller code *****
app.controller('InventoryCtrl', function ($scope) {
var x = document.getElementById("1").innerHTML; // giving a null value
console.log(x);
$scope.rowCollection = [{
id: 100,
inventory_serialno: 'HW13FGL'
}, {
id: 101,
inventory_serialno: 'SM123GH'
}, {
id: 102,
inventory_serialno: 'LK90100'
}];
});
You could do it like this:
<input value="{{rowCollection[2].inventory_serialno}}" />
Example
However I would place the input inside the ng-repeat to keep it clean, and achieve the layout you like inside a big wrapper, something like this:
<div class="grid" ng-repeat="row in rowCollection">
<div class="col">
<h6 id="{{$index}}">{{row.inventory_serialno}}</h6>
<hr>
<div class="form-group">
<form>
<input value="{{row.inventory_serialno}}"/>
</form>
</div>
</div>
</div>
If you need an input for each item, use ng-repeat.

Categories