AngularJS showing value based on id - javascript

How can I change data based on id that is passed from json file.
JSON:
{
"hotels": [
{
"id" : 1,
"name": "some hotel 1",
"category" : [{
"id" : 1,
"hotel_id" : 1,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
},
{
"id" : 2,
"name": "some hotel 2",
"category" : [{
"id" : 1,
"hotel_id" : 2,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
}
]
}
in my html I have ng-repeat like:
<p>Hotel names</p>
<ul>
<li ng-repeat="hotel in list.hotels">
{{hotel.name}}
<ul class="thumbnails">
<p>Category</p>
<li ng-repeat="cat in hotel.category">
{{cat.name}}
</li>
</ul>
</li>
</ul>
So this will show all what I have in that json file and I'm trying to limit it to show only data for one hotel (I know that I can do it with something like {{hotel[0].name}}) but there must be better approach, and also how can I use some kind of a switch by pressing the button to show data from hotel with id 1 to hotel with id 2 in the same div and vice versa?
Thank you.

You could use ng-repeat to create the links to display the hotel based on the click like in the following demo or in this fiddle.
For the categories you can use another ng-repeat (not added in the demo).
angular.module('demoApp', [])
.controller('mainController', MainController);
function MainController() {
this.hotels = [
{
"id" : 1,
"name": "some hotel 1",
"category" : [{
"id" : 1,
"hotel_id" : 1,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
},
{
"id" : 2,
"name": "some hotel 2",
"category" : [{
"id" : 1,
"hotel_id" : 2,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
}
];
this.selectedHotel = this.hotels[0];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as mainCtrl">
{{hotel.name}}
<div>
Hotel name: {{mainCtrl.selectedHotel.name}}
Category: {{mainCtrl.selectedHotel.category}}
</div>
</div>

To answer your question, notice ng-if added
<p>Hotel names</p>
<ul>
<li ng-repeat="hotel in list.hotels">
{{hotel.name}}
<ul class="thumbnails">
<p>Category</p>
<li ng-repeat="cat in hotel.categories" ng-if="cat.id == yourid">
{{cat.name}}
</li>
</ul>
</li>
</ul>
You can change yourid by using the current controller. And as other people suggest, you shouldn't use ng-repeat if you want to display only one element

Related

how to show a different tooltip for each item in a list using javascript or angular js?

I have a list of items displayed in a grid on the screen. As I hover the mouse over the items, I'd like to show a specific tooltip for each item.
How can I accomplish that using javascript, jquery or angular js, please?
Thanks.
You can use angular ui tooltip.
$scope.titles = [
{
"id" : 1,
"title" : "title1",
"tooltip" : "tip1"
},
{
"id" : 2,
"title" : "title2",
"tooltip" : "tip2"
},
{
"id" : 3,
"title" : "title3",
"tooltip" : "tip3"
},
{
"id" : 4,
"title" : "title4",
"tooltip" : "tip4"
},
]
in HTML
<p ng-repeat = "x in titles" tooltip-placement="top-left" uib-tooltip="{{x.tooltip}}">{{x.title}}</p>
Have a look at plunker
You could just add the html attribute "title" to the items.
As example, lets say your items is an ordered list. just do it like this:
<ol>
<li title='this is item number one'>Item One</li>
<li title='this is the second items'>Item Two</li>
<li title='third!'>Item Three</li>
</ol>
For more fancy tooltip, you could just use CSS. Or for me, I usually use Bootstrap for my project, so I just use Bootstrap Tooltip which is:
<li data-toggle="tooltip" title="This is item no 1!">Item One</li>

How to exclude an array/object element with Handlebars?

Right now I have this json structure
"administration" : [
{
"name" : "Sigfried Bermudez",
"role" : "Associate Director"
},
{
"name" : "Karen Madrigal",
"role" : "QA Manager"
},
{
"name" : "Jorge Lopez",
"role" : "Project Manager"
}
]
as you see the last element in that array says "role" : "Project Manager", and the way I am excluding this element from the view is this
{{#each chart-container.[3].administration}}
{{#unless #last}}
<span>{{#key}} {{this.name}}</span>
{{/unless}}
{{/each}}
but what about that element changes the position?
what I need to know is if I can do something like {{#unless this.role.toLowerCase().indexof("project")}} or what is the best option in this case? if there is a way to do this from the HTML, it would be awesome :)
Working example: JsFiddle
Use Handlebars helper:
var entry_template = document.getElementById('entry-template').innerHTML;
var data = [
{
"name" : "Sigfried Bermudez",
"role" : "Associate Director"
},
{
"name" : "Karen Madrigal",
"role" : "QA Manager"
},
{
"name" : "Jorge Lopez",
"role" : "Project Manager"
}
]
Handlebars.registerHelper("ifvalue", function(conditional, options) {
if (conditional !== options.hash.notequals) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
var template = Handlebars.compile(entry_template);
var template_with_data = template(data);
document.getElementById('data').insertAdjacentHTML('afterbegin', template_with_data);
Template:
<script id="entry-template" type="text/x-handlebars-template">
{{#each this}}
{{#ifvalue this.role notequals="Project Manager"}}
{{this.name}}
{{/ifvalue}}
{{/each}}
</script>
<div id="data">
</div>

Can angular directives call themselves?

I have some sample data in JSON format:
{
"menus" : [
{"name" : "Item 1", "children" : [
{"name" : "Item 1.1", "url" : "http://www.website.com1/1"},
{"name" : "Item 1.2", "url" : "http://www.website.com1/2"},
{"name" : "Item 1.3", "children": [
{"name" : "Item 1.3.1", "url" : "http://www.website.com1/3/1"},
{"name" : "Item 1.3.2", "url" : "http://www.website.com1/3/2"},
{"name" : "Item 1.3.3", "url" : "http://www.website.com1/3/3"}
]}
]},
{"name" : "Item 2", "children": [
{"name" : "Item 2.1", "url" : "http://www.website.com2/1"},
{"name" : "Item 2.2", "url" : "http://www.website.com2/2"},
{"name" : "Item 2.3", "url" : "http://www.website.com2/3"}
]},
{"name" : "Item 3", "url" : "http://www.website.com3"}
]
}
I want to build a menu tree that matches the stucture of the JSON. So I made a directive:
app.directive('menuItem',
function(){
return {
restrict : "E",
scope: { data : '='},
replace:true,
templateUrl: 'directives/menu-item.html'
};
});
I add the directive to my HTML and it works great for the first layer:
<menu-item data="menu.data.menus"></menu-item>
What I want to happen is that if model the directive is using has a 'children' property, I want it to build a new node using the same template as itself:
<ul class="menu-items" ng-repeat="item in data">
<li class="menu-item">
<div>{{item.name}}</div>
<div ng-if="item.children.length">
<!-- when I add this line I get problems -->
<menu-item data="item.children"></menu-item>
</div>
</li>
</ul>
I get the following error:
Error: [$rootScope:inprog]
http://errors.angularjs.org/1.3.0-beta.13/$rootScope/inprog?p0=%24digest
Question is, how can I get the desired functionality, and how should I think about what's going on to understand this better?
Fiddle to come...
Ok Thanks. Yes this was in fact the same issue adressed in How to handle recursive rendering of data using AngularJS
For this particular case, it would be important to mention that in it's present formulation the template would need to use "ng-init" to properly recurse.
<ul class="menu-items" ng-repeat="item in data">
<li class="menu-item">
<div>{{item.name}}</div>
<div ng-include="'directives/menu-item.html'" ng-init="data = item.children" class="submenu-item"></div>
</li>
</ul>

Best way of getting the list of html values and populating them in a backbone-requirejs application

Here is the scenario, the page is made of backbone views (multiple views, around 20) and about 30 templates. All structured using requirejs architecture. But some of the values in the template such as heading tiles, sub heading titles and drop down values come from a single json object returned by an ajax request during page load. How do I pass these values around multiple templates?
If I understood correctly then you can do in the following way:
Link to jSFiddle
HTML:
<div id="container"></div>
<script type="text/template" id="modelTemplate">
<h1 data - id = "<%=Id%>" > <%= Name %> </h1>
<ul>
<%_.each(Titles,function(title){%>
<%=_.template($("#titleTemplate").html())(title)%>
<%});%>
</ul>
</script>
<script type="text/template" id="titleTemplate">
<li> <%= Name %>
<ul>
<%_.each(SubTitles,function(subTitle){%>
<%=_.template($("#subTitleTemplate").html())(subTitle)%>
<%});%>
</ul>
</li>
</script>
<script type="text/template" id="subTitleTemplate">
<li> <%= Name %> </li>
</script>
And JavaScript (instanceOfModel is some model that you populates with ajax request):
var model = Backbone.Model.extend({});
var instanceOfModel = new model({
Id: 1,
Name: "Some Name",
Titles: [{
Name: "First Title",
SubTitles: [{
Name: "SubTitle Name 1"
}, {
Name: "SubTitle Name 2"
}]
}, {
Name: "SecondTitle",
SubTitles: [{
Name: "SubTitle Name 3"
}, {
Name: "SubTitle Name 4"
}]
}, {
Name: "Last Title",
SubTitles: [{
Name: "SubTitle Name 5"
}, {
Name: "SubTitle Name 6"
}]
}]
});
var modelTemplate = _.template($("#modelTemplate").html());
$("#container").append(modelTemplate(instanceOfModel.toJSON()));

jstree types plugin does not display custom icons

I have a simple HTML layout that looks like this:
<div id="foo">
<ul>
<li id="id1">some category 1
<ul><li>some text</li></ul>
<ul><li>some text</li></ul>
</li>
<li id="id2">some category 2
<ul><li>some text</li></ul>
<ul><li>some text</li></ul>
</li>
</ul>
</div>
The jstree definition looks like this
$('#foo').jstree({
"core" : {
"animation" : 0
},
"themes" : {
"theme" : "classic",
"dots" : false,
"icons" : true
},
"sort" : function (a, b) {
return this.get_text(a) > this.get_text(b) ? 1 : -1;
},
"types" : {
"valid_children" : [ "folder" ],
"types" : {
"folder" : {
"valid_children" : [ "file" ],
"icon" : { "image" : "/path/to/images/folder.png"},
"max_depth" : 1
},
"file" : {
"valid_children" : [ "none" ],
"icon" : { "image" : "/path/to/images/file.png" },
}
}
},
"plugins" : [ "html_data", "themes", "contextmenu", "search", "sort", "types" ]
});
However, I am still getting the generic theme icons for the files.
Category should have a folder and the sub-categories should have a file. Am I missing something?
Here is the answer. For each type, "folder", "file", etc you put in the list item rel= where something is "folder" and whatnot. Then in your jstree configuration, you have these settings for the types plugin:
'types' : {
'valid_children' : [ 'folder' ],
'types' : {
'folder' : {
'valid_children' : [ 'file'],
'max_depth' : 1
},
'file' : {
'valid_children' : [ 'none' ],
'icon' : { 'image' : safari.extension.baseURI + 'images/file.png' },
}
}
},
We define what to do with each "rel" type here. This way, jstree will pick up the rel type in the list item and figure out what to do with it from these definitions.
In version 3.x you should use data-jstree li attribute like this :
HTML
<html>
<ul id="browser">
<li data-jstree='{"type":"folder"}'>My folder</li>
<li data-jstree='{"type":"file"}'>My file</li>
</ul>
</html>
Javascript
$("#browser").jstree({
"types" : {
"folder" : {
"icon" : "icon-folder-open"
},
"file" : {
"icon" : "icon-file"
}
},
"plugins" : [ "types" ]
});
Use the rel attribute
<div id="foo">
<ul>
<li id="id1" rel="folder">some category 1
<ul><li rel="file">some text</li></ul>
<ul><li rel="file">some text</li></ul>
</li>
<li id="id2" rel="folder">some category 2
<ul><li rel="file">some text</li></ul>
<ul><li rel="file">some text</li></ul>
</li>
</ul>
</div>
jsTree types doc
type_attr
A string. Default is "rel".
Defines the attribute on each li node, where the type attribute will be stored.
For correct usage in IE - do not assign to "type" - it triggers an IE bug.

Categories

Resources