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
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>
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>
"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.
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)}}
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