ng-repeat with click modifying input - angularjs

<input ng-model = "val">
<a href ng-click="val = 1"> val = 1 </a>
<div class="test" ng-controller="Ctrl">
<table>
<thead>
<tr>
<th>let</th>
<th>num</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="thing in data">
<td>
<a href ng-click="val = 1">
{{thing.let}}
</a>
</td>
<td>{{thing.num}}</td>
</tr>
</tbody>
Is there a way to make an input change based on a click in an ng-repeat?
In this jsfiddle you can the input change with a click outside of an ng-repeat, but in the repeat it doesn't change the input.
http://jsfiddle.net/Hp4W7/2403/

The problem is that you are setting the val property in a child scope created by ng-repeat.
The solution is to create a function that assigns this value to the parent scope:
$scope.changeVal = function(val){
$scope.$parent.val = val;
}
And call it with ng-click="changeVal(1)"
Fiddle here: http://jsfiddle.net/nawd7jjc/

ng-repeat always make new scope for every iteration so if you change any primitive value inside ng-repeat ("val" in this case) then it will not refer to the actual "val". So to solve it, it should be a object type, for ex. obj.val something
Below is the working solution for this problem:
<div class="test" ng-controller="Ctrl" ng-init="obj.val=12345">
<input ng-model = "obj.val">
<a href ng-click="obj.val = 2"> val = 2 </a>
<table>
<thead>
<tr>
<th>let</th>
<th>num</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="thing in data">
<td>
<a href ng-click="obj.val = thing.num">
{{thing.let}}
</a>
</td>
<td>{{thing.num}}</td>
</tr>
</tbody>
</table>
<div>

Related

Angular ng-repeat with ng-if not working on tr tag

In the below Div i am using ng-repeat across some data to populate a list. while doing this i would like to NOT have a a certain TR tag created if it fits a certain requirement by using the ng-if directive on x.Equipment_Cost_Child != 0 However regardless of the expression I can't get the ng-if to work properly.
How can i get it to only show the TR if x.Equipment_Cost_Child > 0 ?
I have tried "x.Equipment_Cost_Child > 0"
I have also attached the ng-if directly to the tr tag instead of a div tag.
what do you think?
<div ng-repeat="x in reservationdata" ng-click="customerClickedEvent(x.ID)">
<table class="unit">
Item:{{$index + 1}}
<tr>
<td style="font-weight:bold">Equipment Type: </td>
<td style="font-weight:bold">{{x.EquipmentType}}</td>
</tr>
<tr>
<td style="font-weight:bold" >Equipment Count: </td>
<td style="font-weight:bold">{{x.Equipment_Count}}</td>
</tr>
<tr>
<td>Adult Quantity: </td>
<td>{{x.Equipment_Count_Adult}} Cost # ${{x.Duration_Cost_Adult}}</td>
</tr>
<div ng-if="x.Equipment_Cost_Child != 0"> //this line doesn't work
<tr>
<td>Child Quantity: </td>
<td>{{x.Equipment_Count_Child}} Cost # ${{x.Duration_Cost_Child}}</td>
</tr>
</div>
<tr>
<td>Sending Letters: </td>
<td> {{x.Equipment_Form_Status}}</td>
</tr>
<td> Total Cost For Item: </td>
<td> ${{(x.Equipment_Count_Adult * x.Duration_Cost_Adult)+(x.Equipment_Count_Child * x.Duration_Cost_Child)}}
Use both ng-if and ng-repeat within one tag:
<tr ng-repeat="feature in features"
ng-if="feature.id === 1" >
</tr>
Or, if you want to conditionally display some templates you may use ng-switch for example:
<tr
ng-repeat="feature in features"
ng-switch="feature.id" >
<span ng-switch-when="1"></span>
<span ng-switch-when="2"></span>
</tr>
Replace:
<div ng-if="x.Equipment_Cost_Child != 0"> //this line doesn't work
<tr>
<td>Child Quantity: </td>
<td>{{x.Equipment_Count_Child}} Cost # ${{x.Duration_Cost_Child}}</td>
</tr>
</div>
By:
<tr ng-show="x.Equipment_Cost_Child > 0">
<td>Child Quantity: </td>
<td>{{x.Equipment_Count_Child}} Cost # ${{x.Duration_Cost_Child}}</td>
</tr>
<div> tag is breaking your <tr> list. You can use ng-if directly on <tr>.
EDIT: use ng-show or ng-hide to show/hide elements. It is much lighter weight, because ng-if triggers a DOM recompilation and generates a new scope.

Angularjs hide row if another row is selected

