Show/Hide Angular Directive On Button Click - angularjs

I have a HTML page with three buttons. I also have two Angular directives. What I'm trying to accomplish is when button a is clicked, I want directive 1 to show and directive 2 to hide. When button 2 is clicked, I want directive 1 to hide and directive 2 to show. Here is are my directives:
.directive('topPosts', function () {
return {
restrict: 'E',
templateUrl: 'topPosts.html',
controller: 'PostsController'
}
});
.directive('otherPosts', function () {
return {
restrict: 'E',
templateUrl: 'otherPosts.html',
controller: 'PostsController'
}
});
here is my controller:
.controller('PostsController', ['$scope', 'PostsFactory', function($scope, PostsFactory) {
$scope.posts = [];
$scope.showTopPosts = true;
$scope.showOtherPosts = false;
$scope.topPosts = function() {
$scope.showTopPosts = true;
$scope.showOtherPosts = false;
};
$scope.otherPosts = function() {
$scope.showTopPosts = false;
$scope.showOtherPosts = true;
};
$scope.areTopPosts = function(posts) {
return posts.privacy === 'public' && posts.comments > 10 && posts.views > 9000 && posts.title.length < 40;
};
$scope.areOtherPosts = function(posts) {
return posts.comments <= 10 && posts.views <= 9000 && posts.title.length >= 40;
};
var init = function() {
PostsFactory.getPosts.success(function(data) {
$scope.posts = data;
});
};
init();
}]);
here is my partial that holds both directives:
<div class="container">
<top-posts ng-show='showTopPosts'></top-posts>
<other-posts ng-show='showOtherPosts'></other-posts>
</div>
and here is my index.html:
<body ng-controller='PostsController'>
<nav class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="/main"></a>
</div> <!-- END NAVBAR-HEADER -->
</div> <!-- END CONTAINER-FLUID -->
</nav>
<div class="container">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default" ng-click="topPosts()">Top Posts</button>
<button type="button" class="btn btn-default" ng-click="otherPosts()">Other Posts</button>
<!-- <button type="button" class="btn btn-default" ng-click="dailyTopPost()">Daily Top Post</button> -->
</div>
</div>
<div ng-view class='slide-animation'></div>
What's currently happening is the functions are getting called, but the directives are not showing/hiding on the button clicks.

I put work code in a codepen and it seems to be working fine http://codepen.io/arthur_souviron/pen/pEMMaJ/
I think your issue come from the way you store $scope.showTopPosts
and $scope.showOtherPosts. Try to store them inside an object instead of setting them directly under $scope
Eg :
$scope.data = {
showTopPosts: true,
showTopPosts: false
}
and in your template : <top-posts ng-show="data.showTopPosts"></top-posts>

Simply add a div before the directive:
<div class="container">
<div ng-show='showTopPosts'><top-posts ></top-posts></div>
<div ng-show='showOtherPosts'><other-posts ></other-posts></div>
</div>

Related

Angular Scroll on Click

I am having an issue getting Angular Scroll to work.I am trying to scroll from the landing div to another section on the page with a button click. My code formatted really strangely, so let me know if further clarification is needed.
HTML
<div class="cover">
<div class="big-logo">
<i class="fa fa-trello"></i>
<span> My Kanban</span>
<br>
<button class="arrow" ng-click="bc.toLists()" du-smooth-scroll>
<i class="fa fa-angle-double-down fa-sm animated flash infinite" aria-hidden="true"></i>
</button>
</div>
</div>
<div class="story-board content">
<button class="add-list" ng-click="bc.addingList = !bc.addingList">
Add List
</button>
<div ng-if="bc.addingList">
<form ng-submit="bc.addList(bc.newList)">
<input style="margin-left: 5px" ng-model="bc.newList.name"/>
<button type="submit">+</button>
</form>
</div>
<div class="list" ng-repeat="list in bc.lists">
<button style="font-size: 10px;background: none;border:none; color: black" ng-click="bc.removeList(list)">x</button>
<list-component list-obj="list"></list-component>
</div>
</div>
init.js
angular.module('kanban', ['duScroll'])
app.js
angular.module('kanban')
.component('boardComponent', {
templateUrl: 'app/components/board/board.html',
controller: BoardController,
controllerAs: 'bc'
})
BoardController.$inject = ['EsService']
function BoardController(EsService) {
var bc = this;
bc.lists = EsService.getLists();
bc.addingList = false;
bc.removeList = function(list){
EsService.removeList(list.id);
}
bc.addList = function(list){
EsService.createList(list);
bc.newList = {};
}
bc.toLists = function() {
bc.cover = angular.element(document.getElementsByClassName('cover'));
bc.content = angular.element(document.getElementsByClassName('content'));
bc.cover.scrollTo(bc.content, 0, 1000);
}
}
For a JQuery free answer, you can use $anchorScroll
Create your anchor link:
<button ng-click="$ctrl.scrollTo('anid')">Scroll</button>
Create the anchor to scroll to:
<div id="anid">Land here</div>
Then your controller:
controller: function($anchorScroll) {
this.scrollTo = function(id) {
$anchorScroll(id);
}
}
I would recommend letting your controller handle the scrolling as opposed to the directives. You will have much tighter control that way and can therefore debug any issues.
Here's an example using the scrollToElement method. Once you have this logic in place you can switch it out to any method you need.
Here's a working demo
angular
.module('app', ['duScroll'])
.component('cmpExample', {
templateUrl: 'path/to/template.html',
controller: function($document) {
var vm = this;
vm.scrollTo = function(id) {
$document
.scrollToElement(
angular.element(document.getElementById(id)), 0, 1000
);
}
}
});
html
<button ng-click="$ctrl.scrollTo('target')">
<div id="target">Content further down the page</div>

