Work with multiple Forms and its values - angularjs

Assume an certain amount of forms created by ng-repeat, which allows the user to sum something up like a+b and display the result instantly.
How would the Controller look like?
<div data-ng-repeat="form in forms">
<form name={{form.name}}>
<input type="text" name="a" ng-modal="?">
<input type="text" name="b" ng-modal="?">
</form>
<p>{{?.result}}</p>
</div>
The question marks within the html should be something unique I guess. And the controller may access something like an array of forms from scope ... but maybe someone has a suggestion

If I understand your question correctly and assuming you have defined the forms in an array for example, below code should work for you:
<!DOCTYPE html>
<html data-ng-app="formApp">
<head>
<script type="text/javascript" src="https://code.angularjs.org/1.2.26/angular.js"></script>
<script type="text/javascript">
var formApp = angular.module("formApp",[]);
formApp.controller("formController", function($scope)
{
$scope.forms = [{name: "Foo"}, {name: "Bar"}];
});
</script>
</head>
<body data-ng-controller="formController">
<div data-ng-repeat="form in forms">
<form name={{form.name}}>
<input type="text" name="a" data-ng-model="form.someField">
<input type="text" name="b" data-ng-model="form.someOtherField">
</form>
<p>{{form.someField + form.someOtherField}}</p>
</div>
</div>
</html>
So basically you were right when mentioning "array of forms from scope".
The important thing to know is that angular creates a new scope for every item in the collection when using ng-repeat. This means, you do not need to use unique member names. "form.someField" for example always references the member of the current scope.
The calculation you would like to perform could be done inline as in my example or you could move it to an own method on a "class" from which all items in the form collection will inherit.
By the way: it's "data-ng-model" and not "data-ng-modal" ;)

Related

Function to add and show up a new object in an array

