im new to angular and was struck linking dropdown selected to ng-click button
<div class="col-xs-2">
<select name="cars" ng-model="dropdown_data">
<option>email</option>
<option>phone</option>
<option>username</option>
</select>
</div>
<br />
<div class="col-xs-4">
<button type="button" class=" " data-ng-click="search_{{dropdown_data}}()">Search</button>
</div>
<script>
var ng = angular.module('myApp', []);
ng.controller('ctrl', function($scope, $http) {
$scope.search_phone = function() {
alert("phone")
}
$scope.search_email = function() {
alert("email")
}
})
</script>
this seems to be fairly simple but im not sure what im doing wrong...Im not able to show alerts depending on selected dropdown
Plunker link http://plnkr.co/edit/Iicm9tvfizXxNl3MwtZI?p=preview
any help is much appriciated...thanks in advance
There were few things that you needed in the plunkr.
Firstly you need to define on the HTML that it is in fact an Angular Application (via the ngApp attribute).
Secondly you need to define a controller for your view (via the ngController attribute).
Once you have those things in place, you need to understand what this would do
ng-click="search_{{dropdown_data}}()"
If you think about how ng-click works, it registers a function on click. This happens on the compile phase of a directive (as you can see on its sourcecode).
This means that when the directive compiles, it will register the function with the name search_{{dropdown_data}} and even though the dropdown_data will be interpolated later on when its value changes, the originally bound function won't update.
However if you had dropdown_data as an attribute or as a key to a map of functions that will work. Here an example of how you may do that:
$scope.search = {
phone: function() {
alert("phone")
},
email: function() {
alert("email")
}
};
and on the button: data-ng-click="search[dropdown_data]()"
Here a working plunkr: http://plnkr.co/edit/u4vJj2a0r1a95w64crHM?p=preview
I am also new in angular but have used same functionality without search button direct given anchor link try this if you need,
<div ng-app="myApp">
<div ng-controller="setContent">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Subject
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="a in subjects">{{a}}</li>
</ul>
</div>
var app = angular.module('myApp', []);
app.controller('setContent', function($scope, $http) {
$scope.subjects = ['Math', 'Physics', 'Chemistry', 'Hindi', 'English'];
});
});
The problem is this data-ng-click="search_{{dropdown_data}}()". Better to pass a value to the function like this:
<button type="button" data-ng-click="search(dropdown_data)">Search</button>
$scope.search = function(type) {
alert(type)
}
also dont forget ng-app and ng-controller.
see the plunker
Related
I'm using this https://github.com/amitava82/angular-multiselect multiselect dropdown for my project.
In my html:
<am-multiselect class="sv-manage-multiselect-dropdown"
ng-model="nameList.name"
options="name as name.key for name in nameList"
multiple="true"
</am-multiselect>
This dropdown has a "checkall" and "uncheckall" button in the dropdown, which I WANT to remove, while keeping the functionality of the multi-select.
This is the html in the directive the guy uses:
src/multiselect.tmpl.html
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" ng-click="toggleSelect()" ng-disabled="disabled" ng-class="{'error': !valid()}">
{{header}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<input class="form-control input-sm" type="text" ng-model="searchText.label" ng-keydown="keydown($event)" autofocus="autofocus" placeholder="Filter" />
</li>
<li ng-show="multiple" role="presentation" class="">
<button class="btn btn-link btn-xs" ng-click="checkAll()" type="button"><i class="glyphicon glyphicon-ok"></i> Check all</button>
<button class="btn btn-link btn-xs" ng-click="uncheckAll()" type="button"><i class="glyphicon glyphicon-remove"></i> Uncheck all</button>
</li>
<li ng-repeat="i in items | filter:searchText" ng-class="{'selected': $index === selectedIndex}">
<a ng-click="select(i); focus()">
<i class='glyphicon' ng-class="{'glyphicon-ok': i.checked, 'empty': !i.checked}"></i> {{i.label}}</a>
</li>
</ul>
</div>
I wan't to just remove/override the checkall and uncheckall buttons WITHOUT editing this library's directive. I can override the CSS in my personal file.css, but how do I override the HTML template he uses. Thanks
I see 3 ways you could do it:
Add your own template to replace this one like this (reference):
<script type="text/ng-template" id="multiselect.tmpl.html">
html template without buttons here
</script>
The potential issue with this is that you would be overriding this template everywhere it's used. But maybe you are using this in a bunch of places and that makes sense.
Add a decorator to the directive that removes the part of the template you don't want during the compile phase and allows the rest of the directive to perform as usual:
decorator('amMultiselectPopupDirective' ['$delegate', function($delegate) {
var directive = $delegate[0];
var compile = directive.compile;
directive.compile = function(tElement, tAttrs) {
var link = compile.apply(this, arguments);
if (tAttrs.disableCheckAll) {
tElement.find('li[ng-show="multiple"]').remove();
// this code could be different, but the gist is that it would remove or hide the stuff you don't want
}
return function() {
link.apply(this, arguments);
};
};
return $delegate;
}]);
The potential issue here is that you would be changing the template for this directive everywhere the directive is used. That's why in my example I made the template change conditional based on some attribute you could define, like disableCheckAll.
Use template-url attribute that is already defined for this directive and create your own template that doesn't have these buttons:
<script type="text/ng-template" id="yourowntemplate.html">
html template without buttons here
</script>
<am-multiselect ...
template-url="yourowntemplate.html">
</am-multiselect>
I would say 3 is probably the best way to do it. But 1 could work better if you wanted to override the default, and then you wouldn't have to pass in the template-url everytime you use the am-multiselect directive.
Edit: Here is a working example for 3: http://plnkr.co/edit/m0lZSHUJ8MHslqCNPnCc?p=info
Overlap his directive with your own div with class: "no-btns"
Add this css:
.no-btns .dropdown-menu li:nth-child(2) {display:none;}
Example:
<style>
.no-btns .dropdown-menu li:nth-child(2) {
display:none;
}
</style>
<div class="no-btns">
<am-multiselect class="sv-manage-multiselect-dropdown"
ng-model="nameList.name"
options="name as name.key for name in nameList"
multiple="true"
</am-multiselect>
</div>
I have a div that I am hiding/showing using angular in my HTML, but I want to know how to check if it is currently hidden or not in my controller.
Any solutions I have found so far are jQuery based using 'hasClass' to find ng-hide, but I don't want to use jQuery.
My div looks like this
<div class="item item-input" ng-show="showDetails"></div>
<button class="button button-block button-light leftTextButton"
ng-click="showDetails = ! showDetails; updateTimes()">
<i ng-class="{'icon icon ion-minus-round': showDetails,
'icon icon ion-plus-round': !showDetails}"></i> End Time</button>
I thought from my controller I could just call if($scope.showDetails) and that would return true or false, but it is undefined.
How can I check if a div if hidden or showing from my controller? Thanks
I'm guessing you are having a scoping issue. Passing it to the function that will check it is the best bet. Otherwise if it is in scope the controller should be able to access it.
angular.module('MyApp', [])
.controller('MyController', ['$scope',
function($scope) {
$scope.myBoolean = false;
$scope.checkMyBooleanOnScope = function() {
alert($scope.myBoolean);
};
$scope.checkMyOtherBooleanOnScope = function() {
alert($scope.myOtherBoolean);
};
$scope.checkBooleanByPassingIt = function(bool) {
alert(bool);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyController">
<p>myBoolean predefined in the controller:{{myBoolean}}
<input type="checkbox" ng-model="myBoolean" />
</p>
<p>
<button ng-click="checkMyBooleanOnScope()">checkMyOtherBooleanOnScope</button>
<button ng-click="checkBooleanByPassingIt(myBoolean)">checkMyBooleanByPassingIt</button>
</p>
<p>myOtherBoolean defined on the page with ng-model:{{myOtherBoolean}}
<input type="checkbox" ng-model="myOtherBoolean" />
</p>
<p>
<button ng-click="checkMyOtherBooleanOnScope()">checkMyBooleanOnScope</button>
<button ng-click="checkBooleanByPassingIt(myOtherBoolean)">checkMyOtherBooleanByPassingIt</button>
</p>
</div>
I am trying to set up custom themeing on my app, so what I am doing is letting the user choose certain themes and it will change the apps theme holistically. I have a service which sends a piece of json and listens for it changing inside the controller of each view. Now this works fine within the view itself - for reference here's some snippets of the working code.
my factory controlling the theme -
angular.module('demoApp')
.factory('templatingFactory', function () {
var meaningOfLife =
{
'h1': '#ea6060',
'bg': '#ffffff'
};
return {
setTheme: function(theme) {
meaningOfLife = theme;
},
getTheme: function() {
return meaningOfLife;
}
};
});
One of my example controllers showing and changing the theme (and listening for changes)
$scope.themeStore = templatingFactory.getTheme();
console.log($scope.themeStore);
//send new themes
$scope.themeOne = function () {
var newT1 = { 'h1': '#8A6516',
'bg': '#000000'};
templatingFactory.setTheme(newT1);
};
$scope.themeTwo = function () {
var newT2 = { 'h1': '#ffffff',
'bg': '#ea6060'};
templatingFactory.setTheme(newT2);
};
$scope.themeThree = function () {
var newT3 = { 'h1': '#ea6060',
'bg': '#ffffff'};
templatingFactory.setTheme(newT3);
};
//listen for new themes
$scope.watchThemes = templatingFactory.getTheme();
$scope.$watch(templatingFactory.getTheme, function (newTheme) {
$scope.themeStore = newTheme;
});
and then on the template/view itself i do something like this -
<h3 ng-style="{ 'color' : themeStore.h1 }">Title</h3>
So my issue is that this works fine inside the view. However the ng-view tag is inside the body and outside of it are the body containers, as well as the header and footer menus that I would like to be able to hook onto with this theme object. So my quesiton is, is there any way to use that scope outside of the ng-view? I don't think it's possible but I'm not sure how else I could access and put a ng-style on the header footer and body to change some css on it with this method I am using.
So for a simple reference it looks like this -
<body ng-app="myApp">
<div class="container">
<div class="header" ng-style="{ 'background-color' : themeStore.bg }">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<i class="fa fa-bars"></i>
</button>
<div class="headerLogo"></div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
<div ng-view class="velocity-opposites-transition-slideUpIn" data-velocity-opts="{ duration: 500 }" ng-style="{ 'background-color' : themeStore.bg }"> </div>
<div class="footer">
<p></p>
</div>
</div>
</body>
So as you can see - I'm trying to hook onto the header to change the background color, which does not work like this. What I noticed though, is if I put it on the ng-view div itself, it works alright.
I would much appreciate any input as I've been stuck on this for a while. Thank you for taking the time to read!
The DOM elements outside of your ng-view must have controllers of their own, with templatingFactory injected as a dependency.
First I would modify the html like so:
<div class="header" ng-controller="headerController" ng-style="{ 'background-color' : themeStore.bg }">
Then add headerController to your module:
angular.module('demoApp').controller('headerController', function($scope, templatingFactory){
$scope.themeStore = templatingFactory.getTheme();
$scope.$watch(templatingFactory.getTheme, function (newTheme) {
$scope.themeStore = newTheme;
});
});
A more reusable solution would be to create a directive that adds this controller functionality to whatever DOM element it is applied to, but the above is a little more straight forward.
I think the best way to have angular functions and variables outside ui-view or ng-view is to use a global service. in this case you should do your theming logic inside 'templatingFactory'. Then inject this service not in your controllers, but in your module.
angular.module('demoApp').run(['$rootScope', 'templatingFactory', function($rootScope, templatingFactory){
$rootScope.templatingService = templatingFactory;
}]);
So your service will be avaible in the $rootScope. now you can use it this way.
<body ng-app="myApp">
<div class="container">
<div class="header" ng-style="{ 'background-color' : templatingService.getTheme().bg }"> </div>
</div>
</div>
ps: I'm relative new in angular too, so I don't know nothing about good/wrong practices!
For the directive approach, a simple example might look something like this:
demoApp.directive('themeHeader', function (templatingFactory) {
return {
restrict: 'A',
link : function (scope, element, attrs) {
scope.$watch(templatingFactory.getTheme, function () {
element.css('background-color', newTheme.bg);
});
}
}
});
and the html would look like this:
<div theme-header>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><i class="fa fa-bars"></i></button>
<div class="headerLogo"></div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right"></ul>
</div>
I am having a hard time understanding why the following code stops working altogether. Basically when I try to hide and show an ng-include using ng-show from the $parent scope it works fine. For instance in the attached plnkr if you hit "Create New" then "Cancel", or just "Toggle" the visibility of the ng-include is appropriately set.
However, if I try to set the visibility from the child scope Cancel, it works once, and then it fails completely. When you hit the "Cancel" button that is in the ng-include, the variable "createItemVisible" from the parent scope that controls visibility is somehow corrupted.
I've read through many other posts on $parent scope but I never saw a mention of where it works once and then not again.
The plnkr is here http://plnkr.co/edit/1tNpTzEBnTRHgvx6o0dc?p=preview
Here is the index.html code:
<div ng-controller="MainCtrl">
<h3>Items</h3>
<button type="button" class="btn btn-primary" ng-click="createItem()">Create New Item</button>
<button type="button" class="btn btn-alert" ng-click="createItemVisible=!createItemVisible">Toggle</button>
<button type="button" class="btn btn-danger" ng-click="createItemVisible=false">Cancel</button>
<div ng-include="'inlineform.html'" ng-show="createItemVisible"></div>
</div>
Here is the inlineform.html code:
<div ng-controller="ItemDetailCtrl">
<button type="button" class="close" ng-click="cancelItemDetail()">×</button>
<h3>New Item</h3>
<button ng-click="cancelItemDetail()" class='btn btn-danger'>Cancel</button>
</div>
Here is the script:
var myApp = angular.module('myApp', []);
myApp.controller('MainCtrl', function($scope) {
$scope.createItemVisible = false;
$scope.createItem = function() {
$scope.createItemVisible = true;
};
});
myApp.controller('ItemDetailCtrl', function($scope) {
$scope.cancelItemDetail = function() {
$scope.$parent.createItemVisible = false;
}
});
From a comment by Ilan Frumer I was able to better understand that you should not use primitives on the scope. I created a namespace to hold my variable.
var main = {
createItemVisible : false
};
Then I registered this namespace with the scope.
$scope.main = main;
I then updated any references accordingly.
Here is the updated plnkr http://plnkr.co/edit/1tNpTzEBnTRHgvx6o0dc?p=preview
Let's say i have a search box and i want to display it after user click on button . so far so good .
but i want to add another feature , when user click anywhere search box go away .
How can i do this with AngularJs ?
this is my code :
HTML
<button class="btn btn-info " ng-click="addStyle()" ><i class="fa fa-search"></i>
Search</button>
<input type="text" placeholder="Type" class="{{noneStyle}} {{visibleStyle}}">
Angular
app.controller("MainCtrl", function($scope,$http){
$scope.noneStyle = "noneVisible";
$scope.addStyle = function(){
$scope.noneStyle = "visibleStyle";
}
})
any idea ?
Thx in advance
I'd recommend use ng-if instead
app.controller("MainCtrl", function($scope,$http){
$scope.visible = true;
$scope.changeStatus = function(){
$scope.visible = !$scope.visible;
}
$scope.hideAll= function(){
$scope.visible=false;
}
})
HTML
<div class="well" ng-controller="MyController">
<button class="btn btn-primary" ng-disabled="checked" ng-click="changeStatus()" ng-blur="hideAll()">BUTTON</button>
<hr/>
{{visible}}
<input type="text" placeholder="Type" ng-if="visible">
</div>
look at this jsFiddle
try it out!
Use ng-blur/ng-focus to achieve this.
I demonstrate a simple code over here. http://jsfiddle.net/lookman/1Lp95or0/
var myApp = angular.module('myApp',[]);
myApp.controller('MyController', function($scope) {
$scope.visible = true;
$scope.changeStatus = function(){
$scope.visible = !$scope.visible;
}
$scope.hideAll= function(){
$scope.visible=false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyController">
<button ng-disabled="checked"
ng-click="changeStatus()">Click to show/hide the input box</button>
<hr/>
<p>Current visible status: {{visible}}</p>
<input type="text" placeholder="Type" ng-show="visible" ng-blur="hideAll()">
</div>
</div>
Note that in this example, you need to click on input box first before clicking elsewhere to hide it. I hope this is what are you looking for and this helps.
Use the ng-blur directive to update your model when the user clicks somewhere else:
<button class="btn btn-info " ng-click="addStyle()" ng-blur="removeStyle()">
You could do it using standard JavaScript, registering an event listener once the search box is displayed and unregistering it, as soon as the user has clicked anywhere:
$scope.addStyle = function()
{
$scope.noneStyle = "visibleStyle";
// register event listener
document.addEventListener("click", hideSearchBox);
}
function hideSearchBox()
{
// set style to hide search box
$scope.noneStyle = "noneVisible";
// unregister event listener
document.removeEventListener("click", hideSearchBox);
}
I'm not sure if there is a more Anuglar-way of doing it. To do so, you would need to register something on document level, as you want the search box to be hidden if you click anywhere. And "anywhere" might not be where the Angular root scope is registered..