I have a text area field where it inputs 4 types of personal details separated by commas. I need to validate each of those 4 values using regular expression. This is my approach but it is not much of the angular way to do the validations.
var form = angular.module('form', []);
form.controller('helloController', ['$scope', function($scope){
var submitted = false;
var validNumber = new RegExp('numberRegExp');
var validArea = new RegExp('areaRegExp');
var validCity = new RegExp('cityRegExp');
$scope.submit = function(hello){
$scope.number = false;
$scope.area = false;
$scope.city = false;
if (issue){
$scope.submitted = true;
var splittedDetails = hello.details.split(",");
var trimmedDetails = $.map(splittedDetails, $.trim);
if (!validNumber.test(trimmedDetails[0])) {
$scope.inputversion.jiraIssue.$invalid = true;
$scope.number = true;
}else if (!validArea.test(trimmedDetails[1])) {
$scope.inputversion.jiraIssue.$invalid = true;
$scope.area = true;
}else if (!validCity.test(trimmedDetails[2])) {
$scope.inputversion.jiraIssue.$invalid = true;
$scope.city = true;
}else{
alert("Form now submitting");
}
}
};
}]);
<form class="form-horizontal" name="helloForm" ng-controller="helloController" ng-submit="submit(hello)" novalidate ng-app="form">
<div class="form-group" ng-class="{ true:'has-error'}[submitted && helloForm.personal-details.$invalid]">
<label for="helloForm" class="col-sm-2 control-label">Details</label>
<div class="col-sm-10">
<textarea class="form-control" rows="5" ng-model="hello.details" placeholder="number, area, city, details ex: 90********, XYX, XYZ" name="personal-details" required></textarea>
<p ng-show="submitted && helloForm.personal-details.$error.required" class="help-block"> Details are required.</p>
<p ng-show="submitted && number" class="help-block">Please check the format of issue number</p>
<p ng-show="submitted && area" class="help-block">Please check the format of product area</p>
<p ng-show="submitted && city" class="help-block">Please check the format of priority</p>
</div>
</div>
</form>
This approach can validate only one detail at a time. But ideally it should validate dynamically in much of the angular way. Please suggest your ideas.
Thanks
No offense, but this seems like a really bad way to validate 3 bits of expected data. Comma delimiting will only work if and only if the user puts 2 and only 2 commas into the field.
Assuming you want persisted data from the form (transfers from one page to another) you will want a Model for this module. The best way to do this is via the .service (since there is only one instance of each named service in a module in Angular). I'll also be using the format that will actually work with minified code and best practices, careof John Papa.
It also assumes you have declared the module elsewhere (declare uses brackets [] while recall does not).
angular.module('form')
.service("DataService", DataService)
DataService.$inject = ["$rootScope"];
function DataService($rootScope) {
var vm = this; //security in declaring (root)scope objects
vm.phone = {value: '', placeholder: 'Enter your phone number'};
vm.area = '';
vm.city = '';
};
Your controller would have little in it aside from the use of the $scope/$rootScope variables (with 2-way binding to fields and the Model) and your submit function for when the user tries to submit.
angular.module('form')
.controller('FormController', FormController);
FormController.$inject = ['$scope', 'DataService'];
function FormController($scope, DataService) {
var vm = this;
vm.phone = DataService.phone;
vm.area = DataService.area;
vm.city= DataService.city;
function submit() {
//persist the data to the next page/controller/etc.
DataService.number = vm.number;
DataService.area = vm.area;
DataService.city = vm.city;
//do work here
};
You can do all of your validation within your HTML, using Angular's 2-way binding of data. Assuming you're also using BootStrap, each field should look similar to the below:
<!-- phone field (required/validated) -->
<div class="row form-group" ng-class="{'has-warning': helloForm.phone.$invalid && helloForm.phone.$dirty,'has-error': helloForm.phone.$error.required && helloForm.phone.$touched}">
<label for="phone" class="col-md-3 control-label">Phone:</label>
<div class="col-md-9">
<input type="text" id="phone" name="phone" ng-model="vm.phone.value" placeholder="{{vm.phone.placeHolder}}" value="{{vm.phone.value}}" ng-required="true"class="skinny form-control" ng-pattern="/^\+?[-0-9)(]{8,31}[0-9x]{0,6}$/i" />
<p class="required" ng-show="helloForm.phone.$invalid || helloForm.phone.$error.required">*</p>
<p class="good" ng-show="helloForm.phone.$valid">✔</p>
</div>
<p class="help-block" ng-show="helloForm.phone.$error.pattern && helloForm.phone.$dirty">Phone format: +15558675309x52 or (555)867-5309x52</p>
<p class="help-block" ng-show="helloForm.phone.$error.required && helloForm.phone.$touched">Phone is a required field</p>
</div><br />
Rather than my E.164 (for international numbers) and American Standard phone combination validation (regex inside the ng-pattern field), you can use curly braces to declare your variable regex comparable. I hope this helps or at least points you in the right direction.
Thanks for reading,
C§
Related
i try to make simple CRUD with angularjs and php api
the problem is in angularjs
i have code like this :
$scope.editData = function(pid) {
$scope.hideform = false;
$scope.edit = false;
$scope.pid = $scope.projects[pid].pid;
$scope.title = $scope.projects[pid].title;
$scope.pcode = $scope.projects[pid].pcode;
$scope.type = $scope.projects[pid].type;
$scope.proj_type = $scope.projects[pid].proj_type;
};
$scope.saveData = function(pid, title, pcode, type2, proj_type){
$http.post("api/getProject.php",
{type: "edit", id:pid, title:title, pcode:pcode, type2:type2, proj_type:proj_type})
.success(function(data) {
notification(data.success, data.message);
$scope.hideform = true;
});
};
and have form for editing data (edit button clicked , then show form edit with ng-model loaded on it
like this
<form class="form-horizontal" ng-hide="hideform" ng-submit="saveData(pid,title, pcode, type, proj_type)">
<h3 ng-hide="edit">Edit Project:</h3>
<div class="form-group">
<label class="col-sm-2 control-label">PID:</label>
<div class="col-sm-10">
<input type="text" ng-model="pid" ng-disabled="!edit" placeholder="PID">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Title:</label>
<div class="col-sm-10">
<input type="text" ng-model="title" placeholder="Title">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Pcode:</label>
<div class="col-sm-10">
<input type="text" ng-model="pcode" placeholder="Pcode">
</div>
</div>
<button class="btn btn-success" ng-disabled="error || incomplete">
<span class="glyphicon glyphicon-save"></span> Save Changes
</button>
</form>
the script are working , but everytime i click save editing then click edit button (on each row on table) , the ng-model on form input still same like the last data what i save but other input are changed , ex : i edited title , when click edit button on different row on the table , just pcode changed to different row data , the Title still same like the last data i edit
sorry if my explanation make all of you confuse
Any help will be appreciated
here is the image if my explanation not clear
This problem resolved using
$scope.selectedProject = $scope.projects[pid];
so editData function look like this
$scope.editData = function(pid) {
$scope.hideform = false;
$scope.edit = false;
$scope.pid = $scope.projects[pid].pid;
$scope.title = $scope.projects[pid].title;
$scope.pcode = $scope.projects[pid].pcode;
$scope.type = $scope.projects[pid].type;
$scope.proj_type = $scope.projects[pid].proj_type;
$scope.selectedProject = $scope.projects[pid];
};
and ng-model (on every input)
need to change like this
<input type="text" ng-model="selectedProject.pid" ng-disabled="!edit" placeholder="PID">
instead of this
<input type="text" ng-model="pid" ng-disabled="!edit" placeholder="PID">
Now every ng-model changed every edit button has been click after save Changes button clicked :)
Thank you!
Second time I open this thread; had many answers on the last, but nobody gave an actual answer. My code is still not working and I'm beginning to think something very stupid is happening, or Angular is just not working properly.
This is my DOM, which I add through a directive:
<form ng-controller="controlFormulario as formCtrl">
<div style="width:50%; margin-left: 160px; margin-top: 2%">
<div class="form-group">
<label for="inputTitulo">Título</label>
<input type="titulo" class="form-control" id="inputTitulo" ng-model="formCtrl.formulario.titulo">
</div>
<div class="form-group">
<label for="inputTexto">Texto</label>
<textarea class="form-control" id="inputTexto" ng-model="formCtrl.formulario.texto"></textarea>
</div>
<div class="form-group">
<label for="fecha">Fecha</label>
<input type="fecha" class="form-control" id="fecha" ng-model="formCtrl.formulario.fecha" disabled>
</div>
<div class="form-group" >
<button ng-model="isDisabled" class="btn btn-primary" style="height:35px;width:100px;float:right;" ng-init="formCtrl.formulario.isDisabled = true" id="submit"
ng-disabled="isDisabled">
Enviar
</button>
</div>
</div>
</form>
And these are the controller and the directive:
var app = angular.module('app', []);
app.controller('controlFormulario', ['$scope', function($scope) {
var cf = this;
cf.formulario = [];
cf.formulario.fecha = new Date();
if(cf.formulario.texto != "" && cf.formulario.titulo != ""){
$scope.isDisabled = false;
} else {
$scope.isDisabled = true;
}
}]);
app.directive('formulario', [function() {
return {
restrict: 'E', // C: class, E: element, M: comments, A: attributes
templateUrl: 'modules/formulario.html',
controller: 'controlFormulario'
};
}]);
The thing I'm trying is pretty... easy? It's just getting the button active when some text is on the text and author inputs. Pretty straightforward, you know. Well, nothing is working.
Tried a normal ng-model binding to a previously written controller variable, like formCtrl.isDisabled. Didn't work.
Tried using the $scope (like now) and binding the ng-disabled attribute to the $scope.isDisabled variable. Didn't work.
Tried using a normal expression to write the "disabled" rule. Not an elegant fix, but it could work... so bad it didn't, either.
I'm getting a little frustrated to not being able to do such easy thing, so I guess I need some of your help to find out where I'm failing!
Well, you initialize $scope.isDisabled once, when the controller is instantiated, and never change it after. So, naturally, it keeps the same value forever.
Change
ng-disabled="isDisabled"
to
ng-disabled="isDisabled()"
and add the following function to the scope:
$scope.isDisabled = function() {
return cf.formulario.texto == "" || cf.formulario.titulo == "";
}
Also, note that you instantiate the controller twice for each directive instance:
once because the directive has
controller: 'controlFormulario'
and once because the template has
ng-controller="controlFormulario as formCtrl"
You should use one or the other, but not both.
Have you try to use ng-class :
<div ng-class="isDisabled ? 'class to Disabled':''">
I hope it 'll help you.
You can try this if you did not already tested :
For Dom :
<button ng-model="isDisabled" class="btn btn-primary" style="height:35px;width:100px;float:right;" ng-init="formCtrl.formulario.isDisabled = true" id="submit"
ng-disabled="FuncIsDisabled()">
And in controller you can make something like this :
function FuncIsDisabled(){
if(cf.formulario.texto != "" && cf.formulario.titulo != ""){
$scope.isDisabled = false;
} else {
$scope.isDisabled = true;
}
return $scope.isDisabled;// I'm not sure that this row is mandatory with the scope management
}
I have a form that user will have to fill in. Some fields are dates and i don't want user to have to type in today's date.
My Form
<div class="row" ng-controller="JobOrderController as jOrder">
<form class="form-inline" ng-submit>
<div class="form-group">
<label for="todaysDate"><h4><span class='glyphicon glyphicon-flag'></span> Date</h4>Date </label>
<input type="text" class="form-control" id="todaysDate" ng-model="jOrder.orderData.date" value="{{ 2 + 4 }}" >
</div>
......... more code .........
My Controller
angular.module('jobOrderCtrl', ['jobOrderService'])
.controller('JobOrderController', function(Jobs, socketio) {
var vm = this;
vm.createOrders = function() {
vm.message = '';
Jobs.createOrders(vm.orderData)
.success(function(data) {
vm.orderData = '';
vm.message = data.message;
});
};
});
I try out using js to write to that date input field, but is not showing due to angular data binding.
So what i want is the date input value field to be today's date. So how do i go about and do this?
Where do you set the date?
orderData should be an object with the form fields - NOT a string
initialize the orderData:
var vm = this;
vm.orderData = { date : new Date()};
and remove the value property form the html input field. Also set type to date
<input type="date" class="form-control" id="todaysDate" ng-model="jOrder.orderData.date" >
I have a 2 form input (firstName, lastName) and I want to check if they are unique (form validation) by querying my database. So I basically want to have a callback when two of my input elements is inputted.
What is the angular way of doing this?
I'm thinking of getting the element and using .on('blur') while checking if the other input is valid but this feels very jQuery like.
use ng-blur on the inputs.
Here's an example:
HTML:
<div ng-app='myApp' ng-controller='myCtrl'>
Username : <input type='text' ng-model='model.username' ng-blur='checkInputs()' /><br/>
Password: <input type='text' ng-model='model.password' ng-blur='checkInputs()' /> <br/>
</div>
JS:
var app = angular.module('myApp',[]);
app.controller('myCtrl', function($scope){
$scope.model = {username:'', password:''};
$scope.checkInputs = function(){
if($scope.model.username != '' && $scope.model.password != ''){
if($scope.model.username == 'testuser' || $scope.model.password == 'testpass')
{
alert('insert unique fields!!!!')
}
}
}
});
func will sit in your controller in this case and will have access to the username\password. You need to perform an ajax to check this, but I assume you got the point..
Here's a Fiddle.
I'm trying to show some editable results to the users, so I show them through an input field. This is a basic example of what I'm doing:
<div class="form-group">
<label>First number</label>
<input type="text" ng-model="first" ng-required="true" class="form-control">
</div>
<div class="form-group">
<label>Second number</label>
<input type="text" ng-model="second" ng-required="true" class="form-control">
</div>
<div class="form-group">
<label>The sum is: {{first + second }}</label>
<input type="text" ng-model="result" ng-required="true" class="form-control">
</div>
In the result's div, I used a label to test if the result is being obtained correctly, and it is. But if I edit the first or second values, the input's result doesn't update.
This is the controller used (yeah, the form is in a modal):
var ModalInstanceCtrl = function ($scope, $modalInstance) {
$scope.result = $scope.first + $scope.second;
$scope.confirm = function () {
$modalInstance.close(result);
};
$scope.cancelNewBet = function () {
$modalInstance.dismiss('cancel');
};
};
I thought the value was supposed to get automatically updated once I define how it is obtained. But clearly it misses something to change the result through script...
Thanks in advance.
What do you want to happen when the user edits the results input? Do you want the data binding to break (I assume not and ignore this possibility)? Do you want one of the inputs to adjust to the proper value?
If you only want to display the output, do this, in your controller:
$scope.result = function() { return $scope.first + $scope.second; }
And in your view:
{{ result() }}
But if you want the user to be able to edit the result and (let's say) have second be assigned (result - first), then you'd want something like this in your view (by the way, note the type="number"):
<input type="number" ng-change="adjustResult()" ng-model="first">
<input type="number" ng-change="adjustResult()" ng-model="second">
<input type="number" ng-change="adjustInput()" ng-model="result">
And in your controller:
$scope.adjustResult = function() {
$scope.result = $scope.first + $scope.second;
};
$scope.adjustResult(); // initialize result
$scope.adjustInput = function() {
$scope.second = $scope.result - $scope.first;
}