I just got started with playing around with AngularJS and I would like to build an app, that just adds another personĀ“s name and his/her date of birth.
I have got already initial data (2 persons and their date of birth (dob).
By writing down the full name and dob and then pressing the add button, I would like to have another person added as well as his/her dob - and this new person should be also listed and visible in the list.
So far I made it that the function creates a new object. But unfortunately I am not able to combine the input data with the new added object in a proper way.
Can somebody help me? Maybe there is an easier way to do it
So far I created this:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
</head>
<body>
<script>
var app = angular.module("myBirthApp",[]);
app.controller("myCtrl", function($scope){
$scope.birthdays=[
{fullName:'Jane Doe', dateOfBirth:'08.03.1990'},
{fullName:'John Doe', dateOfBirth:'19.11.1995'}];
// create new array with addItem!
$scope.addItem = function () {
$scope.birthdays.push($scope.addMe);
}
});
</script>
<div ng-app="myBirthApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="x in birthdays"><p>Name: {{x.fullName}}</p> <p>Date of birth: {{x.dateOfBirth}}</p> </br></li>
</ul>
<form>
<fieldset>
<legend>Add a person</legend>
First name and last name: <input type="text" ng-model="fullName"></br>
Date of birth: <input type="date" ng-model="dateOfBirth"></br>
<button ng-click="addItem()">Add</button>
</fieldset>
</form>
</div>
</body>
</html>
You could declare a variable:
$scope.person = {
fullName: '',
dateOfBirth: null
};
and bind it to ngModel inputs:
<input type="text" ng-model="person.fullName"><br />
<input type="date" ng-model="person.dateOfBirth">
and then in addItem method push it to birthdays array. (Of course it needs further additions, validation checks etc but this is the basic idea)
Check here a working demo: DEMO

Why won't this ng-pattern filter numbers?

I have an AngularJS single page application. One view has a textbox that I want to only accept numbers for an integer field. I have entered this code in the controller and this textbox in the view, but when I run the view it accepts any keyboard characters. Can you tell me how I need to modify this to work?
$scope.FilterNumbersOnly = /^\d+$/;
<input ng-model="x.COLUMN_VALUE" ng-pattern="FilterNumbersOnly" />
From the AngularJS documentation, ng-pattern will set the pattern key on the error object when the values input into the text-based field do not pass the specified regex test.
This says nothing about prohibiting users from inputting text. If you would like to add that behavior, you need to listen to the pattern key on the error object and attach handlers to it. When the input is invalid, the error object will reflect this, and you should respond by preventing user input. Or you can take whatever such action you deem necessary.
To prevent user input, you can set the disabled attribute on the input field when the pattern key on the error object is set.
One simple way to accomplish this is with the ng-if directive.
<input disabled ng-if="!form.input.$valid" />
<input ng-if="form.input.$valid" />
Here is a link to a working example.
You can do it using:
ngChange directive;
ngMask module (Always I need handle inputs with masks I use it).
I made this snippet showing both ways:
(function() {
"use strict";
angular.module('app', ['ngMask'])
.controller('mainCtrl', function($scope) {
$scope.checkNumber = function() {
$scope.input = $scope.input.replace(/\D+/, '');
}
})
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngMask/3.1.1/ngMask.min.js"></script>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body ng-controller="mainCtrl">
<form name="form" novalidate>
<label for="withoutMask">Input without mask: </label>
<input type="text" id="withoutMask" ng-model="input" ng-change="checkNumber()">
<hr>
<label for="mask">Input with mask: </label>
<input type="text" id="mask" mask="d" repeat="15" restrict="reject" limit="false" ng-model="otherInput">
</form>
</body>
</html>
why not use the built-in HTML support?
<input type="number">
supported - http://caniuse.com/#search=input%20type%3D%22number%22

Why those 3 fields don't get updated together?

Following this video tutorial, I am trying to bind three text inputs together.
But only the first get updated.
Here is my JsFiddle attempt
the index.html relevant part :
<body ng-app="">
<input type="text" placeholder="Your text" ng-model="data.message"></input>
<h2>{{data.message}}</h2>
<div ng-controller="FirstController">
<input type="text" placeholder="Your text" ng-model="data.message"></input>
<h2>{{data.message}}</h2>
</div>
<div ng-controller="SecondController">
<input type="text" placeholder="Your text" ng-model="data.message"></input>
<h2>{{data.message}}</h2>
</div>
</body>
script.js
function FirstController($scope){
}
function SecondController($scope){
}
What did I miss ?
Please also notice, that I do need the nested div tags and controller, as the purpose is to use scope inheritance.
Also, these global function definitions for the controllers are a choice, as I wanted to keep the video author method for now, in my real projects I will use the best practise which consist of using a module var controller() method).

angularjs get value from input in recursive template

How'd I get the value to controller from a nested view? I'd like to mention that I have a recursive approach.
HTML
<textarea ng-model="inputValue" class="ng-valid ng-dirty ng-valid-parse ng-touched"></textarea>
Full HTML structure can be found here
Edit:
I want to get the value of the textarea in my controller. (e.g. $scope.inputValue ); currently getting undefined
see this jszfiddle
http://jsfiddle.net/7qbucc62/
<div ng-app="app">
<div ng-controller="firstController">
<textarea ng-model="inputValue"></textarea>
<textarea ng-model="inputValue"></textarea>
</div>
</div>
<script>
(function abc()
{
var app=angular.module("app",[]);
app.controller("firstController",function($scope)
{
$scope.inputValue="";
});
})();
</script>
I think this is what you are asking
you can use $scope.inputValue directly in your controller. It will provide you the value of textarea

How to create an angular validation message directive

I am new to angular and maybe trying to do the wrong thing.
What I am trying to, is to create a validation message directive, which can show validation message for a specific input field in a form. It should only show the validation message for required fields in case the input field is missing a value.
I've tried with the following HTML:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<form name="myForm">
<input name="myInput" type="text" x-ng-model="object.input" required/><br/>
<span ng-show="myForm.myInput.$error.required" >Value required (working)</span><br/>
<span x-msg-required="myForm.myInput"></span>
</form>
</body>
</html>
and the JS:
var app = angular.module('myApp', []);
app.directive('msgRequired', function() {
return {
link : function(scope, element, attrs) {
element.text('Value required');
attrs.$set('ngShow', attrs.msgRequired + '.$error.required' );
}
};
});
The first span element with out directive shows the validation message as expected. The span element with my directive seems to always show the validation message. I am for sure not understanding the directives in angular. What am I missing or is there better ways of streamlining validation messages in angular?
There is a plunker: http://plnkr.co/edit/Gjvol8inw1DlWjHomZQw
I was also bothered by this with Angular and created a directive suite in AngularAgility called Form Extension to fix this very issue. It automatically generates validation messages for you based on whats on your element. It is also very configurable and even will generate labels for you if you'd like.
Consider normally having to type something like this to get validation:
<div ng-form="exampleForm">
<label for="firstName">First Name *</label>
<div>
<input type="text" id="firstName" name="firstName" ng-model="person.firstName"
ng-minlength="2" />
<div ng-show="exampleForm.firstName.$dirty && exampleForm.firstName.$error.minlength">
First Name must be at least 2 characters long.
</div>
</div>
</div>
That's a pain. With the plugin you can do something like this instead:
<div ng-form="exampleForm">
<div>
<input type="text" aa-auto-field="person.firstName" ng-minlength="2" />
</div>
</div>
Here are some relevant links:
Extensive demo
Blog post explaining it
Source on GitHub
So I see this is a couple months old, but in case anyone is looking for something that works:
I updated your Javascript to this:
var app = angular.module('myApp', []);
app.directive('msgRequired', function($compile) {
return {
//transclude: true,
restrict: "A",
link: function(scope, element, attrs) {
element[0].innerHTML = 'Value required in angular directive';
attrs.$set('ngShow', attrs.msgRequired + ".$error.required");
$compile(element)(scope)
}
};
});
which seems to work. I am however doing something VERY similar in another project, and getting an infinite compile loop :( Investigating that...
plnkr lives here.

Resources