Show/hide element with angularjs - angularjs

Hi i want to show and hide div element when i click on my button with angular using ng-click and ng-show. This is my code:
HTML
<ons-page ng-controller="search">
<ons-button class="ion-android-search" ng-click="showDetails = ! showDetails"></ons-button>
<input ng-show="showDetails" type="search" class="search-input" ng-model="search" placeholder="Buscar">
</ons-page>
JS
var app = angular.module('app');
app.controller('search', function($scope){
$scope.showDetails = true;
});
I try to use this example code: http://jsfiddle.net/asmKj/
This is my project: http://recorramisiones.com.ar/rutadelaselva/app/, go to "alojamientos" menu item to see my problem.
Thanks!

The button is not within your ng-controller.
This part:
<ons-button class="ion-android-search ng-isolate-scope button effeckt-button button--large--cta slide-left" style="font-size:20px;" modifier="large--cta" ng-click="showDetails = ! showDetails">
is defined before this part:
<div ng-app="" ng-controller="search" class="ng-scope">
So when you try to modify showDetails it doesn't do anything.

Related

Get value from ng-repeat outside of ng-repeat

I got a header bar outside of ng-repeat:
<ion-header-bar class="headerView" ng-show="!hideAll">
<button id="shareImage" class="button button-icon icon ion-share" style="color:#fff" ng-click="shareImageTo({{originalImageSource}})"></button>
<button class="button button-outline button-light close-btn" ng-click="closeModal()">{{::actionLabel}}</button>
</ion-header-bar>
And a slidebox where images are shown:
<ion-slide ng-repeat="single in slides track by $index">
<div class="item item-image gallery-slide-view">
<img ng-src="{{single.original}}">
<input type="text" ng-model="originalImageSource" value="{{single.original}}">
</div>
</ion-slide>
{{single.original}} is an URL to an image. But this URL is not placed in the input field. It is shown when I´m deleting this ng-model statement.
If a user clicks the button #shareImage the ShareImageTo(URL) function is executed. But with an undefined value for {{originalImageSource}}.
Any thoughts on how i could pass the URL in {{single.original}} to this ShareImageTo() function?
With $ionicSlideBoxDelegate you can get the current slide index via currentIndex(). That enables you to get the URL by $scope.slides[$ionicSlideBoxDelegate.currentIndex()].original in your ShareImageTo()-method like that:
$scope.ShareImageTo = function() {
var URL = $scope.slides[$ionicSlideBoxDelegate.currentIndex()].original;
//your logic
};
Another approach would be to use ion-slide-box's directive on-slide-changed.
Template:
<ion-slide-box on-slide-changed="slideHasChanged($index)">
...
</ion-slide-box>
Controller:
$scope.slideHasChanged = function(index) {
$scope.originalImageSource = $scope.slides[index].original;
//.. some more logic
}
Just create a div that wrap around both your navbar and your slidebox, and place your ng-repeat in that div :)

ng-repeat filter is not working for repeat variable assignments

