angular ng-repeat creating multiple forms syntax error - angularjs

I'm ng-repeating over a collection of items, and each item I want to have its own form and its own submit button, which will send that form info to the submit function. I needed to know which item is being submitted, so I figured I'd create one form per item and that would indicate which one is being submitted. Currently, it's in an li ng-repeat like so:
<input ng-model="query" type="text" placeholder="Filter by" autofocus>
<ul class="gNow">
<li ng-repeat="item in selRole.selectRoles | multifilter:query">
<form name="selRoleForm-{{item.rowId}}" ng-submit="selRole.selectRole(selRoleForm-{{item.rowId}})" novalidate>
<div class="card">
<p>Card Name: {{item.cardName}}</p>
<p>.. other form elements here ..</p>
<p><button type="submit">Select</button></p>
</div>
</form>
</li>
</ul>
I'm getting the following error:
[$parse:syntax] Syntax Error: Token '{' invalid key at column 33 of
the expression [selRole.selectRole(selRoleForm-{{item.rowId}})]
starting at [{item.rowId}})].
What am I doing incorrectly - or is there a better way to approach this problem?
This SO post is the closest that I could find to my problem, but still, I'm not sure I understand how to adjust to my specific needs.
UPDATE:
Thanks to all the responses which lead me to the solution. I needed to not include the form name in the submit function, but the item instead. That was all that was missing.
old (syntax error):
ng-submit="selRole.selectRole(selRoleForm-{{item.rowId}})"
new (working):
ng-submit="selRole.selectRole(item)"

Just store the form name in your ng-repeated array:
<input ng-model="query" type="text" placeholder="Filter by" autofocus>
<ul class="gNow">
<li ng-repeat="item in selRole.selectRoles | multifilter:query">
<form name="{{item.formName}}" ng-submit="selRole.selectRole(item.formName)" novalidate>
...

Use ngForm :
<div class="form-group" ng-repeat="item in selRole.selectRoles | multifilter:query">
<ng-form name="userFieldForm">
<label></label>
<input >
</ng-form>
</div>

You just need to reverse the conversion in the concatenation of the names.
When parsing a parameter on ng-submit what you need to convert is the hard-coded string, not the rowId.
would be something like that:
<input ng-model="query" type="text" placeholder="Filter by" autofocus>
<ul class="gNow">
<li ng-repeat="item in selRole.selectRoles | multifilter:query">
<form name="selRoleForm-{{item.rowId}}" ng-submit="selRole.selectRole('selRoleForm-'+item.rowId)" novalidate>
<div class="card">
<p>Card Name: {{item.cardName}}</p>
<p>.. other form elements here ..</p>
<p><button type="submit">Select</button></p>
</div>
</form>
</li>

Related

How to obtain values from input fields with Angular JS after ng-repeat

I'm new in AngulsrJS and I've got following code:
<form ng-if="editorCtrl.edit" class="form-horizontal" role="form" ng-submit="editorCtrl.saveEntry()">
<div class="form-group">
<div class="col-md-6" ng-repeat="(key,field) in editorCtrl.editEntry">
<label>{{key}}</label>
<input type="text" class="form-control" value={{field}} />
</div>
</div>
<!-- ng-model="editorCtrl.toSave[key]" ng-value="{{field}}" that part was in input attributes -->
<div class="form-group">
<div style="padding-left:110px">
<input type="submit" value="Update selected entry" ng-disabled="form.$invalid" class="btn btn-primary"/>
</div>
</div>
</form>
Now I need to obtain values from input fields. I tried to use ng-model="editorCtrl.toSave[key], but it's not working in a correct way.
Any suggestions how to resolve this situation ?
if you can consider no necesary the "toSave" object maybe you can use the 2-way data binding properly only using editEntry Object :
<input type="text" class="form-control" value={{field}} ng-model="editorCtrl.editEntry[key]"/>
In this way after a submit you will get editEntry with the fields modifieds (or not), here is an example
https://jsfiddle.net/pv8qrwty/1/
run the example and if you modified the fields after you press the submit button it will be displayed in your browser console
hope this help ! and sorry for my english !

Bind ng-model dynamically with unknown input type

