Angular Form Not Submitting in Ng-repeat - angularjs

Hello i have a form inside a table row within an ng-repeat, inside that form i have a number field and a button(custom directive named "action") now when that button is clicked i want the form to do validation before submitting but when i try nothing happens i get no errors.
<table class="table schedules">
<thead>
<tr>
<th style="text-align:center;" > Ticket Type</th>
<th style="text-align:center;" > Ticket Price (GHS)</th>
<th style="text-align:center;" > How many?</th>
<th></th>
</tr>
</thead>
<tbody>
#if (count($ticketTypes) <= 0))
<tr ng-hide="d.ticketTypes.length > 0">
<td style="text-align:center;" colspan="5">
<h4 style="">There are no tickets available.</h4>
</td>
</tr>
#endif
<tr ng-repeat="type in d.ticketTypes">
<form name="ticketForm" ng-submit="ticketForm.$valid && addToCart('event', d, type.id, $index)" novalidate>
<td style="text-align:center;" ><b><% type.fee_cat_desc %></b></td>
<td style="text-align:center;" ><b><% type.event_fee | currency : '₵' %></b></td>
<td style="text-align:center;" ><b><input type="number" ng-model="line.d.ticket_no" class="form-control" min="1" max="30" style="width:80px !important;" ng-required/></b></td>
<td>
<action text='Buy Ticket' state='<% state %>' index='<% $index %>' selected='<% selectedIndex %>'></action>
</td>
</form>
</tr>
</tbody>
</table>
This is my action directive:
html:
<button type="submit" ng-class="{ 'btn-set': isReady === true || isWorking === true || isComplete === true || hasFailed === true, 'btn-ready-state': isReady === true || selected != index, 'btn-working-state': isWorking === true && selected == index, 'btn-failed-state': hasFailed === true }" ng-cloak>
<i ng-if="isReady === true || selected != index" class="fa fa-shopping-cart"></i>
<img ng-src="/images/loading - small.png" class="img" ng-show="isWorking && selected == index "></span>
<i ng-if="isComplete && selected == index " class="fa fa-check"></i>
<span class="text">
<span ng-if="isReady === true || selected != index"><% text %></span>
</span>
</button>

One of the thing you missed to name="" attribute on a form, it is needed to start form validation on field by angular
<input type="number" name="ticket_no-{{$index}}" ng-model="line.d.ticket_no"
class="form-control" min="1" max="30" style="width:80px !important;" ng-required/>
Refer this SO Answer for more Explaination

You've got multiple <form>s with the same name. This is a problem for angular because it references each form by its name. A quick fix would be to use $index or type to make the names different.
<tr ng-repeat="type in d.ticketTypes">
<form name="ticketForm_{{type}}" ng-submit="ticketForm.$valid && addToCart('event', d, type.id, $index)" novalidate>
<td style="text-align:center;" ><b><% type.fee_cat_desc %></b></td>
<td style="text-align:center;" ><b><% type.event_fee | currency : '₵' %></b></td>
<td style="text-align:center;" ><b><input type="number" ng-model="line.d.ticket_no" class="form-control" min="1" max="30" style="width:80px !important;" ng-required/></b></td>
<td>
<action text='Buy Ticket' state='<% state %>' index='<% $index %>' selected='<% selectedIndex %>'></action>
</td>
</form>
</tr>

Make sure that you have a input field with the type="button" and the name="submit"

Related

How to show and hide a table column after checking a condition in every row in ng repeat loop angular js?

