Unable to bind $scope objects in ng-model for input - angularjs

I'm trying to bind my Controller's object values to inputs using ng-model, if I add it ng-repeat it is binding data, but if i call it directly it is not binding data to inputs. Thank you :)
Angular Controller
SMSApp.controller('studentUpdateController', function ($scope, $routeParams, GetStudentService) {
$scope.stuid = $routeParams.STUDENTID != null ? $routeParams.STUDENTID : 0;
GetStudentService.getbyId($scope.stuid).then(function (result) {
$scope.obj = JSON.parse(result);
$scope.obj = $scope.obj.Table;
console.log($scope.obj);
});
});
Console Log's
HTML Code
<div class="col-md-4 form-group">
<label>First Name</label>
<input type="text" class="form-control" ng-model="obj.FIRSTNAME" placeholder="First Name" required />
</div>
<div class="col-md-4 form-group">
<label>Middle Name</label>
<input type="text" class="form-control" ng-model="obj.MIDDLENAME" value="" placeholder="Middle Name" required />
</div>

It is because your obj is an array. If you do not want to use ng-repeat in other words if you are sure you will have only 1 item in your array you can try the following
<div class="col-md-4 form-group">
<label>First Name</label>
<input type="text" class="form-control" ng-model="obj[0].FIRSTNAME" placeholder="First Name" required />
</div>
<div class="col-md-4 form-group">
<label>Middle Name</label>
<input type="text" class="form-control" ng-model="obj[0].MIDDLENAME" value="" placeholder="Middle Name" required />
</div>

Related

Programmatically apply classes to angularjs form

I have an angular directive to facilitate the adding of bootstrap classes at runtime to streamline the need to apply "form-group", "control-label" and "form-control". This works perfectly as long as I don't try to include multiple levels at once, meaning that I cannot seem to make this work to include multiple divs in "form-group. I have attached the code, raw HTML and processed HTML for review to see if someone might have some insight into how I might modify to make this tool meaningful.
Directive:
(function () {
"use strict";
angular.module("ppac")
.directive("formfix", formfix);
var addClasses = function (element) {
var input = element.querySelector("input, textarea, select");
var type = input.getAttribute("type");
if (type !== "checkbox" && type !== "radio") {
input.classList.add("form-control");
}
var label = element.querySelector("label");
label.classList.add("control-label");
element.classList.add("form-group");
};
function formfix() {
return {
restrict: "A",
link: function (scope, element) {
addClasses(element[0]);
}
}
}
})();
HTML Form:
<form name="contactForm" ng-submit="model.submit()" novalidate>
<div class="form-horizontal">
<div formfix>
<label for="firstName" class="col-md-2">First Name</label>
<div class="col-md-3">
<input type="text" name="firstName" id="firstName" ng-model="model.contact.firstName" />
</div>
<label for="lastName" class="col-md-2">Last Name</label>
<div class="col-md-3">
<input type="text" name="lastName" id="lastName" ng-model="model.contact.lastName" />
</div>
</div>
</div>
</form>
Processed HTML:
<form name="contactForm" ng-submit="model.submit()" novalidate="" class="ng-pristine ng-valid">
<div class="form-horizontal">
<div formfix="" class="form-group">
<label for="firstName" class="col-md-2 control-label">First Name</label>
<div class="col-md-3">
<input type="text" name="firstName" id="firstName" ng-model="model.contact.firstName" class="ng-pristine ng-valid form-control ng-empty ng-touched">
</div>
<label for="lastName" class="col-md-2">Last Name</label>
<div class="col-md-3">
<input type="text" name="lastName" id="lastName" ng-model="model.contact.lastName" class="ng-pristine ng-untouched ng-valid ng-empty">
</div>
</div>
</div>
</form>
You can use ng-class to add class dynamically as the document says
The ngClass directive allows you to dynamically set CSS classes on an
HTML element by databinding an expression that represents all classes
to be added.
Reference
https://docs.angularjs.org/api/ng/directive/ngClass

Add call error message from controller in angular material?

I want to add error message, something like this:
<md-input-container>
<label>Last Name</label>
<input name="lastName" ng-model="lastName" required>
<div ng-messages="userForm.lastName.$error" ng-show="userForm.lastName.$dirty">
<div ng-message="required">Here is some message</div>
</div>
</md-input-container>
But want to call rendering from controller:
callMessage() {
// How can I implement this?
}
I assume you are not using controller as syntax, so you will have to define a function on the $scope object within your controller:
function YourController($scope,...){
$scope.callMessage = function(){
//you can access your form using $scope.userForm
return "yourString";
}
}
Your markup would change as follows:
<md-input-container>
<label>Last Name</label>
<input name="lastName" ng-model="lastName" required>
<div ng-messages="userForm.lastName.$error" ng-show="userForm.lastName.$dirty">
<div ng-message="required">{{callMessage()}}</div>
</div>
The important part is that you define your function on the $scope so that Angular actually can bind the {{callMessage()}} part in the markup to your function.
You may do,
<md-input-container>
<label>Last Name</label>
<input name="lastName" ng-model="lastName" required>
<div ng-messages="userForm.lastName.$error" ng-show="vm.callMessage(userForm.lastName.$dirty)">
<div ng-message="required">{{vm.myMessage}}</div>
</div>
And from controller
callMessage(isDirty) {
// Your conditional message with respect to "isDirty" parameter
isDirty ? this.myMessage = 'Dirty Message' : false;
return isDirty;
}
You may call directly $error in your controller after you have set up form.
View
<md-input-container>
<label>Last Name</label>
<input name="lastName" ng-model="lastName" required>
<div ng-messages="userForm.lastName.$error" ng-show="userForm.lastName.$dirty">
<div ng-message="required">{{errorMsg}}</div>
</div>
</md-input-container>
Controller
var isError = $scope.userForm.lastName.$error;
if (isError) {
$scope.errorMsg = 'Hey, this is error message';
}