This JS Fiddle will give better information on the code.
The selected item should filter other value and i shall have a button outside the list item what will reassign the selected value to null so all list items are displayed.
Clicking on the radio button it should hide the other elements.
CONTROLLER
var myApp = angular.module("repeat",["ngSanitize"]);
myApp.controller("repeatController", function($sce, $window, $scope){
$scope.test ="Controller is working fine";
$scope.lists=[{"name":"asdf","desc":"dummy text 1"},{"name":"wee","desc":"dummy text 2"},{"name":"fgs","desc":"dummy text 3"}]
});
HTML
<li ng-repeat ="list in lists | filter:{name:selected}">
<label ng-click="selected = list.name">
<input type="radio">
{{list.name}}{{selected}}
</label>
</li>
If I correctly understood what you need here is the JSFiddle to hide the radio button not clicked:
HTML:
<div ng-app="repeat" ng-controller="repeatController">
<li ng-repeat ="list in lists" ng-hide="selected !== undefined && selected !== list.name">
<label ng-click="$parent.selected = list.name">
<input type="radio" name="selector" />
{{list.name}}-{{selected}}
</label>
</li>
</div>
JS:
var myApp = angular.module("repeat", []);
myApp.controller("repeatController", function($sce, $window, $scope){
$scope.test ="Controller is working fine";
$scope.lists=[{"name":"asdf","desc":"dummy text 1"},{"name":"wee","desc":"dummy text 2"},{"name":"fgs","desc":"dummy text 3"}]
});
As suggested, you also need to remove the ngSanitize from the Fiddle or add it as file too (for example adding this resource but for the purpose of the fiddle you don't need it https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-sanitize.min.js)
You have the problem with ngSanitize, Please remove the ngSanitize in your module then it's working good.
Your module should be like this below code
var myApp = angular.module("repeat",[]);
See this Working Demo

Script block not working in AngularJS ng-repeat section

The script block not working in AngularJS ng-repeat section. The issue is given below.
<div ng-repeat="user in users">
<input type="text" ng-model="{{user.mobile}}" ng-value ="{{user.mobile}}">
<script>
$(function () {
var mobile ="{{user.mobile}}";
alert("{{user.mobile}}");
});
</script>
</div>
Script-tags in AngularJS expression will not evaluate.
This is also not the way you want to do this. Do this in a controller, directive, but not in your DOM.
https://groups.google.com/forum/?fromgroups#!topic/angular/9d-rhMiXDmg

AngularJS - ui-bootstrap accordion - using ng-controller inside ng-repeat doesn't work

I'm trying to construct an accordion list that shows more details when the accordion expands. Here is a simplified version of the template:
<body ng-controller="MainController as main">
<accordion>
<accordion-group ng-repeat="r in main.results" ng-controller="DetailsController as d">
<accordion-heading ng-click="d.getDetails(r.id)">
{{r.name}}
</accordion-heading>
<ul>
<li ng-repeat="v in d.details">{{v.detail}}</li>
</ul>
</accordion-group>
</accordion>
</body>
The DetailsController initially has an empty details array, but when the function getDetails() is called, that array is populated by a service (detailsService is simply an abstracted $resource call). This part works when not being applied to an accordion, but in this specific situation, nothing happens with the accordion heading is clicked. See below:
app.controller('DetailsController', function(detailsService) {
var vm = this
var details = []
var detailsPopulated = false
var getDetails = function(id) {
console.log('getDetails()')
if (!vm.detailsPopulated) {
console.log('Getting details')
detailsService.get({id: id}, function(data) {
vm.details = data.results
vm.detailsPopulated = true
});
}
}
return {
details: details,
getDetails: getDetails
}
});
This controller works in other cases, but for some reason, the ng-click on the accordion header does not invoke the getDetails function at all - if it did, I would see "getDetails()" in the console, since that is the first statement of the getDetails function.
Even simpler: setting up a controller with mock "details" doesn't work.
app.controller('DetailsController', function() {
var details = [{detail: 'Test'}]
return {
details: details
}
});
Template:
<body ng-controller="MainController as main">
<accordion>
<accordion-group ng-repeat="r in main.results" ng-controller="DetailsController as d">
<accordion-heading>
{{r.name}}
</accordion-heading>
<ul>
<li ng-repeat="v in d.details">{{v.detail}}</li>
</ul>
</accordion-group>
</accordion>
</body>
Not even this simplified example with the service and ng-click removed works.
Can anyone advise a solution? I am also trying to accomplish this using the "controller as" technique instead of using $scope everywhere.
You can not bind ng-click to <accordion-heading> beacause ui.bootstrap will use different DOM for heading. You can take a look at developer console to see what ui.bootstrap translate <accordion-heading> into DOM.
<div class="panel-heading">
<h4 class="panel-title">
<span class="ng-scope ng-binding">Header 1</span>
</h4>
</div>
I think you want to dynamically load the content of accordion. One way to achieve this is to $watch when the accordion is opened and perform loading. I have created this fiddle to demonstrate the idea. Something you must notice :
You can not put ng-controller inside accordion-group because it will raise error multiple directive asking for isolated scope. This is beacause <accordion-group> is an isolated scope and angular will not allow two scope : one from controller scope and one from directive isolated scope to bind into the same html. Reference. One way to work around it is to put a div with ng-controller and ng-repeat outside accordion-group
<div ng-repeat="r in main.results" ng-controller="DetailsController as d">
<accordion-group>
...
</accordion-group>
</div>
You can add attrs is-open to accordion-group and $watch for its change and perform loading. Accordion directive will change is-open value when you open or close the accordion.
Hope it helps.

How to show preloader inside button instead text Angular JS?

I use Angular JS library ngActivityIndicator.
I tried to show preloader inside element div instead text when button is pushed:
<div ng-activity-indicator="CircledDark">
<div ng-click="Add();" class="btn shareBtn">
<div ng-view></div>
<span>Text</span>
</div>
</div>
I posted <div ng-view></div> inside and have added directive ng-activity-indicator="CircledDark" to parent element.
When I click button, I call function that display preloader:
$activityIndicator.startAnimating();
But preloader is created outside of button:
<div ng-show="AILoading" class="ai-circled ai-indicator ai-dark-spin"></div>
This is official documantation, from here I have taken example:
https://github.com/voronianski/ngActivityIndicator#directive
How to show preloader inside button instead text Angular JS?
I think the only solution is to separate your ng-view and button, at least they do something similar in their sample page. So, in your markup you could do something like this:
<div ng-click="add()" class="btn btn-default" ng-activity-indicator="CircledDark">
<span ng-show="!AILoading">Add</span>
</div>
<div ng-view ng-show="!AILoading">{{ delayedText }}</div>
And in your controller:
$scope.delayedText = "";
$scope.add = function() {
$activityIndicator.startAnimating();
$timeout(function() {
$scope.delayedText = "Here we are!";
$activityIndicator.stopAnimating();
}, 3000);
};
Here is full Demo, you can play with CSS a little so the size of the button won't change when text is replaced by icon.

Resources