I have a problem with show/hide column in a table with ng-repeat after checking a condition. Here is my code.
<div class="row">
<div class="col-md-12 col-no-pad-mob">
<div class="content-box-with-label without-label with-data-view">
<table class="table table-striped table-bordered table-hover table-responsive table-data-view">
<tr>
<th> </th>
<th>Fee Type</th>
<th>Fee</th>
<th class="th_DSCR_Cal">Capitalize</th>
<th class="th_DSCR_Cal">Amortize</th>
<th>Amortized Interest</th>
<th>Recurring Fee</th>
<th class="boo-tbl-tr-config">Setting</th>
</tr>
<tr ng-repeat="amo in item.trialCalculation.listTrialAmortization | filter:{active: true}">
<td class="boo-tbl-tr-config">
<md-checkbox ng-model="amo.isApply" ng-change="GenerateFee_ChangeEvent(item.trialCalculation.listTrialAmortization,amo, item)" aria-label="Checkbox 1" ng-value="amo.isApply" ng-disabled="statusMatched == true"></md-checkbox>
</td>
<td>
{{amo.feeType}}
</td>
<td>
<input class="form-control" step=".01" ng-model="amo.fee" ng-readonly="statusMatched == true || amo.feeType ==='Stamp Duty'|| amo.feeType ==='Document Fee'|| amo.feeType ==='Introducer Fee'|| amo.feeType ==='Insurance Fee'" ng-disabled="amo.isApply === false"
ng-pattern="/[0-9.,]+/" format="number" type="text" ng-change="ResetAmortization_ChangeEvent(item.trialCalculation.listTrialAmortization,amo, item)">
</td>
<td class="boo-tbl-tr-config">
<md-checkbox ng-model="amo.capitalize" ng-change="ValidateCapitalize_ChangeEvent(item.trialCalculation.listTrialAmortization,amo)" aria-label="Checkbox 1" ng-disabled="statusMatched == true || amo.isApply == false || amo.isCapitalizeEnable == false || amo.amortize == true"></md-checkbox>
</td>
<td class="boo-tbl-tr-config">
<md-checkbox ng-model="amo.amortize" ng-change="GenerateAmortization_ChangeEvent(item.trialCalculation.listTrialAmortization,amo, item)" aria-label="Checkbox 1" ng-value="amo.amortize" ng-disabled="statusMatched == true || amo.isApply == false || amo.isAmortizeEnable == false || amo.capitalize == true"></md-checkbox>
</td>
<td>
<input class="form-control" step=".01" ng-model="amo.amortizedInterest" ng-disabled
ng-pattern="/[0-9.,]+/" format="number" type="text" ng-readonly="true">
</td>
<td>
<input class="form-control" step=".01" ng-model="amo.recurringFee" ng-disabled
ng-pattern="/[0-9.,]+/" format="number" type="text" ng-readonly="true">
</td>
<td ng-hide="statusMatched == true" class="boo-tbl-tr-config">
<a href="#" ng-show="cprinit.editable==true && (amo.isCapitalizeEnable==false || amo.amortize==true)"
ng-click="GenerateAmortization_ChangeEvent(item.trialCalculation.listTrialAmortization,amo, item)" ng-disabled="amo.isApply === false || amo.amortize === false"><i class="fa fa-refresh" aria-hidden="true"></i></a>
</td>
</tr>
<tr ng-hide="statusMatched == true" class="add_new_expen">
<td colspan="8">
<md-button class="md-fab md-mini md-primary inline-input" data-toggle="modal" data-target="#addincomemodal_{{$index}}">
<md-icon md-svg-src="~/Content/images/add-plus-button.svg"></md-icon>
</md-button>
<label class="label-addnewexpen" data-toggle="modal" data-target="#addincomemodal_{{$index}}">Add New Fee Type</label>
</td>
</tr>
</table>
</div>
</div>
</div>
I need to show settings column if only if all the data rows should be checked a condition and at least one row is passed the condition. If any of data row is not able to pass the condition the settings column should not be shown.
Use a function in your controller to this. Loop through all the rows to check for the condition, set $scope.shColumn = true when the condition is met.
In your HTML.
<th ng-if="shColumn">Settings</th>

using Angularjs How to bind dropdown value control from the table by clicking on edit button?