Adding html to UI bootsrap popover inside directive

I am an angular beginner and I wish to add an html button inside a popover that I am creating within a directive. Specifically, my directive allows the user to highlight text on the page and a popover will then appear around the selected text. It works for plain text content in the popover but not html. This is the directive as it is now
app.directive('replybox', function ($timeout, $window, $compile, $sce) {
var linkFn = function (scope, element, attrs) {
var exampleText= element.find('p');
var btn = element.find('button');
var windowSelection="";
exampleText.bind("mouseup", function () {
scope.sel = window.getSelection().toString();
windowSelection=window.getSelection().getRangeAt(0);
if(scope.sel.length>0) {
scope.showModal = true;
scope.$apply();
}
});
btn.bind("click", function () {
range = windowSelection;
var replaceText = range.toString();
range.deleteContents();
var div = document.createElement("div");
scope.pophtml = $sce.trustAsHtml("<p>hello world</p> <button>x</button>");
div.innerHTML = '<poper>' + replaceText + '</poper>';
var frag = document.createDocumentFragment(), child;
while ((child = div.firstChild)) {
frag.appendChild(child);
}
$compile(frag)(scope);
range.insertNode(frag);
scope.selection="None";
});
};
return {
link: linkFn,
restrict: 'A',
scope: {
entities: '=',
selection:'='
},
template: `<ng-transclude></ng-transclude>
<div class="modal fade in" style="display: block;" role="dialog" ng-show="showModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
{{sel}}
</div>
<div class="radio">
<div ng-repeat="x in entities">
<div class="radio">
<label>
<input type="radio" name="choice" ng-model="$parent.selection" ng-value = "x">
{{x}}
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="showModal=false">
Ok
</button>
</div>
</div>
</div>
</div>`,
transclude: true
};
});
The part that is not working is this part
scope.pophtml = $sce.trustAsHtml("<p>hello world</p> <button>x</button>");
div.innerHTML = '<poper>' + replaceText + '</poper>';
I have a feeling there is something wrong with the above two lines.

Bind data to modal

I am trying to pass some data with a function to display on a modal, yet the usual approaches to binding are not working, I was hoping someone could point me in the right direction.
$scope.openModal = function (obj) {
//$scope.data = {type: obj.type, descriptions: obj.description, isDone: obj.isDone, createDate: obj.createDate, priority: obj.priority};
$scope.data = obj;
console.log($scope.data);
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'modalTemplate.html',
controller: 'View1Ctrl',
resolve: {
data: function () {
return $scope.data;
}
}
});
}
Template
<!-- MODAL -->
<div>
<div ng-controller="View1Ctrl">
<script type="text/ng-template" id="modalTemplate.html">
<div class="modal-header">
<h3 class="modal-title">Item Details</h3>
</div>
<div class="modal-body">
<ul>
<li>Type: <span ng-model="data.type"></span></li>
<li>Description: <span ng-model="data.description"></span></li>
<li>Date: <span ng-model="data.createDate"></span></li>
<li>Priority: <span ng-model="data.priority"></span></li>
<li>Finished: <span ng-model="data.isDone"></span></li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="$close()">OK</button>
</div>
</script>
</div>
Also tried {{data.type}} etc, and ng-bind. I now my $scope.data is populated because it is showing as much in the console.
You should inject data (resolve object) into your modal controller then add it to the $scope object.
You should remove ng-controller="View1Ctrl" from template.

Toggling a Twitter Bootstrap (3.x) Modal using AngularJS

