Angular Directive with Reset functionality - javascript

I have a directive called filterButton, which will let user to select the filter option and add the check mark on the right. Now I have a reset button in filter.html. Once the user click the reset button, all the filter field will set back to default. I had tried couple methods, it didn't work. Any suggestion? Thank you in advance.
app.js
app.directive('filterButton', function () {
return {
restrict: 'EA',
templateUrl: 'template/filter-button.html',
replace: true,
scope: {
list: '=', //two-way binding
selected: '=', //two-way binding
field: '#', //one-way binding
},
link: function ($scope) {
$scope.selected = [];
$scope.setSelectedOption = function() {
var id = this.option.id;
if(_.contains($scope.selected, id)) {
$scope.selected = _.without($scope.selected, id)
} else {
$scope.selected.push(id);
}
return false;
};
$scope.isChecked = function(id) {
if(_.contains($scope.selected, id)) {
return "fa fa-check pull-right-selected";
}
return "";
};
}
}
});
filter-button.html
<div class="row filter-item">
<div class="btn-group" dropdown is-open="{open: open}">
<button type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle ng-disabled="disabled">Fiter By {{field}} <span class="caret"></span></button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu">
<li data-ng-repeat="option in list" class="dropdown-btn"> <a data-ng-click="setSelectedOption()">{{option.name}}<span data-ng-class="isChecked(option.id)"></span></a></li>
</ul>
</div>
filter.html
<filter-button list="statusList" selected="selectedStatus" field="Status" popover="Error Customer? or No Error Customer?" popover-trigger="mouseenter"></filter-button>
<filter-button list="systemList" selected="selectedSystemType" field="System Type" popover="N+1 or Stand alone?" popover-trigger="mouseenter"></filter-button>
<filter-button list="customerFilterList" selected="selectedCustomer" field="Customer" popover="Male or Female?" popover-trigger="mouseenter"></filter-button>
<div class="row filter-item">
<div class="filter-label">
<button class="btn btn-primary">Reset</button>
</div>
</div>

You can reinitialize the selected arrays on the reset click button:
<button class="btn btn-primary" ng-click="reset()">Reset</button>
In you controller:
$scope.reset = function() {
$scope.selectedStatus = [];
$scope.selectedSystemType = [];
$scope.selectedCustomer = [];
}

Related

How I can prepand an html tag before an element

I have a page Initially with buttons and then a table (ag-grid).
<div class="row"> <-- Button -->
<button class="btn btn-sm btn-primary"
</button>
</div>
<div class="" ag-grid="ag_grid_options" ></div> <!-- Table-- >
I want to create a directive (a button which does something), which is alligned with the above button.
I have created this directive:
app.directive('exportData', function(){
return {
restrict: 'A',
template: '<button class="btn btn-sm btn-primary"> GOD IS HERE </button>',
link: function(scope) {
}
};
});
and I have modified the tag for ag-grid-option to something like this:
<div class="" ag-grid="ag_grid_options" export-data></div>
But the button comes in new line instead of alligning with the previous button. So my question is, Is there a way to prepand the button with the previous button?
I have requirement of using this as attribute only of ag-grid. Can anyone please help me here.
Try something like this:
app.directive('exportData', function(){
return {
restrict: 'A',
link: function(scope, element, attrs, model){
element.parent().prepend('<button class="btn btn-sm btn-primary"> GOD IS HERE </button>');
};
}
});
A better solution can be to create a wrapper:
app.directive('exportData', function(){
return {
restrict: 'A',
link: function(scope, element, attrs, model){
// Create a wrapper
var wrapper = $('<div class="wrapper"></div>');
element.wrap(wrapper);
// Compile and attach the button
var button = $('<button class="btn"> GOD IS HERE </button>');
element.before(button);
};
}
});

AngularJS / AngularFire - Pass Objects with ng-click