i only bind the drop-down related value, by clicking on edit button within table, its not working within drop-down
Here is my angularjs code
myapp = angular
.module('myapp', ["ui.router", 'ngAnimate', 'angular-loading-bar', 'ui-notification', 'smart-table', 'ui.bootstrap'])
.controller('DemoCtrl', function ($scope, $interval, Notification, cfpLoadingBar, $http) {
GetAll();
function GetAll() {
$http.get("/api/AddCatagories").then(function (response) {
$scope.cate = response.data
}, function () {
alert("Error")
})
}
$scope.subcateedit = function (Id) {
$http.get("/api/AddSubCatagories/" + Id).then(function (response) {
cfpLoadingBar.start();
$scope.SubCata = response.data
cfpLoadingBar.complete();
})
}
})
Html Table Code is here you can view all code..i only bind the drop-down related value, by clicking on edit button within table, its not working within drop-down
<table st-table="sub" st-safe-src="subcate" class="table table-striped">
<thead>
<tr>
<th style="color:black">Id</th>
<th style="color:black" width="100px">SubCatagoryName</th>
<th style="color:black" width="100px">CatagoryName</th>
<th style="color:black">Action</th>
</tr>
<tr>
<th colspan="5">
<label>Search..</label>
<input st-search placeholder="search" class="input-sm form-control" type="search" />
</th>
</tr>
</thead>
<tbody>
<tr st-select-row="row" st-select-mode="multiple" ng-repeat="row in sub">
<td style="color:black">{{row.Id}}</td>
<td style="color:black">{{row.SubCataName}}</td>
<td style="color:black">{{row.tblcatagory.CataName}}</td>
<td>
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default" ng-click="subcateedit(row.Id)">
<i class="glyphicon glyphicon-pencil" style="color:black">
</i>
</button>
<button type="button" class="btn btn-danger" ng-click="subcatedelete(row.Id)">
<i class="glyphicon glyphicon-trash" style="color:white">
</i>
</button>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="itemsByPage"></div>
</td>
</tr>
</tfoot>
</table>
html form code:
<section class="panel">
<header class="panel-heading danger">
Add Catagory
</header>
<div class="panel-body" ng-controller="DemoCtrl">
<div ng-form="frm" name="loginForm"
class="pure-form pure-form-aligned" autocomplete="off">
<div class="position-center">
<div class="form-group" ng-class="{ 'has-error' :loginForm.ddl.$invalid && !loginForm.ddl.$pristine }">
<label>SubCatagory Name*</label>
<p>{{ SubCata.tblcatagory.CataName }}</p>
<select required name="ddl"
value="{{ SubCata.tblcatagory.CataName }}"
class="form-control"
ng-model="SubCata"
ng-options="item.CataName for item in cate">
</select>
<p ng-show="loginForm.ddl.$dirty && loginForm.ddl.$error.required"
class="help-block">Catagory Name is required</p>
</div>
<div class="form-group" ng-class="{ 'has-error' :loginForm.name.$invalid && !loginForm.name.$pristine }">
<label>SubCatagory Name*</label>
<input type="text" name="name" class="form-control" ng-model="SubCata.SubCataName"
ng-minlength="3" ng-maxlength="20" required>
<p ng-show="loginForm.name.$dirty && loginForm.name.$error.required"
class="help-block">SubCatagory Name is required</p>
<p ng-show="loginForm.name.$error.minlength" class="help-block">
SubCatagory Name is too short.
</p>
<p ng-show="loginForm.name.$error.maxlength" class="help-block">
SubCatagory Name is too long.
</p>
</div>
<button type="submit" class="btn btn-primary" ng-click="submitSubForm(loginForm.$valid , SubCata)"
ng-disabled="loginForm.$invalid">
Submit
</button>
</div>
</div></div>
</section>
UPDATE
now one issue is that ng-model="SubCata.tblcatagory.CataName" due to this i can't get the this {{SubCata.tblcatagory.Id}} id in the controller $scope
<select required name="ddl" class="form-control"
ng-model="SubCata.tblcatagory.Id"
ng-options="item.Id as item.CataName for item in cate">
</select>
i get id from this code
<label>SubCatagory Name*</label>
<p>{{ SubCata.tblcatagory.CataName }}</p>
<select required name="ddl"
value="{{ SubCata.tblcatagory.CataName }}"
class="form-control"
̶n̶g̶-̶m̶o̶d̶e̶l̶=̶"̶S̶u̶b̶C̶a̶t̶a̶"̶
̶n̶g̶-̶o̶p̶t̶i̶o̶n̶s̶=̶"̶i̶t̶e̶m̶.̶C̶a̶t̶a̶N̶a̶m̶e̶ ̶f̶o̶r̶ ̶i̶t̶e̶m̶ ̶i̶n̶ ̶c̶a̶t̶e̶"̶
ng-model="SubCata.tblcatagory.CataName"
ng-options="item.CataName as item.CataName for item in cate">
</select>

Display Data On Modal Screen Based On User Selection Using Check Box

