How to submit angular js form using ng-click? - javascript

I want to provide id and date though the html form and then submit these values
to the js controller and execute one of my endpoint with that values (adminId and adminDate). I think something is missing.
// adminForm.html
<form class="form-horizontal" role="form" ng-controller="AdminController">
<input class="form-control" id="adminId" placeholder="adminId" ng-model="formInfo">
<input class="form-control" id="adminDate" placeholder="adminDate" ng-model="formInfo">
<button type="submit" ng-click="adminUpload()" class="btn btn-success">AdminUpload</button>
</form>
// AdminController.js
define([], function() {
function AdminController($scope, $http) {
$scope.adminUpload = function() {
$http.get('/app/endpoint/$scope.adminId/$scope.adminDate').success(
function () {
alert("Something went wrong!");
}
).error(
function () {
alert("Everything fine!");
}
);
};
}
AdminController.$inject = ['$scope', '$http'];
return AdminController;
}
);

There are a few errors in your code, the template, and the controller. I'll list them one by one to explain and provide one example,
The live example
https://plnkr.co/edit/G3f6X0mUVwQ4Nxj2
The Explanation
In Template:
Your ng-model in both inputs are referencing the same model. You should make reference to different elements (or different attributes of the same element). So, I used other elements for the sake of the example.
Your button is type=submit. It's a problem because the submit default behavior is POST the form information (and load the form's action). So, I redefined the button just as a button.
In Controller:
You're not interpolating the string on the request of the URL. You're always fetching '/app/endpoint/$scope.adminId/$scope.adminDate'. You should be fetching '/app/endpoint/(value of $scope.adminId)/( value of $scope.adminDate)'.So I used a template literal (The strings with the back quote symbol)and concatenate the strings with the variable values.
You were using success/error functions in the inverse order. Your success says "Something went wrong!" and your error says "Everything fine!"
Based on AngularJS documentation (https://docs.angularjs.org/api/ng/service/$http), there are no success/error functions after $http.get, so even when they were so used and they were part of AngularJS maybe they aren't in your version. So, my recommendation would be to use the recommendation function which is then(successCallback, errorCallback)
After all this explanation the code would be
template
<form class="form-horizontal" role="form">
<input
class="form-control"
id="adminId"
placeholder="adminId"
ng-model="adminId"
/>
<input
class="form-control"
id="adminDate"
placeholder="adminDate"
ng-model="adminDate"
/>
<button type="button" ng-click="adminUpload()" class="btn btn-success">
AdminUpload
</button>
</form>
controller
$scope.adminUpload = function () {
const url = `/app/endpoint/${$scope.adminId}/${$scope.adminDate}`;
alert(url);
$http
.get(url)
.then(function () {
alert('Everything fine!');
}, function () {
alert('Something went wrong!');
});
};

Related

Sending request with angular - empty elements in request

I'm sending POST request with angular with submitted form.
I have optionals input fields and when I type something there and delete it then in my request I have this field containing "".
Is that how it should be?
Thats how my form look:
<label class="col-md-2 col-xs-2 my-label" for="contactFirstName">Imię</label>
<div class="col-md-3 col-xs-3">
<input type="text" class="form-control" id="contactFirstName" name="contactFirstName"
placeholder="Imię"
ng-model="loan.newLoan.contactPerson.firstName" >
</div>
And thats how I'm sending the request:
function create() {
return RequestFactory.save({id1:'loans', id2:'create'},vm.newLoan,
function () {
MessageFactory.setSuccess({show:true, msg:'success'});
$state.reload('loan.new');
}, function(response){
vm.isError = true;
ErrorFactory.errorHandler(vm.errorMessages, response);
});
}
And when sending, in my request json with this field looks like this:
{"firstName":""}
Is that ok? Or there should't be this field in the request if its empty?
What should I do with this?
Is that ok?
Yes or not, depends of what your backend service is expecting.
You can remove the empty fields in Angular by doing something like
function create() {
var data = {};
if (vm.newLoan.contactPerson.firstName) {
data.firstName = vm.newLoan.contactPerson.firstName;
}
RequestFactory.save({ id1: 'loans', id2: 'create' }, data, ...);
}
And you should do a supplementary check in your backend service to remove the empty fields if you don't want to save it. Never trust the data sent from a client, even if you validate the data in JavaScript. Always do an extra check in the server code.
Hence your html input field is not required, it is perfectly fine.Hope your backed service also an optional field.If it's a required field then you have to check as shown below when you press the Save button.
This is just an example:
Html
<button type="submit" class="btn btn-primary blue" ng-
click="vm.save(yourFormName.$valid)"> Save</button>
JS
//to save
vm.save = function (isValid) {
if (isValid) {
//fires save method here
}
};

How to validate empty text box for mandatory field in button click in angular js

Can anybody tell How to validate empty text box for mandatory field in button click in angular js after validate i need to call web service call .Can anybody tell how to implement?
Use this:
<form name="yourForm">
<input name="name" ng-model="model.name" type="text" required />
<div ng-messages="yourForm.name.$error">
<div ng-message="required">Name is required!</div>
</div>
<button ng-click="send()">Send</button>
</form>
And in controller js:
$scope.send = function () {
if ($scope.yourForm.$valid) {
// TODO: send model to server
}
}
Don't forget:
Include Angular ngMessages module in your app.
Good luck
You can use 'required' attribute to make sure they enter a value in the field
<input type="text" name="userName" ng-model="user.name" required>
For the service call you can have a javascript method onClick , for example:
<button type="button" class="button" name="Search" id="searchButton" ng-click="getUserInfo()">Search</button>
then you do an ajax call in the Angular module
$scope.getUserInfo = function()
{
if ($scope.fetchData)
{
var data = {
func: "USERINFO",
searchUserId: $('#searchUserId').val()
};
$http({method:'POST',
url:'/MYAPP/getuser',
data: $.param(data),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
.success(function(data, status, header, config) {
$scope.users = data;
})
.error(function(data,status, headers, config) {
alert('Error getting user infos ');
})
}
}
This is a quick example. the /MYAPP/getuser maps to a REST service that returns the data in JSON format. The success(function) is what gets executed when the call is executed successfully and the data is returned. You can bind the returned data to an angular table or control for display.
.error is executed if the call fails
As for the REST services, You can write it in JAVA or C# or whatever language you like, as long as it returns JSON.

How do I reset a form in angularjs?

See Fiddle: http://jsfiddle.net/hejado/7bqjqc2w/
I'm trying to form.reset() my form using angular.
HTML:
<div ng-controller="formCtrl">
<form name="resetme" id="resetme">
<input ng-model="text" type="text" />
<input file-model="file" type="file" />
<button type="button" ng-click="resetForm()">reset</button>
</form>
</div>
JS:
.controller('formCtrl', function($scope) {
$scope.resetForm = function() {
//$scope.resetme.reset();
document.getElementById('resetme').reset();
};
});
Please note: I'm using this kind of form to ajax-upload a file. The page is not refreshing and I don't want to use any reset-buttons. (I'm using one in the fiddle for simplicity.) I want to call the reset-function after the fileupload is finished (via http success).
I'm using
<input type="file" />
so I can't reassign empty values to all my inputs, because file inputs are readonly.
Calling the reset() function on the DOM element works, but I was told talking to the DOM in angular would be evil, so...
I'd like to know, how this would be done the angular way. I tried naming the form and referencing it via $scope.formname but I'm not able to call Web API functions... (commented line)
How can I achieve this?
UPDATE
After reading some of the answers, I should make clear, that I am using ngModel and a custom directive fileModel to get a hold of the file-object.
Some of the solutions worked in resetting the value of the input field, but the model is not cleared (neither file, nor text). Custom directives are the answer to that, but this kinda exceeds the scope of this question.
I wrote about this topic a couple years ago. I don't know if the Angular team has yet implemented a native form reset directive but you can do so yourself. There are a couple caveats to this implementation: it only works for one model (if you need to support more see the followup post) and the issue of when to initialize the original values. Also, I never tested this with file inputs so I am not sure it would work with those.
There was an issue for this but it was closed due to inactivity. :/
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', ['$scope',
function($scope) {
$scope.myModel = {
foo: 'Boop',
bar: 'Beep'
};
$scope.myModelCopy = angular.copy($scope.myModel);
}
]);
myApp.directive('resetDirective', ['$parse',
function($parse) {
return function(scope, element, attr) {
var fn = $parse(attr.resetDirective);
var masterModel = angular.copy(fn(scope));
// Error check to see if expression returned a model
if (!fn.assign) {
throw Error('Expression is required to be a model: ' + attr.resetDirective);
}
element.bind('reset', function(event) {
scope.$apply(function() {
fn.assign(scope, angular.copy(masterModel));
scope.form.$setPristine();
});
// TODO: memoize prevention method
if (event.preventDefault) {
return event.preventDefault();
} else {
return false;
}
});
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
<form reset-directive="myModel" name="form">
<input type="text" ng-model="myModel.foo" />
<input type="text" ng-model="myModel.bar" />
<input type="reset" value="Reset" />
<pre>myModel: {{ myModel | json }}</pre>
<pre>myModelCopy: {{ myModelCopy | json }}</pre>
<pre>form pristine: {{ form.$pristine }}</pre>
</form>
</div>
</body>
You can try :
reset
$scope.resetForm = function(form) {
//Even when you use form = {} it does not work
form.fieldA = null;
form.fieldB = null;
///more fields
}
Or
$scope.resetForm = function(form) {
//Even when you use form = {} it does not work
angular.copy({},form);
}
See Demo
You'd want to attach ng-model to each of your input fields then null them out via $scope. Either that or make a custom directive
I've just had a similar problem with forms not resetting. Here's what I would do:
In your resetform() function, I would include statements that set both of your ng-models in your input to "". For example:
**HTML**
<input ng-model="text" type="text" />
<input file-model="file" type="file" />
**JS**
.controller('formCtrl', function($scope) {
$scope.resetForm = function() {
$scope.text = "";
$scope.file = null;
};
});
Not certain if this will work for file-models but I'm certain it will remove the text. Best of luck!
If you don't want to use ng-model and proper reset type of button you can use this code, however this is not proper angular way to reset the form but it will work
$scope.reset = function(){
$('form').children('*').each(function(){
$(this).val('');
});
}
Here's the Plunker
To reset the form data use following code :
$scope.resetEmployeeData = function() {
$scope.employeeCred.userName = '';
$scope.employeeCred.employeeNo = '';
$scope.employeeCred.sapNo = '';
$scope.employeeCred.emailD = '';
$scope.employeeCred.mobileNo = '';
**this**.createEmployee.$setPristine();
**this**.createEmployee.$setUntouched();
};
use this rather than $scope.

Input from the form is not passed to the controller and keeps being "undefined"

I have the hardest time dealing with forms and passing values from them to the controller. I have the same story every time: the ng-model and everything is set up but the controller is not accepting what I'm trying to pass it and thus gives me that the var is not defined. Would anyone suggest how to deal with this and how to properly setup forms with Angular? Their documentation is darn awful!
Here's the markup of the form:
<div>
<form name="thisForm" ng-submit="submit()" class="wa-id-submit-form">
<label>Submit your number</label>
<input name="wa_id" ng-model="submission" type="text" class="form-control" required />
<input type="submit" class="form-control" name="submit" value="Submit" />
</form>
</div>
Here's the function and the var I'm trying to pass it to:
$scope.submit = function() {
var data = {
"wa_id": $scope.wa_id
};
console.log($scope.wa_id);
var hookphp = submitIdService.submitId();
hookphp.save(data,
function(result){
console.log(result);
};
The php side of this all works just fine and doesn't need to be looked at. I just need to pass that one line from the input to the data variable and it's not. Am I not making the ng-model and such talk properly to each other?
},
function(result){
console.log('NO GO');
}
);
};
You should use corresponding ngModel to access data in controller, not input name:
var data = {
wa_id: $scope.submission
};
I have been reminded of something very important when dealing with ng-models here
The ng-model has to have a .notation in it to function properly. It's possible that it would function without it as well, but even people who help develop Angular strongly recommend using it with a "."
Here's what had to be done with my code:
<form ng-submit="submit()" class="wa-id-submit-form">
<label>Submit your number</label>
<input name="waid" ng-model="waid.submission" type="text" class="form-control" required />
<input type="submit" class="form-control" name="submit" value="Submit" />
</form>
an ng:
$scope.waid = {};
$scope.submit = function() {
var data = {
"wa_id": $scope.submission
};
var hookphp = submitIdService.submitId();
hookphp.save(data,
function(result){
console.log(result);
},
function(result){
console.log('NO GO');
}
);
};
An object had to be declared "empty" prior to being able to use it in the function as well.

How to submit a form in Angular

I have an html form that I am validating with an Angular controller. If the validation fails, I apply certain classes to the html. If it passes, I want to let the form submit itself. Although this seems very straightforward, I haven't found an easy way to do this. One method I have found uses the $scope.$broadcast function to tell the form to submit, however, I am using the Controller as Ctrl syntax so I would rather not use $scope. Is there anyway to submit a form from a controller?
My simplified HTML
<form ng-controller="LoginCtrl as login" ng-submit="login.validate()" method="post">
<input ng-model="login.username" />
<input ng-model="login.password" />
</form>
JS
var app = angular.module("app", []);
app.controller("LoginCtrl", ["$http", function($http) {
this.username = "";
this.password = "";
this.validate = function() {
//validate
if (valid) {
// somehow form.submit()
}
};
}]);
I am somewhat new to Angular so forgive me if this is an obvious quesion ;)
EDIT:
I need to clarify that I am looking to avoid submitting the form with AJAX (i.e. $http.post). Basically what I want is the controller equivalent of calling form.submit().
USE CASE:
Let me explain exactly what I am trying to do.
User arrives at login page
User enters credentials
User hits Submit
Controller asks server (using api path) if the credentials are valid
if valid then
Tell the form to submit to regular login path // how?
else
Immediately tell the user they submitted invalid credentials
This way the User gets immediate feedback if they entered incorrect credentials.
All of this I have implemented except for the actual form submission.
Simplest approach would be wrap all the form element data into one object. You don't have to create this object if you have no data to prepopulate, ng-model will create it for you.
<form ng-controller="LoginCtrl as login" ng-submit="login.validate()" method="post">
<input ng-model="login.MyFormData.username" />
<input ng-model="login.MyFormData.password" />
</form>
This will result in an object in your controller scope looking like:
$scope.MyFormData={
username :'foo',
password:'bar'
}
When ready to submit:
$http.post('path/to/server', $scope.myFormData).success(response){
/* do something with response */
})
I have an example with the bare minimum code here. Note, it is self validating, and you don't even need to submit anything from the COntroller! you can include the action and method fields as form attributes, and angular will submit the form if it is valid
HTML
<form name="LoginCtrl as loginForm" method="Post" action="not-a-real-script.php">
<input type="text" name="name" ng-model="loginData.name" placeholder="username" required="" />
<input type="password" name="password" ng-model="loginData.password" placeholder="Password" required />
<input type="submit" ng-disabled="loginForm.$invalid" value="Login" />
</form>
JS
angular.module('app', [])
.controller('LoginCtrl', function($scope) {
$scope.loginData = {};
});
I think you want to have validation as part of your form submission flow. Try something like this:
HTML
<form ng-controller="LoginCtrl as login" ng-submit="login.submit()" method="post">
<input ng-model="auth.username" />
<input ng-model="auth.password" />
<div class="error" ng-hide="valid">Something is invalid...</div>
</form>
JS
var app = angular.module("app", []);
app.controller("LoginCtrl", ["$http", "$scope", function($http, $scope) {
$scope.valid = true;
$scope.auth.username = "";
$scope.auth.password = "";
var valid = function() {
// validate
return valid; // true or false
};
this.submit = function() {
if (valid()) {
$http.post('/your/auth/url', { auth: auth }).success(function(response) {
// whatever you're doing to store the auth response.
});
} else {
// use this to conditionally show error messages with ng-show
$scope.valid = false;
}
};
}]);
I'm not sure I understand your comment about using the controller-as syntax. That shouldn't change how you use $scope.

Categories

Resources