How to mimic a HTML Form request in Angularjs? - javascript

I made an app using Laravel so most of the pages uses simple HTML Form to send HTTP requests.
I recently decided to use Angular Material to code my front-end, but as all of the input components forces to use ng-model, I want to mimic the behavior of the simple HTML Form Submission using an Angular Controller.
For example: I want this
index.html
<form action="/confirm" method="POST">
<input type="text" name="name">
<input type="submit" value="Submit">
</form>
By using this
index.html
<input type="text" name="name" ng-model="name">
<form action="/confirm" method="POST" ng-submit="submit($event)">
<input type="submit" value="Submit">
</form>
app.js
var app = angular.module('MyApp', []);
app.controller('AppController', ['$scope', function($scope){
$scope.submit = function(e){
e.preventDefault();
var url = e.currentTarget.getAttribute('action');
var data = {
name : this.name
};
// Some code here that I can't figure out
// Which will mimic the simple HTML Form Submission
};
}]);
One solution is to append a hidden input inside the form for each of the inputs outside the form. I don't want to do it that way, it will be very in-efficient.
Any other ways? Thank You.
And it will be great if anyone knows how to handle this for a file input.

Javascript:
app.controller("MainCtrl", ["$scope", "$http", function($scope, $http) {
$scope.name = null;
$scope.submitForm = function(name) {
//submitting form items depend on what your /confirm endpoint is expecting
//is it expecting JSON, form data in the body, etc?
//JSON
var payload = {
name: name
};
//submitting via FormData
//var payload = new FormData();
//payload.append("name", name);
//use $http to post to server
$http.post('/confirm/', payload).then(function(response) {
//success
}, function() {
//an error has occurred
});
}
}]);
HTML:
<form id="myForm" name="myForm" ng-submit="submitForm(name)">
<!-- bind model to input using ng-model -->
<input required type="text" ng-model="name" />
<button ng-disabled="myForm.$invalid" type="submit" ng-click="submitForm(name)">Submit</button>
</form>

You could use the $http service to make http calls you code should look like this
var url = e.currentTarget.getAttribute('action');
var data = {
name : this.name
};
$http({
method: url,
url: '/confirm',
data:data
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});

Related

Pre fill and submit a form in in a view with AngularJS

I have this very simplified AangularJS app. It is working very well.
Now, I need to fill some fields and submit the form directly from the view, without user interaction.
Here's the Javascript code (once again, simplified and I removed many other elements)
mainApp.controller("resultsController",FormController);
function FormController($scope,APIService) {
$scope.result ="";
$scope.search = { keywords: "",
result:1,
term: "-1",
subject: "-1"};
$scope.searchNow = function() {
APIService.getTheResults($scope);
} // $scope.searchNow
}
function getResults($http) {
var results = {};
url = "...";
results.searchResults = function() {
var lurl = url + "a=s";
return $http( {method: "JSONP", url:lurl} );
} // results.searchResults
results.getTheResults = function(scope) {
var lurl = url;
$http({
method: 'POST',
url:lurl,
data:jQuery.param(scope.search),
headers:{'Content-Type':'application/x-www-form-urlencoded'}})
.success(function(lresponse){
var theResponse;
theResponse = eval(lresponse);
scope.mydata = theResponse.data[0]
})
.error( function(data,status) {
scope.result = status;
});
} // results.getTheResults
return results;
} // function getResults($http)
And here is the HTML view:
<html lang="en" ng-app="courseCatalog" ng-controller="resultsController">
<!-- some head info -->
<body>
<form id="search_form" name="search_form" ng-submit="searchNow()">
<!--
form fields in here, for example:
-->
<input type="text" id="txtkeywords" name="keywords" ng-model="search.keywords">
<input type="text" id="txtsubject" name="term" ng-model="search.subject">
<input type="text" id="textterm" name="subject" ng-model="search.term">
<input id="submit-button" name="submit-button" type="submit"
value=" Search Now "/>
</form>
<!-- Here is the , I pre-populate some form fields -->
<div id='filter_holder' class='hidden_box'>
<div class='hidden_box'>{{search.term='1|201601';}}</div>
<div class='hidden_box'>{{search.subject='6|BIO';}}</div>
</div>
<!-- And here, I try to manually submit the form -->
<script type="text/javascript">
document.getElementById('submit-button').click();
</script>
</body>
But I only get the page to reload with all the formfields in the url:
...url.../?txtterm=-1&txtsubject=-1&submit-button=+Search+Now+
I tried also submitting with document-form-submit but I get no results.
If I remove all the pre-fill/submit and manually fill and send the form I get the correct results.
Any idea on how to submit the form from the view?
Try using form method post. So change your form tag to:
<form id="search_form" name="search_form" ng-submit="searchNow()" method="post">
As described in this chapter at w3schools, when using post method the data will not be shown in the url.
"POST offers better security because the submitted data is not visible
in the page address."
Solved: I noticed that the page was trying to submit the form too quickly. First, I set a timer to 5 seconds after the form loaded and then call the click function of the submit button.
Then, I just used a window.unload function to be called when the entire DOM is created:
window.onload = function(){ document.getElementById('submit-button').click(); };
And that is working fine. I hope this helps some other people.
Thanks!

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