I have a modal (bootstrap) where I load Objects from the Firebase Database. Now I added a ng-Click to "select" an Object.
I want to select 8 Object and "collect" them. After I collected these 8 Objects, I want to pass them to another ng-Click. When I click on the second ng-Click these 8 (selected) Objects are pushed to the Database.
Do you have any idea how to archive that? Thank you!
This is my modal:
<div class="col-md-12">
<ul class="list-group">
<li ng-repeat="team in teams" class="list-group-item">{{ team.allUserTeamName + " - " + team.allUserTeam }}
<i class="fa fa-plus-circle" aria-hidden="true" ng-init="item.isClicked = false" ng-click="selectMembers(team); item.isClicked =!item.isClicked" ng-class="{clicked : item.isClicked}"></i>
</li>
</ul>
</div>
<div class="modal-footer">
<div class="col-md-12">
<div class="row pad-team-selection-view">
<button class="btn btn-info" ng-click="createGameplanWithSelectedMembers(team)">Spielplan erstellen</button>
</div>
</div>
</div>
This is my Controller:
app.controller('modalCreateGameplanController', ['$scope', '$timeout', '$http', '$firebaseArray', '$firebaseObject', function ($scope, $timeout, $http, $firebaseObject, $firebaseArray) {
$scope.selectUsers = 'Teilnehmer';
$scope.$on('modal', function (event, args) {
var ref = firebase.database().ref("users");
var teams = $firebaseObject(ref);
teams.$loaded().then(function () {
$scope.teams = [];
angular.forEach(teams, function (key) {
$scope.teams.push({
allUserTeamName: key.firstname,
allUserTeam: key.team
});
$scope.selectMembers = function (key) {
console.log(key);
};
$scope.createGameplanWithSelectedMembers = function () {
console.log(teams);
};
});
});
});
}]);
In the view use ng-disabled and use selected length as condition to disable the button .
<div class="col-md-12">
<ul class="list-group">
<li ng-repeat="team in teams" class="list-group-item">{{ team.allUserTeamName + " - " + team.allUserTeam }}
<i class="fa fa-plus-circle" aria-hidden="true" ng-init="item.isClicked = false" ng-click="selectMembers(team); item.isClicked =!item.isClicked" ng-class="{clicked : item.isClicked}"></i>
</li>
</ul>
</div>
<div class="modal-footer">
<div class="col-md-12">
<div class="row pad-team-selection-view">
<button class="btn btn-info" ng-click="createGameplanWithSelectedMembers(team)" ng-disabled="selectCount==8">Spielplan erstellen</button>
</div>
</div>
</div>
In the controller keep a tracker for selected items $scope.selectCount
app.controller('modalCreateGameplanController', ['$scope', '$timeout', '$http', '$firebaseArray', '$firebaseObject', function ($scope, $timeout, $http, $firebaseObject, $firebaseArray) {
$scope.selectUsers = 'Teilnehmer';
$scope.$on('modal', function (event, args) {
var ref = firebase.database().ref("users");
var teams = $firebaseObject(ref);
teams.$loaded().then(function () {
$scope.selectCount=0;
$scope.teams = [];
angular.forEach(teams, function (key) {
$scope.teams.push({
allUserTeamName: key.firstname,
allUserTeam: key.team
});
$scope.selectMembers = function (key) {
$scope.selectCount=$scope.selectCount+1;
console.log(key);
};
$scope.createGameplanWithSelectedMembers = function () {
console.log(teams);
};
});
});
});
}]);

How can I pass a list as a parameter to a dialog?

Y must pass a list of data to a dialog to fill a combobox.
In other part of the code I passed a string to dialogs, but, using the same method for this case, It didn´t work.
Here is my js code:
$scope.addPartido = function () {
if ($scope.dataProv.locationsProv.provincias) {
$modal.open({
templateUrl: '../../secure/addPartido/addPartidoDialog.html',
controller: function ($scope, $modalInstance) {
$scope.close = function () {
$modalInstance.close();
};
}
});
}
};
Inside my controler I have the variable $scope.dataProv.locationsProv.provincias fill with de data.
And here is my html code:
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<label>Provincia<span class="text-danger">*</span></label>
<div class="dropdown">
<select ng-options="item.name for item in dataProv.locationsProv.provincias| orderBy:'name'"
ng-id="mySelProvincia" class="form-control" required="required"
ng-model="selectedProv">
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="close()">
Cerrar
</button>
</div>
</div>
</div>
It is easy!
This code works perfectly:
$scope.addPartido = function () {
if ($scope.dataProv.locationsProv.provincias) {
$modal.open({
templateUrl: '../../secure/addPartido/addPartidoDialog.html',
controller: function ($scope, $modalInstance, listProv) {
$scope.statusProv = 'loading...';
$scope.provincia = "Select provincias";
$scope.dataProv = {
"locationsProv": {}
};
$scope.dataProv.locationsProv.provincias = listProv;
$scope.close = function () {
$modalInstance.close();
};
},
resolve: {
listProv: function () {
return $scope.dataProv.locationsProv.provincias;
}
}
});
}
};

adding and removing classes in angularJs using ng-click

