Ng-click does not work outside of my tr tag AngularJS - angularjs

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.

Related

How can i conditionally display an element using AngularJS

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>

im new to angularjs , ng-if was not working. order1 value is im giving externally

<tr ng-repeat=" x in list " ><div ng-if ="order1 == x.orderNo">
<td>{{x.ShippingLine}}</td>
<td>{{x.orderNo}}</td>
<td>{{x.Buyer}}</td>
<td>{{x.Items}}</td>
<td>{{x.Quantity}}</td>
<td>{{x.shipTo}}</td>
<td>{{x.CapitalItem}}</td>
<td>{{x.Status}}</td>
<td>{{x.Type}}</td>
<td>{{x.Comments}}</td>{{x.orderNo}}</tr></div>
{{x.orderNo}}
</table>
Your <div> tag starts inside the <tr> and ends outside of the </tr>
Further more please note that even if the <div> was correcly placed, you would get an empty tr
You most likely need to put the ng-if on the tr instead.
Look at this fiddle

ng-repeat over a div not working

I have used ng-repeat numerous times already in the past, but for some reason I cannot yet understand why it is not on the following situation:
I have an array of objects called registers which I am referencing on the ng-repeat but nothing happens.
I know the array is populated because I have seen it on numerous console.log and because it works if I move the ng-repeat over to the <tbody>
<div ng-repeat = "r in registers">
<!-- START HEADER -->
<tbody class="js-table-sections-header">
<tr>
<td class="text-center">
<i class="fa fa-angle-right"></i>
</td>
<td class="font-w600">Denise Watson</td>
</tr>
</tbody> <!-- END HEADER -->
<tbody>
<tr>
<td class="text-center"></td>
<td>
<!-- Summernote Container -->
<div class="js-summernote-air">
<p>End of air-mode area!</p>
</div>
</td>
</tr>
</tbody>
<!-- END TABLE -->
</div>
I was hoping someone could tell me if there is something I may be ignoring.
Thanks in advance.
I think I just ran into this same problem. It stems from <div> not being a valid elment within a <table>.
I'm guessing that since you have <tbody> there, that there is a <table> tag that was left out of your snippet. <div>s aren't allowed in a table, so the browser moves it before the table. In my situation, doing this, causes the angular scope to change so that there was nothing to iterate over. You can verify this by using the developer tools of your browser.
So, my guess is that you probably want to move the ng-repeat onto the <tbody> or <table> tag.
If you want to use ng-repeat in "div" tag means use "span"
inside div tag. instead of using "table" and its sub attributes..
else use your ng-repeat inside "table" or "thead" or "tr" also
it will iterate rows ...
than only ng-repeat will works.

ng-hide or ng-show does not work if its controlled from within a ng-repeat

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.

Why my ng-show doesn't work?

I have the following code :
<div ng-init="showDetail = false">
<table>
<tbody>
<tr ng-repeat="dataTable in arrayTableData">
<td ng-repeat="data in dataTable.data" ng-click="showDetail = true;">{{data}}</td>
</tr>
</tbody>
</table>
<div ng-show="showDetail">
<button ng-click="showDetail = false">Close</button>
</div>
</div>
My variable showDetail changes value when you click on a data of the table, but my div showDetailCell not appear.
If I change the initialisation of showDetail with true the detail appear and disappear when you click on the button, but the click on the cell doesn't display showDetailCell.
ng-repeat will get its own scope. Due to Javascript inheritance, whenever variable from parent object is assigned in child scope will create new variable. It will no more reference to parent object variable. Better use . notation in the scope variable.
Instead of showDetail, use detail.toggle will solve the problem.

Resources