"I've displayed 20 records in navigation tab and against each records I've added coloumn for checkbox. My requirement is if user selects records (row) 1, 4, 8 using checkbox and click on "Edit" button on top of Navigation tab then it should display on Modal screen so that user can edit it.
if he/she selects records 5, 8, 6 then records should be display in that particular order.
I google it but couldn't find any related posts.
Below is my HTML code:
<div ng-app="RecordApp" ng-controller="recordcontroller" class="container-fluid">
<div class="input-group">
<ul class="nav nav-tabs">
<li role="menu" class="active"><a href="#" data-toggle="tab" >User Data</a></li>
</ul>
<table class="table">
<thead>
<tr>
<th>
Select
</th>
<th>
Test1
</th>
<th>
Test2
</th>
<th>
Test3
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in Records | orderBy:SortBy:Reverse ">
<td>
<input type="checkbox" checked="checked" ng-model="record.Selected" ng-change="Checked(record)" />
</td>
<td>{{ record.Test1 }}</td>
<td>{{ record.Test2 }}</td>
<td>{{ record.Test3 }}</td>
</tr>
</tbody>
</table>
</div>
following is my AngularJs code for populating the navigation tab
$http.get(pageBaseUrl + "api/records").success(function (records) {
$scope.Records = records;
$scope.IsLoading = false;
});
Below is the code of Button and Modal screen:
<div class="input-group">
<button type="button" data-target="#editRecords" data-toggle="modal" class="btn btn-primary navbar-btn">
<span class="glyphicon glyphicon-floppy-disk"></span>
Edit Multiple Records
</button>
</div>
<div id="editRecords" class="modal" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h2>Edit Data For Selected Records </h2>
</div>
<div class="modal-body">
<table class="table-condensed table-striped">
<thead>
<tr>
<th>Test 1</th>
<th>Test 2</th>
<th>Test 3</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in Records | orderBy:SortBy:Reverse">
<td><input type="text" class="form-control input-sm" /></td>
<td><input type="text" class="form-control input-sm" /></td>
<td><input type="text" class="form-control input-sm" /></td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="SaveRecords();">Save Records</button>
<button type="button" class="btn btn-default" data-dismiss="modal" ng-click="UnmarkForEdition()">
Cancel
</button>
</div>
</div>
</div>
</div>
Thanks for the code, here is my solution,
JSFiddle Demo
Issues:
First I check if the object contains any selected checkboxes using the code.
$scope.checkCheckbox = function(){
return $filter('filter')($scope.Records, {Selected: true}).length === 0;
}
In the above code, I check the ng-repeat array if there is any object containing the property Selected:true, if there are none, then the length will be zero which using a comparator operator, I return a boolean. This is used by the HTML element button attribute ng-disabled and disables the input.
<button type="button" ng-disabled="checkCheckbox()" data-target="#editRecords" data-toggle="modal" class="btn btn-primary navbar-btn">
<span class="glyphicon glyphicon-floppy-disk"></span>
Edit Multiple Records
</button>
When the edit multiple records, button is clicked, I open the modal, and in the code I have added a simpleng-if` which will show only the inputs where the checkbox is selected!
<tr ng-if="record.Selected" ng-repeat="record in Records | orderBy:SortBy:Reverse">
<td><input type="text" class="form-control input-sm" /></td>
<td><input type="text" class="form-control input-sm" /></td>
<td><input type="text" class="form-control input-sm" /></td>
</tr>
Let me know if this fixes the issue.

Display table rows in angularjs, if data exists

I want to have a table consisting of 3 columns, the code looks like this
<table class="table-striped table-bordered table-condensed">
<tbody>
<tr ng-if="$index%3==0" ng-repeat="permission in vm.parent.getAllPermissions(category)">
<td ng-repeat="i in [0,1,2]" class="col-xs-2">
<span>
<input type="checkbox" checklist-model="vm.data.permissions" checklist-value="vm.parent.getPermission(category,$parent.$index+i)"> {{vm.parent.getPermissionTitle(category,$parent.$index+i) || " "}}
</span>
</td>
</tr>
</tbody>
</table>
That works great except for a small issue.
There's simply not enough json data to fill 3 rows, so 2 checkboxes are displayed empty
What I tried, is writing something like
vm.hasPermission = function(category, index) {
var permissions = vm.getAllPermissions(category);
return permissions && index < permissions.length
};
And then something like
<span>
<input ng-if="vm.parent.hasPermission(category,$parent.$index+i)"type="checkbox"
checklist-model="vm.data.permissions" checklist-
value="vm.parent.getPermission(category,$parent.$index+i)"> {{vm.parent.getPermissionTitle(category,$parent.$index+i) || " "}}
</span>
It fixes the problem but not on all tables, some tables would still have empty checkboxes.
I get the permission titles like this
vm.getPermissionTitle = function(category, index) {
var permissions = vm.getAllPermissions(category);
if (index < permissions.length) {
return i18n.get(permissions[index]);
} else {
return '';
}
};
I tried removing the return, didn't fix it.
change:
<td ng-repeat="i in [0,1,2]" class="col-xs-2">
<span>
<input type="checkbox" checklist-model="vm.data.permissions" checklist-value="vm.parent.getPermission(category,$parent.$index+i)"> {{vm.parent.getPermissionTitle(category,$parent.$index+i) || " "}}
</span>
</td>
for:
<td ng-repeat="i in [0,1,2]" class="col-xs-2">
<span ng-if="vm.parent.getPermissionTitle(category,$parent.$index+i)!=''">
<input type="checkbox" checklist-model="vm.data.permissions" checklist-value="vm.parent.getPermission(category,$parent.$index+i)"> {{vm.parent.getPermissionTitle(category,$parent.$index+i)}}
</span>
</td>
if I understood well your code and your problem, vm.parent.getPermission(category,$parent.$index+i) returns the text (permission) so just check that is not empty... it may also work like:
<td ng-repeat="i in [0,1,2]" class="col-xs-2">
<span ng-if="vm.parent.getPermissionTitle(category,$parent.$index+i)">
<input type="checkbox" checklist-model="vm.data.permissions" checklist-value="vm.parent.getPermission(category,$parent.$index+i)"> {{vm.parent.getPermissionTitle(category,$parent.$index+i)}}
</span>
</td>
because vm.parent.getPermission(category,$parent.$index+i) returning nothing could evaluate false.
I haven't try it.
The solution is
<table class="table-striped table-bordered table-condensed">
<tbody>
<tr ng-if="$index%3==0" ng-repeat="permission in vm.parent.getAllPermissions(category)">
<td ng-repeat="i in [0,1,2]" class="col-xs-2">
<span ng-if="vm.parent.getPermission(category,$parent.$index+i)">
<input type="checkbox" checklist-model="vm.data.permissions" checklist- value="vm.parent.getPermission(category,$parent.$parent.$index+i)">
{{vm.parent.getPermissionTitle(category,$parent.$parent.$index+i)}}
</span>
</td>
</tr>
</tbody>
</table>
So basically {{vm.parent.getPermissionTitle(category,$parent.$parent.$index+i)}}

AngularJS - Custom common directive validation for all fields in a row

I am trying to implement custom validation to check user typed entry is valid or not.
EX: Existing row
ORIG DEST DESK REGION
HYD MAS 20 34
Scenario's:
1)When user enter new row with same values i need to show validation error.
2)When user enter same orig, dest and region with different desk then also i need to validation error.
I have created custom validation which will check current row with all rows in list and return false if any scenario found.
I need to call this directive on any value change of ORIG or DEST or DESK or REGION and show error message at single place.
I tried with giving directive for all fields, but getting error for every filed not common.
Is there any possibility to do this?
HTML:
<form novalidate id="ODDRForm" name="ODDRForm">
<table>
<thead>
<tr>
<th >
<span>ORIG</span>
</th>
<th >
<span>DEST</span>
</th>
<th >
<span>DESK</span>
</th>
<th >
<span>REGION</span>
</th>
</tr>
</thead>
<tbody class="tbody_border_bottom">
<tr ng-repeat="row in List" ng-form="rowForm">
<td >
<input check-duplicate type="text" name="origin" ng-model="row.orig" required /><br/>
<div ng-messages="rowForm.orig.$error" ng-if="ODDRForm.$submitted || rowForm.orig.$touched">
<span ng-message="required">Required</span>
<span ng-message="checkDuplicate">Not a valid entry</span>
</div>
</td>
<td >
<input check-duplicate type="text" name="dest" ng-model="row.dest" required /><br/>
<div ng-messages="rowForm.dest.$error" ng-if="ODDRForm.$submitted || rowForm.dest.$touched">
<span ng-message="required">Required</span>
<span ng-message="checkDuplicate">Not a valid entry</span>
</div>
</td>
<td >
<input check-duplicate type="text" name="desk" ng-model="row.desk" required /><br/>
<div ng-messages="rowForm.desk.$error" ng-if="ODDRForm.$submitted || rowForm.desk.$touched">
<span ng-message="required">Required</span>
<span ng-message="checkDuplicate">Not a valid entry</span>
</div>
</td>
<td >
<input check-duplicate type="text" name="region" ng-model="row.region" required /><br/>
<div ng-messages="rowForm.region.$error" ng-if="ODDRForm.$submitted || rowForm.region.$touched">
<span ng-message="required">Required</span>
<span ng-message="checkDuplicate">Not a valid entry</span>
</div>
</td>
</tr>
</tbody>
</table>
JavaScript:
app.directive('checkDuplicate', [ '$http', function($http) {
return {
require : '^ngModel',
link : function(scope, element, attrs, ngModel) {
var bool = true;
ngModel.$parsers.push(function(value) {
for(var i in scope.List) {
if(scope.List[i].orig == scope.row.orig && scope.List[i].dest == scope.row.dest
&& scope.List[i].desk == scope.row.desk && scope.List[i].region == scope.row.region
&& scope.List[i].$$hashkey != scope.row.$$hashkey) {
bool = false;
}
}
ngModel.$setValidity('checkDuplicate', bool);
return value;
})
},
}
} ]);
In your case there is no reason to add directives, you can just watch model changes and validate, give me the sample code I can show you how

Resources