Using ngModel to bind dynamically generated inputs - javascript

I'm fairly new to Angular so bear with me if I have some rookie mistakes here :)
I am dynamically adding inputs based on some properties that need to be filled out (this.properties) and I want to bind each of those dynamic inputs to some object (this.selectedProperties = {}) so that I end up with something like this.
this.properties = [new MyData { name = "theName", examples = "theExamples" },
new MyData { name = "anotherName", examples = "moreExamples" }];
this.selectedProperties = { "theName": "valueFromBinding", "anotherName": "anotherValueFromBinding" }
Here's a slimmed down version of what I have so far. Everything is working other than the ngModel to set the selected values.
<div *ngFor="let property of this.properties">
<label>{{property.name}}</label>
<input type="text" placeholder="{{property.examples}}"
[ngModel]="this.selectedProperties[property.name]"
name="{{property.name}}Input">
</div>
Thanks!

Try like this :
component.html
<div *ngFor="let property of properties">
<label>{{property.name}}</label>
<input type="text" placeholder="{{property.examples}}" [ngModel]="selectedProperties[property.name]" name="{{property.name}}Input">
</div>
component.ts
export class AppComponent {
properties = [
new MyData { name: "theName", examples: "theExamples" },
new MyData { name: "anotherName", examples: "moreExamples" }
];
selectedProperties = {
"theName": "valueFromBinding",
"anotherName": "anotherValueFromBinding"
};
}

Turns out I needed two way binding so that selectedProperties[property.name] would update when the user changed it in the UI

Related

Add element references to repeated items in Aurelia

So I have a list of objects in my viewModel that need access to each of their own individual elements. I tried using element.ref, but there was no element in the object.
persons.js
export class PersonsViewModel {
persons = [{
id: 0,
name: 'Matt'
}]
// this function fails, person.el is undefined
increase(person) {
person.el.style.height = person.el.clientHeight + 10;
person.el.style.width = person.el.clientWidth + 10;
}
}
persons.html
<template>
<div repeat.for="person of persons" element.ref="el">
<div>${person.name}</div>
<button click.delegate="increase(person)">+</button>
</div>
</template>
The element.ref binding respects binding contexts just like all other bindings, and so the element.ref must reference the person object when attaching the element property.
<div repeat.for="person of persons" element.ref="person.el">

Cannot get correct syntax for #Html.ListBoxFor()

I've a series of #Html components which are built dynamically including ListBoxFor(). With the others I've given them an ID which I then use to populate a model value called inputvalues, which holds the values of each component whenever it changes. This works well but I had to change the original DropDownListFor() for ListBoxFor() but although the new syntax works, I cannot assign it an ID value as I did before without getting a syntax error. The code looks like this..
#if (Model != null)
{
#Styles.Render(BundleConfig.Styles_MultiSelect)
IEnumerable<SelectListItem> filetypes = from filetype in Model.ListOptions
select new SelectListItem
{
Value = filetype.ID.ToString(),
Text = filetype.Name,
Selected = Model.SelectedListOptionID == null ? false : Model.SelectedListOptionID > 0
};
<div class="editor-section">
<div class="label">
#Html.DisplayEditLabel(Model.Label, Model.Required.Value)
</div>
<div class="field large-text-field">
#*Original drop down replaced by ListBoxFor() but with ID
#Html.DropDownListFor(m => m.SelectedListOptionID, new SelectList(Model.ListOptions, "ID", "Name", Model.SelectedListOptionID).OrderBy(l => l.Value), new Dictionary<string, object>{
{"id", "personField_" + Model.ID}})*#
#Html.ListBoxFor(m => m.ListOptions, filetypes, new { #class = "multiselectFileTypes" })
</div>
</div>
}
#Scripts.Render(BundleConfig.Scripts_MultiSelect)
<script>
$("#personField_" + "#Model.ID").change(function () {
cnt++;
var uploadValue = JSON.stringify({
"id": "#Model.ID",
"order": cnt,
"required": "#Model.Required",
"libraryUploadConfigType": 3,
"customFieldTypeID": 5,
"selectedListOptionID": $(this).val()
});
inputValues = inputValues + uploadValue;
});
$(".multiselectFileTypes").multiselect({
noneSelectedText: 'All Options',
minWidth: 230,
selectedList: 6
});
</script>
Although the syntax for the original DropDownlistFor() worked and updated inputvalues the component didn't work. Having changed it to ListBoxFor() the component works but I can't seem to assign the ID 'personField_' without getting an error.
Any help would be appreciated.
I can't see that you try to assign ID in your ListBoxFor helper.
It should be like this:
#Html.ListBoxFor(m => m.SelectedListOptionIDs, filetypes, new { #class = "multiselectFileTypes" })
And SelectedListOptionIDs field of your model should be IList or IEnumerable, or Array of your ID type (probably IList<int>). Then it will work fine on View and bind correct on form POST.
See reply from Stephen Meucke above.

How to Use JSON Object to populate Knockout Form

