I need to show an Edit icon on a particular element, but as hovering it shows the Edit icon on each element in ng-repeat. How can I achieve it using controllerAs?
Please provide me solution for the same. I'm able to achieve through normal behaviour($scope), but unable to get it through a controller.
Here is the link -- >
enter code herehttp://plnkr.co/edit/ETMyoDLR8HPFIZFrA90n?p=preview
Here is what you need. Instead of setting the hoverEdit with the controller use it instead with the task.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function() {
var ma = this;
ma.tasks = [{
name: 'Item One'
},
{
name: 'The second item'
},
{
name: 'Three items is the best'
}
];
ma.hoverIn = function(task) {
task.hoverEdit = true;
};
ma.hoverOut = function(task) {
task.hoverEdit = false;
};
});
/* Put your css in here */
li {
width: 200px;
list-style-type: none;
padding: 6px 10px;
}
li:hover {
background: #EEE;
}
.animate-show {
-webkit-transition: all linear 0.5s;
transition: all linear 0.5s;
opacity: 1;
}
.animate-show.ng-hide-add,
.animate-show.ng-hide-remove {
display: inline-block !important;
}
.animate-show.ng-hide {
opacity: 0;
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl as ma">
<ul>
<li ng-repeat="task in ma.tasks" ng-mouseover="ma.hoverIn(task)" ng-mouseleave="ma.hoverOut(task)">
{{task.name}}
<span ng-show="task.hoverEdit" class="animate-show">
<a>
<img src="https://cdn2.iconfinder.com/data/icons/freecns-cumulus/16/519584-081_Pen-16.png" alt="">
Edit
</a>
</span>
</li>
</ul>
</body>
</html>
Hope it helps :)
you can use $index to set the index to hoverEdit
ma.hoverIn = function(index){
ma.hoverEdit = index;
};
ma.hoverOut = function(){
ma.hoverEdit = null;
};
checking if you are hovering the index and display it using ng-show
<ul>
<li ng-repeat="task in ma.tasks" ng-mouseover="ma.hoverIn($index)" ng-mouseleave="ma.hoverOut()">
{{task.name}}
<span ng-show="ma.hoverEdit == $index" class="animate-show">
<a>
<img src="https://cdn2.iconfinder.com/data/icons/freecns-cumulus/16/519584-081_Pen-16.png" alt="">
Edit
</a>
</span>
</li>
here is the plunker
There is one more solution please have a look into this added plunker code.
<body ng-controller="MainCtrl as ma">
<ul>
<li ng-repeat="task in ma.tasks" ng-mouseover="ma.hoverIn(task)" ng-mouseleave="ma.hoverOut(task)">
{{task.name}}
<span ng-show="task.hoverEdit" class="animate-show">
<a>
<img src="https://cdn2.iconfinder.com/data/icons/freecns-cumulus/16/519584-081_Pen-16.png" alt="">
Edit
</a>
</span>
</li>
</ul>
</body>
var app = angular.module('plunker', ['ngAnimate']);
app.controller('MainCtrl', function() {
var ma=this;
ma.tasks = [
{name: 'Item One', hoverEdit : false},
{name: 'The second item', hoverEdit : false},
{name: 'Three items is the best', hoverEdit : false}
];
ma.hoverIn = function(obj){
obj.hoverEdit = true;
};
ma.hoverOut = function(obj){
obj.hoverEdit = false;
};
});
Related
How can i save the titles selecteds of a ng-click in a method in controller?
<div ng-click="selectItem(dimension, $event)">
<span text="{{dimension.title}}" title="{{dimension.title}}">Item 1</span>
</div>
<div ng-click="selectItem(dimension, $event)">
<span text="{{dimension.title}}" title="{{dimension.title}}">Item 2</span>
</div>
<div ng-click="selectItem(dimension, $event)">
<span text="{{dimension.title}}" title="{{dimension.title}}">Item 3</span>
</div>
I am editing a qlik sense extension and need to save the selections in the app.
A better idea would be to identify objects with a unique identifier rather than a title that can be repeated. If the dimension object has an ID(or some other unique value) use it.
Adapt code below to your needs:
var app = angular.module("myModule", []);
app.controller("myCtrl", function($scope) {
var vm = this;
vm.dimensions = [
{
title: 'Title 1'
},{
title: 'Title 2'
},{
title: 'Title 3'
},{
title: 'Title 4'
},{
title: 'Title 5'
},{
title: 'Title 6'
},
];
vm.selected = [];
vm.selectItem = function(item, event) {
if(!vm.isSelected(item)) {
vm.addItem(item);
} else {
vm.removeItem(item);
}
// Show selected list
console.log(vm.selected);
}
vm.isSelected = function(item) {
return vm.selected.indexOf(item.title) != -1;
}
vm.addItem = function(item) {
vm.selected.push(item.title);
}
vm.removeItem = function(item) {
var index = vm.selected.indexOf(item.title);
vm.selected.splice(index, 1);
}
});
.element {
margin: 20px;
line-height: 10px;
border-bottom: 1px solid black;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myModule">
<div ng-controller="myCtrl as ctrl">
<div ng-repeat="dimension in ctrl.dimensions" ng-click="ctrl.selectItem(dimension, $event)">
<span text="{{dimension.title}}" title="{{dimension.title}}" class="element">
{{ dimension.title }}
<span ng-if="ctrl.isSelected(dimension)">- checked</span>
</span>
</div>
</div>
</div>
I have an accordion expand is working fine but collapse is not working,it should work like accordion,for ex when I click 'title 2' its content should expand and 'title 1' content should collapse.below is my code,I am new to angularjs.Anyone can help me.If its in jquery also fine.
HTML
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css'>
<body ng-app="app">
<h1>Dynamic accordion: nested lists with html markup</h1>
<div ng-controller="AccordionDemoCtrl">
<div>
<div ng-repeat="group in groups">
<div class="parents" ng-click="item=1"><i class="glyphicon-plus"></i> {{ group.title }}
</div>
{{ group.content }}
<ul class="childs" ng-show="item==1">
<li ng-repeat="item in group.list">
<span ng-bind-html="item"></span>
</li>
</ul>
</div>
</div>
</div>
</body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-sanitize.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js'></script>
<script src="js/index.js"></script>
index.js
angular.module('app', ['ui.bootstrap','ngSanitize','angular.filter']);
angular.module('app').controller('AccordionDemoCtrl', function ($scope) {
$scope.oneAtATime = true;
$scope.groups = [
{
title: 'title 1',
isOpen: true,
list: ['<i>item1a</i> blah blah',
'item2a',
'item3a']
},
{
title: 'title 2',
list: ['item1b',
'<b>item2b </b> blah ',
'item3b']
},
{
title: 'title 3',
},
{
title: 'title 4',
},
{
title: 'title 5',
}
];
});
I suggest you those functions :
$scope.open = function (index) {
$scope.groups[index].isOpen = !$scope.groups[index].isOpen;
$scope.closeOthers(index);
}
$scope.closeOthers = function (index) {
for(var i = 0; i < $scope.groups.length; i++) {
if (i !== index)
$scope.groups[i].isOpen = false;
}
}
open is fired when clicking on a parent, closeOthers is called in open. I init a visible boolean to parents. Each time user clicks on a parent, it set visible to true, and others to false.
<div ng-controller="AccordionDemoCtrl">
<div>
<div ng-repeat="group in groups track by $index">
<div class="parents" ng-click="open($index)"><i ng-class="{'glyphicon-minus': group.isOpen, 'glyphicon-plus': !group.isOpen}"></i> {{ group.title }}
</div>
{{ group.content }}
<ul class="childs" ng-show="group.isOpen">
<li ng-repeat="item in group.list">
<span ng-bind-html="item"></span>
</li>
</ul>
</div>
</div>
</div>
Working demo
I just need ** only data and title must be increase their font size** when I changed the switch statement but i dont want to increase size of font size of right corner how can i do that
<!DOCTYPE html>
<html ng-app="myApp">
<head>
***emphasized text***
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="angular-gridster.min.css"></link>
<link rel="stylesheet" href="wid.css"></link>
</head>
<body ng-controller="myController" >
<div gridster ng-controller="myCtrl" >
<ul>
<li gridster-item="item" ng-repeat="item in Items">
<div my-widget ></div>
</li>
</ul>
</div>
<select ng-model="fontStyle" ng-change="style()">
<option value="larger">larger</option>
<option value="middle">middle</option>
<option value="small">small</option>
</select>
</body>
</html>
my script goes here which contains the controller as well as directive.
var app=angular.module('myApp',['gridster'])
app.controller('myController',function($scope){
$scope.Items = [
{ sizeX: 2, sizeY: 1, row: 0, col: 0, obj:{data:54565463,right:67566,title:'Headers'}},
{ sizeX: 2, sizeY: 1, row: 0, col: 0, obj: {data:65476756,right:12344,title:"Income"}}]
$scope.style = function() {
style = $scope.fontStyle;
switch (style) {
case 'larger':
$scope.myStyle = {
"font-size": "2.3em",
}
break;
case 'middle':
$scope.myStyle = {
"font-size": "2.0em"
}
break;
case 'small':
$scope.myStyle = {
"font-size": "1.3em",
}
break;
default:
alert('/#larger');
}
}
});
app.directive('myWidget',function(){
return{
restrict:"EA",
scope:{
title:'#',
data:'=',
},
templateUrl:'spare.html',
}
});
and my spare html is below -
<span ng-controller="myController" >
<div class="panel-body" >
<h1 class="title" >{{data.title}}</h1>
<i class="fa fa-dollar"></i>{{data.data}}
</h1></div>
<p id="rightcorner"><i class="fa fa-level-up"></i>{{data.right}}
</p>
</span>
Use ng-style for elements that you want assign style dynamically.
See documentation for details and examples.
If you want to add style which is stored in $scope.myStyle it goes like that:
<div ng-style="myStyle">...</div>
Complete example:
HTML:
<div ng-app="app" ng-controller="myController">
myStyle current value: {{myStyle}}
<div ng-style="myStyle">
element with style
</div>
<button ng-click=changeStyle()>
Change style
</button>
</div>
JS:
angular.module("app", []).controller("myController", function($scope) {
$scope.myStyle = {
color: 'red'
};
$scope.changeStyle = function() {
$scope.myStyle = {
color: 'blue'
};
}
});
Working jsfiddle
I am learning angularjs and I came across some behaviour that I can't understand. I render a list of items in ng-repeat, each has a button to remove itself from the $scope's array - this works as expected but once I added a sortable to the list strange things started to happen.
Here is the running example showing the issue:
https://embed.plnkr.co/eQWcxZ7p8CcACfk6Z53X/
In the example - if I move [^] item 4 (Rocket Launcher) to position 1 and use Rocket Launcher's delete [X] button the list gets updated (i.e. item 4 - Rocket Launcher - that was on position 1 is removed) but the other items delete buttons stop working. Basically moving items and deleting them somehow break the bindings (?).
The code:
(function() {
'use strict';
var app = angular.module('myApp', []);
app.controller('myAppController', function($scope) {
$scope.boxes = [];
$scope.removeBoxItem = function(box, item) {
console.log('Removing "' + item.name + '" form box "' + box.name + '"...');
var index = box.items.indexOf(item);
box.items.splice(index, 1);
console.log(box);
};
this.init = function() {
var e;
e = new Box({
name: 'Red box'
});
$scope.boxes.push(e);
e.items.push(new Item({
index: 1,
name: 'Rock'
}));
e.items.push(new Item({
index: 2,
name: 'Scissors'
}));
e.items.push(new Item({
index: 3,
name: 'Paper'
}));
e.items.push(new Item({
index: 4,
name: 'Rocket launcher'
}));
e = new Box({
name: 'Green box'
});
e.items.push(new Item({
index: 1,
name: 'Chuck the Plant'
}));
e.items.push(new Item({
index: 2,
name: 'Hamster'
}));
e.items.push(new Item({
index: 3,
name: 'Tentacle Chow'
}));
$scope.boxes.push(e);
};
this.init();
});
app.directive("sortable", ["$timeout", function($timeout) {
return {
template: '<div class="sortable" ng-transclude></div>',
transclude: true,
scope: {
'handle': '#'
},
link: function(scope, element, attrs) {
$timeout(function() {
//console.log(element)
var sortable = element.find('> div');
console.log(sortable[0]);
scope.sortable = Sortable.create(sortable[0], {
handle: scope.handle || null
});
});
}
};
}]);
}());
function Box(args) {
this.name = args.name || null;
this.items = [];
}
function Item(args) {
this.index = args.index || null;
this.name = args.name || null;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" />
<style>
.container {
border: 1px solid #929292;
padding: 5px;
}
.header {
font-size: 1.2rem;
padding: 10px 15px;
background-color: #F5F5F5;
border-bottom: 2px solid #E2E2E2;
}
.body {
background-color: #F2F2F2;
padding: 10px 10px;
margin-bottom: 10px;
}
.body .item {
border: 1px solid #D2D2D2;
padding: 5px;
margin-bottom: 5px;
}
.body .options {
float: right;
}
.body .options .delete {
cursor: pointer;
}
.body .options .handle {
cursor: move;
}
.debug {
margin-top: 20px;
border-top: 1px dotted #929292;
}
</style>
</head>
<body>
<div ng-app="myApp" ng-controller="myAppController as appCtrl">
<div class="container">
<div ng-repeat="box in boxes">
<div class="header">{{ box.name }}</div>
<div class="body">
<div data-sortable="" data-handle=".handle">
<div class="item" ng-repeat="item in box.items">
{{item.index }}) {{ item.name }}
<div class="options">
<span ng-click="removeBoxItem(box, item)" class="delete">[X]</span>
<span class="handle">[^]</span>
</div>
</div>
</div>
</div>
</div>
<div class="debug">
<pre>{{ boxes | json }}
</pre>
</div>
</div>
</div>
<script data-require="jquery#3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script data-require="Sortable.js#1.6.0" data-semver="1.6.0" src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.js"></script>
<script data-require="angular.js#1.6.6" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script>
<script src="script.js"></script>
</body>
</html>
I am confused by this, in my real code things get even more broken - I made a collapsible directive that surrounds the "Boxes" so I can open and manipulate one at a time - in that case moving item 4 to position 1 and deleting it removes all items from the view (but not from the $scope). Than adding new item to the $scope's array causes items to correctly reappear. For now I created simpler version as I guess this is all somehow connected.
I am aware the sortable should set the objects indexes etc but for now I'd like to understand what is happening. I suspect I have some issues with understanding what is going on with scopes (?). Would be grateful for any help.
I am rewriting an angular select option, previously I was using a bootstrap btn-group class with numerous li classes, which used ng-click to set a filter in my ng-repeat list which worked perfectly. Like so:
<li role="menuitem">
<a ng-click="myFilter = { moving: true }">Delivery & Removals</a>
</li>
However, after some feedback, I have been asked to change it to a <select> with <option> set up, so to reflect the selected option.
I have added a list to my controller scope, like so:
$scope.taskCategories = [
{'cat': 'Moving & Delivery', 'filter': 'moving: true'},
{'cat': 'DIY', 'filter': 'DIY: true'},
{'cat': 'Marketing', 'filter': 'marketing: true' }
]
Here is the select
{{ selectedCat.filter }}
<select ng-model="selectedCat" ng-value="x.filter" ng-options="x.cat for x in taskCategories">
</select>
Here is my ng-repeat
data-ng-repeat="task in vm.tasks | filter:search | filter:myFilter | filter: { filter: selectedCat.filter } : true | orderBy:predicate:reverse | filter:x as results"
To give a bit of relevance, my ng-click filters work like so:
ng-click="myFilter = { moving: true }"
However, when I click on one of my select values, which are ng-repeating through the $scope.taskCategories just fine, my ng-repeat returns 0 results, which is not correct.
If anyone could give me any pointers on where I am going wrong, I would greatly appreciate it. Thanks in advance! :)
You can create a custom filter and search by the property inside the object, as the following:
(function(angular) {
'use strict';
angular.module('ngRepeat', ['ngAnimate'])
.controller('repeatController', function($scope) {
$scope.tasks = [
{
'created': "2016-07-02T21:01:56.095Z",
'description':"hang it",
'dueDate':"2016-07-02T22:00:00.000Z",
'inPersonTask':true,
'isCurrentUserOwner':false,
'moving':true,
'profileImageURL':"modules/users/client/img/profile/default.png",
'statusAssigned':false,
'statusClosed':false,
'statusOpen':true,
'taskLocation':"eerywhere",
'title':'example 3'
},
{
'created': "2016-07-02T21:01:56.095Z",
'description':"hang it",
'dueDate':"2016-07-02T22:00:00.000Z",
'inPersonTask':true,
'isCurrentUserOwner':false,
'DIY':true,
'profileImageURL':"modules/users/client/img/profile/default.png",
'statusAssigned':false,
'statusClosed':false,
'statusOpen':true,
'taskLocation':"the world",
'title':'example 2'
},
{
'created': "2016-07-02T21:01:56.095Z",
'description':"hang it",
'dueDate':"2016-07-02T22:00:00.000Z",
'inPersonTask':true,
'isCurrentUserOwner':false,
'marketing':true,
'profileImageURL':"modules/users/client/img/profile/default.png",
'statusAssigned':false,
'statusClosed':false,
'statusOpen':true,
'taskLocation':"the world",
'title':'example 3'
}
];
$scope.taskCategories = [
{'cat': 'Moving & Delivery', 'filter': 'moving: true'},
{'cat': 'DIY', 'filter': 'DIY: true'},
{'cat': 'Marketing', 'filter': 'marketing: true' }
];
})
.filter('customFilter', function() {
return function(items, search) {
if (!search) {
return items;
}
return items.filter(function(element) {
// Ex: moving: true, becomes just 'moving'
return Object.getOwnPropertyNames(element).find(x => x == search.substring(0, search.indexOf(':')));
});
};
});
})(window.angular);
.example-animate-container {
background:white;
border:1px solid black;
list-style:none;
margin:0;
padding:0 10px;
}
.animate-repeat {
line-height:30px;
list-style:none;
box-sizing:border-box;
}
.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
transition:all linear 0.5s;
}
.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
opacity:0;
max-height:0;
}
.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
opacity:1;
max-height:30px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example</title>
<link href="animations.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.min.js"></script>
</head>
<body ng-app="ngRepeat">
<div ng-controller="repeatController">
<!-- list of tasks /-->
<h3>List of tasks, without filter</h3>
<ul class="example-animate-container">
<li class="animate-repeat" ng-repeat="task in tasks">[{{$index + 1}}] {{ task.title }}, {{ task.taskLocation }}</li>
</ul>
<!-- list of tasks with filter /-->
<h3>List of tasks with filter -- results are not showing</h3>
<p>{{ selectedCat }}</p>
<select ng-model="selectedCat" ng-options="x.cat for x in taskCategories" ng-value="x.filter">
</select>
<ul>
<li class="animate-repeat" ng-repeat="task in tasks | customFilter: selectedCat.filter">
[{{$index + 1}}] {{ task.title }}, {{ task.taskLocation }}</li>
</ul>
</div>
</body>
</html>