I am looking for some help with a little Angular App.
I have a group of items/images that when a plus icon is clicked, all other items are covered and the selected item is not covered.
I want to now trigger this from outside of the ng-repeat.
I am looking for a way to trigger the cover effect when clicking on a text link, as well as the plus icon now used.
Have it use both options.
So far I have the text triggers fire off a id, that can be used in the app code.
Here is a Working FIDDLE.
Here is the original question that Avijit Gupta did for this.
Avijit's post is the excepted answer.
Any help with this is greatly appreciated.
The nav Text trigger code...
<div class="col-xs-12 navText">
<ul>
<li><a href data-id='1' data-ng-click="idLocation($event)">ONE</a></li>
<li><a href data-id='2' data-ng-click="idLocation($event)">TWO</a></li>
<li><a href data-id='3' data-ng-click="idLocation($event)">THREE</a></li>
<li><a href data-id='4' data-ng-click="idLocation($event)">FOUR</a></li>
<li><a href data-id='5' data-ng-click="idLocation($event)">FIVE</a></li>
</ul>
</div>
The app code...
// nav text trigger id's
$scope.idLocation = function (e) {
ids = $(e.target).data('id');
console.log(ids);
};
$scope.setToInitialState = function() {
$scope.blocks.forEach(function(block) {
$scope.isSelected[block.id] = false;
$scope.isCovered[block.id] = false;
});
};
$scope.selectBlock = function(id) {
$scope.isSelected[id] = !$scope.isSelected[id];
$scope.isCovered[id] = false;
if ($scope.isSelected[id]) {
$scope.blocks.forEach(function(block) {
if (block.id !== id) {
$scope.isCovered[block.id] = true;
$scope.isSelected[block.id] = false;
}
});
}
else {
$scope.setToInitialState();
}
};
});
How it works...
I suggest you to use the same ng-repeat in tag li and the same function selectBlock in tag a.
<div class="row">
<div class="col-xs-12 navText">
<ul>
<li ng-repeat="block in blocks"><a href data-ng-click="selectBlock(block.id)">{{block.name}}</a></li>
</ul>
</div>
</div>
Also I add the field name for each element in blocks.
$scope.blocks = [
{
id: '1',
name: 'ONE',
block: "1",
},
{
id: '2',
name: 'TWO',
block: "2",
},
{
id: '3',
name: 'THREE',
block: "3",
},
{
id: '4',
name: 'FOUR',
block: "4",
},
{
id: '5',
name: 'FIVE',
block: "5"
}
];
To Answer my own question.
One way to trigger the cover effect from outside of the ng-repeat.
What I did here was to use the selectBlock() in a data-ng-click and just hard code the ID into the selectBlock().
Like this...
<li><a href data-ng-click="selectBlock('1')">ONE</a></li>
<li><a href data-ng-click="selectBlock('2')">TWO</a></li>
<li><a href data-ng-click="selectBlock('3')">THREE</a></li>
<li><a href data-ng-click="selectBlock('4')">FOUR</a></li>
<li><a href data-ng-click="selectBlock('5')">FIVE</a></li>
Here is the demo of it working by clicking the TEXT and the +/- icon.
Working FIDDLE.
Related
I have radio buttons and 'delete' text with ng repeat,here based on radio button checked I need to show the delete text,whenever I click on radio button 'delete' text should show and again when I click to next radio button 'delete' should hide for previous unchecked radio button and should show for next checked radio button.
For me its working but onclick of next radio button previous 'delete' text is not hiding.Code is given below.Can anyone help me I am new to angularjs.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.div_ = [];
$scope.items = [{
id: 1,
title: "first item"
},
{
id: 2,
title: "second item",
},
{
id: 3,
title: "third item",
}
];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<script src="app.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
<ul ng-repeat="item in items">
<li style="color:red;display:inline" ng-click="item=1"><input type="radio" name="samename" value={{$index}}></li>
<li style="color:blue;display:inline;margin-left:100px;" name="samenaame" ng-show="item==1" ng-show="item==1">delete</li>
</ul>
</div>
I tried to do minimum amount of changes to your main code, but I think it is flawed.
Not sure what you are trying to achieve with the multiple ul's you had, so I removed them.
You can use ng-repeat-start and -end as in this example, maybe that's what you want.
This code will only show one extra "li" depends on which ID you selected. (using a "helper" property)
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.div_ = [];
$scope.selectedItem;//or nothing
$scope.items = [{
id: 1,
title: "first item"
},
{
id: 2,
title: "second item",
},
{
id: 3,
title: "third item",
}
];
$scope.handleClick = function (item) {
$scope.selectedItem = item;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
<ul>
<li ng-repeat-start="item in items" style="color:red;display:inline" ng-click="handleClick(item)">#Item={{item.id}}
<input type="radio" name="samename" value={{$index}}>
</li>
<li ng-repeat-end style="color:blue;display:inline;margin-left:100px;" ng-show="selectedItem==item">delete #{{item.id}}</li>
</ul>
</div>
I'm trying to do a tree menu on my site.
I want the subitems to show/hide when I click the parent.
This solution don't work. Even tho it changes the item.active value to false/true. Any ides my friends?
Here is my HTML:
<div id="sidebar-wrapper">
<div class="cssTreeMenu tree">
<ul class="sidebar-nav">
<li ng-repeat="item in items" >
<a ui-sref="{{item.sref}}" ui-sref-active="active" ng-click="testcolaps($index)">{{item.name}}</a>
<ul ng-show="{{item.active}}" class="navbarColorOnClick">
<li ng-repeat="subItem in item.subItems" ui-sref-active="active">
<a ui-sref="{{subItem.sref}}">{{subItem.name}}</a>
</li>
</ul>
</li>
</ul>
</div>
Here is my controller:
$scope.testcolaps = function (index) {
$scope.items[index].active = !$scope.items[index].active;
};
$scope.items = [
{
name: "Test",
sref: "kpi.test",
active: false,
subItems: [
{
name: "Selectable KPI menu",
sref: "kpi.selectableKpiMenu"
},
{
name: "Test",
sref: "kpi.test"
}
]
},
{
name: "Test2",
sref: "kpi.test",
active: false,
subItems: [
{
name: "Selectable KPI menu 2",
sref: "kpi"
},
{
name: "Test 2",
sref: "internal"
}
]
},
];
As you can se my items have a active: property who I change to true/false. But still nothing happens in my menu. If I hard-code it to true it is showing like it should but still the click-event doesn't work.
The expression inside the ng-show need an expression without {{}} interpolation. Basically you need to remove {{}}.
ng-show="item.active"
I would like to display a list based on which item is selected in a dropdown.
When I use the code below, I'm getting this error:
TypeError: Cannot read property 'type' of undefined
Any suggestions on how to do this right?
HTML:
<select class="form-control" ng-model="editProject.project.type"
ng-options="project as project.type for project in editProject.options track by project.type">
</select>
<ul class="list-group">
<li class="list-group-item" ng-repeat="benefit in editProject.foods()">{{snack}}</li>
</ul>
Controller:
.controller('EditProjectCtrl', function () {
var editProject = this;
editProject.options = [
{'type': 'Fruits'},
{'type': 'Vegetables'},
{'type': 'Desserts'}
];
editProject.snacks = function() {
if(editProject.project.type == 'Fruits') {return [
'Grapes',
'Oranges',
'Apples',
]}
if(editProject.project.type == 'Vegetables') {return [
'Broccoli',
'Spinache',
'Kale',
]}
else {return [
'Cookies',
'Cake',
'Pie']}
};
You are almost there. There was a mismatch between the ng-model of the select element, and the conditions in the controller. I also replaced benefit in editProject.foods() with snack in editProject.snacks():
<select class="form-control" ng-model="editProject.project" ng-options="project as project.type for project in editProject.options track by project.type"></select>
<ul class="list-group">
<li class="list-group-item" ng-repeat="snack in editProject.snacks()">{{snack}}</li>
</ul>
Because editProject.project is not defined until you select a project, you have to initialize it in the controller:
editProject.project = {};
See fiddle
I am using angular-ui's sortable-ui module and am trying to raise a cancel so that the dragged items returns to it original location in the source list. Unfortunately I cannot get this working. Here is an example:
http://jsfiddle.net/Ej99f/1/
var myapp = angular.module('myapp', ['ui.sortable']);
myapp.controller('controller', function ($scope) {
$scope.list = ["1", "2", "3", "4", "5", "6"];
$scope.list2 = ["7", "8", "9"];
$scope.sortableOptions = {
update: function(e, ui) {
if (Number(ui.item.text()) === 6) {
ui.item.parent().sortable('cancel');
}
},
receive: function(e, ui) {
ui.sender.sortable('cancel');
ui.item.parent().sortable('cancel');
},
connectWith: ".group",
axis: 'y'
};
});
angular.bootstrap(document, ['myapp']);
Any help would be gratefully appreciated.
well, when it comes to angular, all roads lead to the data "the single source of truth". So update your model back to it's original state, before the move, and you're all set :)
example below has two lists, the first one being restricted for
its sorting (the update method)
and for sending an item (receive method on list 2)
the second list you can sort, and send items to list 1
(using foundation4 for css)
<div ng-app="test">
<div ng-controller="sortableTest">
<div class="small-4 columns panel">
<ul data-drop="true"
ui-sortable="sortable.options.list1" ng-model="sortable.model.list1">
<li ng-repeat="fruit in sortable.model.list1"
data-id="{{ fruit.id }}">{{ fruit.label }}</li>
</ul>
</div>
<div class="small-4 columns panel">
<ul data-drop="true"
ui-sortable="sortable.options.list2" ng-model="sortable.model.list2">
<li ng-repeat="element in sortable.model.list2"
data-id="{{ element.id }}">{{ element.label }}</li>
</ul>
</div>
<div class="clear"></div>
<br />
<span ng-repeat="fruit in sortable.model.list1">{{ fruit.label }} </span><br />
<span ng-repeat="element in sortable.model.list2">{{ element.label }} </span><br />
<span ng-repeat="fruit in sortable.oldData.list1">{{ fruit.label }} </span><br />
<span ng-repeat="element in sortable.oldData.list2">{{ element.label }} </span><br />
</div>
</div>
js:
var test = angular.module('test', ['ui.sortable']);
test.controller('sortableTest', function($scope, $timeout) {
$scope.sortable = {
model: {
list1: [{id: 1, label: 'apple'},{id: 2, label: 'orange'},{id: 3, label: 'pear'},{id: 4, label: 'banana'}],
list2: [{id: 5, label: 'earth'},{id: 6, label: 'wind'},{id: 7, label: 'fire'},{id: 8, label: 'water'}]
},
oldData: {
list1: [],
list2: []
},
options: {
list1: {
update: function(event, ui) {
console.debug('up-list1');
$scope.sortable.oldData.list1 = $scope.sortable.model.list1.slice(0);
$scope.sortable.oldData.list2 = $scope.sortable.model.list2.slice(0);
// DO NOT USE THIS! it messes up the data.
// ui.item.parent().sortable('cancel'); // <--- BUGGY!
// uncomment and check the span repeats..
$timeout(function(){
$scope.sortable.model.list1 = $scope.sortable.oldData.list1;
$scope.sortable.model.list2 = $scope.sortable.oldData.list2;
});
},
connectWith: 'ul'
},
list2: {
update: function(event, ui) {
console.debug('up-list2');
},
connectWith: 'ul',
receive: function(event, ui) {
console.debug('re-list2');
$timeout(function(){
$scope.sortable.model.list1 = $scope.sortable.oldData.list1;
$scope.sortable.model.list2 = $scope.sortable.oldData.list2;
});
}
}
}
};
});
you can of course use a service or something to store the old value. One can use ui.sender to differentiate the senders, if you have more that two..
I have this data structure, search:
{
id: '1',
name: 'Foo'
service_ids:
[
3,
8,
12
]
}
I then have another data structure, services, that matches the ids from service_ids above with the below:
[
{
id: 3,
name: 'Fighter'
},
{
id: 4,
name: 'Typhoon'
},
{
id: 8,
name: 'Kung'
},
{
id: 12,
name: 'Builder'
}
]
I want to display this in a form using AngularJS. The name is fine. I want to display all possible services as checkboxes and if the search has one of the services checked then it is ticked in the checkbox. Something like:
<li ng-repeat="search in searches">
<input ng-model="search.name">
<ul>
<li ng-repeat="service in services">
<input type="checkbox">
{{service.name}}
</li>
</ul>
</li>
I don't know how to link that checkbox to the service_ids and the services. Any help appreciated.
I am using $resource.
Update
Ignore my answer, misread you nesting request.
If anyone needs nesting guidance see below:
The best way to nest in angular that I have found is to create a template which is aware of child items like this:
<script type="text/ng-template" id="tree_item_renderer.html">
<span>{{tag.Name}}</span>
<ul ng-show="tag.Children.length > 0">
<li ng-repeat="tag in tag.Children" ng-include="'tree_item_renderer.html'" ></li>
</ul>
</script>
<ul class="tag-list">
<li ng-repeat="tag in tags" ng-include="'tree_item_renderer.html'" ></li>
</ul>
If I understand your question it should be as easy as:
<input type="checkbox" ng-model="search.service_ids[service.id]">
And you should also get bi-directional binding.
Updated
Just realized search.service_ids is an array not a map. So the solution above is not accurate.
You might want instead to use a filter:
<input type="checkbox" ng-checked="search.service_ids | contains:service.id">
Then
filter('contains', function() {
return function(haystack, needle) {
return haystack.indexOf(needle) >= 0;
}
});