I am trying to show Email valid messages using below code but problem is email error message not showing in red color. How can I resolve this problem?
https://codepen.io/rama-krishna-the-selector/pen/PXOwQp?editors=1010
.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<!-- JAVA SCRIPT REFERENCES -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
<script src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="plunker" >
<div ng-controller="DynamicFormController">
<h3>Dynamic Radio Buttons</h3>
<form name="myForm" class="form-horizontal" role="form" ng-submit="submitForm()">
<div ng-repeat="field in entity.fields">
<ng-form name="form">
<!-- EMAIL FIELDS -->
<div ng-if="field.type=='email'" class="form-group" ng-class="{ 'has-error' :
form[field.name].$dirty && form[field.name].$error.required,
'has-success': form[field.name].$valid}">
<label class="col-sm-2 control-label">{{field.label}}</label>
<div class="col-sm-6">
<input type="{{ field.type }}" dynamic-name="field.name" id="{{field.name}}" ng-model="field.data"
class="form-control" required />
<p class="help-block" ng-show="form[field.name].$dirty && form[field.name].$error.required">{{field.name}}
is required</p>
<p class="help-block" ng-show="form[field.name].$dirty && form[field.name].$error.email">Please enter valid {{field.name}}</p>
<!-- <p class="help-block" ng-show="{{'form.'+field.name+'.$dirty && form.'+field.name+'.$error.required'}}">required</p> -->
</div>
</div>
</ng-form>
</div>
<br/>
<button ng-disabled="myForm.$invalid" type="submit" id="submit">Submit</button>
<br/>
<pre>{{entity|json}}</pre>
<br/>
</form>
</div>
</body>
</html>
.js
var app = angular.module('plunker',[]);
app.controller('DynamicFormController', function ($scope, $log) {
// we would get this from the api
$scope.entity = {
name : "Course",
fields :
[
{type: "text", name: "firstname", label: "Name" , required: true, data:""},
{type: "radio", name: "color_id", label: "Colors" , options:[{id: 1, name: "orange"},{id: 2, name: "pink"},{id: 3, name: "gray"},{id: 4, name: "cyan"}], required: true, data:""},
{type: "email", name: "emailUser", label: "Email" , required: true, data:""},
{type: "text", name: "city", label: "City" , required: true, data:""},
{type: "password", name: "pass", label: "Password" , min: 6, max:20, required: true, data:""},
{type: "select", name: "teacher_id", label: "Teacher" , options:[{name: "Mark"},{name: "Claire"},{name: "Daniel"},{name: "Gary"}], required: true, data:""},
{type: "checkbox", name: "car_id", label: "Cars" , options:[{id: 1, name: "bmw"},{id: 2, name: "audi"},{id: 3, name: "porche"},{id: 4, name: "jaguar"}], required: true, data:""}
]
};
$scope.submitForm = function(){
$log.debug($scope.entity);
}
})
.directive("dynamicName",function($compile){
return {
restrict:"A",
terminal:true,
priority:1000,
link:function(scope,element,attrs){
element.attr('name', scope.$eval(attrs.dynamicName));
element.removeAttr("dynamic-name");
$compile(element)(scope);
}
}
})
Well you can add a class like this:
ng-class="{'has-error': form[field.name].$error.email }"
So your element will change to :
<p class="help-block has-error" ng-class="{'has-error': form[field.name].$error.email }" ng-show="form[field.name].$dirty && form[field.name].$error.email">Please enter valid {{field.name}}</p>
And to your classes you can add a error class like this:
.has-error
{
color:red !important;
}
Update HTML with following directive with condition in tag at message Please enter valid {{field.name}}
ng-class="{'red':form[field.name].$error.email}"
add CSS class
.red{color:#ff0000;}
!important is not required in this case
Related
i have a dynamic form in angular. and i want to send the response as json. how do i generate JSON from the form?
here's the complete code,I have to get json, and post it to some api.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="dyf" ng-submit="submit()">
<form name="userFormOne" novalidate>
<table>
<tr class="form-group" ng-repeat="x in names">
<td><label>{{ x.Field }}</label>
</td><td><input type="text" class="form-control" placeholder="{{x.Comment}}" required>
</td>
</tr>
</table>{{data}}
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('dyf', function($scope, $http) {
$http.get("http://localhost:5000/gu")
.then(function (response) {$scope.names = response.data;console.log(response.data);});
$scope.data ={};
});
</script>
</body>
</html>
In AngularJs we use ng-model to bind inputs value to our controller, sample:
This full sample to figure out how to create a simple form, from array and how to send it as JSON to your API.
Note: On submit check your console, and see the objects value.
var app = angular.module("app", []);
app.controller("ctrl",
function ($scope) {
var options = [
{ name: "a" },
{ name: "b" },
{ name: "c" }
];
$scope.names = [
{ id: 1, field: "insert name", name: "name", placeholder: "your name is", value:null, type:"text" },
{ id: 2, field: "insert phone", name: "phone", placeholder: "your phone is", value: null, type: "tel" },
{ id: 3, field: "insert age", name: "age", placeholder: "your age is", value: null, type: "number", min: 0, max: 20 },
{ id: 4, field: "select country", name: "country", placeholder: "your country is", value: null, type: "select", options: options }
];
$scope.sendMe = function() {
console.log($scope.names);
}
});
<!DOCTYPE html>
<html ng-app="app" ng-controller="ctrl">
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<form name="userFormOne" novalidate>
<table>
<tr class="form-group" ng-repeat="x in names">
<td>
<label>{{ x.field }}</label>
</td>
<td ng-if="x.type != 'select'">
<input type="{{x.type}}" min="{{x.min}}" max="{{x.max}}" ng-model="x.value" name="{{x.name}}" placeholder="{{x.placeholder}}" ng-required="true">
{{x.value}}
</td>
<td ng-if="x.type == 'select'">
<select ng-model="x.value" name="{{x.name}}" ng-options="item as item.name for item in x.options">
</select>
{{x.value}}
</td>
</tr>
</table>
<button ng-disabled="userFormOne.$invalid" ng-click="sendMe()">sendMe</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>
</html>
var inputs={
'firstname': '',
'lastName':'',
'account':{
'role':'',
'status':''
}
}
This is my model array. I want to display it dynamically in Webpage and by modifying the json array the changes should affect the form too.
Here is the image
UPD:
for your situation, you can use ng-switch to generate elements according to conditions.
Notice(already included in the code snippet):
ng-repeat will generate it's own scope, so your model won't update unless you bind it with the original scope. ref here.
OLD ANSWER:
use ng-model to implement two-way-databinding.
refer the code snippet below:
angular.module("app", []).controller("myCtrl", function($scope) {
$scope.inputs = {
'firstname': 'test first name',
'lastName': 'test last name',
'account': {
'role': 'test role',
'status': 'test status'
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.4/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<!-- First Name: <input type="text" ng-model="inputs.firstname"><br>
Last Name: <input type="text" ng-model="inputs.lastName"><br> Account Role: <input type="text" ng-model="inputs.account.role"><br>
Account Status: <input type="text" ng-model="inputs.account.status"><br> -->
<div ng-repeat="(key1, value) in inputs" ng-switch="key1">
<div ng-switch-when="account">
<div ng-repeat="(key2, value2) in value">
{{key1 | uppercase}} => {{ key2 | uppercase}}
<input type="text" ng-model="inputs[key1][key2]">
</div>
</div>
<div ng-switch-default>
{{key1 | uppercase}}
<input type="text" ng-model="inputs[key1]">
</div>
</div>
{{inputs}}
</div>
/My html should look like this/
<head>
<script data-require="angular.js#1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<script type="text/ng-template" id="tree-structure">
<label>{{dt}}</label><input type="text" name="" value="{{dt.label}}">
<ul class="childElement">
<li ng-repeat="dt in dt.nodes" ng-include="'tree-structure'">
</li>
</ul>
</script>
<ul class="parentList">
<li ng-repeat="(key, value) in inputs" >
<div ng-repeat="(key1, value1) in value">
<label>{{key1}}</label>
<input type="text" name="" value="{{value1}}">
<!-- <div ng-repeat="(key2, value2) in value1">
<label>{{key2}}</label><input type="text" name="" value="{{value2}}">
</div> -->
</div>
<div ></div>
</li>
</div>
</ul>
</body>
</html>
Some observations :
Your JSON should be formatted properly with type of the field.
If you want to access the object properties as a form fields then it should be structured in a good way so that we can dynamically add the type of the field as well.
[{
name: 'firstName',
type: 'text'
}, {
name: 'lastname',
type: 'text'
}, {
account: [{
name: 'role',
type: 'text'
}, {
name: 'status',
type: 'text'
}]
}]
As your JSON have nested objects. So, first iterate it recursively and create one dimensional array then create the fields using 1D array.
DEMO
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
var inputs = [{
name: 'firstName',
type: 'text'
}, {
name: 'lastname',
type: 'text'
}, {
account: [{
name: 'role',
type: 'text'
}, {
name: 'status',
type: 'text'
}]
}];
$scope.fields = [];
function structuredObj(obj) {
for (var i in obj) {
if (obj[i].type == 'text') {
$scope.fields.push(obj[i]);
} else {
structuredObj(obj[i])
}
}
};
structuredObj(inputs);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<form name="myForm" novalidate>
<div ng-repeat="item in fields" class="form-group">
<input
name="item.name"
type="{{ item.type }}"
placeholder="{{ item.name }}"
ng-model="item.value"
required />
</div>
<button ng-disabled="myForm.$invalid">Submit</button>
</form>
</div>
<div ng-repeat="(key1, value1) in myPersonObj">
<div ng-repeat="(key, value) in value1">
<label>{{key}}</label>
<input type="text" name="" value="{{value}}">
</div>
</div>
var app = angular.module("test",[]);
app.controller("MainCtrl",function($scope){
$scope.inputs = [
{
"firstname" : "Test"
},{
"lastname" : "Test1"
},{
"Account" : [
{"role" : "Test3"},
{"status" : "Test4"},
]
},
{
"Account1" : [
{"role" : "Test3"},
{"status" : "Test4"},
]
},
{
"Account2" : [
{"role" : {
'dim3': {
'dim4':{
'dim5':'cccc'
}
}
}
},
{"status" : "Test4"},
]
}
];
$scope.person = [];
$scope.myPersonObj = [];
/*console.log($scope.keys(inputs));*/
$scope.checkIndex1 = function(arg, myPersonObj)
{
if (angular.isArray(arg) || angular.isObject(arg)) {
angular.forEach(arg, function (value, key) {
console.log(value);
if(angular.isObject(value) || angular.isArray(value))
{
$scope.checkIndex1(value, myPersonObj);
}
else
{
console.log("pushing");
myPersonObj.push(arg);
}
});
}
else
{
console.log("pushing1");
myPersonObj.push(arg);
}
}
$scope.checkIndex1($scope.inputs, $scope.myPersonObj);
console.log("myPersonObj :"+ JSON.stringify($scope.myPersonObj));
console.log($scope.inputs);
I have a dynamically created data. Based on this I am creating a form. But problem is option is not added to to the select. What is wrong in this.
customerB :
{
rows:3,
columns: 2,
name: 'customerB',
fields:
[
{type: "select", name:"teacher_id", label: "Teacher" , endpoint: "/teachers", required: true, check:[ { id : "1982", name : "Mr Bob"}, { id : "18273", name : "Mrs Katrine"} ]}
],
}
HTML
<div class="rows" ng-repeat="field in customerB">
<div class="columns" ng-repeat="newvalue in field">
<div class="controls" ng-switch="newvalue.type">
<div class="form-group">
<label class="control-label">{{newvalue.label}}</label>
<select class="form-control" ng-switch-when="select" ng-model="hiii" ng-required="newvalue.required" ng-options="item.id as item.name for item in newvalue.check">
</select>
</div>
</div>
</div>
</div>
You got an object which got an array, inside the array you got another array which is not correctly manipulating.
Try understanding the following code snippet:
HTML:
<select name="repeatSelect" id="repeatSelect">
<option ng-repeat="option in data.availableOptions" value="{{option.id}}">{{option.name}}</option>
</select>
JS
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
]
OR follow the link: https://docs.angularjs.org/api/ng/directive/select
This assumption might be wrong but I think in here ng-repeat="field in customerB" you are accessing object property directly without the scope variable. So you need to add whatever the scope variable name in front of the property name.
<div class="rows" ng-repeat="field in obj.customerB">
Other than that code you provided work perfectly.
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.obj = { customerB :
{
rows:3,
columns: 2,
name: 'customerB',
fields:
[
{type: "select", name:"teacher_id", label: "Teacher" , endpoint: "/teachers", required: true, check:[ { id : "1982", name : "Mr Bob"}, { id : "18273", name : "Mrs Katrine"} ]}
],
}}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div class="rows" ng-repeat="field in obj.customerB">
<div class="columns" ng-repeat="newvalue in field">
<div class="controls" ng-switch="newvalue.type">
<div class="form-group"> <label class="control-label">{{newvalue.label}}</label> <select class="form-control" ng-switch-when="select" ng-model="hiii" ng-required="newvalue.required" ng-options="item.id as item.name for item in newvalue.check"></select> </div>
</div>
</div>
</div>
</div>
I am trying to generate a HTML form with angularjs ngRepeat. I load a JSON file that contains the fields of desired form and save this object in my $scope. I have a ngRepeat element that generates form inputs based on the JSON object.
The problem is when I print $scope.<myFormName> it just have one field name "{{header.name}}" as I expect some fields based on my JSON model.
Actually I see the form generated in HTML properly but the same thing does not happen in angular scope.
angular.module("myApp",[])
.controller("myCtrl",["$scope",function($scope){
// In this funtion I Set fields of form and make my model empty
$scope.getHeaders = function () {
console.info('getHeaders');
$scope.headersForCreation = [
{
name: 'givenName',
type: 'string',
caption: "nameAndFamily"
},
{
name: 'userName',
type: 'string',
caption: "userName"
},
{
name: 'password',
type: 'password',
caption: "password"
},
{
name: 'passwordConfirm',
type: 'password',
caption: "passwordConfirm"
},
{
name: 'mail',
type: 'string',
caption: "email"
},
{
name: 'mobile',
type: 'string',
caption: "mobile",
regex: '0[1-9][0-9]{9}'
}
];
$scope.userInputsInCreation = {};
angular.forEach($scope.headersForCreation, function (headerItem, key) {
$scope.userInputsInCreation[headerItem.name] = '';
});
}; // end of get header
$scope.getHeaders();
console.log($scope.createForm)
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl" id="add-container-access" ng->
<form class="form-horizontal" name="createForm" init="getHeaders()">
<div class="form-group" ng-repeat="header in headersForCreation" >
<label for="id-{{header.name}}" class="col-sm-4 control-label">
{{header.caption}}: </label>
<div class="col-sm-8"
ng-class="{'has-error': createForm.{{header.name}}.$error.$invalid }">
<input type="header.type" class="form-control"
name="{{header.name}}" ng-required="{{header.notNull}}"
id="id-{{header.name}}"
ng-model="userInputsInCreation[header.name]" >
</div>
</div>
<div class="form-group">
<div class="col-sm-2">
<button class="btn btn-default" >
ADD
<i class="glyphicon glyphicon-plus-sign"></i>
</button>
</div>
</div>
</form>
</div>
Because your controller initialized before AngularJS form directive.
angular.module("myApp",[])
.controller("myCtrl",["$scope","$timeout",function($scope, $timeout){
// In this funtion I Set fields of form and make my model empty
$scope.getHeaders = function () {
console.info('getHeaders');
$scope.headersForCreation = [
{
name: 'givenName',
type: 'string',
caption: "nameAndFamily"
},
{
name: 'userName',
type: 'string',
caption: "userName"
},
{
name: 'password',
type: 'password',
caption: "password"
},
{
name: 'passwordConfirm',
type: 'password',
caption: "passwordConfirm"
},
{
name: 'mail',
type: 'string',
caption: "email"
},
{
name: 'mobile',
type: 'string',
caption: "mobile",
regex: '0[1-9][0-9]{9}'
}
];
$scope.userInputsInCreation = {};
angular.forEach($scope.headersForCreation, function (headerItem, key) {
$scope.userInputsInCreation[headerItem.name] = '';
});
}; // end of get header
$scope.getHeaders();
$timeout(function(){ console.log($scope.createForm); });
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl" id="add-container-access" ng->
<form class="form-horizontal" name="createForm" init="getHeaders()">
<div class="form-group" ng-repeat="header in headersForCreation" >
<label for="id-{{header.name}}" class="col-sm-4 control-label">
{{header.caption}}: </label>
<div class="col-sm-8"
ng-class="{'has-error': createForm.{{header.name}}.$error.$invalid }">
<input type="header.type" class="form-control"
name="{{header.name}}" ng-required="{{header.notNull}}"
id="id-{{header.name}}"
ng-model="userInputsInCreation[header.name]" >
</div>
</div>
<div class="form-group">
<div class="col-sm-2">
<button class="btn btn-default" >
ADD
<i class="glyphicon glyphicon-plus-sign"></i>
</button>
</div>
</div>
</form>
</div>
I have a label that has class value based on 3 different conditions.
status = true => domain available
status =false=> domain not available
click => domain is selected
but when click on it, class should change to 'check-yes1'. How can i make it to change cssClass when clicked?
<div ng-repeat="(key,value) in newReg.checkedDomains | groupBy: 'domain'">
<label class="checkbox-inline" ng-class="{'check-yes' : ext.status==true}" ng-repeat="ext in value">
<input type="checkbox">
</label>
</div>
i even tried something like
<label class="checkbox-inline" ng-click="updateSelectStatus(ext.status,true)" ng-class="updateSelectStatus(ext.status,false)" ng-repeat="ext in value">
<input type="checkbox">
</label>
$scope.updateSelectStatus = function (status, selected) {
if (selected) {
return 'checked';
}
return status == 'true' ? 'check-yes' : '';
}
sorry to confuse with the mess :)
Full example:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<style>
.check-yes {
background-color: green;
}
.available {
background-color: yellow;
}
.not-available {
background-color: red;
}
</style>
</head>
<body ng-app="plunker">
<div ng-controller="MainCtrl">
<div ng-repeat="(key,value) in newReg.checkedDomains">
<label class="checkbox-inline"
ng-class="{'check-yes': ext.available && ext.status,
'available': ext.available && !ext.status,
'not-available': !ext.available}"
ng-repeat="ext in value">
{{ext.name}} <input type="checkbox" ng-model="ext.status" ng-disabled="!ext.available">
</label>
</div>
</div>
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.newReg = {checkedDomains:
[
[{
status: true,
available: true,
name: 'com'
},{
status: false,
available: false,
name: 'org'
}],
[{
status: false,
available: true,
name: 'net'
},{
status: false,
available: true,
name: 'biz'
}]
]
};
}]);
</script>
</body>
</html>
Instead of binding to a function, use model.
<label class="checkbox-inline" ng-class="{'check-yes' : ext.status}" ng-repeat="ext in value">
<input type="checkbox" ng-model='ext.status'/>
</label>