Cannot create property 'subjects' on number '1' using AngularJs - javascript

I want to select multiple subjects across one course but can't do so
I have two dropdown lists one for course selection and one for subjects selection. For multiple selection of the subjects I use the angular-chosen plugin, I can select multiple subjects only in the case when the Course is not selected from the dropdown list. But when I select the Course from the dropdown list then I can't select even one subject from the dropdown list
Following is my AddCourseController.js and related HTML
(function() {
var myApp = angular.module("myApp");
var AddCourseController = function($scope, CourseService, TeacherService) {
var onCourses = function(courses) {
$scope.courses = courses;
}
var onError = function(response) {
$scope.error = true;
$scope.errors = response.data;
};
CourseService.courses().then(onCourses, onError);
TeacherService.getSubjects().then(function(data) {
$scope.subjects = data
});
};
myApp.controller("AddCourseController", AddCourseController);
}());
<div class="form-group">
<label>Select Course</label>
<select ng-model="course" class="form-control"
ng-options="course.IdCourse as course.Name for course in courses track by course.IdCourse">
</select>
</div>
<div class="form-group" ng-class="{ 'has-error' :
addCourseForm.subjects.$invalid && !addCourseForm.subjects.$pristine }">
<label class="pull-left">Select Subjects</label>
<a class="pull-right btn btn-primary btn-xs" data-toggle="modal" data- target="#add-subject">Add Subject</a>
<select chosen multiple class="form-control"
ng-model="course.subjects"
ng-options="subject.IdSubject as subject.Name for subject in subjects">
</select>
<p ng-show="addCourseForm.subjects.$invalid &&
!addCourseForm.subjects.$pristine" class="help-block">Subject is required.
</p>
</div>

Change the course selector to return the entire course object to the ng-model:
<div class="form-group">
<label>Select Course</label>
<select ng-model="course" class="form-control"
ng-options="course ̶.̶I̶d̶C̶o̶u̶r̶s̶e̶ as course.Name for course in courses track by course.IdCourse">
</select>
</div>

Related

Uncaught ReferenceError: Unable to process binding with KnockoutJS