I have a HTML form where I have few questions with different answer type. For example question 1 has answer of type multi check box, question 2 has answer type of radio button, question 3 has answer type of text area.
There can be "n" number of questions with any of the above type.
Using ng-repeat I am able to render the questions on the HTML.
Now the problem is to read the answers filled by user. I need to send the response on submit of the form. I am not able to understand how to bind ng-model to each question.
<form id="SubmitForm" name="SubmitForm" class="form-horizontal" role="form">
<div ng-repeat="question in questions">
<div class="col-sm-10">
<span>{{$index+1}}. {{question.question}}</span>
<div ng-if="question.optionType.id == '1'"><!-- Multiple Choice -->
<div class="checkbox" ng-repeat="option in question.options | split track by $index">
<label><input name="{{question.id}}" type="checkbox" value="" ng-model="answer_question.id">{{option}}</label>
</div>
</div>
<div ng-if="question.optionType.id == '2'"><!-- radio button -->
<div class="radio" ng-repeat="option in question.options | split track by $index">
<label>
<input type="radio" name="{{question.id}}">
{{option}}
<br>
</label>
</div>
</div>
<div ng-if="question.optionType.id == '3'"><!-- text box -->
<textarea rows="5" name="{{question.id}}"></textarea>
</div>
</div>
</div>
<div class="form-group" align="center">
<button id="completeSurvey" name="completeSurvey" class="btn btn-info" ng-click="complete()"><span class="glyphicon glyphicon-ok-sign"></span> Done</button>
</div>
</form>
How do I collect all the data entered by the user and use it in the "complete()" method?
Because of the 2-way binding native to AngularJS, you don't really need to do anything.
As the user updates any of the inputs bound by ng-model to the underlying data model Angular will take care of synchronization.
You can simply call ng-click='complete(questions)' and you'll get the latest & greatest user's input scoped to your complete function.
In your <input> and <textarea> just add ng-model="question.answer". Then you can access the answers through each question's answer property.

How can i add validation ng-maxlength into ng-repeat with error message?

I have a simple code :
<div class="row" ng-repeat="aDiagnosis in diagnosisListForPrescription">
<div class="col-md-4 padding-right-zero" id={{aDiagnosis.rowIndex}}>
<input class="form-control" name="aDiagnosisName" ng-model="aDiagnosis.Name" ng-disabled="true">
</div>
<div class="col-md-4 padding-right-zero form-group" show-errors id={{aDiagnosis.rowIndex}}>
<input class="form-control" name="aDiagnosisResult" ng-maxlength="200" ng-model="aDiagnosis.Result" />
<p class="help-block" ng-if="form.aDiagnosisResult.$error.maxlength">Too Large</p>
</div>
</div>
and use $scope.form.$valid to generate the error message.
But problem is since use ng-repeat every time it finds the same name and when i want to generate second list by clicking a button ,,first error message is gone and error-message now works on the second text (obviously).
So How can i generate error-message each and every time dynamically ,,so every text form in ng-repeat,it has it's own error-message.
You can generate dynamically name attribute of your inputs in ng-repeat. For example, you can put $index (or id of your objects or whatever you want) to generate unique name for your inputs.
<div class="row" ng-repeat="aDiagnosis in diagnosisListForPrescription">
<div class="col-md-4 padding-right-zero" id={{aDiagnosis.rowIndex}}>
<input class="form-control" name="aDiagnosisName-{{$index}}" ng-model="aDiagnosis.Name" ng-disabled="true">
</div>
<div class="col-md-4 padding-right-zero form-group" show-errors id={{aDiagnosis.rowIndex}}>
<input class="form-control" name="aDiagnosisResult-{{$index}}" ng-maxlength="200" ng-model="aDiagnosis.Result" />
<p class="help-block" ng-if="form['aDiagnosisResult-' + $index].$error.maxlength">Too Large</p>
</div>
</div>
Example on plunker.

Angular JS ng-show/ hide based on drop-down list selected value

