ng-submit will not allow duplicate values - angularjs

Why does Angular not allow duplicate data to be submitted? I am using ng-list to write all points scored using a simple controller.
For example - If a player inputs '10' into my app and then another player also does the same the ng-submit will stop functioning completely. I haven't specified anything else to allow this to happen. How can I change this default behaviour so users are allowed to post duplicate values?
Controller:
bowlingApp.controller('bowlPoints', function ($scope){
$scope.bowlPoints = [];
$scope.addBowlPoints = function() {
$scope.bowlPoints.push($scope.enteredPoints);
};
});
HTML
<form ng-submit="addBowlPoints()" role="form">
<div class="form-group">
<label>Player Score</label>
<input type="text" class="form-control" ng-model="enteredPoints">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<tr>
<ul>
<td>Player </td>
<td ng-repeat="points in bowlPoints ">{{points}}</td>
</ul>
</tr>

ng-submit works fine, in your example it adds value to array bowlPoints, but you just can not to see it.
To see an array and that ng-submit works fine you can type {{bowlPoints}} in your HTML file.
But if you want to see all data in table and if you want your table will to update and angular dynamically add your columns - you need to add track by in your ng-repeat
<td ng-repeat="points in bowlPoints track by $index ">{{points}}</td>
Demo: http://plnkr.co/edit/oFMm9Jqk034IRvS1qOCO?p=preview

I believe submit only does something if the form is dirty. Since the first submit will have cleared the dirty state, it won't do anything. You could try manually setting the dirty state of the form. Failing that, you could use ng-click instead and do the form submission yourself.

Related

Can ng-model replace Ids?

Is there a way to avoid IDs while creating elements i.e. using ng-model it is easier to validate form fields and other stuff?
<div ng-repeat="x in TestData">
<input type="text" id="nameField-{{$index}}"/>
</div>
The above code will display the number of input boxes equal to the length of the TestData array where every text box will have a unique id "nameField-0", "nameField-1" and so on, using these IDs we can take the textbox values, validate the fields etc.
<div ng-repeat="x in TestData">
<input type="text" ng-model=""/> <!-- what shall be done here to have unique IDs -->
</div>
Although going with IDs is working fine for me but as far as I can understand If I use IDs then that will not be a pure angular way (or IDs cannot be replaced by mg-models), correct me If I am wrong.
You don't need to grab element with id/name/etc. You can use ng-model to bind your values and ng-pattern to validate them.
<div ng-repeat="x in testData">
<ng-form name="tForm">
<input type="text" name="tInput" ng-model="x.name" ng-pattern="/^[A-Z]*$/" />
<span ng-if="tForm.tInput.$error.pattern" style="color:red">Invalid!</span>
</ng-form>
</div>
See this jsbin.
In your controller add this,
$scope.nameField = [];
in ng-reapeat add this,
<div ng-repeat="x in TestData">
<input type="text" ng-model="nameField[$index]"/>
</div>
nameField will be an array with all your values.
<div ng-repeat="x in TestData" ng-init='this["nameField-"+x]'>
<input ng-model='this["nameField-"+x]'/>
</div>
You use ng-init to add new variables to the controller, "this" refer to your scope, and since the scope is an object, since this[bla] == this.bla tou are actually saying, add to my scope a variable name "nameField=" and you add the x value.
after you have created your variable, just use it in the same way in your ng-model.
If you want to show your variable's value in any div/span, just use it via ng-bind:
<div ng-bind='this["nameField-"+x]'></div>