I've been trying to get a Bootstrap Model to be hidden on load, and then show it after clicking a button, but have been unsuccessful so far. I am pretty new to AngularJS so bear with me if I'm not doing this correctly. Here's what I've got so far:
Modal Angular Directive (modal.js):
angular.module('my.modal', ['modal.html'])
.directive('myModal', function () {
return {
restrict: 'E',
transclude: true,
replace: false,
templateUrl: 'modal.html',
link: function(scope, element, attrs) {
element.modal('hide')
scope.toggleModal = function() {
if (attrs.showModal === true) {
element.modal('hide')
attrs.showModal = false
} else {
element.modal('show')
attrs.showModal = true
}
}
}
};
});
Modal Template (modal.html):
<div id="{{id}}" showModal="false" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<div class="content" ng-transclude></div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="showModal = false">Cancel</button>
</div>
</div>
</div>
</div>
And finally, the button to toggle the modal (index.html):
...
<my-modal>
<p>Some content</p>
</my-modal>
<button class="btn btn-default" type="button" ng-click="toggleModal()">Toggle me!</button>
...
All this does is show the modal on page load (between my header and all the other content, so it's not floating above anything) and the toggle button does not work.
I've managed to get it working by using the Bootstrap 3 Modal properties and dynamically changing styling and classes of the modal directive based on it's show or hide state, though there are no animations:
Modal Angular Directive (modal.js):
angular.module('my.modal', ['modal.html'])
.directive('myModal', [function () {
return {
restrict: 'E',
transclude: true,
replace: false,
templateUrl: 'modal.html',
controller: 'ModalCtrl',
link: function(scope, element, attrs) {
if (attrs.title === undefined) {
scope.title = 'Modal Title Placeholder';
} else {
scope.title = attrs.title;
}
scope.$watch('showModal', function (value) {
if (value) {
scope.displayStyle = 'block';
scope.modalFadeIn = 'in';
} else {
scope.displayStyle = 'none';
scope.modalFadeIn = '';
}
});
}
};
}).controller('ModalCtrl', ['$scope', function ($scope) {
$scope.toggleModal = function() {
$scope.showModal = !$scope.showModal;
};
$scope.$open = function() {
$scope.showModal = true;
};
$scope.$close = function() {
$scope.showModal = false;
};
});
Modal Template (modal.html):
<div role="dialog" tabindex="-1" class="modal fade" ng-init="showModal = false" ng-show="showModal" ng-style="{display: displayStyle}" ng-class="modalFadeIn">
<div class="modal-backdrop fade in" style="height: 100%"> </div>
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">{{title}}</h3>
</div>
<div class="modal-body">
<div class="content" ng-transclude></div>
</div>
</div>
</div>
</div>
The call to open the modal can be done using the open or toggleModal function. A custom button needs to be placed in the modal to close the modal.

how to handle scope in angular js

I am working with angular js for my dashboard. I have an over all minimize button to minimize all widget and then each widget have own minimize button. I done with following script its not working.
when i click widget minimize button its minimize all widget. but i want minimize that widget only.
var dashboard = angular.module("dashboard",['ui.bootstrap']);
dashboard.controller('dash-control', ['$scope', function($scope) {
$scope.isHidden = false;
$scope.toggle = function(){
$scope.isHidden = !$scope.isHidden;
};
$scope.toggleonce= function()
{
if( this.isHidden === true)
this.isHidden = false;
else
this.isHidden = true;
};
}]);
HTML code like follow:
<div class="contentpanel" ng-app="dashboard" ng-controller="dash-control as ctrl">
<button class="btn btn-white" type="button" ng-click="toggle()"><i class="fa fa-minus-square"> </i> </button>
<div>
<i class="fa fa-minus"></i>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 1</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
<div>
<i class="fa fa-minus"></i>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 2</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
......
.....
.....
</div>
I would rather create a directive with isolated scope for represent a inner widget. for instance;
dashboard.directive('myWidget',function(){
return {
scope:{},
template:"<div>\r\n<a href=\"\" class=\"tooltips\" ng-click=\"toggleonce()\" title=\"Minimize Panel\"><i class=\"fa fa-minus\"><\/i><\/a>\r\n<div class=\"row tinychart\" ng-show=\"isHidden\">asdasdasd<\/div>\r\n<div class=\"row tinychart\" ng-hide=\"isHidden\">sdasdasd<\/div>\r\n\r\n <\/div>",
link:function($scope)
{
$scope.isHidden = false;
$scope.toggle = function(){
$scope.isHidden = !$scope.isHidden;
};
$scope.togglesingle = function()
{
if( this.isHidden === true)
this.isHidden = false;
else
this.isHidden = true;
};
}
}
});
Then In Html Body;
<div class="contentpanel" ng-app="dashboard" >
<button class="btn btn-white" type="button" ng-click="toggle()"><i class="fa fa-minus-square"> </i> </button>
<div my-widget></div>
<div my-widget></div>
</div>
Note that I haven't run and check the example. I hope you got the idea.
Edited:
The ng-repeat will loop the array (list) and initiate each element to 'item' variable. You can pass that data to your directive. Check the updated code.

Resources