I've a form inside table.
<table class='table table-bordered'>
<caption>ADD NEW BRAND</caption>
<tbody>
<form ng-app="" class="form-horizontal" role="form" name="myForm">
<div class="form-group">
<TR>
<TD>Brand Name</TD>
<TD>
<input type="text" class="form-control" name="name" ng-model="newbrand.Name" placeholder="Enter Brand Name" required>
<span style="color:red" ng-show="myForm.name.$dirty && myForm.name.$invalid">
<span ng-show="myForm.name.$error.required">Brand Name is required.</span>
</span>
</TD>
</TR>
</div>
</form>
</tbody>
</table>
When input field is empty, it should give a indication that Brand Name is required. But its not working.
Can someone please help me on this.
You can do that using directive:-
For an example:
html
<body ng-controller="MainCtrl">
<form novalidate class="person" name="personForm" test-directive validation="submitPerson" ng-submit="submitForm(personForm)">
<h3>Person form</h3>
<input type="text" required name="first-name" ng-model="person.firstName" ng-class="{'valid':personValid}" />
<input type="submit" value="post" />
</form>
</body>
Controller & Directive
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.person = {
firstName: 'Clem'
};
$scope.submitPerson = function(form, element) {
console.log("Person validation here!")
if(form.$valid) {
$scope.personValid = true;
}
else {
$scope.personValid = false;
}
};
});
app.directive('testDirective', function ($compile) {
return {
restrict: 'A',
scope: true,
link: function (scope, ele, attrs) {
scope.submitForm = function(form) {
eval("var fn = scope." + attrs.validation);
fn(form, ele);
}
}
};
})
Credit :- Form validation in angular
Related
I'm using AngularJS 1,5 and the trick which I'm looking for is below.
For example, this is form:
<form name="main">
<div ng-repeat="user in users" ng-init="subForm='tags'+$index">
<ng-form name="{{subform}}"
<input type="text" name="username" ng-model="user.username" required/>
<input type="text" name="name" ng-model="user.name" required/>
<input type="email" name="email" ng-model="user.email" required/>
<input type="hidden" name="status" ng-model="user.status"/>
</ng-form>
</div>
</form>
I want to watch my models gathered from the ng-form child in the controller to check on their validity.
self.Scope.$watch('main[subForm].$valid', function ()
{
if (self.Scope.myform.subForm.$valid)
{
$scope.user.status = true;
}
});
Is there any way to implement something like that or should I create a custom directive.
In this sample we create our model as "forms" and send it to the directive, the parent form is valid if one of that forms is complete, by complete each form the user state will change
index.html
<div class="container" ng-app="app" ng-controller="ctrl">
<form name="parent_form">
<ng-form data-form="parent_form" data-list="forms"></ng-form>
<button type="submit" class="btn btn-default" ng-disabled="parent_form.$invalid">Submit</button>
</form>
</div>
app.js
var app = angular.module("app", []);
app.controller("ctrl", function ($scope) {
$scope.forms = [
{ name: "form1", isValid: false },
{ name: "form2", isValid: false }
];
});
ngForm.html
<div name="form_{{form.name}}" ng-repeat="form in list">
<h3>{{form.name}}</h3>
<div class="form-group">
<label for="username">username</label>
<input type="text" class="form-control" id="username" name="username" ng-model="form.user.username" ng-required="true" />
</div>
<div class="form-group">
<label for="name">name</label>
<input type="text" class="form-control" id="name" name="name" ng-model="form.user.name" ng-required="true" />
</div>
<div class="form-group">
<label for="email">email</label>
<input type="email" class="form-control" id="email" name="email" ng-model="form.user.email" ng-required="true" />
</div>
<label>user state is:</label>{{form.user.status}}
<hr />
</div>
ngForm.js
Directive with form handler
app.directive("ngForm", function ($filter) {
return {
restrict: 'E',
templateUrl: "ngForm.html",
scope: {
list: "=",
form: "="
},
link: function (scope) {
var isValid = function (list) {
var hasUser = $filter("filter")(list, { hasUser: true }, true);
if (hasUser.length >= 1) {
scope.form.$invalid = false;
} else {
scope.form.$invalid = true;
}
angular.forEach(list, function (item) {
if (angular.isDefined(item.user)) {
if ((angular.isDefined(item.user.username) && item.user.username !== null) &&
(angular.isDefined(item.user.name) && item.user.name !== null) &&
(angular.isDefined(item.user.email) && item.user.email !== null)) {
item.user.status = true;
item.isValid = true;
item.hasUser = true;
} else {
item.user.status = false;
item.isValid = false;
item.hasUser = false;
}
}
});
}
scope.$watch("list", function (nVal) {
if (nVal) {
isValid(nVal);
}
}, true);
}
}
});
Form is empty, submit button dissabled, when user selected all input field submit button now dissable to enable that status change that time I need to call function to show progressbar.I tried bellow code.
html
----
<html>
<body>
{{message}}
</body>
</html>
You can check form validation on progress bar if form is valid then display progress bar
HTML Code
<style>
button.st{
padding:5px ;
border:1px solid #ccc;
/* background:green; */
/* border:1px solid lightblue; */
/* color:darkblue; */
margin:10px;
}
.progressbar{
border:1px solid #fff;padding:10px;border-radius:1px;width:60%;margin:10px;background:#999;color:red;
}
p{
margin-left:10px;
}
</style>
<body >
<div ng-controller="MyCtrl">
<p progressbar prog="form1.$valid ? '50':'10'" ></p>
<form name="form1" novalidate>
<p>
<span style="color:blue">1) select One</span><br/>
<input type="radio" ng-model="user.q1" name="grp1" value="A" ng-required="true"/>A
<input type="radio" ng-model="user.q1" name="grp1" value="B" ng-required="true"/>B
<input type="radio" ng-model="user.q1" name="grp1" value="C" ng-required="true"/>C
</p>
<p>
<span style="color:blue">2) select two</span><br/>
<input type="radio" ng-model="user.q2" name="grp2" value="A" ng-required="true"/>A
<input type="radio" ng-model="user.q2" name="grp2" value="B" ng-required="true"/>B
<input type="radio" ng-model="user.q2" name="grp2" value="C" ng-required="true"/>C
</p>
<button class="st" ng-disabled="form1.$invalid"> submit</button>
</p>
</form>
</div>
</body>
</html>
Controller js Code
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.name = 'World';
$scope.name = 'pelase select all fileds';
$scope.progressBar = false;
$scope.progressbarShow = function(){
$scope.progressBar = true;
}
});
app.directive('progressbar', [function() {
return {
restrict: 'A',
scope: {
'progress': '=prog'
},
template: '<div class="stripe" style="background-color: #C7D2D2; height:30px; width:100%;"> <div ng-style="style" style="background-color:#8CD211; height:100%"></div> </div>',
controller: function($scope, $element, $attrs) {
$scope.$watch(function() {
$scope.style = {"width": $scope.progress + "%"}
})
}
}
}])
please check working plnkr http://plnkr.co/edit/y35BnTUG36ChnCSC2YYH?p=preview
You can use $watch on $scope.user to watch change in radio buttons
$scope.$watch("user", function() {
if(!angular.isUndefined($scope.user.q1) && !angular.isUndefined($scope.user.q2))
$scope.increaseProgress = 50;
}, true);
angular.module("app", [])
.controller("main", ['$scope', function($scope) {
$scope.user={};
$scope.increaseProgress = 10;
$scope.progressBarShow = function() {
alert("Coming");
$scope.increaseProgress = 50;
}
$scope.$watch("user", function() {
if(angular.isUndefined($scope.user.q1) && angular.isUndefined($scope.user.q2))
$scope.increaseProgress = 50;
}, true);
}])
.directive('progressbar', [function() {
return {
restrict: 'A',
scope: {
'progress': '=progressbar'
},
template: '<div class="stripe" style="background-color: #442; height:50px; width:100%;"> <div ng-style="style" style="background-color:#CD2; height:100%"></div> </div>',
controller: function($scope, $element, $attrs) {
$scope.$watch(function() {
$scope.style = {
"width": $scope.progress + "%"
}
})
}
}
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<div ng-app="app" ng-controller="main">
<div progressbar="increaseProgress" ng-show="form1.$valid"></div>
<form name="form1" novalidate>
<p>
<span style="color:blue">1) select One</span>
<br/>
<input type="radio" ng-model="user.q1" name="grp1" value="A" ng-required="true" />A
<input type="radio" ng-model="user.q1" name="grp1" value="B" ng-required="true" />B
<input type="radio" ng-model="user.q1" name="grp1" value="C" ng-required="true" />C
</p>
<p>
<span style="color:blue">2) select two</span>
<br/>
<input type="radio" ng-model="user.q2" name="grp2" value="A" ng-required="true" />A
<input type="radio" ng-model="user.q2" name="grp2" value="B" ng-required="true" />B
<input type="radio" ng-model="user.q2" name="grp2" value="C" ng-required="true" />C
</p>
<button class="st" ng-disabled="form1.$invalid"> submit</button>
</form>
</div>
Am trying to display the time format data from the firebase database, that I have connected to the angular app, the html tag with the input type"text" is displaying fine on the dashboard but there is the problem with the time format and it is not getting displayed.
Here is the below HTML code
<div class = "row" ng-controller = "taskCtrl" >
<div class = "col-md-5">
<h3> Add Task </h3>
<form ng-submit= "addtask()">
<div class="form-group">
<select ng-model="selectedName" ng-options="X as X.Appname for X in appy">
</select>
</div>
<div class="form-group">
<label >Task Name</label>
<input type="text" class="form-control" ng-model = "tname" placeholder="Task Name">
</div>
<div class="form-group">
<label >Task Description</label>
<input type="text" class="form-control" ng-model = "tdes" placeholder="Task Description">
</div>
<div class="form-group">
<label >Task start time </label>
<input type= "text" class="form-control" ng-model = "tstime" placeholder="Task start time" >
</div>
<div class="form-group">
<label >Task Info</label>
<input type="time" class="form-control" ng-model = "tetime" placeholder="Task end time">
</div>
<div class="form-group">
<label >Phone number</label>
<input type="text" class="form-control" ng-model = "phno" placeholder="Phone number">
</div>
<button type = "submit" class = "btn btn-default">Submit</button>
</form>
</div>
<div class = "col-md-7">
<h3> Contacts</h3>
<table class= "table table-striped">
<thead>
<tr>
<th>Task Name </th>
<th>Task Description</th>
<th>Task Start time </th>
<th>Task End Time </th>
<th> Task Status </th>
</tr>
<tbody>
<tr ng-repeat = "tas in task">
<td> {{tas.tname}}</td>
<td> {{tas.tdes}}</td>
<td> {{tas.tstime}}</td>
<td> {{tas.tetime}}</td>
</tr>
</tbody>
</thead>
</table>
</div>
</div>
Here is the below javascript code :
'use strict';
angular.module('myApp.task', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/task', {
templateUrl: 'views/task.html',
controller: 'taskCtrl'
});
}])
.controller('taskCtrl', ['$scope','$firebaseArray',function($scope, $firebaseArray) {
var ref = new Firebase('https://contactlist9934.firebaseio.com/task');
$scope.task = $firebaseArray(ref);
var ref3 = new Firebase('https://contactlist9934.firebaseio.com/application');
$scope.appy = $firebaseArray(ref3);
$scope.addtask = function(){
var r1;
var r2;
var r3;
var r4;
r1 = $scope.tstime.toString();
r2 = r1.substring(16,24);
r3 = $scope.tetime.toString();
r4 = r3.substring(16,24);
$scope.task.$add({
tname: $scope.tname,
tdes: $scope.tdes,
etime: r2,
ttime: r4,
appname: $scope.selectedName.Appname
}).then(function(ref){
var id = ref.key();
console.log('Added Task' +id);
$scope.name = '';
$scope.email = '';
});
}
}])
.controller('myCtrl', function($scope) {
});
The text fields are getting displayed fine but the time format is not getting diaplayed, help me out on this one !!
You could use a filter for this and convert the tstime and tetime in your controller to your desired format like this:
$scope.tstime = $filter('date')($scope.tstime, 'yyyy/MM/dd');
$scope.tetime = $filter('date')($scope.tetime, 'yyyy/MM/dd');
Or if you want to use a directive and use it in multiple inputs you can make a directive something like this:
.directive('formatDate', ['$timeout', '$filter', function ($timeout, $filter) {
return {
require: 'ngModel',
link: function ($scope, $element, $attrs, $ctrl) {
var dateFormat = 'yyyy/MM/dd';
$ctrl.$parsers.push(function (viewValue) {
var pDate = Date.parse(viewValue);
if (isNaN(pDate) === false) {
return new Date(pDate);
}
return undefined;
});
$ctrl.$formatters.push(function (modelValue) {
var pDate = Date.parse(modelValue);
if (isNaN(pDate) === false) {
return $filter('date')(new Date(pDate), dateFormat);
}
return undefined;
});
$element.on('blur', function () {
var pDate = Date.parse($ctrl.$modelValue);
if (isNaN(pDate) === true) {
$ctrl.$setViewValue(null);
$ctrl.$render();
} else {
if ($element.val() !== $filter('date')(new Date(pDate), dateFormat)) {
$ctrl.$setViewValue($filter('date')(new Date(pDate), dateFormat));
$ctrl.$render();
}
}
});
}
};
}]);
And bind it to your input like this:
<input type= "text" class="form-control" format-date ng-model="tstime" placeholder="Task start time">
<input type="time" class="form-control" format-date ng-model="tetime" placeholder="Task end time">
This is fixed now, as I was trying to fetch the data from the firebase, the below variables should match in the below codes :- -
HTML
<tr ng-repeat = "tas in taski">
<td> {{tas.tname}}</td>
<td> {{tas.tdes}} </td>
<td> {{tas.etime}}</td>
<td> {{tas.ttime}}</td>
<td> {{tas.appname}}</td>
</tr>
Script
$scope.task.$add({
tname: $scope.tname,
tdes: $scope.tdes,
etime: $scope.tstime,
ttime: r4,
appname: $scope.selectedName.Appname
}).then(function(ref)
This post is a follow up of
this
(the goal is set img to visibily and set the src)
html
<form class="form-horizontal" role="form" name="form" data-ng-submit="add()">
<div class="form-group">
<input type="text" name="title" tabindex="1" class="form-control" placeholder="{{ 'items.form.title' | translate }}" data-ng-model="item.title" required="required" data-ng-minlength="3" data-ng-maxlength="25" user-feedback />
</div>
<div class="form-group">
<input type="text" name="ingredients" tabindex="2" class="form-control" placeholder="{{ 'items.form.ingredients' | translate }}" data-ng-model="item.ingredients" required="required" ng-pattern="/^\w(\s*,?\s*\w)*$/" user-feedback />
</div>
<div class="form-group">
<input type="text" name="price" tabindex="3" class="form-control" placeholder="{{ 'items.form.price' | translate }}" data-ng-model="item.price" required="required" data-smart-float user-feedback />
</div>
<div class="form-group">
<button type="button" tabindex="4" class="btn btn-default btn-lg" item="item" data-uploader>{{ 'items.form.upload' | translate }}</button>
<input type="text" name="url" style="display:none;" required="required" data-ng-model="item.url" />
</div>
<div class="form-group form-no-required clearfix">
<div class="pull-right">
<button type="submit" tabindex="5" class="btn btn-primary" data-ng-disabled="form.$invalid">{{ 'items.form.submit' | translate }}</button>
</div>
</div>
</form>
js
app.controller('ItemsUpdateController', function ($scope, item, Items, $state) {
item.$loaded().then(function(data) {
$scope.item = data;
});
$scope.add = function() {console.log($scope.item);
/* Items.update(item.$id,$scope.item).then(function () {
$state.transitionTo('items');
});*/
}
});
app.directive('uploader', function() {
return {
restrict: 'A',
scope:{
item: '='
},
link: function(scope, element, attrs) {
if (window.File && window.FileReader && window.FileList && window.Blob) {
var fileElem = angular.element('<input type="file" style="display:none;">');
var imgElem = angular.element('<img src="" width="50" style="margin-left:10px;visibility:hidden;">');
element.after(fileElem);
element.after(imgElem);console.log(scope.item); //This give me undefined
/*if(scope.item.url){
imgElem.css('visibility','visible');
imgElem[0].src = scope.item.url;
}*/
fileElem.on('change',function(e){
e.stopPropagation();
var files = e.target.files;
var reader = new FileReader();
reader.onloadend = function () {
var url = reader.result;
imgElem.css('visibility','visible');
imgElem[0].src = url;
scope.$apply(function () {
scope.item.url = url;
});
}
reader.readAsDataURL(files[0]);
});
element.on('click', function(e) {
e.stopPropagation();
fileElem[0].click();
});
element.on('$destroy',function(){
element.off('click');
});
fileElem.on('$destroy',function(){
fileElem.off('change');
});
}
},
};
});
Why console.log(scope.item); give me undefined
but I can see the right values fill the form ?
and how can I get the value ?
(btw I've tried also with $timeout or $apply but both doesn't work)
I've also tried with
scope.$watch('item', function(newVal, oldVal){
console.log(newVal, oldVal);
}, true);
but I've got
[Exception... "Illegal operation on WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)"
and I don't really understand why
console.log(scope.item);// Object { $$conf={...}, $id="-J_C-q-6bIW9PBZzqpAg"
console.log(angular.equals({}, scope.item));// but this is true !
Ugly ends up
//controller
$scope.item = item;
$scope.item.$loaded().then(function(data) {
$scope.item = data;
});
//directive
if(scope.item.$id){
scope.item.$loaded().then(function(data) {
imgElem.css('visibility','visible');
imgElem[0].src = data.url;
});
if anyone have got a better solution is welcome :)
}
I've got this code:
factory
app.factory('Items', function($firebase,FIREBASE_URL) {
var ref = new Firebase(FIREBASE_URL);
var items = $firebase(ref.child('items')).$asArray();
var Item = {
all: function () {
return items;
},
create: function (item) {
return items.$add(item);
},
get: function (itemId) {
return $firebase(ref.child('items').child(itemId)).$asObject();
},
update: function (itemId, item) {
return $firebase(ref.child('items').child(itemId)).update(item);
},
delete: function (item) {
return items.$remove(item);
}
};
return Item;
});
route
app.config(function($stateProvider) {
$stateProvider
.state('items_update', {
url: '/items/update/:id',
templateUrl: 'views/items/form.html',
controller:'ItemsUpdateController',
resolve:{
item:function(Items,$stateParams){
return Items.get($stateParams.id);
}
}
})
});
controller
app.controller('ItemsUpdateController', function ($scope, item, $state) {
$scope.item = item;
console.log($scope.item.url);
$scope.add = function() {
Items.update($scope.item).then(function () {
$state.transitionTo('items');
});
}
});
why console.log($scope.item.url); give me undefined ?
but in the view I've got all the data
html
<form class="form-horizontal" role="form" name="form" data-ng-submit="add()">
<div class="form-group">
<input type="text" name="title" tabindex="1" class="form-control" placeholder="{{ 'items.form.title' | translate }}" data-ng-model="item.title" required="required" data-ng-minlength="3" data-ng-maxlength="25" user-feedback />
</div>
<div class="form-group">
<input type="text" name="ingredients" tabindex="2" class="form-control" placeholder="{{ 'items.form.ingredients' | translate }}" data-ng-model="item.ingredients" required="required" ng-pattern="/^\w(\s*,?\s*\w)*$/" user-feedback />
</div>
<div class="form-group">
<input type="text" name="price" tabindex="3" class="form-control" placeholder="{{ 'items.form.price' | translate }}" data-ng-model="item.price" required="required" data-smart-float user-feedback />
</div>
<div class="form-group">
<button type="button" tabindex="4" class="btn btn-default btn-lg" item="item" data-uploader>{{ 'items.form.upload' | translate }}</button>
<input type="text" name="url" style="display:none;" required="required" data-ng-model="item.url" />
</div>
<div class="form-group form-no-required clearfix">
<div class="pull-right">
<button type="submit" tabindex="5" class="btn btn-primary" data-ng-disabled="form.$invalid">{{ 'items.form.submit' | translate }}</button>
</div>
</div>
</form>
ENDS UP
as in the #Frank van Puffelen comment
I worked it out with:
app.controller('ItemsUpdateController', function($scope, item, $state) {
item.$loaded().then(function(data) {
$scope.item = data;
console.log($scope.item.url);
});
$scope.add = function() {
Items.update($scope.item).then(function() {
$state.transitionTo('items');
});
}
});
This is because by the time your console.log($scope.item.url); runs, the data hasn't been loaded from Firebase yet. Angular listens for a notification from Firebase/AngularFire to know when the data has loaded and then updates the view.
Also see angularfire - why can't I loop over array returned by $asArray? and Trying to get child records from Firebase.