Angular validation (can't reach controller if required fields are empty)

I'm trying to implement validation for a form using Angular 1.1.1 and Ionic.
There are many "wallets" and the user needs to send a new "value" to each of the wallet. There's also a specified previous value of the wallet. The validation should check if all the input field are filled out and if the new value is bigger than previous.
My form (index.html):
<form name="myForm" ng-submit="sendValues(wallets)" ng-controller="valuesCtrl">
<div class="row" ng-repeat="wallet in wallets">
<div class="col item item-input-inset">
<label class="item-input-wrapper item-text-wrap">
<input name="wallet_{{wallet.id}}" type="number" ng-model="wallet.value" type="text" required/>
</label>
<span ng-show="myForm.wallet_{{item.id}}.$error.required">!!!</span>
</div>
<div class="col item">{{ wallet.previous }}</div>
</div>
<button class="button" type="submit">Submit</button>
</form>
It results in always showing "!!!" error for empty input even if the user haven't already submitted the form. I tried to use $scope.myForm.submitted=true; in the controller but the problem is it reaches the controller only if all the fields are filled out.
My controller (values.js):
'Use Strict';
angular.module('App')
.controller('valuesCtrl', function($scope, $localStorage, UserService, $state) {
$scope.sendValues = function(wallets){
debugger;
...
})
Can anyone help me to figure out why I can't see the debugger window if not all the fields are with info?
Can you suggest how to make a custom validation? (new value should be bigger than previous)
It results in always showing "!!!" error for empty input even if the user haven't already submitted the form?
Your ng-show should be
ng-show="myForm.$submitted==true && myForm.wallet_{{item.id}}.$error.required"
and form should be have novalidate attribute if you want custom validation
<form name="myForm" ng-submit="sendValues(wallets)" novalidate>
otherwise it will do default html validation
I tried to use $scope.myForm.submitted=true; in the controller but the problem is it reaches the controller only if all the fields are filled out
Its because ng-submit will validate for true condition($valid==true) for every form control element .
If it is filled and valid data then only form $valid flag is set to true otherwise not.In case $valid==true,you will able to submit the form and function in controller get fired
you can use
<input type="submit" ng-click="sendValues(wallets)" value="Save" />
if you want to submit the form without validation and want to do validation in controller
You can read more from angular#form

Angular checkboxes and ng-repeat not showing up in model

I'm not sure what I'm doing wrong but I'd like the value of checkboxes to show up as an array in the stores property. Nothing ever shows up. I feel like I'm not utilizing the ng-model properly.
Controller
$scope.parameters = {
myMainOptions:
{
teams: ['angels', 'giants', 'orioles', 'bluejays', 'athletics']
}
}
View
<li ng-repeat="t in parameters.myMainOptions.teams">
<input ng-model="form.selectedTeams[t]" type="checkbox" /> {{t}}
</li>
<button class="btn btn-sm" type="submit" ng-click="submit(form)">SUBMIT</button>
you will need to initialize an array in scope to fill the data into it,,
and also you need to use $index to access the current index of each element ,, so that you can make it as an array not with the object is sel as key like here
<input ng-model="boxes[$index]" type="checkbox" />
you can see the js fiddle here
http://jsfiddle.net/vrem17m0/
There's nothing wrong in your code. Just make sure to initialize the form.selectedTeams object and set the angular controller correctly, then you should be good to go.
You can check this JsFiddle to see it working.

Getting the checked checkbox on ngrepeat angularjs

I am using ng-repeat in angularjs to display several checkboxes.
<div class="checkbox" ng-repeat="subject in priceinformation.subjects">
<label>
<input type="checkbox" ng-model="priceinformation.subscriptioninfo.subject.name"> {{subject.name}}
</label>
</div>
The problem is all the checkboxes are using the same model, hence if I check one, all are checked. I want to do it in a way that the model can resolve to different values. e.g.
ng-model="priceinformation.subscriptioninfo.subject.{{subject.name}}"
{{subject.name}} should resolve to something like English, History etc, hence a different model for each checkbox.
But ng-model="priceinformation.subscriptioninfo.subject.{{subject.name}}" is giving an error.
Note: {{subject.name}} is resolving correctly used elsewhere, and 'priceinformation.subscriptioninfo.subject' is working correctly.
Use [] instead of .
ng-model="priceinformation.subscriptioninfo[subject.name]"
Plnkr Demo
Script
$scope.priceinformation ={};
$scope.priceinformation.subjects = [{"name":"English"},{"name":"History"},{"name":"Maths"}];
$scope.priceinformation.subscriptioninfo ={};
<div ng-repeat="item in checks">
<input type="checkbox" ng-model="item.checked">{{item.name}}
</div>
See Plunkr

AngularJS post form to external URL

I have the following form in my AngularJS app which contain hidden fields with values filled based on user selection on some inputs on the form (radio buttons...etc), when the user click on the Submit link I should route the user to an external URL while passing hidden fields just as any normal form submission. Unfortunately I can't do this as some of the hidden field values are dependent on some calculations inside a function of the view related controller (as shown below in controller code, so I was wondering is there a way I can call the controller function from this form, then the controller function post the whole form and its field? Any example is highly appreciated. Thanks.
Note I am using link instead of a button.
<form name="clientPaymentForm" id="clientPaymentForm" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">>
<div>
<fieldset>
<input id="name" type="text" required placeholder="Client Name" ng-model="client.name">
...
...
<input type="hidden" name="amount" ng-value="order.total">
...
...
<a class="orderButton" href="javascript:{}" onclick="document.getElementById('clientPaymentForm').submit(); return false;">Order Now</a>
</fieldset>
</div>
</form>
Controller:
$scope.processOrder = function(){
//Order calculation happens here to update order.total value and can only happen after click click Order Now to place the order...
};
I guess this is a bit late, but what you want to use is the ng-click directive which will allow you to call functions defined directly on the scope.
Assuming that you've defined $scope.processOrder, change your a tag to the following:
<a class="orderButton" ng-click="processOrder()">Order Now</a>
And everything should work as hoped.
Alternatively, you could use ng-submit on the form to have it work when you press the "Enter" or "Return" key, as in:
<form name="clientPaymentForm" id="clientPaymentForm" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" ng-click="processOrder()">.

Resources