How to use Sinatra to highlight navigation menu when on current page? - css

I am having trouble calling the css to indicate the current page that will allow a color tab to show when a page is clicked. I know the "current-menu-item" class works because when you do:
<li id="menu-item" class="current-menu-item">
About Us
</li>
You are able to see the properties associated with the task. I don't know what else to try and I am looking for insight on what I might be doing wrong.
This is my main.rb file
require 'bundler/setup'
require 'rubygems'
require 'sinatra'
require 'sinatra/activerecord'
require 'sinatra/flash'
require 'sinatra/reloader' if development?
require './config/environments'
require 'pathname'
require 'uri'
require './routes/init'
require './helpers/init'
require './models/init'
get '/' do
erb :"index.html"
end
get '/about-us' do
erb :"about_us.html"
end
get '/services' do
erb :"services.html"
end
get '/sign-up' do
erb :"sign_up.html"
end
init.rb
require_relative 'user.rb'
helper1.rb
helpers do
def active_page?(path='')
request.path_info =='/'+path ? 'active_page': nil
end
end
layout.erb
<div class="menu-main-menu-container">
<ul id="menu-main-menu" class="menu">
<li id="menu-item" class="menu-item">
Home
</li>
<li id="menu-item" class="menu-item">
Services
</li>
<li id="menu-item" class="<%= current-menu-item if '/about-us' == active_page? %>" >
About Us
</li>
<li id="menu-item" class="menu-item ">Sign Up</li>
</ul>
</div>

two things, first:
you want to display the string, "current-menu-item" and not the object current-menu-item if the conditional is true, so you want to move the quotes
change:
<li id="menu-item" class="<%= current-menu-item if '/about-us' == active_page? %>" >
to:
<li id="menu-item" class=<%= "current-menu-item" if '/about-us' == active_page? %>>
second:
the conditional and helper method are not used correctly
the helper would be used best if it returned true or false
change the helper method to the following:
def active_page?(path='')
request.path_info == '/' + path
end
then back to the layout:
<li id="menu-item" class=<%= "current-menu-item" if active_page?("about-us") %>>
logically, this will accomplish what you are trying to do.

Related

ExpressJs: using Navbar on views

I'm using ExpressJS and EJS as my Views.
in my navbar I have links that need to have a class="active" when the user is on that current page. put if I use partials in my views. how am I going to do it?
sample
Index.ejs
<ul class="nav navbar-nav navbar-right">
<li><a class="active" href="/Index">Home</a></li>
<li>About</li>
<li>Work</li>
</ul>
About.ejs
<ul class="nav navbar-nav navbar-right">
<li>Home</li>
<li><a class="active" href="/About">About</a></li>
<li>Work</li>
</ul>
Work.ejs
<ul class="nav navbar-nav navbar-right">
<li>Home</li>
<li>About</li>
<li><a class="active" href="/Work">Work</a></li>
</ul>
that is my way of doing it!.. by making a navbar everytime I make a new page
how should I make it that when i render a new page is doesn't need to render the navbar again?
You could pass the value of the "active" route as a local var to the partial..
<%- include('partial/nav', {active: "About"}); %>
Then, check the active var to set the "active" class in the nav partial template:
<ul class="nav navbar-nav navbar-right">
<li><a <%if(active=="Home"){%>class="active"<%}%> href="/Index">Home</a></li>
<li><a <%if(active=="About"){%>class="active"<%}%> href="/About">About</a></li>
<li><a <%if(active=="Work"){%>class="active"<%}%> href="/Work">Work</a></li>
</ul>
Here's a similar approach
You should load your navigation like this--
<script>
$("#header").load("header.ejs");
</script>
Then retrieve the url of the current page and from that retrieve the active page name . Then use this function to add the active class to the current page,
$(document).ready(function($){
var url = window.location.href;
$('.nav li a[href="'+url+'"]').addClass('active');
});
NOTE: you need to retrieve the page name from your url through some function as it would be the full page url.
You will have to write the header.ejs only once and include it on every page.
Hope this helps!

access parent sub array key handlbars