I have a html/angularjs table that contains the ff :
<tbody ng-repeat="x in Persons">
<tr>
<td>{{x.FirstName}}</td>
<td>{{x.LastName}}</td>
<td>{{x.Department}}</td>
<td>
<a href"#" data-ng-click="x.show = !x.show">
Sales Details
</a>
</td>
</tr>
<tr>
<td ng-show="x.show">
<!--user sales details here-->
</td>
</tr>
</tbody>
Currently, if I click on the first row it shows the details but I need to click it again to hide it. I want to hide the first row details if the 2nd row is clicked. How do I go about this?
Try this. i hope this what exactly what you want.
var app = angular.module("app", []);
app.controller("name", function($scope) {
$scope.Persons=[{"FirstName":"Ramesh","show":false},{FirstName:"Suresh","show":false}];
$scope.showorhide = function(index){
var currentOption=$scope.Persons[index].show;
$scope.Persons.forEach(x=>x.show=false);
$scope.Persons[index].show=!currentOption;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="name">
<table>
<tbody ng-repeat="x in Persons">
<tr>
<td>First Name</td>
<td>
<a href"#/" style="color:red" ng-click="showorhide($index)">
open/close
</a>
</td>
</tr>
<tr ng-show="x.show">
<td >
{{x.FirstName}}
</td>
</tr>
</tbody>
</table>
</div>
you need a method for this
take a look
https://stackblitz.com/edit/js-tv6dog?file=index.js
js:
$scope.clicked = function(index){
let currentOption=$scope.Persons[index].show;
$scope.Persons.forEach(x=>x.show=false);
$scope.Persons[index].show=!currentOption;
}
html
<td>
<a href"#" data-ng-click="clicked($index)">
Sales Details
</a>
</td>
and of course add track by to ng-repeat
<tbody ng-repeat="x in Persons track by $index">

(AngularJS) Make a "ng-show" true specifically for one element in a ng-repeat

I'am begining in Angular, and i'am asking if is it possible to make a "ng-show" true for one element in a "ng-repeat", and make it false for others?
I explain myself with this code:
html file :
<tbody ng-repeat="elem in List" ng-init="visible = false">
<tr ng-class="elemSelected(elem)">
<td colspan="3">
<a href ng-click="clickElemScroll(Elem)" >
<span class="glyphicon" ng-class="visible? 'glyphicon-chevron-down' : 'glyphicon-chevron-right'"></span>
<strong>{{elem.name}} </strong>
</a>
</td>
</tr>
<tr ng-show="visible" >
blabla
</tr>
</tbody>
js file :
$scope.clickElemScroll = function (elem) {
if ($scope.elemSelected === elem) {
$scope.visible = true
}
};
As you know, the issue is all the elem will be scrolled, how to make only the element which I click visible ?
You can set a new property onto the element to use in the ngRepeat. Also, not sure what is going on with ng-class but I don't recommend using a function in there. If you are trying to set a class when selected, try something like ng-class="{'selected': elem.selected}"
<tbody ng-repeat="elem in List">
<tr ng-class="elemSelected(elem)">
<td colspan="3">
<a href ng-click="elem.selected = !elem.selected">
<span class="glyphicon" ng-class="visible? 'glyphicon-chevron-down' : 'glyphicon-chevron-right'"></span>
<strong>{{elem.name}} </strong>
</a>
</td>
</tr>
<tr ng-show="elem.selected">
blabla
</tr>

AngularJS ng-show Not Working with ng-click?

i don't understand what my ng-show not working when i click on my button with ng-click...
thanks for help.
<div ng-show="showMe == 1">
<h5>Ajouter</h5>
<input type="texte">
</div>
<table>
<thead>
<tr>
<th>Numéro :</th>
<th>Type de Produit :</th>
</tr>
</thead>
<tbody ng-repeat="product in shopCtrl.tableProduct">
<tr>
<td>{{product.id}}</td>
<td>{{product.name}}</td>
<td class="text-right">
<div>
<button ng-click="showMe = 1">Ajouter</button>
</div>
</td>
</tbody>
</table>
The answer of gtlambert is true. However if you have more than one level of ng-repeat or another directive that does the same thing you'll have trouble.
To not have any trouble use objects like this :
$scope.params = {showMe:0};// init in controller
<div ng-show="params.showMe == 1">
<button ng-click="params.showMe = 1">
This will always works whatever the number of ng-repeat/directive you use.
When you use ng-repeat this creates a new scope. To access the main controller scope from inside the ng-repeat you need to use $parent.
So, change your ng-click to $parent.showMe = 1 and this will fix the problem:
<button ng-click="$parent.showMe = 1">Ajouter</button>
Here you go. I have a working example. showMe becomes a member of your controller.
function ShopController() {
this.showMe = false;
this.tableProduct = [{
id: 1,
name: "Bar"
}];
}
angular.module('app', [])
.controller('ShopController', ShopController);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ShopController as shopCtrl">
<div ng-show="shopCtrl.showMe">
<h5>Ajouter</h5>
<input type="texte">
</div>
<table>
<thead>
<tr>
<th>Numéro :</th>
<th>Type de Produit :</th>
</tr>
</thead>
<tbody ng-repeat="product in shopCtrl.tableProduct">
<tr>
<td>{{product.id}}</td>
<td>{{product.name}}</td>
<td class="text-right">
<div>
<button ng-click="shopCtrl.showMe = true">Ajouter</button>
</div>
</td>
</tbody>
</table>
</div>

ng-show does not work with custom directive

I've just started using AngularJS and wanted to create a custom template directive for creating "in-place" editable tables. The idea would be to have something like:
<tr ng-repeat="customer in model.customers">
<ng-template ng-hide="customer === model.selectedCustomer"> <!-- display template-->
<td>{{customer.name}}</td>
</ng-template>
<ng-template ng-show="customer === model.selectedCustomer"> <!-- edit template -->
<td><input type="text" ng-model="customer.name"/></td>
</ng-template>
</tr>
It could then also be extended to specify a templateUrl e.g. <ng-template template-url="foo.html"></ng-template>
When I apply the ng-show directive to my custom directive it does not work. Here's the code for my directive:
var demo = angular.module("demo", [])
.directive("ng-template", function() {
return {
restrict: "E",
replace: true,
transclude: true
}
});
and HTML (http://jsfiddle.net/benfosterdev/ASXyy/):
<div ng-app="demo">
<table>
<tr ng-repeat="name in ['jane', 'john', 'frank']">
<ng-template ng-show="name !== 'frank'">
<td>{{name}}</td>
</ng-template>
</tr>
</table>
</div>
Furthermore, when I look at the generated HTML my custom directive doesn't even appear in the table:
<div ng-app="demo" class="ng-scope">
<ng-template ng-show="name !== 'frank'" class="">
</ng-template>
<table>
<tbody>
...
</tbody>
</table>
</div>
Essentially I'm trying to avoid writing code like this (setting the ng-show directive on every <td> element):
<table>
<tr ng-repeat="customer in customers">
<ng-template>
<td ng-hide="isSelected">{{customer.name}}</td>
<td ng-hide="isSelected">{{customer.age}}</td>
<td ng-hide="isSelected"><button ng-click="edit(customer)"</td>
<td ng-show="isSelected"><input type="text" ng-model="customer.name"/></td>
<td ng-show="isSelected"><input type="text" ng-model="customer.age"/></td>
<td ng-show="isSelected"><button ng-click="save(customer)"</td>
</ng-template>
</tr>
</table>
A couple of things occur to me when I look at your code.
ng-include offers very similar functionality to your proposal for extending ng-template. If you're going to load a view based on the state of the underlying model then I think this would be the way to go.
If you're not going to be loading the template from a separate view file, why not just use ng-show (or ng-if / ng-switch, which I prefer in most cases) on your td element?
Here is some example code using ng-include:
<table>
<thead>
<th>One</th>
<th>Two</th>
<th>Three</th>
<th></th>
</thead>
<tbody>
<tr ng-repeat="item in items" ng-include="getTemplate(item)"></tr>
</tbody>
</table>
Here is the full JSFiddle: http://jsfiddle.net/qQR6j/2.
Use ng-repeat-start and ng-repeat-end to specify the two alternative <tr> tags.
<div ng-app="demo">
<table ng-controller="Ctrl">
<tr ng-repeat-start="name in ['jane', 'john', 'frank']" ng-hide="isSelected(name)">
<td>{{name}} <button ng-click="select(name)">edit</button></td>
</tr>
<tr ng-repeat-end ng-show="isSelected(name)">
<td>{{name}}!</td>
</tr>
</table>
</div>
With this javascript
var demo = angular.module("demo", []);
demo.controller("Ctrl",
function Ctrl($scope) {
var selected;
$scope.isSelected = function(name) {
return selected === name;
};
$scope.select = function(name) {
selected = name;
};
});
Live example: http://jsfiddle.net/6FtjG/1/
Your browser renders the 'ng-template' outside of the table because its not a valid child of tr. Even if you have set replace to true, the directive needs to be rendered before it can be replaced.
You can see it is because of the table, because this does work:
<div>
<div ng-repeat="name in ['jane', 'john', 'frank']">
<ng-template ng-show="name !== 'frank'">
<div >{{name}}</div>
</ng-template>
</div>
</div>
see: Fiddle
This is something your browser does so you cannot avoid it.

Resources