passing data from controller to placeholders of the view in angularjs

I'm getting set of data by calling a GET method in angularjs.
controller
$scope.edit = function (id) {
var edit_url = 'http://localhost/AwtCW2012002/api/restApiController/editQuestion.json?question_id=' + id;
$http.get(edit_url)
.success(function (data) {
console.log(data);
})
.error(function () {
})
};
Data from the GET method is like follows
How can I pass the data into respective fields in my view (into placeholders, as this view is used to edit existing data)
view
<div class="container" ng-controller="questionEditCtrl">
<form class="form-horizontal" role="form" name='quizAdd' ng-submit="submit(data)">
<div class="form-group">
<label class="control-label col-sm-2" for="question">Question:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="question" ng-model="data.question" placeholder="Enter Question">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer1">Answer 1:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer1" ng-model="data.ans1" id="answer1" placeholder="Enter Answer 1">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer2">Answer 2:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer2" ng-model="data.ans2" id="answer2" placeholder="Enter Answer 2">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer3">Answer 3:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer3" ng-model="data.ans3" id="answer4" placeholder="Enter Answer 3">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer4">Answer 4:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer4" id="answer4" ng-model="data.ans4" placeholder="Enter Answer 4">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer5">Answer 5:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer5" id="answer5" ng-model="data.ans5" placeholder="Enter Answer 5">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="sel1">Select Correct Answer:</label>
<div class="col-sm-10">
<select class="form-control" ng-model="data.correct_ans" id="sel1">
<option>{{data.ans1}}</option>
<option>{{data.ans2}}</option>
<option>{{data.ans3}}</option>
<option>{{data.ans4}}</option>
<option>{{data.ans5}}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
</div>
You are getting the response in array. Use ng-repeat to render you fields. What you perform ng-repeat, you can add placeholder like,
placeholder="Write Answer {{$index}}"
Firstly, populate a $scope variable with the data from the api for it to be available for binding in the template:
$http.get(edit_url)
.success(function (data) {
$scope.data = data; //populate a scope variable
})
.error(function () {
});
Then, you can use one time expressions :: for your placeholders as follows:
placeholder="{{::data.ans1}}"
This will ensure only the default value of data.ans1 which was fetched from the api will be used as the placeholder. All subsequent changes to data.ans1 will change the value, but the placeholder will remain the same.

$scope.formName.fieldName.$setValidity is not working

I would like to set invalid with angular when firstname is equals to lastname and change the color using styles to red.
http://jsbin.com/japir/2
function RegoController($scope) {
$scope.app = {
firstName: "Saroj"
};
$scope.$watch("app.lastName", function(newVal, oldVal) {
if (!!$scope.app.lastName && !!newVal)
if (angular.lowercase($scope.app.firstName) === angular.lowercase(newVal)) {
debugger;
$scope.form.inputLastName.$setValidity("sameName", false);
}
});
}
<body ng-app>
<div class="container" ng-controller="RegoController">
<div class="col-lg-4">
<form name="form">
<div class="form-group">
<label for="inputFirstName">First Name</label>
<input id="inputFirstName" class="form-control" type="text" ng-model="app.firstName" placeholder="Enter your firstname" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputLastName">Last Name</label>
<input id="inputLastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputEmail">Email</label>
<input id="inputEmail" class="form-control" type="email" ng-model="app.email" placeholder="Enter your email" required />
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save" />
</div>
</form>
{{app}}
</div>
</div>
</body>
The problem is that you are trying to select a form input that has no name; thus making it unable to find the field you are trying to invalidate. Here is a working example:
JSBIN: http://jsbin.com/yozanado/1/
Input field with name:
<input id="inputLastName" name="lastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
Javascript:
$scope.form.lastName.$setValidity("sameName", false);
AngularJS form validation relies on the name of the form and the name of the fields to find the validation models on scope.
For example, if your HTML is:
<form name="form">
<input name="firstName" ng-model="firstName" />
</form>
You will be able to access the validation $error property on scope using the name attributes:
$scope.form.firstName.$error.sameName
To fix the issues you're having, add a name attribute to your input fields.
JSBin Demo

how to trigger form validation in angularjs programmatically on a dirty field

I'm setting some form values on an angular form and need to have the validation trigger/set the field to dirty programmatically. The current bug requires the user to actually interact with the form field to trigger the "required" validation and to have it turn green.
FB.Event.subscribe('auth.authResponseChange', function(response) {
if (response.status === 'connected') {
FB.api('/me', function(response) {
var scope = angular.element($("#PhotoUploadForm")).scope();
scope.$apply(function(){
scope.user.firstName = response.first_name;
scope.user.lastName = response.last_name;
scope.user.email = response.email;
});
});
And here is the html
<form no-validate id="PhotoUploadForm" name='form' action="/uploaded" enctype="multipart/form-data" method="POST" role="form" ng-controller="Controller">
<div class="col-md-5">
<div class="form-group">
<label class="control-label" for="firstName" >First Name</label>
<input type="text" class="form-control" id="firstName" name="firstName" ng-model="user.firstName" required />
</div>
<div class="form-group">
<label class="control-label" for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" name="lastName" ng-model="user.lastName" required />
</div>
<div class="form-group">
<label class="control-label" for="email">Email</label>
<input type="email" class="form-control" id="email" name="email" ng-model="user.email" required />
</div>
</div>
</form>
You can do it this way:
angular.element('#PhotoUploadForm').scope().user.firstName.$dirty = true
Let me know if it helps.

Resources