form validation using angularjs - javascript

I have a form
<form name="formName">
<table>
<tr>
<td><input type="text" ng-model="validate" required/></td>
</tr>
</table>
</form>
<button type="button" class="btn btn-default" ng-click="validate()">save</button>
as you can see, the button is outside the form.. I want to validate the form when I click the button into $scope.validate();
the question is, how can I achieve that using angularjs ?

It does not matter if button is in or outside the form, the validation is performed always when any of the proprties of the model changes. So the only problem that remains is when to display error message.
btw required is from HTML5 ng-required is the attribute you should use.
The code below displays error message when any of the properties changes
<div ng-app="mod">
<div ng-controller='MCtrl'>
<form name="formName" novalidate>
<table>
<tr>
<td>
<input type="text" name="prop" ng-model="model.property" ng-required="true" />
<span ng-show="formName.prop.$error.required">Required</span>
</td>
</tr>
</table>
</form>
<button type="button" class="btn btn-default" ng-click="validate(formName)">save</button>
</div>
mod.controller('MCtrl', function ($scope) {
$scope.model = { property : ''};
$scope.validate = function(form){
alert(form.$valid);
}
});
If youd like to display the errors only when the form is submitted you add one variable to track it like it the code below (note additional variable in ng-show="formName.prop.$error.required && submitted"
<div ng-app="mod">
<div ng-controller='MCtrl'>
<form name="formName" novalidate>
<table>
<tr>
<td>
<input type="text" name="prop" ng-model="model.property" ng-required="true" />
<span ng-show="formName.prop.$error.required && submitted">Required</span>
</td>
</tr>
</table>
</form>
<button type="button" class="btn btn-default" ng-click="validate(formName)">save</button>
</div>
mod.controller('MCtrl', function ($scope) {
$scope.model = { property : ''};
$scope.submitted = false;
$scope.validate = function(form){
$scope.submitted = true;
alert(form.$valid);
}
});

Related

Hide form after submit JQuery

I have a html form inside the table and i want to make it disappear after the user submits the form
Form:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<td colspan="3">
<h6>Have Discount Coupon? Apply it here...</h6>
</td>
<td>
<div id="form">
<form class="coupon" method="post">
<input type="text" name="coupon" placeholder="Enter Coupon Code" autocomplete="off">
<input type="submit" name="coupon" value="Apply Coupon">
</form>
</div>
</td>
</tr>
<script type="text/Javascript">
$('#form').submit(function() {
$(this).hide();
});
</script>
After the submission, the form is still visible and nothing happening.
The problem is the selector:
$('#form')
The <form> element does not have the attribute id="form" — (that's the <div id="form"> - not a form and therefore not submittable) — all you need to do is target the actual <form> element. Change your code to this:
$('form').submit(function(e) { //NOTE: Removed "#"
e.preventDefault();
$(this).hide();
})
And it will work:
$('form').submit(function() {
$(this).hide();
})
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<tr>
<td colspan="3">
<h6>Have Discount Coupon? Apply it here...</h6>
</td>
<td>
<div id="form">
<form class="coupon" method="post">
<input type="text" name="coupon" placeholder="Enter Coupon Code" autocomplete="off">
<input type="submit" name="coupon" value="Apply Coupon">
</form>
</div>
</td>
</tr>
You have to prevent the default action first in order to hide the form using event.preventDefault()
Further if you're working on a commercial level and you want your form to be submitted without redirection, then you can use XHR request
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<td colspan="3">
<h6>Have Discount Coupon? Apply it here...</h6>
</td>
<td>
<div id="form">
<form class="coupon" method="post">
<input type="text" name="coupon" placeholder="Enter Coupon Code" autocomplete="off">
<input type="submit" name="coupon" value="Apply Coupon">
</form>
</div>
</td>
</tr>
<script type="text/Javascript">
$('#form').submit(function(event) {
event.preventDefault();
// ... XHR request to submit form
$(this).hide();
});
</script>
There is a Problem in the approach that You use.Each time you run click the submit button in the page your page gets reloaded **this will hide the form when you click and again render the whole page from the begining. because of that you want be able to get what you want.Instead try to send data using Ajax by having a button rather than using the default form submission approach

html javascript chage the value of my <div> but refresh the page for 1 second and then is all null

I am try to display under my form the new value.
<form>
<h2>AES Encryption</h2>
<table>
<tr>
<td>
<label for="inputValue">Text to encrypt</label>
</td>
<td>
<input type="text" id="inputValue" size="50" name="inputValue" />
</td>
</tr>
<tr>
<td>
<label for="inputPassword">Password:</label>
</td>
<td>
<input type="text" id="inputPassword" size="50" name="inputPassword" />
</td>
</tr>
<tr>
<td>
<input type="submit" value="Verschlüsseln" id="submitButton" onclick="encryptAES()"/>
</td>
</tr>
</table>
<div id="afterPressed" hidden="true">
<h3 id="resultTitle"></h3>
<p id="result"></p>
<br>
<h3>Code</h3>
Download
</div>
</form>
and my Script:
function encryptAES() {
var value = document.getElementById("inputValue").value;
var password = document.getElementById("inputPassword").value;
var encrypted = base64toHEX(CryptoJS.AES.encrypt(value, password));
document.getElementById("afterPressed").removeAttribute("hidden");
document.getElementById("resultTitle").innerHTML = "Result";
document.getElementById("result").innerHTML = encrypted;
}
When I click the button the code works for 1 second and then refresh the form as null
I want to show the result in the div result tag, but the page is updated and everything disappears and the code is hidden again.
Your form is submitting, so the values are displayed in the browser and then the page reloads.
You can either set the onsubmit property of the form like this:
<form onsubmit="return false;">
Or you can use an <input type="button"> or <button> instead of the <input type="submit"> that is... well, submitting the form.
Update your form tag with <form onsubmit="return false;">. This will prevent the page from getting submitted.

How to submit Multiple Form data with ng-model on single submit

Hi I want to post all form data with same model name. that is my code in this i also clone tr tag to create more form with same name classes & Model .
<tr class="row_1">
<form name="myForm1" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
</form>
</tr>
<tr class="row_1">
<form name="myForm2" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
</form>
</tr>
<tr class="row_1">
<form name="myForm3" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
</form>
</tr>
</tbody>
</table>
<!-- </form> -->
<button class="btn btn-primary" ng-click="saveJob(job)" id="save_exit">Save & Exit</button>
<button class="btn btn-warning" onclick="cloneRow()" id="add_job">Add Row</button>
angular Code Like That
$scope.saveJob = function(data) {
console.log(data);
//http request goes here
}
EDIT: This structure is not good. I think you are trying to create a lot of rows and select table DOM and datas. It is not an angular way!
How to do that with angular way
You need to define an array in your controller.
$scope.jobList = [];
You need to define a push method. Your save method work with jobList array.
$scope.addEmptyJob() = function(){
var newJob = {};
$scope.jobList.push(newJob);
}
You need to define a repeating td and one submit button.
<form name="myForm_{{$index}}" class="sub_job">
<tr class="row_1" ng-repeat="job in jobList">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
<td>
<button class="btn btn-warning" ng-click="addEmptyJob()" id="add_job">Add New Row</button>
</td>
</tr>
<button type="submit" class="btn btn-primary" ng-click="saveJob(job)" id="save_exit">Save & Exit</button>
</form>
OLD ANSWER for single save.
You need to define every form with a button. And every form have to be unique. So you can use $index for unique. End you need to add type="submit" to buttons for form control.
<tr class="row_1" ng-repeat="job in myArray track by $index">
<form name="myForm_{{$index}}" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
<td>
<button type="submit" class="btn btn-primary" ng-click="saveJob(job)" id="save_exit">Save & Exit</button>
<button type="submit" class="btn btn-warning" onclick="cloneRow()" id="add_job">Add Row</button>
</td>
</form>
</tr>
You can achieve this thing with array and ng-repeat rather than cloning html element.
HTML
<table><tbody>
<tr class="row_1" ng-repeat="job in jobs track by $index">
<form name="myForm" class="sub_job">
<td><input type="text" name="quantity[]" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity[]" ng-model="job.quality"/></td>
</form>
</tr>
</tbody></table>
<button class="btn btn-primary" ng-click="save()" id="save_exit">Save & Exit</button>
<button class="btn btn-warning" ng-click="clone()" id="add_job">Add Row</button>
Angular Controller
// You can fetch this array of jobs from server for showing purpose
$scope.jobs = [
{
quantity: "1.0" ,
quality: "A"
},
{
quantity: "2.0" ,
quality: "B"
}
]
$scope.clone = function(){
// You can change default values for new job to appear
var empty = {
quantity: "" ,
quality: ""
};
$scope.jobs.push(empty);
}
$scope.save = function(){
// You can send this array of jobs to server for saving purpose
console.log($scope.jobs);
}
You can't have a single model for multiple input elements, because if you change value in either of the input boxes, it will overwrite it with the latest value. Assuming you start filling the form, from form1 to form3, and do a submit, the model will hold value entered in the last used input box, i.e form3.
To solve your problem you need to use a collection, array or object (preferably array) as your model.
Your controller would be something like:
var JobModel = function() {
return {
jobs: [],
addRow: function() {
var model = {
quantity: "",
quality: "",
};
this.jobs.push(model);
},
save: function() {
console.log(this.jobs);
},
submit: function(){
for(var i=0;i<this.jobs.length;i++){
doSomeHTTPRequest(this.jobs[i]);
}
}
};
};
$scope.jobModel = new JobModel();
Your HTML will be somthing like:
<button ng-click="jobModel.addRow()">
Add Job
</button>
<div ng-repeat="job in jobModel.jobs">
<input type="text" ng-model="job.quantity" placeholder="Quantity">
<input type="text" ng-model="job.quality" placeholder="Quality">
</div>
<button ng-click="jobModel.save()">
Save Jobs
</button>
To submit your form with same name you would need to iterate over the jobs array and make ajax calls for each

Populate dropdown value inside ng-repeat

I am facing an issue with my Angular code, while populating the dropdown inside a HTML table (Code given below).
Could you please help me with what should be done inside modify() to populate the dropdown ?
HTML Code:
<table class="table" ng-app="empApp" ng-controller="employeeController">
<thead>
<tr class="info">
<th>Emp Name</th>
<th>Status</th>
<th colspan="2"> </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="emp in employees">
<td>
<div ng-hide="editingData[emp.id]">{{ emp.name }}</div>
<div ng-show="editingData[emp.id]"><input type="text" ng-model="emp.name" /></div>
</div>
</td>
<td>
<div ng-hide="editingData[emp.id]">{{ emp.status.name }}</div>
<select ng-show="editingData[emp.id]" class="form-control" ng-model="emp.status"
ng-options="status.id as status.name for status in statuses"></select>
</td>
<td colspan="2">
<div class="btn-group">
<button type="submit" class="btn btn-primary" ng-hide="editingData[employee.id]" ng-click="modify(emp)">Modify</button>
<button type="submit" class="btn btn-primary" ng-show="editingData[employee.id]" ng-click="update(emp)">Update</button>
</div>
</td>
</tr>
</tbody>
</table>
Javascript Code:
var empApp = angular.module("empApp", []);
empApp.controller('employeeController', function($scope, $http) {
$scope.statuses = [{"id":1,"name":"Active"}, {"id":1,"name":"Inactive"}];
$scope.employees = [{"id":1,"name":"Mark","status":{"id":1,"name":"Active"}},{"id":2,"name":"Sara","status":{"id":2,"name":"Inactive"}}];
$scope.editingData = {};
for (var i = 0, length = $scope.employees.length; i < length; i++) {
$scope.editingData[$scope.employees[i].id] = false;
}
$scope.modify = function(employee){
$scope.editingData[employee.id] = true;
//Set Employee Status correctly here to populate the dropdown
};
});
My problem is I am NOT able to populate the dropdown with the existing value, as show in the diagram below:
I made this plunker, check if it's what you need.
1: Both status are with id 1. Change them
From:
$scope.statuses = [{"id":1,"name":"Active"}, {"id":1,"name":"Inactive"}];
To:
$scope.statuses = [{"id":1,"name":"Active"}, {"id":2,"name":"Inactive"}];
2:Change your select ng-model to emp.status.id.
From:
<select ng-show="editingData[emp.id]" class="form-control" ng-model="emp.status"
ng-options="status.id as status.name for status in statuses"></select>
To:
<select ng-show="editingData[emp.id]" class="form-control" ng-model="emp.status.id"
ng-options="status.id as status.name for status in statuses"></select>
3: Change your buttons ng-hide/ng-show
From:
<div class="btn-group">
<button type="submit" class="btn btn-primary" ng-hide="editingData[employee.id]" ng-click="modify(emp)">Modify</button>
<button type="submit" class="btn btn-primary" ng-show="editingData[employee.id]" ng-click="update(emp)">Update</button>
</div>
To:
<div class="btn-group">
<button type="submit" class="btn btn-primary" ng-hide="editingData[emp.id]" ng-click="modify(emp)">Modify</button>
<button type="submit" class="btn btn-primary" ng-show="editingData[emp.id]" ng-click="update(emp)">Update</button>
</div>
Update:
As #Rajesh said below you can store the status_id instead of entire status object. Check his fiddle.
Just replace your select tag part with this code
<select ng-show="editingData[emp.id]" class="form-control" ng-model="emp.status"
ng-options="status as status.name for status in statuses track by status.id"></select>
This is because in ng-model you are passing the full object and you need the full object to be tracked by ID in order to fill the dropdown and relevant dropdown value to be selected
Also in your buttons:
<div class="btn-group">
<button type="submit" class="btn btn-primary" ng-hide="editingData[emp.id]" ng-click="modify(emp)">Modify</button>
<button type="submit" class="btn btn-primary" ng-show="editingData[emp.id]" ng-click="update(emp)">Update</button>
</div>
Because you are referencing it by 'emp' and not 'employee' inside ng-repeat as it will be dynamic
You are looping through
<tr ng-repeat="emp in employees">
But in the select list, you are toggling based on:
editingData[employee.id]
Try changing that to
editingData[emp.id]
use emp.id in your button and also in your modify function and loop
use $scope.employees[i].isVisible = false and ng-hide = $scope.employees.isVisible ng-show = $scope.employees.isVisible

How to search in AngularJS after typing 4 chars in input

I have a MySQL database and I search in it using AngularJS. How to search only if I print 4 or more chars in this input?
HTML code:
<div class="search">
<form action="" method="post" class="searchform" >
<input type="search" name="" placeholder="Search" class="inputsearchform" ng-model="search"/>
<input type="submit" name="" value="" class="submitsearchform" />
</form>
</div>
<div class="songlist" >
<table id="songlistTableR" ng-controller='main_control'>
<tr><th>Name</th><th>Link</th></tr>
<tr class="rowR" ng-repeat="data in loaded | filter:{song_name: search}">
<td><i class="fa fa-plus"></i>{{data.song_name}}</td>
<td><a href="{{data.link}}" target='_blank'>Youtube</a></td>
</tr>
</table>
</div>
JS code:
var app = angular.module('test_table', []);
app.controller('main_control',function($scope, $http){
load();
function load(){
$http.get("http://localhost:7001/load").success(function(data){
$scope.loaded=data;
});
}
});
I'm sure this is a duplicate question, but the solution is to just add the ng-minlength attribute. Used as this:
<input type="search" name="" placeholder="Search" class="inputsearchform" ng-model="search" ng-minlength="4"/>
That should accomplish what you are wanting.

Categories

Resources