Does aliasing work with function calling in ng-disabled? - angularjs

First, have a look at my current code:
$scope.disableParticipant = function (memberObj) {
if($scope.memberObj.membertype==1){
return true;
} else if($scope.memberObj.membertype==2 && $scope.program.updatePermission){
return true;
}
return false;
};
<table>
<tbody>
<tr ng-repeat="memberObj in members | orderBy : ['membername'] as resultMem track by memberObj.id">
<td align="middle" title="Add/Remove Participant" class="width40">
<input type="checkbox" ng-disabled="disableParticipant(memberObj)">
</td>
<td>
<$ memberObj.membername $>
</td>
<td>
<input type="checkbox" ng-disabled="(disableParticipant(memberObj) && (program.created_by == memberObj.id))">
</td>
<td>
<input type="checkbox" ng-disabled="(disableParticipant(memberObj) && (program.created_by == memberObj.id))">
</td>
<td>
<input type="checkbox" ng-disabled="(disableParticipant(memberObj) && (program.created_by == memberObj.id))">
</td>
<td>
<input type="checkbox" ng-disabled="(disableParticipant(memberObj) && (program.created_by == memberObj.id))">
</td>
</tr>
</tbody>
</table>
Here I have used 'disableParticipant' function many times. I am searching any way where I do not need to use the function again & again. I supposed that aliasing with the very first use of function should work but it is not working.
<input type="checkbox" ng-disabled="disableParticipant(memberObj) as isDisabled">
& I want it to work like
<td>
<input type="checkbox" ng-disabled="isDisabled && (program.created_by == memberObj.id))">
</td>
It didn't work but if there is any other way around, let me know...

You can use ngInit to assign result of your function to a variable.
<table>
<tbody>
<tr ng-repeat="memberObj in members | orderBy : ['membername'] as resultMem track by memberObj.id"
ng-init="isDisabled = (disableParticipant(memberObj) && (program.created_by == memberObj.id))">
<td align="middle" title="Add/Remove Participant" class="width40">
<input type="checkbox" ng-disabled="disableParticipant(memberObj)">
</td>
<td>
<$ memberObj.membername $>
</td>
<td>
<input type="checkbox" ng-disabled="isDisabled">
</td>
<td>
<input type="checkbox" ng-disabled="isDisabled">
</td>
<td>
<input type="checkbox" ng-disabled="isDisabled">
</td>
<td>
<input type="checkbox" ng-disabled="isDisabled">
</td>
</tr>
</tbody>
</table>

Call this function just after you load your members array
function updateMembersDisability()
{
$scope.members.forEach(function(member){
member.isDisabled = false;
if(member.membertype==1){
member.isDisabled = true;
} else if(member.membertype==2 && $scope.program.updatePermission){
member.isDisabled = true;
}
});
}
And then you can use IsDisabled property directly like this
<td>
<input type="checkbox" ng-disabled="memberObj.isDisabled && (program.created_by == memberObj.id))">
</td>

Aliasing with the as keyword is for controllers only.
You can, however, generate these checkboxes with ng-repeat to have a less boilerplate.
<tr ng-repeat="memberObj in members | orderBy : ['membername'] as resultMem track by memberObj.id">
<td align="middle" title="Add/Remove Participant" class="width40">
<input type="checkbox" ng-disabled="disableParticipant(memberObj)">
</td>
<td>
<$ memberObj.membername $>
</td>
<td ng-repeat="i in [1,2,3,4]">
<input type="checkbox" ng-disabled="disableParticipant(memberObj) && (program.created_by == memberObj.id)">
</td>
</tr>

Add a property in your member object once they are loaded like this,
function updateMembersDisability()
{
$scope.members.forEach(function(member){
Object.defineProperty(member, 'isDisabled', {
get: function() {
if($scope.memberObj.membertype==1){
return true;
} else if($scope.memberObj.membertype==2 && $scope.program.updatePermission){
return true;
}
return false;
}
});
});
}

Related

Edit function is not properly working in angular JS

