I want to display an element conditionally based on the value of another parameter PaymentTypeid. After setting the condition as below the element Payment Channel is not rendering in the UI:
<tr ng-init="paymentMode='BANK CABS'" ng-if="json.name == 'paymentTypeId' && json.property == '1'">
<td><strong>{{ 'label.heading.paymentchannel' | translate }}:</strong></td>
<td ><span >{{paymentMode}} </span></td>
</tr>
However when i refactor the markup as below the element is showing as :
<tr ng-init="paymentMode='BANK CABS'">
<td><strong>{{ 'label.heading.paymentchannel' | translate }}:</strong></td>
<td ><span >{{paymentMode}} </span></td>
</tr>
PaymentTypeId is in a json array defined as follows in the controller:
scope.details = {};
resourceFactory.auditResource.get({templateResource: routeParams.id}, function (data) {
scope.details = data;
scope.details.paymentMode="";
scope.commandAsJson = data.commandAsJson;
var obj = JSON.parse(scope.commandAsJson);
scope.jsondata = [];
_.each(obj, function (value, key) {
scope.jsondata.push({name: key, property: value});
});
});
In the view PaymentTypeid renders as :
<table class="table" data-ng-show="details.commandAsJson" data-anchor>
<tbody>
<tr data-ng-repeat="json in jsondata">
<td class="width20"><strong> {{json.name}}</strong></td>
<td class="width80">{{json.property}}</td>
</tr>
</tbody>
</table>
Any insight on what i might be getting wrong. Im not entirely sure between using ng-if/ng-show or whether im setting json.property correctly.
Assuming that you have knowledge of scope in AngularJS.
There is a difference between using ng-if and ng-show. Whenever you use ng-if , it creates it own child scope. and you can manage it in custom directive that deals with its child scope (child scope is not available in controller unless you write your code in a way, that will make it available in controller) and you can hack the scope to use it in controller too. But that is not the case in ng-show.
When you use ng-show it will not remove your HTML from the DOM tree but if you use ng-if it will also remove your html from DOM tree. (To assist your confusion which one to use)
You have a scope issue here , if i'm getting it right. Use ng-show and it will work.
<div ng-show="condition">
your html markup
</div>
Related
I have a table, I am already given it CSS using ng-class if they satisfy a condition. Now I want to show only those rows who satisfy the same condition on a button click. I have wrote a controller which checks if the data received is within 24 hours are not and marks the data cell. Until this it's working.Now I need to add a button and show only the row which has this td marked as not received in time.
<tbody>
<tr ng-repeat ="data in log">
<td>{{data.UniqueId}}</td>
<td>{{data.Name}}</td>
<td ng-class ="{'data-notreceived' : dataNotReceived('data.receivedTime')}">{{data.receivedTime
}}
</tbody>
</table>
I think something like this should work. Basically, clicking the button will toggle between showing all or only the items marked as 'data not received'.
<tbody>
<tr ng-repeat ="data in log" ng-show="showAll || dataNotReceived(data.receivedTime)">
<td>{{data.UniqueId}}</td>
<td>{{data.Name}}</td>
<td ng-class ="{'data-notreceived' : dataNotReceived('data.receivedTime')}">{{data.receivedTime}}
</tr>
</tbody>
// in controller
$scope.showAll = true;
$scope.onButtonClick = function() {
$scope.showAll = !$scope.showAll;
return false;
}
From the information provided in question what I can say is: Use ng-show to show rows based on your condition.
<tr ng-show ="your_condition">
You could also use an ng-if rather than ng-show. See the differences here.
Really depends on how often the hide/show toggle needs to happen.
<tbody>
<tr ng-repeat="data in log" ng-if="showLast24Hrs(data.ReceivedTime)">
<td>{{data.UniqueId}}</td>
<td>{{data.Name}}</td>
<td>{{data.ReceivedTime}}</td>
</tbody>
and then in the controller,
$scope.showLast24Hrs = function(receivedTime){
if($scope.isLast24Hours) {
return receivedTime < 200; // Write your less than 24 hours check here
}
return true;
}
I wrote this demo on Codepen. Hope that helps.
I am working on an app and I cant seem to figure out why my ng-click only works inside of my (single) tr tag but as soon as I put it into another tr tag it stop working. Keep in mind it was working before I used the ng-repeat within the first tr tag. Here is what my code looks like, any advice would greatly help!
<table>
<tbody>
<tr>
<td ng-click="commentOpen = !commentOpen">
<div class="iconsize">Comment Closed</div>
</td>
<td ng-click="switchOpen = !switchOpen">
<div class="iconsize">Switch Closed</div>
</td>
</tr>
<tr>
<td>
<div ng-show="commentOpen == true">
<textarea>Comment Open</textarea>
</div>
<div ng-show="switchOpen == true">
<p>Switch On</p>
</div>
</td>
</tr>
</tbody>
</table>
I had the ng-repeat on the tag which was causing my ng-click to not fire. I ended up moving my ng-repeat to the tbody and the ng-click and ng-show started working again.
ngRepeat creates new scopes for its children, it just usually seems like it's accessing the same scope because this new scope inherits from its parent.
Meaning, commentOpen is actually referring to a property on the wrong scope.
Below are three potential ways for you to fix this:
1) controller as, and always refer to the controller you're after by name
2) $parent.commentOpen (Don't do this! It becomes very confusing as you nest)
3) Instead of commentOpen and switchOpen, you can use an Object (e.g. $scope.openControls = { comment: false, switch: false }, and then in the td tags you would write something like ng-click='openControls.comment = !openControls.comment'). This way it's passed inherited by reference (where as a boolean would be by value), and keeps synced.
I am trying to hide the div if any of the buttons in the ng-repeat is clicked. However it doesn't seem to work, it leads me to think if ng-hide or ng-show won't work if it is controlled from within a ng-repeat?
<div data-ng-hide="showChooseHardware">
<table class="table">
<tbody>
<tr data-ng-repeat="hardware in hardwares">
<td>{{hardware.name}}</td>
<td>
<button type="button" class="btn" data-ng-click="showChooseHardware=!showChooseHardware"/>
</td>
</tr>
</tbody>
</table>
</div>
This is due to the fact that ng-repeat creates a new scope for each template and due to how prototypal inheritance works in JavaScript (and AngularJS).
Use an object:
$scope.viewModel = { showChooseHardware: false };
HTML:
data-ng-hide="viewModel.showChooseHardware"
And:
data-ng-click="viewModel.showChooseHardware=!viewModel.showChooseHardware"
A great explanation on the issue can be found here.
I recommend using ng-showinstead in this case since the variable is called showChooseHardware.
ngRepeat directive creates new scope in every iteration,for every item in array.It can make a problem,which you have.
I’m having my first steps with angularjs framework, and I’m not understanding how I can update my second ng-repeat data inside each of the first’s item ng-repeat only when a user click on it (lazy loading).
<table class="table table-striped table-hover">
<tbody ng-repeat="customer in customers">
<tr>
<td>
<button ng-click="loadInvoices(customer); showDetails = !showDetails;" type="button" class="btn btn-default btn-xs">
</td>
<td>{{customer.ClientId}}</td>
</tr>
<tr ng-show="showDetails">
<td>
<table class="table table-striped table-hover">
<tbody ng-repeat="invoice in invoices">
<tr>
<td>{{invoice.Id}}</td>
</tr>
</tbody>
</table>
</td>
</tr><!--showDetails-->
</tbody><!--.customer-->
</table>
How can I achieve it? Thanks for your help! :)
You can do something like this:
<button ng-click="loadInvoices(customer);" type="button" class="btn btn-default btn- xs">Invoces</button>
and in controller:
$scope.loadInvoices = function(customer) {
if (this.showDetails = !this.showDetails) {
if (!this.invoices) {
// Load invoices for current customer (probably using service)
Customer.loadInvoices(customer.ClientId).then(function(invoices) {
customer.invoices = invoices;
});
}
}
}
By checking if (!this.invoices) {...} (this points to the current customer scope) you make sure that current customer doesn't have loaded invoices yet and you need to load them. On subsequent button clicks customer.invoices is going to be already available and you will not load data again.
I also added an example how using Customer service would fit into this workflow.
View demo: http://plnkr.co/edit/LerBd9ZTPLwhp8JZ6xwU?p=preview
With the ng-controller directive
Simply use the ng-controller directive to tell that a customer scope will be managed by an instance of the controller you pass in.
With a custom directive
Typical design for this: a customer directive with a customer controller which manages the scope of one customer.
The keys are:
ng-repeat creates child scopes
add a directive to attach a controller to each of those scopes
you can now manage each customer scope independently.
The controller, in both cases
This controller will hold loadInvoices which will attach the invoices array to the customer scope.
Why a custom directive ? You will also be able to have a separate template for a customer, specific pre link and post link functions, etc.
Why a customer specific controller since scope inheritance will enable the loadInvoices context to be the customer specific scope ? Extensibility, testability, decoupling.
Html:
<table>
<thead>
<tr>
<th>Name</th>
<th>DOB</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="member in model.Members" ng-dblclick="Member(member)">
<td>{{member.Name}}</td>
<td>{{member.DOB | date:'yyyy-MM-dd'}}</td>
</tr>
</tbody>
</table>
<div kendo-window="*dialog*" k-title="'Member Profile'" k-visible="false" k-modal="true" k-width="700" k-height="410" k-resizable="false">
<ng-familymember controller="familycontroller"></ng-familymember>
</div>
Controller:
function fooController($scope) {
$scope.Member = function (familyMember) {
$scope.*dialog*.center().open();
}
}
Problem:
I have a collection of objects (i.e. model.Members) used within an ng-repeat directive and I want to be able to double-click on a row and bind the object model to a kendo-window (popup). Inside my controller I'm passing in the model to a function (i.e. Member()) within the controller but I'm not sure how to pass/bind this model to the kendo-window? I could simply move the kendo-window html inside the ng-repeat and use the ng-model directive but that would repeat the kendo-window html (n) times and I don't want that.
Any Suggestions?
I've tried binding the member object to an $scope variable. (i.e. $scope.familyMember = familyMember;). Because the way Prototypal Inheritance works I'm actually creating a copy of the familyMember object and using that in the kendow-window popup.
You should know that I'm also setting up a $watch within the controller on the member object to notify other directives on the page of changes made within the kendo-window.
Any help would be appreciated... I'm a bit lost at this point...