I have a form that i would like to populate using knockout data-binding from a JSON object. I have hard coded the values using knockout. What i am really after is since i have a JSON object how do i turn that into data that knockout can use to populate my form dynamically? Here is my FIDDLE
<p>Hero Name: <span data-bind="text : HeroName" /></p>
<p>Agent Writing Number: <span data-bind="text : HeroCode" /></p>
<p>Contact Phone: <span data-bind="text : ContactPhone" /></p>
var HeroDetails = $.get("GetHeroDetailsForVillianView", {
HeroRequestIdForvillianDetailsView: HeroRequestIdForVillianDetailsView
}, function (returnDataForDetails) {
var results = JSON.parse(returnDataForDetails);
$('#json').text(JSON.stringify({HeroName:'PeterParker', ContactPhone: '123456', HeroCode: 3 }, null, 4));
function ViewModel() {
var self = this;
self.HeroName = ko.observable("Peter Parker");
self.ContactPhone = ko.observable("123456858");
self.HeroCode = ko.observable("2455654");
}
ko.applyBindings(new ViewModel());
Check out this page of the KO documentation for more details. You might also be interested in the mapping plugin.
Here is the pattern I use:
function ViewModel(data) {
var self = this;
self.HeroName = ko.observable(data.HeroName);
self.ContactPhone = ko.observable(data.PhoneNumber);
self.HeroCode = ko.observable(data.HeroCode);
}
var viewModel;
$.getJSON("/some/url", function(data) {
viewModel = new ViewModel(data);
})
ko.applyBindings(viewModel);
There are a few ways to do this, but pretty simple with jQuery.
https://jsfiddle.net/2bwegmsv/4/
I added ids to each of the divs where you want the data and then added this to your javascript:
var myJson = {HeroName:'PeterParker', ContactPhone: '123456', HeroCode: 3 };
$('#hname').append(myJson.HeroName);
$('#agent').append(myJson.ContactPhone);
$('#contact').append(myJson.HeroCode);
May not work precisely as you want, but should point you in the right direction.
Dynamically: Just binding JSON object.
var jsonDataViewModel = {HeroName:'Peter Parker', ContactPhone: '123456', HeroCode: 3};
ko.applyBindings(jsonDataViewModel);
http://knockoutjs.com/documentation/observables.html

Angular Chosen default not working with object

I am using https://github.com/localytics/angular-chosen to allow for select tags with search capability for many options.
The problem I'm having is with preselecting an option on an already saved vendor object. When creating a new one there is now issue, but if we're viewing an existing vendor, I want to show the vendor's name in the select box, rather than the placeholder.
<select chosen
ng-model="myVendor"
ng-options="vendor['public-id'] as vendor.name for vendor in vendors"
data-placeholder="Nah">
</select>
And in my controller, I'm setting the model by hand $scope.myVendor = "Some value"
The problem is that I'm populating the options with an object, instead of a key/value. I found an example of it working with a key/value, but haven't had success adapting this to objects as options.
I've even tried setting myVendor to the matching object that I want selected, with no luck.
Plunker of issue
I updated the plunker and change my previous changes on the plugin. this was not the issue. I don't understand how it was giving me errors there.
The solution is to track with an object and two functions the id and the name:
// Controller
$scope.vendors = [
{
"public-id": "1234",
"name": "stugg"
},
{
"public-id": "4321",
"name": "pugg"
}
];
$scope.myVendor = {name: "pugg", id:""};
$scope.updateMyVendorName = function () {
var found = false,
i = 0;
while (!found && i < $scope.vendors.length) {
found = $scope.vendors[i]['public-id'] === $scope.myVendor.id;
if (found) {
$scope.myVendor.name = $scope.vendors[i].name;
}
i++;
}
}
findVendorByName();
function findVendorByName () {
var found = false,
i = 0;
while (!found && i < $scope.vendors.length) {
found = $scope.vendors[i]['name'] === $scope.myVendor.name;
if (found) {
$scope.myVendor.id = $scope.vendors[i]['public-id'];
}
i++;
}
}
// template
<select chosen class="form-control span6" ng-options="vendor['public-id'] as vendor.name for vendor in vendors" ng-model="myVendor.id" ng-change="updateMyVendorName()">
{{myVendor.name}}

Set default value for dropdownlist using angularjs?

I have code that populates then dropdownlist and the javascript variable that gets the last item in the list. Now all I want to do is select that last item as the default .What am I missing ?
<div class="row">
<div>
<select ng-init="lastItem" ng-model="congressFilter" ng-options="cc.congressLongName for cc in ccList"></select>
</div>
<div class="grid-style" data-ng-grid="userGrid">
</div>
ccResource.query(function (data) {
$scope.ccList.length = 0;
angular.forEach(data, function (ccData) {
$scope.ccList.push(ccData);
})
//Set default value for dropdownlist?
$scope.lastItem = $scope.ccList[$scope.ccList.length - 1];
});
You simply need to asign a value to congressFilter in your controller.
$scope.congressFilter = 'someVal';
It depends a little on how your data looks however.
It might help to new developers. need to add default id for display default item in option.
The below code sample we add [ $scope.country.stateid = "4" ] in controller $scope to set the default.
var aap = angular.module("myApp", []);
aap.controller("MyContl", function($scope) {
$scope.country = {};
$scope.country.stateid = "4";
$scope.country.states = [{
id: "1",
name: "UP"
}, {
id: "4",
name: "Delhi"
}];
});
<body ng-app="myApp">
<div ng-controller="MyContl">
<div>
<select ng-model="country.stateid" ng-options="st.id as st.name for st in country.states">
</select>
ID : {{country.stateid}}
</div>
</div>
</body>

Categories