I have the following array / sub array structure
"filters": {
"types": {
"34": "Ford",
"22": "Jeep",
"18": "Porsche",
},
"locations": [
"Earth",
"Mars",
"Moon",
]
}
and the following handlebars template
{{#if filters}}
{{#each filters}}
<div class="cars">
<ul class="cars__list">
<li class="cars-{{#key}}__title">Filter by {{#key}}:</li>
<li class="cars-{{#key}}__filters">
<ul>
<li class="cars-{{#key}}">View All</li>
{{#each this}}
<li class="cars-{{*want to access filters[key]*}} color={{#key}}">{{this}}</li>
{{/each}}
</li>
</li>
</ul>
</div>
{{/each}}
{{/if}}
I'm having trouble accessing the filters[types] and filters[locations] within the each this loop.
In my CSS I'm using a classes called .cars-type and .cars-location. I want to be able to style each list separately and unfortunately target each li with a class. I want to apply these styles within the each this loop.
I can do it within the filters loop by using {{#key}} but not in the each this loop
I've tried
<li class="cars-{{../filters}}">{{this}}</li>
but this just returns the car type like ford - I want the key ie. '34' in this case
<li class="cars-{{lookup ../filters #index}}">{{this}}</li>
using handlebars helper lookup but again no luck
<li class="cars-{{../this}}">{{this}}</li>
and the above which gives me [object Object]
I've checked out handlebars - is it possible to access parent context in a partial?, handlebars.js: relative paths in partials not working and Lookup helper in handlebars but no luck with any of the solutions
EDIT Here's the HTML output that I want to produce
<div class="cars">
<ul class="cars__list">
<li class="cars-types__title">Filter by types:</li>
<li class="cars-types__filters">
<ul>
<li class="cars-types">View All</li>
<li class="cars-types color-34">Ford</li>
<li class="cars-types color-22">Jeep</li>
<li class="cars-types color-18">Porsche</li>
</ul>
</li>
</ul>
<ul class="cars__list">
<li class="cars-locations__title">Filter by locations:</li>
<li class="cars-locations__filters">
<ul>
<li class="cars-locations">View All</li>
<li class="cars-locations color-0">Earth</li>
<li class="cars-locations color-1">Mars</li>
<li class="cars-locations color-2">Moon</li>
</ul>
</li>
</ul>
</div>
You should reconsider your HTML because a ul cannot be a direct child of another ul. See https://developer.mozilla.org/en/docs/Web/HTML/Element/ul#Usage_context
With that said, we can solve your problem. The Handlebars docs have our answer:
Nested each blocks may access the interation variables via depth based
paths. To access the parent index, for example, {{#../index}} can be
used.
Therefore, your problematic line should look like the following:
<li class="cars-{{#../key}} color-{{#key}}">{{this}}</li>

How to dynamically set a menu item class name with MVC4?

For a new application we are using Bootstrap v3.0, which has the navigation menu defined as follows:
<div id="sidebar">
<ul>
<li class="active"><i class="icon-home"></i> <span>Dashboard</span></li>
<li class="submenu">
<i class="icon-beaker"></i> <span>UI Lab</span> <i class="arrow icon-chevron-right"></i>
<ul>
<li>Interface Elements</li>
<li>jQuery UI</li>
<li>Buttons & icons</li>
</ul>
</li>
<li class="submenu">
<i class="icon-th-list"></i> <span>Form elements</span> <i class="arrow icon-chevron-right"></i>
<ul>
<li>Common elements</li>
<li>Validation</li>
<li>Wizard</li>
</ul>
</li>...
This is currently sitting in a shared _Layout.cshtml, and don't currently see a need to move this into its own shared view.
The layout template consists of several static files with <li class="active"> hard coded for the corresponding menu item within that file.
Since I'm building this with MVC4, I would like to know how to dynamically set this, based on the view being displayed.
Not sure best practice on this. You could try something like this:
<li class="#( RouteVariable.CurrentController.Equals("Home") ? "active" : "")">
Or RouteVariables.CurrentAction may be of use.

Traversing back to parent node in xpath

Below is my HTML
<ul><li class="section">BROADCASTING</li>
<ul>
<li class="subsection"></li>
<li class="circle">STATION BREAK</li>
<li class="circle">Labor pains, hunger pangs</li>
<li class="circle">Wake-up call for Dream Team</li>
<li class="circle">News crew turns rescuer</li>
<li class="circle">Chopper safety had been challenged</li>
<li class="circle">Nielsen adds Dayton..</li>
<li class="circle">Mondale watch</li>
<li class="circle">Those 70s clearances</li>
<li class="circle">Oscar goes to ABC</li>
<li class="circle">Hearst-Argyle gives a green light</li>
<li class="circle">Finding Geena Davis</li>
<li class="circle">Syndication Wrap-up</li>
<li class="circle">CBS TV news pioneer dies at 86</li>
<li class="circle">New York anchor remembered</li>
<li class="circle">News sharing in West Virginia</li>
<li class="circle">News dropping in Orlando</li>
<li class="subsection">Null</li>
<li class="circle">GET WITH THE PROGRAM</li>
<li class="subsection">PEOPLE'S CHOICE</li>
<li class="circle">Syndication as branding</li>
</ul>
</ul>
Now i want to seperate sections and subsections and get the url inside subsections.
i have go to the each sections
Now as per the HTML structure, section is in seperate li which closes before subsection opens, so once i have reached section, i have to move back to ul and then have to continue to get subsection
However when i try ../ to go back to the ul (the one before section), it says ivalid token
This is what i tried to come back to the parent one.
HtmlNodeCollection sections = doc.DocumentNode.SelectNodes("//ul/li[#class='section'][contains(text(), 'BROADCASTING')]../ul");
but this does not works
Can anyone tell me where i am going wrong, it will be a kind help.
You need to change your xpath expression a bit:
var subsections = doc.DocumentNode.SelectNodes("//ul/ul[preceding-sibling::li[#class='section' and .='BROADCASTING']]/li[#class='subsection']");
It searches for <ul> inside <ul> that has <li class="section">BROADCASTING</li> as a previous sibling, and then searches for <li class="subsection"> inside it.
So the code above selects all the subsections under BROADCASTING section.
Hope this helps.

Facelets strategy to identify current selected list item

I am looking for a strategy to avoid code duplication across my site.
The problem is that I have a unordered list that get's repeated in each page I code.
The reason is that I have a list-item that contains an anchor to identify the currentPage. That get's repeated in each page I code.
The reason is that I have a list-item that contains an anchor to identify the currentPage.
This allows me to hilite it with css.
How can I define such a list in a way that I can change it dynamically in facelets?
<ui:define name="leftBar">
<ul class="leftNav">
<li id="home"><a id="**currentPage**" jsfc="h:link" outcome="home">#{global.homeInCaps}</a></li>
<li id="about"><a jsfc="h:link" outcome="about">#{global.aboutInCaps}</a></li>
<li id="blog"><a jsfc="h:link" outcome="blog">#{global.blogInCaps}</a></li>
<li id="tutorials"><a jsfc="h:link" outcome="tutorials">#{global.tutorialsInCaps}</a>
<ul class="leftSubNav">
<li><a jsfc="h:link" outcome="java">#{global.javaNormal}</a>
<ul class="leftSubNav">
<li><a jsfc="h:link" outcome="setupPath">#{global.path}</a></li>
</ul>
</li>
<li><a jsfc="h:link" outcome="ubuntu">#{global.ubuntuNormal}</a></li>
<li><a jsfc="h:link" outcome="virtualbox">#{global.virtualBoxNormal}</a></li>
</ul>
</li>
<li id="contact"><a jsfc="h:link" outcome="contact">#{global.contactInCaps}</a></li>
</ul>
</ui:define>
In JSF you can get the current view ID by
#{facesContext.viewRoot.viewId}
It will return the webcontent-relative path of the view file, e.g. /home.xhtml, /about.xhtml, etc. You could test it with help of the conditional operator in EL to set the classname.
<ui:param name="view" value="#{facesContext.viewRoot.viewId}" />
<li id="home"><a jsfc="h:link" outcome="home" class="#{view == '/home.xhtml' ? 'current' : ''}">#{global.homeInCaps}</a></li>
<li id="about"><a jsfc="h:link" outcome="about" class="#{view == '/about.xhtml' ? 'current' : ''}">#{global.aboutInCaps}</a></li>
<li id="blog"><a jsfc="h:link" outcome="blog" class="#{view == '/blog.xhtml' ? 'current' : ''}">#{global.blogInCaps}</a></li>
...
You can then style the link representing the current page with CSS
.leftNav .current {
color: pink;
}
Shouldn't the leftNav rather be an id?

Resources