AngularJS - How to access a binding value within ng-switch - angularjs

Within a ng-repeat I have a ng-switch conditional. I want the value of the ng-switch argument to be a binding. However the curly-bracket binding doesn't seem to be converted into the expected generated value. I'm aware that ng-switch creates a new scope, and that is surely causing the problem. I know about a 'dot' work-around but as the values here are coming from a service via a controller query, I can't figure out how to implement it in this situation.
html
<tr ng-repeat="user in users">
<td ng-switch on="editState"><p ng-switch-when="noEdit">{{user.username}}</p><input type="text" value="{{user.username}}" ng-switch-when="{{user.username}}"></td>
</tr>
controller.js
$scope.users = Users.query();
-edit-
this is the function that triggers the switch
$scope.editUser = function(usernameEdit) {
$scope.editState = usernameEdit;
};

A single $scope.editState won't work if you want to be able to edit multiple users at the same time. I suggest putting an edit property on each user, and use that property to control the ng-switch:
<tr ng-repeat="user in users">
<td ng-switch on="user.edit">
<span ng-switch-when="true">
<input type="text" value="{{user.username}}">
done
</span>
<p ng-switch-default>
edit {{user.username}}
</p>
</td>
</tr>
Fiddle

Related

How to get hidden input value that was dynamically stored using AngularJS

I'm trying to implement search method for "chat channels" that for every query it represents the compatible results from SQL table from the database.Each result can be distinguished by a unique ID that is also comes from the SQl table.I don't want to show the ID's so I put them in a hidden input for each result using ng-model.Also, for each, result the user have a possibility to subscribe to the channel (subscribe button) displayed in this result,so in order to save the subscription properly,I need to get the ID saved in the hidden input of the same result.
Here's what I tried:
<table class="table table-condensed">
<tr class="separating_line" ng-repeat="x in result">
<!-- ng-bind-html allows to bind a variable to the innerHTML part of the HTML element -->
<td>
<div class="col-md-8">
<h4><b style="color: gray;">{{ x.Name }}</b></h4>
<br><p> {{ x.Description }}</p>
</div>
<div class="col-md-2">
<small><label style="color: gray;">Subscribers </label>{{ x.Subscribersnum }}</label></small><br>
<input id="hiddenId" hidden="hide" ng-model="idval=x.ChanID" />
<button ng-click="subscribechannel()" class="btn btn-primary">Subscribe</button>
</div>
</td>
</tr>
</table>
In the controller I send it in the following way to convenient Servlet:
$http.get("http://localhost:8080/ExampleServletv3/subscribeservlet",{
params: {
subidval: $scope.idval
}
})
But when debugging the value that I get in the servlet is null.
How can I solve this? Any ideas?
Thanks
You don't need any hidden field to do what you want. All you need is to pass a parameter to your function:
<tr class="separating_line" ng-repeat="x in result">
...
<button ng-click="subscribechannel(x)" class="btn btn-primary">Subscribe</button>

Hide html element with same data in ng-repeat in angularjs

I have a array of task in which there are two duplicate departments, but i dont want to show the second duplicate record in ng-repeat, but only for the first record i want to show even if it is duplicate.
Here is my code, can anyone tell me where i'm going wrong.
<tr ng-repeat="t in item.requisitionTask track by t.id">
<td>
<div ng-hide="!$first ? item.requisitionTask[$index-1].department.departmentCode==$index.department.departmentCode : false">
{{t.department.departmentName}}</div>
</td>
Solved it by targeting the data particularly.
<td><div ng-hide="!$first ? item.requisitionTask[$index-1].department.departmentCode==item.requisitionTask[$index].department.departmentCode : false">
I suspect that you want to hide data if the previous item contains the same departmentCode as your current item. As mentioned in my comment, you should move this logic into a function on your controller's scope.
<tr ng-repeat="t in item.requisitionTask track by t.id">
<td>
<div ng-hide="isNotFirstOrSameCodeAsPrevious($index)">
{{t.department.departmentName}}
</div>
</td>
</tr>
In your controller:
function isNotFirstOrSameCodeAsPrevious($index) {
if ($index === 0) return false;
return item.requisitionTask[$index - 1].department.departmentCode ===
item.requisitionTask[$index].department.departmentCode;
}

Ng-click does not work outside of my tr tag 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.

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.

how do I execute a function in angular.js, from an input checkbox?

I have a list of things with switches. How can I get each switch to call a function with that object and the switch as parameters?
I have tried to set the "ng-change" directive for my checkboxes, but the function doesn't seem to get called. How do I call the toggleSync function I made?
I am a total newb, so I'm sorry if I need serious help.
<div id="track-list" ng-controller="Controller" ng-init="update()">
<div class="data-table">
<table class="table table-hover tablesorter">
<tr ng-repeat="item in items">
<td><a href='{[{item.path}]}/{[{item.id}]}'>{[{item.title}]}</a></td>
<td>{[{item.time_created}]}</td>
<td>
<div class=checkbox>
<input ng-model="value" id="check{[{$index}]}" type="checkbox" ng-checked="!item.deleted" ng-change="toggleSync(item.id, this)" ng-true-value="YES" ng-false-value="NO"/>
<label for="check{[{$index}]}">{{value}}</label>
</div>
</td>
</tr>
</table>
function Controller($scope) {
console.log("init");
$scope.items = [];
$scope.toggleSync = function(objectId, input) {
console.log("toggle sync");
}
}
Here is a plunker with your code and some corrections (ie: you used the tags delimiters {[{item.title}]} instead of {{item.title}})
Link: http://plnkr.co/edit/f9ngMMe8XJT4QDlA0Nx0?p=preview.
In this demo, there is a table with rows to display the item.path/item.id as a link, followed by the item.title and a checkbox which value is set to YES/NO according to its state. When the checkbox state has changed, the toggleSync function is called with the item as a parameter. The input checkbox has as model item.value, which is a property available inside of the toggleSync function.

Resources