In a view, I'm trying to add an additional class specification "active" on basis of the page the user is on. I have:
<li <%= if current_page?(root_path) class="hvr-bottom active" : class="hvr-bottom" %>><a href=<%= root_path %>>Home</a></li>
This generates the error:
syntax error, unexpected keyword_class, expecting keyword_then or ';' or '\n' ...
How should I adjust the code to add the additional class only if a specific page is visited?
Your current ternary statement seems to be missing a ?. Try the following:
<li class=<%= current_page?(root_path) ? "hvr-bottom active" : "hvr-bottom" %>> ... </li>
Hope that helps!
Related
I'm currently running into a problem where I am trying to make a li tag have specific classes based on a Ruby variable by using a ternary operator:
<li class=<%= loc == #ruby_var ? "nav-item active" : "nav-item" %>>
...
</li>
I expect the results to be an li element with both the nav-item and active classes if #ruby_var is true:
<li class="nav-item active">
...
</li>
However, for some reason, I am getting unexpected results where it only sets the class to the first part of the string that is in the ternary operator, and leaves the second part outside of the class tag:
<li class="nav-item" active>
...
</li>
I have tried using more than one space in my "nav-item active" string but any white space seems to make the class only accept the first elem in the string.
What is the proper way to use the ternary operator to set an HTML tag's classes?
You can write it like this
<li class="<%= loc == #ruby_var ? "nav-item active" : "nav-item" %>">
# ...
</li>
Note the " outside of the erb expression.
Or you can use tag helper like this
<%= tag.li, class: ["nav-item", (:active if loc == #ruby_var)] do %>
# ...
<% end %>
I like the second option better because I prefer not to mix HTML and ERB when describing a tag.
I'm working with Bootsrtap 4 and I'm trying to add the class active to my nav-item elements whenever their nav-link href attribute is the same as the current url.
On the html side, I uesd a basic url generator as shown below:
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{{ url('/brands') }}" role="button">Brands</a>
</li>
<!-- ... -->
</ul>
And then I used a jQuery method to compare them with the current url:
$('.navbar-nav .nav-item .nav-link').each( () => {
// If the current path and the link url are the same...
if ($(this).attr('href').indexOf(location.pathname) !== 1) {
// ...then add the class 'active' to 'nav-item', its parent
$(this).parent().addClass('active')
}
})
However, I noticed that $(this).attr('href') was undefined, probably because it's a generated url, and therefore nav-item doesn't get the active class.
EDIT: as an example, for now it's a very basic url, without parameter, which looks like this:
http://domain.example/brands
Does anyone know how to solve this problem? Thanks in advance.
I'd recommend you to go another way. Instead of "activating" the link with jQuery, you could easily do it server-side with Laravel:
<ul class="navbar-nav">
<li class="nav-item">
<a class="{{ Request::is('brands*') ? 'nav-link active' : 'nav-link' }}"
href="{{ url('/brands') }}"
role="button">Brands</a>
</li>
<!-- ... -->
</ul>
Explanation:
Laravel uses the template-engine twig for rendering the HTML server-side. Instead of manipulation the DOM client-side, you can easily add an conditional to check for the current request parameters. Laravel gives you nativeliy the possibility to check the request path even with a wildcard.
Your problem is most likely caused by the difference between using () => {} or function () {}
When you use the arrow syntax the prop this is unbound. Meaning that also $(this) will return an empty jQuery object instead of returning the anchor. Any follow up jQuery chaining will return something empty/undefined.
So, changing .each( () => { to .each(function() { will at least fix your undefined problem.
Information about the arrow syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Okay this is what i do generally do in all my laravel projects when it comes to make sidebar or any link "active" on click :-
<li class="nav-item {{ in_array(Route::currentRouteName(),[
'admin.dashboard',
'admin.updates',
])? 'active show' : ''}}">
<i class="typcn typcn-clipboard"></i>Dashboard
<nav class="nav-sub">
Home
</nav>
</li>
Now notice this {{ BladeHelper::sideBar_link_isActive('admin.dashboard') }}
I created dynamic helper function to get the current url and return "active" class
Path : app\Helpers\BladePageHelper
<?php
namespace App\Helpers;
use Route;
class BladePageHelper
{
public static function sideBar_link_isActive($selectedLink){
$currentRouteName = Route::currentRouteName();
if($selectedLink === $currentRouteName){
return 'active';
}else{
return '';
}
}
}
I'm using route name here like
Route::("/","MyController#mymethod")->name("myname")
You can do this with url too.
I hope this helps.
Happy Coding
I a using Spring security with an HTML page using thymeleaf. I have a problem to use the "sec:authorize" property in this case:
<ul class="nav nav-tabs margin15-bottom">
<li th:each="criteriaGroup,iterGroups : ${aGroupList}"
th:class="${iterGroups.index == 0}? 'active'">
<a th:href="'#' + ${criteriaGroup.id}" data-toggle="tab"
th:text="${criteriaGroup.groupName}"></a>
</li>
</ul>
Now I want to add a spring security property like: if I have this particular criteria, I need a authorization (sec:authorize="hasRole('Criteria')") although I will not see the tab corresponding to this criteria:
<ul class="nav nav-tabs margin15-bottom">
<li th:each="aGroup,iterGroups : ${aGroupList}" th:class="${iterGroups.index == 0}? 'active'"
th:sec:authorize="$({criteriaGroup.id =='criteriaA'} || ${criteriaGroup.id =='criteriaB'}) ? 'hasRole('Criteria')'">
<a th:href="'#' + ${criteriaGroup.id}" data-toggle="tab"
th:text="${criteriaGroup.groupName}"></a>
</li>
</ul>
But when I am doing this I have the following error:
org.thymeleaf.exceptions.TemplateProcessingException: Error processing template: dialect prefix "th" is set as non-lenient but attribute "th:sec:authorize" has not been removed during process
How can I avoid it?
Remove th: in front of sec:authorize
The Spring Security 3 integration module is a Thymeleaf dialect. More information can be found here.
Perhaps you'd want to use the #authentication object instead of the sec dialect.
From the docs:
<div th:text="${#authentication.name}">
The value of the "name" property of the authentication object should appear here.
</div>
<li class=<%= #page_name == "home" ? "active span2" : "span2" %>>
turns into:
<li class="active" span2>
When the statement evaluates true.
My expected result is:
<li class="active span2">
Any ideas why this happens?
The quotes within your tags are essentially declaring the contents within as String objects. The output of the statement is a string, but the string will not be encapsulated in quotes. The value of the class attribute must be in quotes in order for the markup to be valid. Subsequently, you'll need to enclose the entire statement within double quotes:
<li class="<%= #page_name == 'home' ? 'active span2' : 'span2' %>">
The output of your statement is actually
<li class=active span2>
which will be turned to your output by most browsers, in an effort to correct invalid markup.
You'll want to have it render this way:
<li class="<%= #page_name == "home" ? "active span2" : "span2" %>">
I'm creating a helper in my rails app where I create a navigation link.
Now I want to add an caret to this link so I can get a nice arrow at the end.
My html should look like this:
<li class='dropdown'>
<a class='dropdown-toggle' data-toggle='dropdown' href='#'
Dropdown
<b class='caret'></b>
</a>
Now I got my helpers setup like this:
content_tag(:li, class: 'active dropdown') do
link_to( text, link, class: 'dropdown-toggle' ) do
content_tag(:b, class: 'caret')
end
end
But when I do this I got this error message:
undefined method `stringify_keys' for "/":String
I also want to add some item to my dropdown so I need to nested some more but I don't know how. Is there anybody who could help me and point me in the right direction?
Thanks!
You’re passing a block to link_to so you shouldn’t pass it link text, as shown in the docs. Try this:
content_tag(:li, class: 'active dropdown') do
link_to(link, class: 'dropdown-toggle' ) do
"#{text}#{content_tag(:b, "", class: 'caret')}".html_safe
end
end