<div id='nav'></div>
<div id='issues'><h2>Issues</h2></div>
<div id='details'></div>
<!-- PUT ANY TEMPLATES YOU NEED HERE -->
<script id="navEJS" type="text/ejs">
<h2>Filter</h2>
<ul>
<li id='critical'>
<%== can.route.link("Critical",{filter: "critical"}) %>
</li>
<li id='important'>
<%== can.route.link("Important",{filter: "important"}) %>
</li>
<li id='unimportant'>
<%== can.route.link("Navel Lint",{filter: "unimportant"}) %>
</li>
</ul>
</script>
<script id="issuesEJS" type="text/ejs">
<h2>Select An Issue for More Details</h2>
<% list( issues, function(issue){ %>
<div class="issue" id="issue_<%= issue.id %>"
<%= (el)-> el.data("issue", issue) %>>
<h3><%= issue.attr('name') %></h3>
<p>STATUS: <%= issue.attr('status') %></p>
</div>
<% }) %>
</script>
<script id="issueEJS" type='text/ejs'>
<h2>#<%= issue.id %> Details</h2>
<p>STATUS: <%= issue.attr('status') %></p>
<p>DESCRIPTION: <%= issue.attr('description') %></p>
</script>
// mock up /issues and /issues/{id}
(function(){
var types = {},
id=0,
all = [];
can.each(["critical","important","unimportant"],function(name){
var num = Math.floor(4*Math.random());
types[name] = can.map(new Array(num+1),function(){
id++;
return {
status : name,
name : "issue #"+id,
id: id,
description: "this is a description for "+id
}
})
all = all.concat(types[name])
})
can.fixture("/issues", function(settings){
return [types[settings.data.status]]
})
can.fixture("/issues/{id}", function(settings){
return $.grep(all, function(issueData){
return issueData.id == settings.data.id
})[0]
})
})();
// An Issue model for loading issues
var Issue = can.Model({
findAll : "/issues",
findOne : "/issues/{id}"
},{});
// A Nav control for the left-side navigation
var Nav = can.Control({
init : function(){
// draw the nav template
this.element.html(can.view("navEJS") );
// highlight the current active element
this.highlight();
},
// when the route filter property changes, highlight acitve
"{can.route} filter" : "highlight",
// remove the old active element, highlight the new one
highlight: function(){
this.element.find('li').removeClass('active')
$("#"+can.route.attr('filter') ).addClass('active')
}
});
// An Issue control for showing a list of issues
// for a given filter.
var Issues = can.Control({
init : function(){
// draw the issues
this.render()
},
// draw the issues when filter changes
"{can.route} filter" : "render",
render : function(){
// if we have selected a filter
if( can.route.attr('filter') ) {
// retrieve the issues
Issue.findAll({
status: can.route.attr('filter')
}, $.proxy(function(issues){
// render them with issuesEJS
this.element.html(
can.view("issuesEJS", {issues: issues})
)
}, this));
} else {
this.element.html("<h2>Issues</h2>")
}
},
// when a user clicks an issue
".issue click" : function(el, ev){
// update the route id property
// with that issue's id
can.route.attr("id",
el.data("issue").id );
},
// when the route id property changes
"{can.route} id" : function(route, ev, id){
// remove current active
this.element.children('.active').removeClass("active");
// highlight new active
this.element.children("#issue_"+id).addClass("active")
}
})
// A Details control to show detailed information
// for an issue
var Details = can.Control({
// when the id property changes, update the details
"{can.route} id" : function(route, ev, id){
var el = this.element;
if( id ) {
can.view("issueEJS",{
issue: Issue.findOne({id: id})
}).then(function(frag){
el.html(frag);
})
}
}
});
// SETUP CODE
// declare routes
can.route(":filter-issues");
can.route(":filter-issues/:id");
// initialize controls
new Nav("#nav");
new Issues("#issues");
new Details("#details");
h2 {
background-color: #789AA1;
color: #304345;
font-family: arial;
border-bottom: solid 2px #A0D5D6;
padding-left: 5px;
}
#nav {
position: fixed;
left: 0px;
width: 20%;
bottom: 0px;
border-right: solid 2px #DCEBDD;
top: 0px;
}
#nav li {padding: 5px;}
.active {
background-color: #AD9A27;
}
#issues {
position: fixed;
left: 20%;
bottom: 0px;
top: 0px;
right: 30%;
overflow: auto;
}
.issue {
padding: 5px;
cursor: pointer;
}
#details {
position: fixed;
right: 0px;
width: 30%;
bottom: 0px;
border-left: solid 2px #DCEBDD;
top: 0px;
}
#details p {
padding: 5px;
}