ng-hide is not working - angularjs

I am new to angularjs.
When I click on "Click Me" the toggle method is called. The value of test changes from false to true, but ng-hide is not acknowledging the new value of test.
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr>
<td><span ng-hide="{{test}}">Testing</**strong text**td>
<td><span>hello</span></td>
</tr>
<tr>
<td style="cursor:pointer"><span ng-click="toggle()">Click Me</td>
<td><span>hello</span></td>
</tr>
</table>
</div>
script.js
var appX = angular.module('myApp', []);
appX.controller('myCtrl', function($scope){
$scope.test = false;
$scope.toggle = function(){
$scope.test = true;
console.log("toggle is working");
};
});

test is not an expression, so remove the curly braces,
<td><span ng-hide="test">Testing</**strong text**td>

Its a syntax error. You are combining both expression binding and directive binding. Below code should work.
Replace ng-hide="{{test}} with ng-hide-"test"

You don't need to tell that you are writing a angular code inside ng-hide as that is already angular directive, it will ditect test variable itself, so don't need to provide a braces over there to.
Simply try like : ng-hide="test"

The ngHide directive shows or hides the given HTML element based on the expression provided to the ngHide attribute.
Since it accepts expression so no need of curly braces!
Change:
ng-hide="{{test}}"
to
ng-hide="test"
You need to use curly braces if the directive was expecting string instead of expression as an attribute value.
Fore more info refer Angular Docs.

Some code changes :
You forgot to close the </span>
<span ng-hide="test">Testing</span>
Remove **strong text** from the closing </td> element.
<td><span ng-hide="test">Testing</span></td>
Ass suggested by Sajeetharan, test is not an expression, so remove the curly braces.
<td><span ng-hide="test">Testing</span></td>
Working demo :
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.test = false;
$scope.toggle = function(){
$scope.test = true;
console.log("toggle is working");
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<table>
<tr>
<td><span ng-hide="test">Testing</span></td>
<td><span>hello</span></td>
</tr>
<tr>
<td style="cursor:pointer"><span ng-click="toggle()">Click Me</span></td>
<td><span>hello</span></td>
</tr>
</table>
</div>

Related

On Checking Check Box Get the child Object Angular Js

I want to achieve a scenario in which when i click TV1 radiobutton i want to get all of its children in the object i.e ProductName TV1, Number Of Channels 1 . Below is my code
Markup :
<div ng-repeat="product in ProductTypes">
<div ng-show="product.selected" ng-repeat="Product in product.ProductList">
<label>
<input type="radio" name="internetProduct{{$parent.$index}}"
ng-model="Product" ng-value="{{Product}}" ng-click="GetValue()" />
{{Product.ProductName}}
</label>
<table>
<tr ng-repeat="(key, val) in Product">
<td>{{key}}</td>
<td>{{val}}</td>
</tr>
</table>
</div>
</div>
Controller (js) :
var app = angular.module('ProductCatalog.controllers', ['ui.bootstrap'])
.controller('OfferCtrlr', function ($scope, $http, $modal) {
$scope.GetValue = function() {
var a = $scope.radio;
}
})
Right now, nothing is coming in $scope.radio. Please helpp.
You can pass the product instance to your ng-click function call as a parameter. So whenever the radio button is clicked, the corresponding product instance will be available inside your function. The below code will give you the instance for radio button. Do the same thing for checkbox, call a function on checking and pass the corresponding instance.(you have not provided the markup for checkbox)
HTML:
<div ng-repeat="product in ProductTypes">
<div ng-show="product.selected" ng-repeat="Product in product.ProductList">
<label>
<input type="radio" name="internetProduct{{$parent.$index}}"
ng-model="checked" ng-value="Product" ng-click="GetValue(Product)" />
{{Product.ProductName}}
</label>
<table>
<tr ng-repeat="(key, val) in Product">
<td>{{key}}</td>
<td>{{val}}</td>
</tr>
</table>
</div>
</div>
JS:
var app = angular.module('ProductCatalog.controllers', ['ui.bootstrap'])
.controller('OfferCtrlr', function ($scope, $http, $modal) {
$scope.GetValue = function(product) {
console.log(product);
}
})
Well, Load all the parent and child objects then show/hide through the AngularJS, through that you will achieve your scenario.

NG-Repeat with NG-show Not executing with dynamic data

Im trying to get a client list and detail view to work but i cant seem to figure it out. The NG-init wont work nor will the ng-click, I can get it to work if its hard coded, but when dynamically loading data it wont work. Id appreciate if anyone can point out the correct way to execute this.
html:
<div ng-controller="ClientCtrl as clients">
<table class="listview">
<tbody>
<tr ng-repeat="stuff in clients.records">
<td><a ng-click="client = {{$index}}" class="client-link">{{stuff.first_name}} {{stuff.last_name}}</a></td>
</tr>
</tbody>
</table>
<div class="detailview">
<div ng-repeat-start="things in clients.records " ng-if="$first">
<div id="contact-{{$index}}" class="tab-pane active" ng-show="client == {{$index}}" ng-init="client = {{$index}}">
<h2>{{things.first_name}} {{things.last_name}}</h2>
</div>
</div>
<div ng-repeat-end="things in clients.records " ng-if="!$first">
<div id="contact-{{$index}}" class="tab-pane active" ng-show="client == {{$index}}" ng-init="client = {{$index}}">
<h2>{{things.first_name}} {{things.last_name}}</h2>
</div>
</div>
</div>
</div>
controller.js:
function ClientCtrl($scope,$http,$interval, $rootScope){
var ClientCtrlData = this;
$http.get("api/clients").success(function(response) {
ClientCtrlData.records = response.records;
});
var promise;
// simulated items array
$scope.items = [];
// starts the interval
$scope.start = function() {
// stops any running interval to avoid two intervals running at the same time
$scope.stop();
// store the interval promise
promise = $interval(
function(){
$http.get("api/clients").success(function(response) {
ClientCtrlData.records = response.records;
console.log("People loaded");
});
}.bind(this)
,1000000 * 10);
};
// stops the interval
$scope.stop = function() {
$interval.cancel(promise);
};
// starting the interval by default
$scope.start();
$scope.$on('$destroy', function() {
$scope.stop();
});
}
angular
.module('inspinia')
.controller('ClientCtrl',ClientCtrl)
plnkr http://plnkr.co/edit/yzN787uL6C82Z6g6JNOq
First off, no need to use ng-click="client = {{$index}}", you're already saying that the code should be parsed by angular so no need for the angular brackets {{ }}.
Second, you need to scope client inside ng-click="client = $index" for example as such ng-click="clients.client = $index", otherwise angular doesn't know where to look for the property.
I also wonder what the need for the ng-init is? I'm guessing this is just mock functionality, because now it will just set the clients.client variable for each item until it ends up being the last one in the list.
In any case, here's a version of your code with fixed syntax, you should be able to take it from here
http://plnkr.co/edit/UyKYvxpErcehizSBKaqy?p=preview
<div ng-controller="ClientCtrl as clients">
<table class="listview">
<tbody>
<tr ng-repeat="stuff in clients.records">
<td>
<a ng-click="clients.client = $index" class="client-link">{{stuff.first_name}} {{stuff.last_name}}</a>
</td>
</tr>
</tbody>
</table>
<div class="detailview">
<div ng-repeat="things in clients.records ">
<div id="contact-{{$index}}" class="tab-pane active" ng-show="clients.client == $index" ng-init="clients.client = $index">
<h2>{{things.first_name}} {{things.last_name}}</h2>
</div>
</div>
</div>
</div>

How can I prevent ngClick to go through parent directive when nesting custom directives inside each other

This question follows on a previous question I had about getting these directives to work:
Previous question about dynamically generating a grid
My Html looks like this:
<div ng-grid ng-collection="entries" ng-collection-headings="headings" ng-button-click="theAction(inp)">
<div ng-checkbox-column></div>
</div>
It generates Html that looks like this:
<div ng-grid="" ng-collection="entries" ng-collection-headings="headings" ng-button-click="theAction(inp)" class="ng-isolate-scope">
<table class="table table-bordered">
<thead>
//Truncated for brevity
</thead>
<tbody>
<tr id="item0" ng-repeat="item in ngCollection" class="ng-scope">
<td ng-checkbox-column="">
<label>
<input type="checkbox" ng-model="item.checked" ng-click="tempButtonClicked()" class="ng-pristine ng-untouched ng-valid"> From the checkbox directive.
</label>
</td>
</tr>
//Truncated for brevity
</tbody>
</table>
</div>
The problem I am having is that the ng-click events of the ng-checkbox-column directive cannot be assigned from the myCtrl controller outside of the ng-grid directive. This is because I created an isolate scope for the ng-grid directive and the ng-checkbox-column directive is sharing the scope of the ng-grid directive.
Is there a way around this?
What options do I have to get this to work?
Is my only option to use events?
The reason I created an isolate scope for the ng-grid directive is so that it can be used more than once in the same controller. Therefore I cannot share the scope of the myCtrl controller.
Here is a plunker showing the problem:
Plunker with working dynamic grid, but limited ng-click
Looking at the plunker, you can click on the buttons to see where the click happens in relation to the "scopes".
I would like the checkboxes to fire their own events and update that status without having to go through the ng-grid directive.
Currently I am handling the ng-click with this:
ng-click='tempButtonClicked()'
and in the ng-checkbox-column controller:
$scope.tempButtonClicked = function () {
var val = "From the checkbox directive";
$scope.buttonClicked(val);
};
where $scope.buttonClicked(val); is a reference to a function defined in the controller of the ng-grid directive:
$scope.buttonClicked = function (inp) {
if (typeof inp != 'undefined')
inp = inp + ", through the grid directive.";
else
inp = "From the grid directive.";
$scope.ngButtonClick({ inp: inp });
};
which in turn, binds it to a function specified through an isolate scope variable defined in the ng-grid directive as:
scope: {
ngButtonClick: "&"
},
I hope what I'm explaining makes sense and someone can shed some more light on the subject.
What I would like to have:
Is a way to bind a function to the ng-checkbox-column directive so that I can call a function in the myCtrl controller when it is clicked.
The reason for this is that I may have multiple column templates in a grid and perform different actions depending on which column is clicked.
With the current way it works, I'll have to define x-amount of functions in the ng-grid directive to use with the templates, which seems like a sloppy way of doing it.
I would LOVE to be able to do this:
<div ng-checkbox-column ng-click-action="someDefinedFunctionInMyCtrl()"></div>
which generates this:
<td ng-checkbox-column="">
<label>
<input type="checkbox" ng-model="item.checked" ng-click="someDefinedFunctionInMyCtrl()"> From the checkbox directive.
</label>
</td>
Got it working using an expression as an attribute and ng-transclude:
http://plnkr.co/edit/3XmsE3d44v8O0AxOoUeF?p=preview
JS:
.directive("ngGrid", function () {
return {
[...]
transclude: true, //added transclude
template: function (element, attrs) {
var children = element.html();
children = children.trim().replace(/div/g, "td");
var htmlText = [
"<input type='button' ng-click='buttonClicked()'",
" value='From the grid directive' />",
"<table class='table table-bordered'>",
"<thead><tr>",
"<th ng-repeat='heading in ngCollectionHeadings'>{{heading}}</th>",
"</tr></thead>",
//added ng-transclude
"<tbody><tr id='item{{$index}}'",
" ng-repeat='item in ngCollection' ng-transclude>",
children,
"</tr></tbody>",
"</table>"
].join('');
return htmlText;
},
[...]
};
})
.directive("ngCheckboxColumn", function () {
return {
restrict: "A",
scope: {
//expression as an attribute
myClick: '&'
},
[...]
controller: function ($scope, $element) {
$scope.tempButtonClicked = function () {
var val = "From the checkbox directive";
//call the expression (val will be available in the expression)
$scope.myClick({val: val});
};
}
};
})
HTML:
<div ng-controller="myCtrl">
<div ng-grid ng-collection="entries"
ng-collection-headings="headings" ng-button-click="theAction(inp)">
<!-- added the my-click expression (use val here) -->
<div ng-checkbox-column my-click="ctrl.theAction(val)"></div>
</div>
<p id="btnClickVal">{{actionVal}}</p>
<input type="button" ng-click="theAction(fromParent)"
value="From the parent controller" />
</div>

how to access data from scope object

I need to get data from $scope.List2 object:
<div ng-app="App">
<div id="firstlist" ng-controller="Controller">
<table id="requesttable" class="RequestTable">
<tr ng-repeat="item2 in List2">
<td class="selectedItem">{{item2.Title}}</td>
</tr>
</table>
<button id="Reqbutton" onclick="SendRequest()">Send</button>
</div>
</div>
The problem is that if I put SendRequest function inside controller then it cannot be called (I get "SendRequest() is not defined" message). And if I put the function outside the controller I cannot access List2.
What do I miss?
As #sp00m suggested. You should use ng-click instead of onclick on the button. The html would look like this then:
<button id="Reqbutton" ng-click="sendRequest()">Send</button>
In your controller
app.controller('testController', ['$scope', function {
$scope.list2 = [];
$scope.sendRequest = function() {
var test = $scope.list2;
...
};
}]);

directive only works inside another directive

i made a directive for filtering data. It uses scope: true and no transclusion. Somehow it only works inside an ng-switch. Maybe also other directives but i havent tried.
My html looks like this:
<my-filter source="{{foodArray}}" filter="reaction,category"> // source and filter are properties on the directive scope
<div>
<div class="span3">
<table class="table table-bordered">
<tr data-ng-repeat="item in filters.reaction"> // filters property of directive scope
<td><input type="checkbox" data-ng-model="item.isChecked" data-ng-change="filterCtrl.filterList()"></td>
<td>{{ item.value }}</td>
</tr>
</table>
</div>
</div>
<table>
<tbody>
<tr data-ng-repeat="food in filteredData"> // filteredData object on the directive scope
// interating through filteredData
</tr>
</tbody>
</table>
</my-filter>
here is my directive and its controller:
angular.module('myModule', [])
.directive('myFilter', function() {
return {
restrict: 'E',
scope: true,
controller: ["$scope", function ($scope) {
var filterCtrl = this;
$scope.filters = {};
filterCtrl.inputArray = [];
filterCtrl.filterList = function() {
/* some code where tmp array is created */
$scope.filteredData = tmp;
}
}],
controllerAs: 'filterCtrl',
link: function(scope, element, attrs, filterCtrl) {
filterCtrl.inputArray = angular.fromJson(attrs.source);
scope.filteredData = filterCtrl.inputArray;
// ...
}
}
});
FilteredData and filters are property of the directives scope. Now when i remove the ng switch around it the data is empty. Also the scope.source property can be an array or an object. When i remove the ng switch and give it an object as source it actually throws a syntax error: SyntaxError: Unexpected end of input
at Object.parse (native)
at Object.fromJson
Which it doesnt throw when i use an array.
Not sure what to make of this. If anybody had this problem before i would love to hear from you.

Resources