When I add any data I am getting values in text box instead of getting it in span.And also after the data gets added I am getting done button instead of getting Update button.Find my full code here:https://jsfiddle.net/GowthamG/jL5oza04/
Is there any error?
<script type="text/javascript">
var app=angular.module("mainapp",[]);
app.controller('mycontrol',function($scope){
$scope.filters=[];
$scope.add=function(filter){
$scope.filters.push(filter);
$scope.filter={};
};
$scope.update = function (index) {
$scope.editing = $scope.filters.indexOf(index);
};
<table border="2">
<tr>
<td>FirstName</td>
<td>LastName</td>
<td>Fees</td>
<td>E-Course</td>
</tr>
<tr ng-repeat="filter in filters track by $index">
<td><span ng-hide="update">{{filter.fname}}</span>
<input type="text" ng-show="update" ng-model="filter.fname">
</td>
<td><span ng-hide="update">{{filter.lname}}</span>
<input type="text" ng-show="update" ng-model="filter.lname">
</td>
<td><span ng-hide="update">{{filter.ffees}}</span>
<input type="number" ng-show="update" ng-model="filter.ffees">
</td>
<td><span ng-hide="update">{{filter.eroll}}</span>
<input type="text" ng-show="update" ng-model="filter.eroll">
</td>
<td>
<button ng-hide="update" ng-click="update = true; update($index)">Update</button>
<button ng-show="update" ng-click="update = false">Done</button>
</td>
<td>
<button ng-click="remove($index)">Remove</button>
</td>
</tr>
</table>
You have to initialize the value of $scope.update in your add functionality to hide the inputs. Now the values will be shown in a span with update button.
$scope.add=function(filter){
$scope.filters.push(filter);
$scope.update=false;
};
Working Demo: https://jsfiddle.net/kz8uLg10/2/

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

angular-strap datepicker disable-dates

Using angular-strap v2.2.1, I have a scenario where I have list of periods every period use min-date and max-date attribute and when set a period in the change of end date ,I should disable this period here is the html :
<div class="row">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th colspan="4" style="border: none"></th>
<th colspan="10" class="text-center">Series Closed</th>
</tr>
<tr>
<th>Period</th>
<th>Period Name</th>
<th>Start Date</th>
<th>End Date</th>
<th>Financial</th>
<th>Sales</th>
<th>Purchasing</th>
<th>Inventory</th>
<th>Payroll</th>
<th>Manufacturing</th>
<th>Expense Management</th>
<th>POS</th>
<th>Bank</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="period in AllPeriods">
<td>1</td>
<td class="col-md-3">
<input type="text" id="PeriodName{{$index}}" class="form-control input-sm"
placeholder="Period Name" ng-model="period.PeriodName">
</td>
<td class="col-md-2">
<div class="input-group">
<input type="text" id="StartDate{{$index}}" class="form-control" ng-model="period.StartDate"
data-date-format="dd/MM/yyyy" data-max-date="{{period.EndDate}}"
data-disabled-dates="{{unavailableDates}}"
autoclose="true"
placeholder="Start Date" bs-datepicker>
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</td>
<td class="col-md-2">
<div class="input-group">
<input type="text" id="EndDate{{$index}}" class="form-control" ng-model="period.EndDate"
data-date-format="dd/MM/yyyy" data-min-date="{{period.StartDate}}"
data-disabled-dates="{{unavailableDates}}"
autoclose="true"
placeholder="End Date" ng-change="DisableDate(period.StartDate,period.EndDate)" bs-datepicker>
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsClosed{{$index}}" ng-model="period.IsClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsSalesClosed{{$index}}" ng-model="period.IsSalesClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsPurchaseClosed{{$index}}" ng-model="period.IsPurchaseClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsInventoryClosed{{$index}}" ng-model="period.IsInventoryClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="PayrollClosed{{$index}}" ng-model="period.PayrollClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsManufacturingClosed{{$index}}" ng-model="period.IsManufacturingClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsExpenseManagementClosed{{$index}}" ng-model="period.IsExpenseManagementClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsPOSClosed{{$index}}" ng-model="period.IsPOSClosed" style="position:static;opacity:10;">
</td>
<td class="text-center">
<input type="checkbox" class="form-control" name="IsBankClosed{{$index}}" ng-model="period.IsBankClosed" style="position:static;opacity:10;">
</td>
</tr>
</table>
</div>
</div>
in the JS :
$scope.AllPeriods = [];
$scope.NumberOfPeriodsChanged = function () {
$scope.AllPeriods = [];
var num = $("#Num").val();
for (var i = 0; i < num; i++) {
var temp = {
YearCode: '',
PeriodName: '',
StartDate: '',
EndDate: '',
IsClosed: '',
IsSalesClosed: '',
IsPurchaseClosed: '',
IsInventoryClosed: '',
PayrollClosed: '',
};
$scope.AllPeriods.push(temp);
}
};
$scope.unavailableDates = [];
$scope.DisableDate = function (start, end) {
$scope.unavailableDates.push({
start: new Date(start),
end: new Date(end)
});
};
i solved this problem by making two functions to return date_to and date_from :
$scope.ToCustomDate = function (index) {
if (index == 0) {
return;
}
var dt = new Date($scope.AllPeriods[index].StartDate);
dt.setDate(dt.getDate() + 1);
return dt;
};
$scope.FromCustomDate = function (index) {
if (index == 0) {
return;
}
var dt = new Date($scope.AllPeriods[index - 1].EndDate);
dt.setDate(dt.getDate() + 1);
return dt;
};
I have tried your example and it seems that it doesn't work dynamically, You can put the disabled dates in advance and add the next period when the user finish editing the first one, or you might forward your question as issue in angular-strap
btw you don't need brackets to set the disabled dates
data-disabled-dates="unavailableDates"
and you need to refactor your function to take index as it keep adding dates to the array
$scope.DisableDate = function( index, start, end ) {
if ( angular.isDate( start ) && angular.isDate( end ) ) {
$scope.unavailableDates[index] = {
start: new Date( start ).toISOString(),
end: new Date( end ).toISOString()
};
}
};

Angular Form Not Submitting in Ng-repeat

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"

Angularjs Binding data to other table by check radio button, and update after click button

<table>
<tr>
<td><input type="radio" name="groupName" value="song" ng-model="$parent.selectedSong"/></td>
<td>{{song.name}}</td>
<td>{{song.artist}}</td>
<td>{{song.genre}}</td>
<td>{{song.price}}</td>
<td>
<input type="button" value="Delete" ng-click="deleteItem(song.id)" />
</td>
<td>
<input type="button" value="View" ng-click="go('OneSong', song)" />
</td>
</tr>
</table>
<table border="1">
<tr><td id="Td1">Correct Table</td></tr>
<tr>
<td>Name: </td>
<td><input type="text" ng-model="editItem.name"/></td>
</tr>
<tr>
<td>Artist: </td>
<td><input type="text" ng-model="editItem.artist"/></td>
</tr>
<tr>
<td>Genre: </td>
<td><input type="text" ng-model="editItem.genre"/></td>
</tr>
<tr>
<td>Price: </td>
<td><input type="text" ng-model="editItem.price"/></td>
</tr>
<tr>
<td colspan="2">
<!--<input type="button" value="Insert "ng-click="addItem()"/>-->
Add New Song
<input type="button" value="Update" ng-click="updateItem()"/>
<input type="button" value="Cancel" ng-click="cancel()"/>
</td>
</tr>
</table>
From the little information you provided, I am taking a stab at this:
http://jsfiddle.net/V44fQ/
var app = angular.module('songApp',[]);
app.controller('SongCtrl',function($scope) {
$scope.edit_song = {};
$scope.song = [
{name:'Heartbreaker',artist:'Led Zeppelin',genre:'Rock',price:'.99'},
{name:'War Pigs',artist:'Black Sabbath',genre:'Rock',price:'.99'}
];
$scope.applySong = function(song) {
$scope.edit_song = angular.copy(song);
$scope.edit_song.song_index = $scope.song.indexOf(song);
};
$scope.saveSong = function() {
var idx = $scope.edit_song.song_index;
$scope.song[idx] = $scope.edit_song;
$scope.cancelSong();
};
$scope.cancelSong = function() {
$scope.edit_song = {};
};
});

Resources