I have a problem with a form in angularjs.
Example with classic html & php
<form name="myForm" action="post.php" method="post" autocomplete="on">
<input name="namename" type="text" />
<input name="email" type="text" />
<input name="submit" type="submit" value="submit" />
</form>
which works as expected. On the second visit, after i submitted the form for the first time, i just need to type the first letter and the input field will suggest something based on the first post.
The same form in angular.
<form name="myForm" ng-submit="test(user)" autocomplete="on">
<input name="name" type="text" ng-model="user.name" autocomplete="given-name" />
<input name="email" type="text" ng-model="user.email" />
<input name="submit" type="submit" value="submit" />
</form>
On the second visit here the form will suggest nothing at all, which is very irritating.
Is there any fix for that?
Example
thanks in advance.
That behaviour you're describing is done by the browser and is not guaranteed to work in all situations. It's actually quite easy to do in AngularJS; just keep track of a shared state object. This can be done in several ways, the most easiest by using the value provider like this:
// Create an injectable object with the name 'userInput'
angular.module('myApp').value('userInput', {});
Now inject this object in the controller that is handling the form like this:
angular.module('myApp').controller('MyController', function($scope, userInput) {
// Assign the state object to the scope so it's available for our view
$scope.user = userInput;
});
Render the form as you did and you'll see that the state of the form is kept. In fact, this is one of the hidden gems when programming with Angular since it allows you to keep very complex state information, which was previously pretty impractical.
Live demo can be found in this plunker.
Edit
One way to get the autocomplete to work is to maintain datalist elements. Just store the previous entered values in an array and use a ng-repeat to render all the options. Associate the input element with the datalist using the list attribute and you'r good to go.
<input list="nameHistory" type="text" ng-model="user.name" />
<datalist id="nameHistory">
<option ng-repeat="item in userHistory.name" value="{{ item }}"></option>
</datalist>
Live demo can be found in this plunker.
Just add to the input tag this attribute autocomplete="off"
Related
I have a form, and the form has multiple inputs that are all bound to different variables. Before submitting the form, I need to do validity checks, pristine checks, etc. For example, I want my submit button to be disabled if every part of the form is pristine, or if something is invalid.
Using Angular 5, I am trying to get access to the .pristine, .valid, and .invalid flags for each input field, but the values are either undefined or "cannot get .pristine of undefined".
I am able to get these flags on the entire form itself, but this doesn't help, because I want to know how to get it for each individual input.
Here is my current code (I've removed a number of my inputs to simplify the example).
<form #editDetailsForm="ngForm" name="editDetailsForm" >
<label for="name"> Name </label>
<input type="text" id="name" name="name" maxlength="40" [(ngModel)]="myName" required />
<label for="description"> Description </label>
<textarea id="description" name="description" maxlength="250" [(ngModel)]="myDescription" required ></textarea>
<button id="submit" type="button"
[disabled]="saveButtonDisabled(editDetailsForm.invalid, editDetailsForm.name.invalid, editDetailsForm.description.invalid)"
(click)="updateDetails()" >
Save
</button>
</form>
If you see, I bind disabled attribute on the Save button to saveButtonDisabled() function, where I want to pass in information about each input's validity. The first argument, editDetailsForm.invalid returns a true or false, but the other values return undefined.
How do I check validity of these individual inputs?
EDIT: I realize I can derive all of this info inside my component because all of the input values are bound. However, it'd be easier just to check a flag or two.
I'm not sure I totally understand what you want to do, but this is how you get access to the form controls .pristine, .invlaid
<input type="text" id="name" name="name" #name="ngModel" maxlength="40" [(ngModel)]="myName" required />
The #name="ngModel" sets a template reference to the FormControl angular creates
Then you should be able to do something like this:
<input type="text" id="name" name="name" #name="ngModel" maxlength="40" [(ngModel)]="myName" required />
<div *ngIf="name.pristine">
Name is Pristine
</div>
Just to clarify, the individual form fields bubble up to the form itself. So if any field has been touched, then the whole form will be pristine == false.
You can access the input controls using the .controls property, like:
<button id="submit" type="button"
[disabled]="editDetailsForm.controls.name?.invalid || editDetailsForm.controls.description?.invalid">
Created a stackblitz. https://stackblitz.com/edit/angular-5ir4k7
Added template reference variable for ngModel and validate using isValid.
Okay, so I asked a variant of this question before, but I think the thread has died at this point, and I have a followup question:
Using a Form to Dynamically Change the URL in the Address Bar
So, I was looking to find a way to use a form to quickly add a product to a Volusion cart by entering it's product code. Turns out, if you're on the cart page, the solution is this snippet:
<form action="ShoppingCart.asp" name="form" method="get">
<input type="text" value="" name="ProductCode">
<input type="submit" value="Add To Cart">
</form>
Well, this doesn't work at all on other pages...knowing very little about how GET forms work, I'd love to better understand why this is, and what I can do to make this work on, say, the homepage.
The site (currently) is: http://ezndb.cwjea.servertrust.com/
As you can see, I have the red area sporting the code that I used on the check out page, but it doesn't work...any suggestions? I know other threads have suggested javascript/jquery or php methods of getting this to happen...
any form with the method ="get" will append data to the url in name value pairs ( the name being the input name
<form action="#" name="form" method="get">
<input name="q" />
<input name="q2" />
<input type="submit" value ="click and look at the address bar, Probably won't work on stack though" />
</form>
It doesn't work because your store is a members only site so the customers cannot add items to the cart until they are confirmed members.
I have a total of two input values. Only one value passes to the url of the next page, but both should. What's causing this?
JSFiddle: http://jsfiddle.net/p8dCC/
HTML:
<!--form action="device" onSubmit=" get_search(); return false;" id="search-form-4" method="get" target="_top"-->
<div class="fix">Brand</div>
<input class="inputs" type="text" id="search_id" name="q3" placeholder="Send this" required="required" />
<br/><br/>
<div class="fix">Model</div>
<input class="inputs" type="text" id="search_id" name="q4" placeholder="And send this one too" required="required" />
<br/><br/>
<input id="search-button" class="" type="submit" value="continue" data-target="http://www.google.com/?item-description" />
<!--/form-->
You have two elements with the same id in html. So when you do this $('#search_id').val() only one of them will get evaluated and not both. Ids are supposed to be unique
After testing your code in a test page, I found that both inputs were in fact being passed through the URL.
You have commented out the form tags which I'm not sure if you did just for purposes on here.
kjs is correct as well, though using the same id would only effect the HTML. Using get as the method would bypass this issue as it would be passed the unique "name" attribute.
A form tag is required if you expect the html submission mechanism to work correctly on its own.
In the Javascript you posted though, you are treating document.location as an html element, wrapping it with jquery, then trying to use jquery's attr method on it. This won't work. Just access "location.href" directly without using jquery.
Additionally, as pointed out by another answer, your ids should all be unique.
At some point during the development of my app, AngularJS forms stopped working... Yes that means they used to work. That is, form elements are supposed to create their own scope with every <input /> by their name. However all my forms are now completely empty, as if I had no input elements with the name attribute. Now I can't make any sort of form validation. I've tried even the most trivial forms and still nothing:
<form name="form>
<input type="text" name="input" required />
</form>
Any suggestions as to how to debug this?
Hi to do validation your input have to have model directive please see here: http://jsbin.com/deref/1/edit
<form name="form">
<input type="text" name="foo" required ng-model="input.model"/>
<span ng-show="form.foo.$error.required">required</span>
</form>
Try console.log on the scope
console.log($scope.form);
If you have your controllers set up correctly, your form should be attached to the scope of controller.
I have on my web application (Play Framework 2.2.1 & Scala) a list of customers who are displayed with ajax and AngularJS. It works fine, and now I want to add a new customer dynamically in my list, with a JS pop up I've made (with jQuery UI).
I search first how to display on browser data sended by the HTML/AngularJS form, but when I click on my submit button, nothing happen... And I don't know why, other AngularJS actions works.
Here is my code :
JavaScript
function AddCustomerController($scope) {
$scope.add = function() {
$scope.customers.push({id: $scope.email, phone: $scope.phone, isActivated: $scope.activation, name: $scope.name, roleType: $scope.roleType});
}
}
HTML
<div id="dialogAddCustomer" title="title" ng-controller="AddCustomerController">
<label id="dialNewCustomerName">Add Customer</label>
<label class="lblPopUp">Email</label>
<input type="text" id="dialNewCustomerEmail" class="form-control" ng-model="email" />
<label class="lblPopUp">Phone Number</label>
<input type="text" id="dialNewCustomerPhone" class="form-control" ng-model="phone" />
<label class="lblPopUp">Customer Activated ?</label> <br />
<input type="radio" name="activation" id="dialNewCustomerYes" value="1" ng-model="activation" /> Yes
<input type="radio" name="activation" id="dialNewCustomerNo" value="2" ng-model="activation" /> No
<label class="lblPopUp">Name</label>
<input type="text" id="dialNewCustomerName" class="form-control" ng-model="name" />
<label class="lblPopUp">Role Type</label> <br />
<select class="form-control" ng-controller="RoleTypesController">
<option ng-repeat="roleType in roleTypes" value="{{roleType.id}}" ng-model="roleType">{{roleType.name}}</option>
</select>
<br />
<button class="btn btn-default" type="submit" ng-click="add()">Validate</button>
</div>
Second, I don't know how to push data to my controller (I've searched already on the web) correctly to insert new customer in database.
Any idea, or tips ?
Maybe you should add AddCustomerController to the HTML, or move the add() function to the CustomerController.
You should also just put a customer object into scope, and add the individual fields to it, and then access it via customer.email, customer.phone and so on. That will help prevent scoping issues and also make the controller code a lot simpler.
Also, this has nothing to do with Play, as you don't send any data to the server (check $http in Angular's documentation on how to do this).
Nothing is ever sent to the server because the code never instructs AngularJS to send anything.
Your add function modifies local scope only, and doesn't invoke $http.post().
You may be thinking too much in html terms and not enough in AngularJS terms. With angular you don't need to have a form; it can be handy - particularly for validation - but it's not required. The model is what is key, with or without a form.
In general, I suggest having your inputs modify parts of an object, so instead of:
<input type="text" ng-model="email" />
<input type="text" ng-model="phone" />
<button type="submit" ng-click="add()">Add</button>
do instead:
<input type="text" ng-model="customer.email" />
<input type="text" ng-model="customer.phone" />
<button type="submit" ng-click="add(customer)">Add</button>
Controller then something like:
function AddCustomerController($scope, $http) {
$scope.customer = {};
$scope.add = function(newCustomer) {
// this assumes newCustomer has been validated
$http.post('/api/customers', newCustomer); // TODO: handle response
}
}
As a side note, the more you get into angular, the less you'll need jquery and jquery ui - I have a rule that a page is either jquery or angular, but never both. YMMV.