I am trying to work how to add a class with ngClick. I have uploaded up my code onto plunker Click here. Looking at the angular documentation i can't figure out the exact way it should be done. Below is a snippet of my code. Can someone guide me in the right direction
<div ng-show="isVisible" ng-class="{'selected': $index==selectedIndex}" class="block"></div>
Controller
var app = angular.module("MyApp", []);
app.controller("subNavController", function ($scope){
$scope.toggle = function (){
$scope.isVisible = ! $scope.isVisible;
};
$scope.isVisible = false;
});
I want to add or remove "active" class in my code dynamically on ng-click, here what I have done.
<ul ng-init="selectedTab = 'users'">
<li ng-class="{'active':selectedTab === 'users'}" ng-click="selectedTab = 'users'"><a href="#users" >Users</a></li>
<li ng-class="{'active':selectedTab === 'items'}" ng-click="selectedTab = 'items'"><a href="#items" >Items</a></li>
</ul>
You just need to bind a variable into the directive "ng-class" and change it from the controller. Here is an example of how to do this:
var app = angular.module("ap",[]);
app.controller("con",function($scope){
$scope.class = "red";
$scope.changeClass = function(){
if ($scope.class === "red")
$scope.class = "blue";
else
$scope.class = "red";
};
});
.red{
color:red;
}
.blue{
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="ap" ng-controller="con">
<div ng-class="class">{{class}}</div>
<button ng-click="changeClass()">Change Class</button>
</body>
Here is the example working on jsFiddle
There is a simple and clean way of doing this with only directives.
<div ng-class="{'class-name': clicked}" ng-click="clicked = !clicked"></div>
you can also do that in a directive, if you want to remove the previous class and add a new class
.directive('toggleClass', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('click', function() {
if(element.attr("class") == "glyphicon glyphicon-pencil") {
element.removeClass("glyphicon glyphicon-pencil");
element.addClass(attrs.toggleClass);
} else {
element.removeClass("glyphicon glyphicon-ok");
element.addClass("glyphicon glyphicon-pencil");
}
});
}
};
});
and in your template:
<i class="glyphicon glyphicon-pencil" toggle-class="glyphicon glyphicon-ok"></i>
You have it exactly right, all you have to do is set selectedIndex in your ng-click.
ng-click="selectedIndex = 1"
Here is how I implemented a set of buttons that change the ng-view, and highlights the button of the currently selected view.
<div id="sidebar" ng-init="partial = 'main'">
<div class="routeBtn" ng-class="{selected:partial=='main'}" ng-click="router('main')"><span>Main</span></div>
<div class="routeBtn" ng-class="{selected:partial=='view1'}" ng-click="router('view1')"><span>Resume</span></div>
<div class="routeBtn" ng-class="{selected:partial=='view2'}" ng-click="router('view2')"><span>Code</span></div>
<div class="routeBtn" ng-class="{selected:partial=='view3'}" ng-click="router('view3')"><span>Game</span></div>
</div>
and this in my controller.
$scope.router = function(endpoint) {
$location.path("/" + ($scope.partial = endpoint));
};
var app = angular.module("MyApp", []);
app.controller("subNavController", function ($scope){
$scope.toggle = function (){
$scope.isVisible = ! $scope.isVisible;
};
$scope.isVisible = false;
});
<div ng-show="isVisible" ng-class="{'active':isVisible}" class="block"></div>
I used Zack Argyle's suggestion above to get this, which I find very elegant:
CSS:
.active {
background-position: 0 -46px !important;
}
HTML:
<button ng-click="satisfaction = 'VeryHappy'" ng-class="{active:satisfaction == 'VeryHappy'}">
<img src="images/VeryHappy.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'Happy'" ng-class="{active:satisfaction == 'Happy'}">
<img src="images/Happy.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'Indifferent'" ng-class="{active:satisfaction == 'Indifferent'}">
<img src="images/Indifferent.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'Unhappy'" ng-class="{active:satisfaction == 'Unhappy'}">
<img src="images/Unhappy.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'VeryUnhappy'" ng-class="{active:satisfaction == 'VeryUnhappy'}">
<img src="images/VeryUnhappy.png" style="height:24px;" />
</button>
If you prefer separation of concerns such that logic for adding and removing classes happens on the controller, you can do this
controller
(function() {
angular.module('MyApp', []).controller('MyController', MyController);
function MyController() {
var vm = this;
vm.tab = 0;
vm.setTab = function(val) {
vm.tab = val;
};
vm.toggleClass = function(val) {
return val === vm.tab;
};
}
})();
HTML
<div ng-app="MyApp">
<ul class="" ng-controller="MyController as myCtrl">
<li ng-click="myCtrl.setTab(0)" ng-class="{'highlighted':myCtrl.toggleClass(0)}">One</li>
<li ng-click="myCtrl.setTab(1)" ng-class="{'highlighted':myCtrl.toggleClass(1)}">Two</li>
<li ng-click="myCtrl.setTab(2)" ng-class="{'highlighted':myCtrl.toggleClass(2)}">Three</li>
<li ng-click="myCtrl.setTab(3)" ng-class="{'highlighted':myCtrl.toggleClass(3)}">Four</li>
</ul>
CSS
.highlighted {
background-color: green;
color: white;
}
I can't believe how complex everyone is making this. This is actually very simple. Just paste this into your html (no directive./controller changes required - "bg-info" is a bootstrap class):
<div class="form-group col-md-12">
<div ng-class="{'bg-info': (!transport_type)}" ng-click="transport_type=false">CARS</div>
<div ng-class="{'bg-info': transport_type=='TRAINS'}" ng-click="transport_type='TRAINS'">TRAINS</div>
<div ng-class="{'bg-info': transport_type=='PLANES'}" ng-click="transport_type='PLANES'">PLANES</div>
</div>
for Reactive forms -
HTML file
<div class="col-sm-2">
<button type="button" [class]= "btn_class" id="b1" (click)="changeMe()">{{ btn_label }}</button>
</div>
TS file
changeMe() {
switch (this.btn_label) {
case 'Yes ': this.btn_label = 'Custom' ;
this.btn_class = 'btn btn-danger btn-lg btn-block';
break;
case 'Custom': this.btn_label = ' No ' ;
this.btn_class = 'btn btn-success btn-lg btn-block';
break;
case ' No ': this.btn_label = 'Yes ';
this.btn_class = 'btn btn-primary btn-lg btn-block';
break;
}

How to force update view from directive event in Angularjs

I have a work and stuck it 2 days. Hope everyone know angularjs help me :).
I need to force a change html when have a change on model. Example:
This is html code:
<!--CAKE LIST-->
<div id="cakelist" ng-controller="CakeListCtrl">
<ul class="thumbnails cake-rack" cakes="cakes" ng-model="cakesModel">
<li class="pull-left cake-unit" ng-repeat="cake in cakes" cake="cake">
<div class="thumbnail">
<a href="{{cake.link}}">
<img ng-src="{{cake.avatar}}" alt="{{cake.title}}" class="img img-rounded img-polaroid" />
</a>
<h5 class="pull-left">
{{cake.title}}
</h5>
Shared
<div class="clearfix"></div>
<ul class="attrs unstyled">
<li>
<div class="pull-left">Mã sản phẩm</div>
<span class="pull-right">{{cake.type}}</span>
</li>
</ul>
</div>
</li>
</ul>
<input type="button" class="btn btn-primary" value="add more cake" class="cake-more" ng-click="addCake()" />
<input type="button" class="btn btn-danger" value="clear cake" class="cake-clear" ng-click="clear()" />
<img alt="Loading" src="/imagesroot/ajax-loader-1.gif" loading-stage="loadingStage" class="cake-loading"/>
</div>
now a have a menu outside of controller:
<div id="cake-catalog" class="cake-catalog">
<ul class="nav">
<li class="active">
<a cake-menu-unit href="sacmscategory50c2302b7ff0a">Nhân vật hoạt hình</a>
</li>
<li>
<a cake-menu-unit href="sacmscategory50c2308717a84">Động vật</a>
</li>
<li>
<a cake-menu-unit href="sacmscategory50c2309da00f6">Tạo hình 3D</a>
</li>
<li>
<a cake-menu-unit href="sacmscategory50c230ba08d9d">Các mẫu hình khác</a>
</li>
</ul>
</div>
I have angular module for add and clear:
var CakeList = angular.module('CakeList', ['ngResource']);
CakeList.service('CakeService', function($rootScope) {
var cakedata = [{avatar:"test", title: "test2"}];
$rootScope.loadCake = false;
var bf = function() { $rootScope.loadCake=true; };
var at = function() { $rootScope.loadCake=false; };
return {
cakes: function() {
bf();
at();
return cakedata;
},
addCake: function() {
bf();
cakedata.push(cake);
at();
},
clear: function() {
cakedata = []; console.log('clear');
}
};
});
CakeList.directive('cakeCatalog', function($rootScope, CakeService) {
var clickfn = function(e) {
e.preventDefault();
CakeService.clear();
};
var nonclickfn = function(e) {
e.preventDefault();
console.log('nonclickfn');
};
return {
restrict: "C",
link: function(scope, element, attrs) {
$rootScope.$watch('loadCake', function(newValue, oldValue) {
if (newValue===true) {
element.find('a').off('click').on('click', nonclickfn);
}
else {
element.find('a').off('click').on('click', clickfn);
}
});
}
};
But when runtime, i put click on a element of menu then the list cake not clear, even i check console.log in console box and see the cakedata really clear!. Can you help me this case ? :)
First of all, the design seems a bit weird by using everywhere $rootScope (among other things). But that's not the cause of the problem. The problem is the $watch which is not correct.
First of all, use loadCake as an object instead of a primitive type:
var loadCake = { loaded: false};
Use the objectEquality parameter in your $watch statement:
$rootScope.$watch('loadCake', function(newValue, oldValue) {
if (!newValue) return;
if (newValue.loaded === true) {
element.find('a').off('click').on('click', nonclickfn);
}
else {
element.find('a').off('click').on('click', clickfn);
}
}, true);

Categories