Using ng-model on two inputs, same value - angularjs

I'd like to use ng-model on input that receive a value of an other input ...
My code doesn't work and I don't understand why, is that possible to set ng-model to an input with Angular values?
My code
var BottomApp = angular.module('BottomApp', []);
BottomApp.controller('SeoArticle', ['$scope', function($scope) {
$scope.seoTitle = document.getElementById('title').value;
$scope.createSeoUrl = function(string){
var string;
string = string.replace(/'+/g, '');
string = string.replace(/"+/g, '');
return string.replace(/\s+/g, '-');
};
}]);
<div ng-controller="SeoArticle">
<input type="text" id="title" name="article[title]" class="form-control" placeholder="title" ng-model="seoTitle">
<input type="text" name="article[seo_title]" value="{{seoTitle2}}">
<input type="text" name="article[seo_url]" value="{{seoUrl2}}">
<div class="ui-block-title"><h5>{{seoTitle}}</h5></div>
<input type="text" id="title" class="form-control" placeholder="title" value="{{seoTitle}}" ng-model="seoTitle2">
<input type="text" id="seo_url" class="form-control" placeholder="seo_url" value="{{createSeoUrl(seoTitle)}}" ng-model="seoUrl2">
<div class="panel">
<div class="seo-overview">
<p class="seo-overview-title">{{seoTitle}}</p>
<p class="seo-overview-url">{{createSeoUrl(seoTitle)}}</p>
</div>
</div>
</div>
:

Here's a working Plunker.
I have added the ng-app call to the body tag
<body ng-app="BottomApp">
and removed the string variable declaration from createSeoUrl.
Edit: I don't think you can do it within the DOM. You should use a watcher. See the updated Plunker.
$scope.$watch("seoTitle", function(newValue) {
$scope.seoTitle2 = newValue;
$scope.seoUrl2 = $scope.createSeoUrl(newValue);
})
<input type="text" id="title" class="form-control" placeholder="title" ng-model="seoTitle2">
<input type="text" id="seo_url" class="form-control" placeholder="seo_url" ng-model="seoUrl2">

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

AngularJs - push Object in array

I can't understand how to push object into an array I tried few different ways and still can't figured it out.
var app = angular.module('myApp',[])
app.controller('dropdown', function($scope, $http){
$scope.userInfo = [];
$scope.pushInArray = function() {
$scope.userInfo.push($scope.users)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="dropdown">
<input type="text" name="name" ng-model="users.name" placeholder="Name">
<input type="text" name="email" ng-model="users.email" placeholder="Email">
<input type="text" name="phoneNo" ng-model="users.phoneNo" placeholder="phone Number">
<button ng-click="pushInArray()">Add</button>
<pre>{{userInfo}}</pre>
</div>
at click of add button I push the users information in userInfo properities. I works on first time but If I modified the the value already stored value also modified(after push value is modifying).
try angular.copy, this will copy the exist object with a new instance.
var app = angular.module('myApp',[])
app.controller('dropdown', function($scope, $http){
$scope.userInfo = [];
$scope.pushInArray = function() {
var user = angular.copy($scope.users);
$scope.userInfo.push(user);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="dropdown">
<input type="text" name="name" ng-model="users.name" placeholder="Name">
<input type="text" name="email" ng-model="users.email" placeholder="Email">
<input type="text" name="phoneNo" ng-model="users.phoneNo" placeholder="phone Number">
<button ng-click="pushInArray()">Add</button>
<pre>{{userInfo}}</pre>
</div>
You need to empty yours users before setting it to new values:
$scope.userInfo = [];
$scope.pushInArray = function(data) {
$scope.userInfo.push(data)
$scope.users = null;
}
HTML:
<input type="text" name="name" ng-model="users.name" placeholder="Name">
<input type="text" name="email" ng-model="users.email" placeholder="Email">
<input type="text" name="phoneNo" ng-model="users.phoneNo" placeholder="phone Number">
<button ng-click="pushInArray(users)">Add</button>
<pre>{{userInfo}}</pre>
Here is the working Plnkr
You need to pass the object to the scope function to persist it.
var app = angular.module('myApp',[])
app.controller('dropdown', function($scope, $http){
$scope.userInfo = [];
$scope.pushInArray = function(data) {
var entry = (JSON.parse(JSON.stringify(data)));
$scope.userInfo.push(entry);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="dropdown">
<input type="text" name="name" ng-model="users.name" placeholder="Name">
<input type="text" name="email" ng-model="users.email" placeholder="Email">
<input type="text" name="phoneNo" ng-model="users.phoneNo" placeholder="phone Number">
<button ng-click="pushInArray(users)">Add</button>
<pre>{{userInfo}}</pre>
</div>

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';
}

How to use ng-if with input textbox alongwith ng-model?

I am using angularjs.
In my html I have 2 input boxes
edit = false;
<input type="text" value="" data-ng-if="edit" ng-model="name">
<input type="text" value="" data-ng-if="!edit" ng-model="singleAppDetails.name">
so here I wanted to show only one input box at a time based on some condition.
But i guess ng-if is not working.Basically if edit == true i want to show singleAppDetails.name and if edit == false then name
HTML DOM:
<div ng-app="myApp">
<div ng-controller="testController">
<input type="text" value="" data-ng-if="edit" ng-model="name">
<input type="text" value="" data-ng-if="!edit" ng-model="singleAppDetails.name">
</div>
</div>
Angularjs:
angular.module('myApp', [])
.controller("testController", function($scope){
$scope.singleAppDetails = {
"name" : "name if not editable"
}
$scope.name = "name if editable";
$scope.edit = false;
})
example: http://codepen.io/anon/pen/NqKQJO
You could try this:
<input type="text" value="" data-ng-if="edit" ng-model="(edit ? name : singleAppDetails.name)">
This way you only use an input to cover both cases.
<div ng-switch="edit">
<div ng-switch-when='false'>
<input type="text" value="" ng-model="singleAppDetails.name">
</div>
<div ng-switch-when='true'>
<input type="text" value="" ng-model="name">
</div>
</div>

Input field displaying as undefined in Angular

I am trying to get the input value for a form field, but when I use the code below, the value displays as undefined.
Any idea what I'm doing wrong here?
.controller('ContactFormCtrl',
function (Contacts) {
var contactForm = this;
contactForm.contacts = Contacts;
contactForm.contact = {};
var mail=contactForm.contact.email;
contactForm.onchange = function () {console.log(mail);};
});
<div class="col-sm-6 form-group">
<label class="control-label" for="email">Email</label>
<input type="email" id="email" name="email" ng-model="contactForm.contact.email" class="form-control" ng-change="contactForm.onchange()" ng-model-options="{ updateOn: 'blur' }" />
</div>
Update the controller as :
.controller('ContactFormCtrl',
function (Contacts) {
var contactForm = this;
contactForm.contacts = Contacts;
contactForm.contact = {};
contactForm.contact.email="";
var mail=contactForm.contact.email;
contactForm.onchange = function () {console.log(mail);};
});
Currently, there is no email property with "contactForm.contact" object. So you need to initialize the email property and it will not give you undefined error.
As you are using controllerAs syntax then you should use alias there contactForm
<div ng-controller="ContactFormCtrl as contactForm">
<div class="col-sm-6 form-group">
<label class="control-label" for="email">Email</label>
<input type="email" id="email" name="email" ng-model="contactForm.contact.email" class="form-control" ng-change="contactForm.onchange()" ng-model-options="{ updateOn: 'blur' }" />
</div>
</div>
And the reason it is undefined is you have reinitialized controller contact object after contactForm.contacts = Contacts; which overrides the value of email.
Update
As discussed in chat you want to show email on blur as well as you want to call onchange function on email validate, for that you should have to use combination of directive ng-change with ng-blur then you should get rid off ng-model-options which don't suits your requirement.
Markup
<div ng-controller="ContactFormCtrl as contactForm">
<form name="myForm">
<div class="col-sm-6 form-group">
<label class="control-label" for="email">Email</label>
<input type="email" id="email" name="email" ng-model="contactForm.contact.email" class="form-control"
ng-change="myForm.email.$valid && contactForm.onchange()" ng-blur="contactForm.onchange()"/>
</div>
</form>
</div>

Resources