in the following code I have one drop-down list (serviceSmallId) for type of service.
It is populated using model info.
There is a second field check-box which should only be visible when drop-down has a selected value of 'Weekly'. I am trying to use ng-show/ hide of angular.
I tried to search for possible solutions but no luck.
Can anyone please guide me what I am doing wrong.
<section id="scrubber-view" class="mainbar" data-ng-controller="scrubber as vm">
<section class="matter">
<div class="container">
<div>
<button class="btn btn-info" ng-click="vm.goBack()"><i class="fa fa-arrow-left"></i>Back</button>
<button class="btn btn-info" ng-click="vm.cancel()" ng-disabled="!vm.canSave"><i class="fa fa-undo"></i>Cancel</button>
<button class="btn btn-info" ng-click="vm.save()" ng-disabled="!vm.canSave"><i class="fa fa-save"></i>Save</button>
<span ng-show="vm.hasChanges" style="color:orange" class="dissolve-animation ng-hide"><i class="fa fa-asterisk"></i></span>
</div>
<div class="row">
<div class="widget wblue">
<div data-cc-widget-header title="{{vm.title}}" subtitle="{{vm.scrubber.scrubberId}}"></div>
<form class="form-horizontal">
<div class="form-group">
<label for="serviceSmallId" class="col-sm-2">Service</label>
<div class="col-sm-4">
<select class="form-control" id="serviceSmallId" ng-model="vm.scrubber.serviceSmallId"
ng-options="item.dataLookupId as item.description for item in vm.serviceSmalls | orderBy:['sortOrder','description']">
</select>
</div>
</div>
<div class="form-group" ng-show="vm.scrubber.serviceSmallId.value=='Weekly'">
<input class="form-control" type="checkbox" id="fullyFlanged" value="Bar" />
</div>
</form>
</div>
</div>
</div>
</section>
</section>
There probably is a more elegant "angular way" solution,
but I updated you code to work here - http://jsbin.com/tupisoriho/1/edit?html,js,output
Explanation of changes
Provided ng-show a value vm.checker
added ng-change to the select element and gave it a function checkerGo which tested to see if dropdown == 'weekly', if yes change vm.checker
Update
there is a more "angular way" - using expressions!
As per #Omri Aharon fiddle/comment below.
You don't need to get the value property because a ng-model don't hold the element but the value itself;
<div class="form-group" ng-show="vm.scrubber.serviceSmallId.value=='Weekly'">
must be
<div class="form-group" ng-show="vm.scrubber.serviceSmallId == 'Weekly'">
EDIT: In your case vm.scrubber.serviceSmallId will contain the ID and not the description Weekly. I suggest you to use ng-change directive to call a function in your controller that will find the item based on ID and set in the controller to be visible for ng-show.
<select class="form-control" id="serviceSmallId" ng-model="vm.scrubber.serviceSmallId"
ng-options="item.dataLookupId as item.description for item in vm.serviceSmalls | orderBy:['sortOrder','description']"
ng-change="vm.selectObj()">
vm.selectObj() will find and set the current selected object in the scope to an controller variable (ex.: vm.selectedItem) and:
<div class="form-group" ng-show="vm.selectedItem.description=='Weekly'">

Issue with ng-model and ng-repeat, duplicate forms

I have a page where multiple forms are created based on ng-repeat. Everything works fine until write something into the input and everything gets duplicated on all the other repeated forms input elements. I have used ng-model="Notify.message" which is nothing but object which takes the value from the input and sends to control on button submit and hence rest of the logic.
I am looking for when if one form is been filled, other forms should keep quite and shouldn't duplicate the values written in input text of form 1.
Here is the code:
<div data-ng-show="alluserposts.length > 0">
<div id="b{{userpost.id}}" data-ng-repeat="userpost in alluserposts" >
<div class="row" style="margin-left: -5px">
<form class="text-center" role="form" id=f1{{userpost.id}} name="userForm"
ng-submit="notify(userForm.$valid, userpost, apiMe)" novalidate>
<div class="row">
<div class="col-xs-8 col-md-4">
<div class="form-group">
<input data-container="body" data-toggle="popover" data-placement="top"
data-content="Any message which you would like to convey to post owner"
type="text" ng-model="Notify.message" data-ng-init="Notify.message=''"
id="u{{userpost.id}}"
placeholder="Enter a Message or Phone number" class="form-control"
required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">It is
required.</p>
<script>$(function () {
$("[data-toggle='popover']").popover();
});
</script>
<input type="hidden" ng-model="Notify.loggedInEmail"
ng-init="Notify.loggedInEmail = result.email"/>
<input type="hidden" ng-model="Notify.postId" ng-init="Notify.postId = userpost.id"/>
<input type="hidden" ng-model="Notify.destEmail"
ng-init="Notify.destEmail = userpost.userEmail"/>
</div>
</div>
<div ng-show="loginStatus.status == 'connected'" class="col-xs-4 col-md-2">
<button class="btn btn-primary" ng-disabled="userForm.$invalid || !userForm.$dirty"
type="submit">
Notify Post Owner
</button>
</div>
</div>
</form>
</p>
</div>
</div>
</div>
</div>
Issue fiddle - jsfiddle
Here you can when something is written in one input, other gets filled too :( . Also Notify is a Java mapped object and message is a variable inside it. Pls let me know how can this can be segragated!
You bind all of your inputs to same variable on $scope.
You must bind every text box to a distinct variable on $scope:
View:
<ul ng-repeat="post in posts">
<li>{{$index}}
<input type="text" ng-model="emails[$index]"/>
</li>
</ul>
Controller:
$scope.emails = [];
I am also at the starting phase of angularjs.
I have faced the same issue few days ago and resolved it by providing dynamic model name in ng-model like
<input type="text" ng-model="Notify[post.userEmail]" ng-init="Notify[post.userEmail] = post.userEmail" />
Working fiddle: Fiddle

Resources