How can I use the following controller to toggle the content inside li tag?
Right now the content is rendered only after that span is clicked, but it won't hide if I click again the span.
Here's my code:
<span ng-click="get_menu_items(folder)>
<i class="fa fa-folder-o"></i>
{{ folder.name }}
</span>
<ul>
<li class="item" ng-repeat="file in folder.files">
<label>
<input type="checkbox" name="file_map[]" value="{{ file.id }}" ng-model="file_map[file.id]" ng-click="update_selection(file.id)"/>
<i class="fa fa-file-o"></i>
<span>{{ file.name }}</span>
</label>
</li>
<li menuitem ng-repeat="folder in folder.folders" ng-model="folder"></li>
</ul>
Controller:
scope.get_menu_items = function(folder){
http.get("/api/folders/" + folder.id).success(function(data){
folder.folders = data.data.folders;
folder.files= data.data.files;
})
}
You can simply create a boolean for show/hide and toggle it on your click method like.
scope.get_menu_items = function(folder){
//if folder.folder exist means we don't need to make $http req again
if(folder.folders){
$scope.showFolder = !$scope.showFolder
}
else{
http.get("/api/folders/" + folder.id).success(function(data){
folder.folders = data.data.folders;
folder.files= data.data.files;
$scope.showFolder = true;
})
}
}
and add ng-if on your view like.
<span ng-click="get_menu_items(folder)>
<i class="fa fa-folder-o"></i>
{{ folder.name }}
</span>
<ul ng-if="showFolder">
<li class="item" ng-repeat="file in folder.files">
<label>
<input type="checkbox" name="file_map[]" value="{{ file.id }}" ng-model="file_map[file.id]" ng-click="update_selection(file.id)"/>
<i class="fa fa-file-o"></i>
<span>{{ file.name }}</span>
</label>
</li>
<li menuitem ng-repeat="folder in folder.folders" ng-model="folder"></li>
</ul>
Hope it helps.
Add a global variable in controller as scope.
Outside controller, add a variable (for example called: toggleVariable) and assign it to false.
Inside controller put this:
scope.toggleVariable = !scope.toggleVariable;
In HTML, add to ul tag: ng-show="toggleVariable".
Give it a try
Related
I got an workaround here and need some help. It is a tree of categories. Some categores can be chosen by a checkbox.
I thougt the cleanest way to do that is via direction. On a <li kw-category-node> element put a on('click', function()) handler, which then does the choosing work (add object to data etc.).
So I came up with this HTML
<script type="text/ng-template" id="category_renderer.html">
<div ng-if="true == true" ng-mouseenter="over = true" ng-mouseleave="over = false">
<input type="checkbox"
ng-model="assignedCategories[category.category_id]"
ng-if="category.childs.length == 0"
ng-click="toggleCategory(category)">
</input> {{ category.name }}
<a href ng-if="over" ng-click="categories.remove(category)">
<small> <i class="fa fa-times"></i> Entf </small>
</a>
</div>
<ul class="list-unstyled">
<li ng-repeat="category in category.childs"
ng-include="'category_renderer.html'"
kw-category-node>
</li>
</ul>
</script>
<ul class="list-unstyled" kw-category-tree>
<li ng-repeat="category in categories.tree"
ng-include="'category_renderer.html'"
kw-category-node>
</li>
</ul>
And a directive like that
admin.directive('kwCategoryNode', ['$interval', 'dateFilter', function($interval, dateFilter) {
function link(scope, element, attrs) {
element.find('input').on('click', function() {
alert("wow, what a click!");
});
}
But element.find("input") wont give me that input element. Maybe the DOM is not loaded completly or I'm just in tilt.
Thanks
I want select DOMs using jQuery.
HTML code
<li>
<span class="node>
<span class="con"></span>
<span class="check"></span>
<img>
<a title="high">abc</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check"></span>
<img>
<a title="high">def</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check"></span>
<img>
<a title="low">zwc</a>
</span>
</li>
I want select "check" class span DOMs what have "a tag" has "high" title in same level.
I tried to click that DOMs using this query:
$('a[title="high"]').each(function() {
$(this).prev().prev().click();
})
but this code have only first match value.
How can I select all DOMs?
My mistake. I want "check" not "con". Thanks.
The point of this question is "all" DOMs what have "high" title attr should be clicked.
you can use .closest().find()
$('a[title="high"]').each(function() {
$(this).closest('.node').find('.con').click();
})
Working Demo
You can use filter() to filter out elements from a set based on condition.
// Get all spans having class `con`
$('span.con').filter(function () {
// If this element has anchor element sibling with `high` as Title
// then return true, else return false
return $(this).siblings('a[title="high"]').length;
}).css('color', 'green');
$('span.con').filter(function() {
return $(this).siblings('a[title="high"]').length;
}).css('color', 'green');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>
<span class="node">
<span class="con">First</span>
<span class="check"></span>
<img>
<a title="high">abc</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Second</span>
<span class="check"></span>
<img>
<a title="high">def</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Third</span>
<span class="check"></span>
<img>
<a title="low">zwc</a>
</span>
</li>
</ul>
Instead of .prev().prev() use siblings() to find the items in the same level and filter with .con.
$('a[title="high"]').each(function() {
$(this).siblings('.con').click();
});
If you want to know why actually your code is not working, you called prev() two times. By first one you select img, the second one will select .check. So you need to call prev() third time to reach .con. This is always confusing and may break anytime if you add more element in between. That's why this approach is not recommended.
As CSS and jQuery don't have previous sibling selector, you can use General sibling selector.
You can use General sibling selectors to select elements having specific attribute and then use jQuery's sibling() to select span.con.
$('span.check ~ a[title="high"]') // Select all anchors having `title` as "high"
// Which are next siblings of `span` having class of `check`
.siblings('span.check') // Select sibling `span` having class `con`
.css('color', 'green');
The selector $('span.check ~ a[title="high"]') will select anchor elements, to get the span, use siblings.
$('span.check ~ a[title="high"]')
.siblings('span.check')
.each(function() {
$(this).css('color', 'green').click();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>
<span class="node">
<span class="con">First</span>
<span class="check">First Check</span>
<img>
<a title="high">abc</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Second</span>
<span class="check">Second Check</span>
<img>
<a title="high">def</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Third</span>
<span class="check">Third Check</span>
<img>
<a title="low">zwc</a>
</span>
</li>
</ul>
Actually your code is working fine. See I tried this,
HTML :
<li>
<span class="node>
<span class="con"></span>
<span class="check" onclick="console.log('span :'+1);"></span>
<img onclick="console.log('img :'+1);">
<a id = "m1" title="high" onclick="console.log('a :'+1);">abc</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check" onclick="console.log('span :'+2);"></span>
<img onclick="console.log('img :'+2);">
<a id = "m2" title="high" onclick="console.log('a : '+2);">def</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check" onclick="console.log('span : low');"></span>
<img onclick="console.log('img : low');">
<a id = "m3" title="low" onclick="console.log('low');">zwc</a>
</span>
</li>
JS:
$(function(){
$('a[title="high"]').each(function() {
// if you want to click all <a>
$(this).click();
// if you want to click all <img>
$(this).prev().click();
// if you want to click all <span> having class check
$(this).prev().prev().click();
});});
Console:
a :1
img :1
span :1
a : 2
img :2
span :2
How can I get the id of a component in AngularJS ?
HTML
<li class="list-group-item" id="person_2" ng-click="invitePerson(this)">
<span class="label label-primary">A</span> Alexandre Dolabella Resende
</li>
JS
$scope.invitePerson = function(id) {
alert(id);
};
The alert returns [Object object], how can I access my component ID ? (in my case, should be person_2)
Console.log
Use $event to get the eventhandler param. From that param we can get the target element and its attributes
<li class="list-group-item" id="person_2" ng-click="invitePerson($event)">
<span class="label label-primary">A</span> Alexandre Dolabella Resende
$scope.invitePerson = function(e){
alert(e.target.id);
}
You can use ng-init or your controller to initialize the value. Then define a model, and you can then pass that model into a controller function, such as invitePerson
Working Plunker
HTML:
<ul>
<li class="list-group-item" id="person_2"
ng-init="person_2=5"
ng-model="person_2"
ng-click="invitePerson(person_2)">
<span class="label label-primary">A</span> Alexandre Dolabella Resende
</li>
</ul>
JS:
app.controller('MainCtrl', function($scope) {
$scope.invitePerson = function(id){
alert(id);
}
When I see "person_2" I immediately think of ng-repeat and maybe you should too if you want to iterate over object in your partial, http://plnkr.co/edit/b6ZePD826FauaY9x8b9p?p=preview
<label for="list">List</label>
<ul id="list">
<li class="list-group-item" id="person{{$index}}" ng-click="invitePerson(person)" ng-repeat="person in persons">
<span class="label label-primary">{{person.label}}</span> {{person.name}}
</li>
</ul>
<label for="invited">Invited</label>
<ul id="invited">
<li ng-repeat="invite in invited track by $index">{{invite.name}}</li>
</ul>
I have two directives to format text of elements.
app.directive("kilometersText", function(){
// writes number as kilometer
})
app.directive("metersText", function(){
// writes number as meter
})
HTML:
<ul>
<li ng-repeat="item in data">
<span kilometers-text="item.length"></span>
</li>
</ul>
I have two buttons that change view to meter or kilometer.
<button type="button"> meter </button>
<button type="button"> kilometer </button>
How can I change directive with these buttons?
Instead of changing the attribute, i suggest to use two spans, one for showing in KMs and other in meters. and then hide them conditionally based on the selected view.
<ul>
<li ng-repeat="item in data">
<span ng-show="item.view == 'kilometer'" kilometers-text="item.length"></span>
<span ng-show="item.view == 'meter'" kilometers-text="item.length"></span>
</li>
</ul>
I'm using .net mvc and razor and I'm displaying items (itemRoom, itemDescription) in my view like this:
#foreach (var item in Model) {
<li class="errorItem">
<a href="#" class="list-group-item">
<i class="fa fa-warning fa-fw"></i> #Html.DisplayFor(modelItem => item.room) : #Html.DisplayFor(modelItem => item.title)
<span class="pull-right text-muted small"><em>5 min ago</em>
</span>
<div>
<ul id="errorExtra" class="nav nav-second-level" style="display: none;">
<li>
<p> #Html.DisplayFor(modelItem => item.description)</p>
<input type="button" id="btnFixed" value="Fixed" class="btn btn-success"/>
</li>
</ul>
</div>
</a>
</li>
}
At the bottom of my page I'm using JQuery to let every item slide open when it's clicked on so that the details and 'Fixed' button become visible. When the user clicks on the Fixed button he gets directed to a confirmation page to delete the item.
<script src="../Assets/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var isOpen = false;
$(".errorItem").click(function (e) {
isOpen = !isOpen;
if (isOpen) {
$(this).find("#errorExtra").slideToggle("slow");
} else {
$(".btn-success").click(function (e) {
window.location.replace("Reports/Delete/2")
})
};
});
});
</script>
Everything works quite all right but the link 'window.location.replace("Reports/Delete/2")' actually has to be 'Reports/Delete/itemID' but how can I mange to get the ID of the item that the user has clicked on and that has slide open? So that THIS item will be deleted on the confirmation page?
do a little change in view, assuming your unique id is with property name Id:
#foreach (var item in Model) {
<li class="errorItem">
<a href="#" class="list-group-item">
<i class="fa fa-warning fa-fw"></i> #Html.DisplayFor(modelItem => item.room) : #Html.DisplayFor(modelItem => item.title)
<span class="pull-right text-muted small"><em>5 min ago</em>
</span>
<div>
<ul id="errorExtra" class="nav nav-second-level" style="display: none;">
<li>
<p> #Html.DisplayFor(modelItem => item.description)</p>
--> change is here <input type="button" id="btnFixed" data-url="#Url.Action("Delete","Reports",new{id=item.Id})" value="Fixed" class="btn btn-success"/>
</li>
</ul>
</div>
</a>
</li>
}
In Jquery:
$(".btn-success").click(function (e) {
var url = $(this).data("url");
window.location.replace(url);
});
Just a small notice: you'll have multiple buttons with the same id="btnFixed" because it's inside of the #foreach loop. Maybe adding some kind of index to it would be reasonable or changing it to the class="btnFixed".
The same with the <ul id="errorExtra" ...>.