We have a multiple page form like below , each page on the form is associated with different model classes. I am trying use the value the users selected in Page 1 and based upon that value selected in Pg1 I need to show/hide the field in Page2.
Page2 has a button which allows the users add courses, when they click on the button few fields shows up in the page in foreach loop and one of the field should show/hide based on the selection made on the previous page. But the above logic throws error like Uncaught ReferenceError: Unable to process binding "visible:" below is the viewmodel
How can I have the binding work properly here and get rid of the error
It's case sensitive. Also, the foreach loop changes the binding context, so you need to do this:
<div class="form-group required" data-bind="visible: $parent.Solution() == 'Other'">
Edit- that is, if you're indeed trying to reference the Solution property from the parent viewmodel. It's not clear from your example wheter a CoursesList item also has such a property.
Just expanding on #Brother Woodrow's answer with an very basic runnable example might help with things.
function ViewModel() {
var self = this;
self.pages = [1, 2]
self.currentPage = ko.observable(1)
self.solutions = ko.observableArray(['Solution 1', 'Solutions 2', 'Other']);
self.solution = ko.observable().extend({
required: {
params: true,
message: "Required"
}
});
self.next = function() {
self.currentPage(self.currentPage() + 1);
};
self.back = function() {
self.currentPage(self.currentPage() - 1);
};
self.CourseDetails = ko.observableArray();
self.addCourse = function() {
self.CourseDetails.push(new coursesList());
}
self.pageVisible = function(page) {
return self.currentPage() == page;
}
}
function coursesList() {
var self = this;
self.otherSolution = ko.observable().extend({
required: {
params: true,
message: "Required"
}
});
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="Page_1" data-bind="visible: pageVisible(1)">
<h2>Page 1</h2>
<div class="form-group required">
<label for="Solution" class="control-label">Solution</label>
<select id="Solution" name="Solution" class="form-control" data-bind="options: solutions, value: solution, optionsCaption: 'Select'"></select>
</div>
<button type="submit" id="NtPg" class="SubmitButton" data-bind="click: next">Next</button>
</div>
<div id="Page_2" data-bind="visible: pageVisible(2)">
<h2>Page 2</h2>
<button type="submit" id="AddCourseInfo" class="SubmitButton" data-bind="click: addCourse">Add Course Info</button>
<div data-bind="foreach:CourseDetails">
<div class="form-group required" data-bind="visible: $parent.solution() == 'Other'">
<label for="OtherSolution" class="control-label">Explain Other Solution : </label>
<input type="text" maxlength="1000" id="OtherSolution" name="OtherSolution" class="form-control" data-bind="value : otherSolution" required/>
</div>
</div>
<button type="submit" id="NtPg" class="SubmitButton" data-bind="click: back">Back</button>
</div>
<pre data-bind="text: ko.toJSON($root)"></pre>

dropdown selected on page load angular

Here is a dropdown :
<div class="col-md-6">
<div class="form-group">
<label class="control-label">Role</label>
<select ng-model="User_Role" class="dropdown form-control" ng-options="t.RoleName for t in rollist track by t.ID">
<option value="" >-- Choose Role --</option>
</select>
</div>
</div>
the dropdown bind here:
$scope.rolelist = function () {
var role = UserService.getroleInfo();
role.then(function (d) {
//debugger;
$scope.rollist = d.data;
}, function (err) {
//debugger;
alert("Some Error Occured ");
});
}
how do selected the dropdown dynamic value in angularjs??
here is the dynamic dropdown <option label="Admin" value="1" >Admin</option>
can any one tell me how do i selected when page load using angular
Try this on your success call back :)
$scope.rollist = d.data;
$scope.User_Role=$scope.rollist[0]; // or $scope.User_Role=$scope.rollist[0].RoleName
here I used direct return in service instead of that you can use your http request in service
var app = angular.module('testApp',[]);
app.service('UserService',function(){
this.getroleInfo=function(){
return [{ID:1,RoleName:"Admin"},{ID:2,RoleName:"User"}];
};
});
app.controller('testCtrl',['$scope','UserService',function($scope,UserService){
/*+role.then(function (d) {
//debugger;
$scope.rollist = d.data;
}, function (err) {
//debugger;
alert("Some Error Occured ");
});*/
//place this below code in inside of your role.then(function(){})
$scope.rollist= UserService.getroleInfo();
$scope.User_Role={ID:2,RoleName:"User"};//here place your dynamic data
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="testApp" ng-controller="testCtrl">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">Role</label>
<select ng-model="User_Role" class="dropdown form-control" ng-options="t.RoleName for t in rollist track by t.ID">
<option value="" >-- Choose Role --</option>
</select>
</div>
</div>
</div>
You could use ng-init in the div and call a function that sets the ng-model value. for example: ng-init="assignValue()", and in the controller:
$scope.assignValue = function(){
$scope.User_Role = $scope.rollist[0]
}

Dropdowns not bound to ng-model in Angular

Something very basic I am missing but I am not able to figure out . I have three fields in a view , two of them are dropdowns.
<div class="form-group row">
<label for="GroupName" class="col-sm-4 form-control-label">Group Name : </label>
<div class="col-sm-8">
<input ng-model="referenceEdit.groupName" id="GroupName" class="form-control" type="text">
</div>
</div>
<div class="form-group row">
<label for="GroupType" class="col-sm-4 form-control-label">Group Type : </label>
<div class="col-sm-8">
<select name="selGroupType" id="selGroupType" class="form-control" ng-change="referenceEdit.populateGroupTypeDetails(selGroupType)" ng-options="groupType.value for groupType in referenceEdit.groupTypes track by groupType.id" ng-model="referenceEdit.groupType"></select>
</div>
</div>
<div class="form-group row">
<label for="GroupAssignmentMethod" class="col-sm-4 form-control-label">Group Assignment Method : </label>
<div class="col-sm-8">
<select name="selGroupAssignmentMethod" id="selGroupAssignmentMethod" class="form-control" ng-options="assignmentMethod.id for assignmentMethod in referenceEdit.assignmentMethods track by assignmentMethod.value" ng-model="referenceEdit.assignmentMethod"></select>
</div>
</div>
Now in controller , I am getting the results for these drop downs in this way :
var row_details = GroupMembershipReferenceServices.getReferenceDataRow();
referenceDataDropDownService.getDropDown(REFERENCE_DATA_CONSTANTS.GROUP_TYPE).success(function (result) {
$scope.referenceEdit.groupTypes = result;
$scope.referenceEdit.groupype = row_details.grp_typ;
}).error(function (result) {
alert("Unable to retrieve dropdown values");
});
referenceDataDropDownService.getDropDown(REFERENCE_DATA_CONSTANTS.GROUP_ASSIGNMENT_METHOD).success(function (result) {
$scope.referenceEdit.assignmentMethods = result;
$scope.referenceEdit.assignmentMethod = row_details.grp_assgnmnt_mthd;
}).error(function (result) {
alert("Unable to retrieve dropdown values");
});
Problem is values are getting populated , like
and we are displaying the values accordingly. The results are like
[0] {id:"1",value:"Chapter Non-Event"}
[1] {id:"2",value:"NHQ Campaign"}
But the row_details.grp_typ is "NHQ Campaign".
Even though I assign it , the drop down option is not selected accordingly .
Have I to assign it to the value property only ? What am I missing ?
use ng-repeat instead of ng-options
eg:
<select name="selGroupType" id="selGroupType" class="form-control" ng-change="referenceEdit.populateGroupTypeDetails(selGroupType)" ng-model="referenceEdit.groupType">
<option value="-1">---</option>
<option ng-repeat="groupType.value for groupType in referenceEdit.groupTypes track by groupType.id" value="{[{groupType.id}]}"> {[{groupType.value}]} </option></select>

Trouble getting ngOptions to work properly in nested select dropdowns

I have created an angular app which records the attributes for a product which is being created. In the page, I have 2 select dropdowns, the first one for selecting the key of the attribute and the second selects the specific value. The json data for each attribute is as follows:-
{
meta_key :"Weight",
meta_values :[
"10","20","30","40","50"
],
type : "text",
unit:"kgs"
}
Each product can have an array of attributes with the only difference being that instead of meta_values as an array, each attribute in a product will have a single value as meta_value. The JSON representation is as follows:-
{
attributes : [
{
meta_key : "Weight",
meta_value : "20",
unit : "kgs"
},
{
meta_key : "Volume",
meta_value : "200",
unit : "cm*cm*cm"
}
]
}
This is what the page looks like.
My concern is that no matter what I am trying, the second select's values which depend entirely upon the value of the first select dropdown, does not get populated.
The empty second dropdown.
I tried populating the second dropdown with static data and it works fine. But the data does not change when it depends on the selection of the first dropdown. Here is my controller.
$scope.attributes = [];
$scope.product = {
attributes: []
};
$scope.current_user = {};
var attribute = {
meta_key: '',
meta_values: '',
unit: ''
};
AuthService.getCurrentUser(function (user) {
$scope.current_user = user;
$scope.product.created_by = $scope.current_user.id;
});
Attributes.fetchAllAttributes(function (response) {
$scope.attributes = response.message;
$scope.attributes.unshift({meta_key: "Select an attribute"});
console.log("Attributes", $scope.attributes);
});
$scope.addAttributes = function () {
$scope.product.attributes.push(attribute);
console.log($scope.product);
initDropDown($scope.product.attributes.length - 1);
};
$scope.initValues = function (index) {
var selectedValue = $scope.product.attributes[index];
console.log(selectedValue,$scope.product.attributes[index].meta_values);
};
And the html partial.
<div class="row attribute" ng-repeat="attribute in product.attributes track by $index">
<div class="input-field col s12 m4">
<select required md-select
ng-model="product.attributes[$index]"
ng-change="initValues($index);"
ng-options="attribute as attribute.meta_key for attribute in attributes">
</select>
<label>Attribute Name</label>
</div>
<div class="input-field col s12 m4" ng-show="product.attributes[$index].type == 'select'">
<select md-select
ng-options="value as value for value in product.attributes[$index].meta_values"
ng-model="product.attributes[$index].meta_value">
</select>
<label>Attribute Values</label>
</div>
<div class="input-field col s12 m4" ng-show="product.attributes[$index].type == 'text'">
<input type="text" id="{{$index }}" ng-model="product.attributes[$index].meta_value">
<label for="{{$index}}">Attribute Values</label>
</div>
<div class="input-field col s12 m2" ng-show="product.attributes[$index].meta_key != 'Select an attribute'">
<input id="unit" disabled ng-model="product.attributes[$index].unit">
<label for="unit" class="active">Unit</label>
</div>
<div class="input-field col s12 m2">
<a ng-click="remove($index);">
<i class="material-icons waves-effect waves-red red-text">close</i>
</a>
</div>
</div>
I have been trying to figure it for a while now. Have tried a lot solutions. But nothing quite works. How do I solve it? Any help will very appreciated.

How to remove models that are no longer bound to dom

I have a form that has a bunch of logic about which elements to show using ng-if. For example I might have a country drop down and if USA is selected it will show the state drop down which was conditioned upon an ng-if for country. Perhaps this was not the best way to do it so if there are recommendations for a different approach for the next project that will be appreciated but I need to finish this project with few major modifications.
The problem is if a user selects a country say USA and then a state, and then selects a different country. The state is still selected within the model. So how would I go about removing the state field. There are deeply nested ng-if's (think about 4-5 levels).
Example
<div ng-if="root.originCountry == 'PAK'">
<div ng-if="root.productType == 'Custom Football Jersey' || root.productType == 'Sublimated Football Jersey'">
<div class="control-group">
<label class="control-label" for="productTypeType">{{root.productType}} Type</label>
<div class="controls">
<select ng-model="root.productTypeType" ng-options="type for type in pakJerseyTypeList" bs-select required></select>
</div>
</div>
<div class="ordered-container">
<div ng-if="root.productTypeType">
<div class="control-group">
<label class="control-label" for="bodyColor">Body Color</label>
<div class="controls">
<select ng-model="root.bodyColor" ng-options="color for color in bodyColorList" bs-select required></select>
</div>
</div>
<div ng-if="root.bodyColor == 'Other'">
<div class="control-group no-count">
<label class="control-label" for="bodyColorPmsCode">Body Color PMS Code</label class="control-label no-count">
<div class="controls">
<input type="text" ng-model="root.bodyColorPmsCode" name='bodyColorPmsCode' required>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You can utilize the ng-change directive to your advantage; set one on a parent select box and implement its handler to clear the values of any child select box depending on it.
Here's a quick snippet illustrating how to achieve this:
<select
ng-model="selectedCountry"
ng-options="country for country in countries"
ng-change="clearCity()">
</select>
<select
ng-model="selectedCity"
ng-if="isJapanSelected()"
ng-options="city for city in japanCities"
ng-change="setCity(selectedCity)">
</select>
var app = angular.module('myModule', []);
app.controller('MainCtrl', function($scope) {
$scope.countries = ['Japan', 'Brasil', 'England'];
$scope.selectedCountry = 'Brasil';
$scope.selectedCity = '';
$scope.japanCities = ['Tokyo', 'Yokohama', 'Osaka']
$scope.isJapanSelected = function() {
return $scope.selectedCountry == 'Japan';
};
$scope.getCity = function() {
return $scope.selectedCity;
};
$scope.setCity = function(city) {
$scope.selectedCity = city;
};
$scope.clearCity = function() {
if (!$scope.isJapanSelected()) {
$scope.selectedCity = '';
}
};
});
Live demonstration on plunker

Categories

Resources