I am using Spring boot and Thymleaf in my application.I am sending a CommonResponse model from backend to view and in that model there is a property "isLoggedIn" which is a boolean
value and i am using that value to add a style like this
<li class="nav-item hide-on-scroll" id="sign_in_menu" th:style="${commonResponse.isLoggedIn == false ? '' : 'display:none'} ">
<a class="nav-link" data-toggle="modal" data-target="#loginModal">Sign in</a>
</li>
when i run this gives me a error
"Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "commonResponse.isLoggedIn == false ? '' : 'display:none'"
It happens when "isLoogedIn" property is part of this model "CommonResponse".but if i pass this as a standalone property it works fine
<li class="nav-item hide-on-scroll" id="sign_in_menu" th:style="${isLoggedIn == false ? '' : 'display:none'} ">
<a class="nav-link" data-toggle="modal" data-target="#loginModal">Sign in</a>
</li>
What is the issue?
When a property is part of the Java bean the properties are referred to by their property name. For example:
class MyBean {
Boolean myBooleanProp;
public Boolean getMyBooleanProp(){ return myBooleanProp; }
}
Then in Thymeleaf you access as ${myBean.myBooleanProp}
Also when using Boolean props, it is sufficient to have ${myBean.myBooleanProp ? 'true' : 'false' } or ${!myBean.myBooleanProp ? 'false' : 'true'}
try the following instead
<li class="nav-item hide-on-scroll" id="sign_in_menu" th:style="${commonResponse.isLoggedIn} ? '' : 'display:none' ">
<a class="nav-link" data-toggle="modal" data-target="#loginModal">Sign in</a>
</li>
Related
I have a search input box to take a string in the frontend with suchfensterAction. The result seems to be correct. But when I click to page 2 or higher I always get the suchfensterAction and never the higher paginated page.
(static function() {
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Myext', 'Myext',
[...\Controller\MyextController::class => 'suchfenster, list,show, new, .....
To show the result in the frontend with pagination i have used following controller code:
...
public function suchfensterAction()
{
return $this->htmlResponse();
}
public function listAction(int $currentPage = 1): \Psr\Http\Message\ResponseInterface
{
$args=$this->request->getArguments();
$gefunden=$this->absolventenRepository->search($this->request->getArguments());
$itemsPerPage = 15;
$arrayPaginator = new \TYPO3\CMS\Extbase\Pagination\QueryResultPaginator($gefunden,
$currentPage, $itemsPerPage);
$pagination = new SimplePagination($arrayPaginator);
$this->view->assignMultiple(
[
'paginator' => $arrayPaginator,
'pagination' => $pagination,
'pages' => range(1, $pagination->getLastPageNumber()),
]
);
return $this->htmlResponse();
}
...
and the templates suchfenster.html
<f:form action ="list" >
<f:form.textfield autofocus ="1" name="query" value="{queryvalue}" placeholder = '{text}' />
<f:form.submit value="Suchen"/><br>
</f:form>
...
und list.html
...
<table>
<f:for each="{paginator.paginatedItems}" as="item" iteration="iterator">
<tr><f:render partial="Item.html" arguments="{item:item}" /></tr>
</f:for>
</table>
<f:render partial="Paginator.html" arguments="{pagination: pagination, pages: pages,
paginator: paginator}" />
...
My Paginator.html:
<ul class="pagination pagination-block">
<f:if condition="{pagination.previousPageNumber} &&
{pagination.previousPageNumber} >= {pagination.firstPageNumber}">
<f:then>
<li class="waves-effect">
<a href="{f:uri.action(action:actionName, arguments:{currentPage: 1})}" title="{f:translate(key:'pagination.first')}">
<i class="material-icons">first_page</i>
</a>
</li>
<li class="waves-effect">
<a href="{f:uri.action(action:actionName, arguments:{currentPage: pagination.previousPageNumber})}" title="{f:translate(key:'pagination.previous')}">
<i class="material-icons">chevron_left</i>
</a>
</li>
</f:then>
<f:else>
<li class="disabled"><i class="material-icons">first_page</i></li>
<li class="disabled"><i class="material-icons">chevron_left</i></li>
</f:else>
</f:if>
<f:for each="{pages}" as="page">
<li class="{f:if(condition: '{page} == {paginator.currentPageNumber}', then:'active', else:'waves-effect')}">
{page}
</li>
</f:for>
<f:if condition="{pagination.nextPageNumber} && {pagination.nextPageNumber} <= {pagination.lastPageNumber}">
<f:then>
<li class="waves-effect">
<a href="{f:uri.action(action:actionName, arguments:{currentPage: pagination.nextPageNumber})}" title="{f:translate(key:'pagination.next')}">
<i class="material-icons">chevron_right</i>
</a>
</li>
<li class="waves-effect">
<a href="{f:uri.action(action:actionName, arguments:{currentPage: pagination.lastPageNumber})}" title="{f:translate(key:'pagination.last')}">
<i class="material-icons">last_page</i>
</a>
</li>
</f:then>
<f:else>
<li class="disabled"><i class="material-icons">chevron_right</i></li>
<li class="disabled"><i class="material-icons">last_page</i></li>
</f:else>
</f:if>
</ul>
Where I have to control the argument 'currentPage'? bzw. where I have to increment 'currentPage'?
The code is doing the pagination correctly, however, I am unable to use the boostrap class that shows the active page
<div class="page-nation">
<ul class="pagination pagination-large">
<li>
#{
if (ViewBag.PageNumber> 1)
{
<a class="page-link" href="#Url.Action("Index", "Boats", new { search= ViewBag.searchData, pageNumber= ViewBag.PageNumber- 1 })">«</a>
}
else
{
<a class="page-link disabled">«</a>
}
}
</li>
#{
var currentPage= ViewBag.PageNumber;
for (var i = 1; i <= ViewBag.totalCount; i++)
{
<li #(currentPage== i ? "class= page-item active" : "")>
<a class="page-link" href="#Url.Action("Index", "Boats", new {search= ViewBag.searchData, pageNumber= i})">#i</a>
</li>
}
}
<li>
#if (ViewBag.PageNumber< ViewBag.totalCount)
{
<a class="page-link" href="#Url.Action("Index", "Boats", new { search= ViewBag.searchData, pageNumber= ViewBag.PageNumber+ 1 })">»</a>
}
else
{
<a class="page-link disabled">»</a>
}
</li>
</ul>
</div>
The part that should show the active item is this, but for some reason, this class is not working
<li #(currentPage== i ? "class= page-item active" : "")>
HTML output:
As can be seen in HTML, the class is called, but it doesn't pass anything to it...
<div class="page-nation">
<ul class="pagination pagination-large">
<li>
<a class="page-link" href="/Barcos?numeroPagina=1">«</a>
</li>
<li>
<a class="page-link" href="/Boats?pageNumber=1">1</a>
</li>
<li class="page-item" active="">
<a class="page-link" href="/Boats?pageNumber=2">2</a>
</li>
<li>
<a class="page-link disabled">»</a>
</li>
</ul>
</div>
You're not adding quotes to the class property value, adding quotes will make your HTML render properly:
<li #Html.Raw(currentPage== i ? "class=\"page-item active\"" : "")>
I have created a common layout for my views, so i put it in the shared folder.
launching the project the index method of the controller trigger and return me the layout with all the images, however when i click on an item in the navbar,which trigger the appropriate an action method,the images from the layout disappear !?
this is my Tag Helpers in the Layout :
<div class="navbar-collapse collapse w-50">
<ul class="navbar-nav">
<li class="nav-item navbar1 ">
<a class="nav-link" asp-controller="Home" asp-action="Index"><span style="text-decoration: underline;"><B>Acceuil</B></span></a>
</li>
<li class="nav-item navbar1">
<a class="nav-link" asp-controller="Home" asp-action="WhoWeAre"><span style="text-decoration: underline;"><B>Qui somme nous</B></span></a>
</li>
<li class="nav-item navbar1">
<a class="nav-link" asp-controller="Home" asp-action="Privacy"><span style="text-decoration: underline;"><B>Specialités</B></span></a>
</li>
</ul>
</div>
and those are the action methods :
public IActionResult Index()
{
return View("WhoWeAre");
}
public IActionResult WhoWeAre()
{
return View();
}
public IActionResult ContactUs()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
M i doing something wrong ?
Update1:
for the image i have a logo in the navbar :
<nav class="navbar navbar-expand-md bg-light navbar-light">
<div class="navbar-collapse collapse w-50">
<ul class="navbar-nav">
<li class="nav-item navbar1 ">
<a class="nav-link" asp-controller="Home" asp-action="Index"><span style="text-decoration: underline;"><B>Acceuil</B></span></a>
</li>
<li class="nav-item navbar1">
<a class="nav-link" asp-controller="Home" asp-action="WhoWeAre"><span style="text-decoration: underline;"><B>Qui somme nous</B></span></a>
</li>
<li class="nav-item navbar1">
<a class="nav-link" asp-controller="Home" asp-action="Specialites"><span style="text-decoration: underline;"><B>Specialités</B></span></a>
</li>
</ul>
</div>
<div>
<!-- this is the logo-->
<img src="images/decoupage/nawrass-logo.png " class="rounded-circle bg-light">....
and in the footer , i have the logo again and some other images:
<div id="footer">
<div class="jumbotron " style="margin-top:0 ; background-color:blue">
<div class="container ">
<div class="row">
<div class="col-md-6">
<div class="card mb-3 " style="background-color: blue">
<div class="row no-gutters">
<div class="col-md-3 ">
<img src="images/decoupage/logo-white.png" class="card-img" alt="my card image">
</div>......
Your image source is relative. MVC uses routing, which makes your URL paths look like "folders".
So "Home" is /, which is the default route, but "Who we are" is /Home/WhoWeAre. This causes the images to be looked up in respectively /images/decoupage/logo-white.png and /Home/images/decoupage/logo-white.png.
Given the images are in the root folder, and not in /Home, you need to prefix your image URLs with /.
I have been trying to get this to work but doesn't seem to work. Basically I need a dynamic navbar. The pre-built .NET template actually has already generated a _LoginPartial.cshtml, which already changes the navbar depending on whether a user is login or not. I have been trying to edit the navbar so that it supports another level of change to check if a user is on a specific page then it will show more or less items depending on whether a boolean (showAll) is set to true or false. However is there a way to set the boolean based on the page? Currently I test it by changing manually and the logic works. I need a dynamic way to control it programmatically. Thank you for your help!
#using Microsoft.AspNetCore.Identity
#inject SignInManager<IdentityUser> SignInManager
#inject UserManager<IdentityUser> UserManager
#{bool showAll = false;}
#if (SignInManager.IsSignedIn(User) && showAll == true)
{
<ul class="nav navbar-nav mr-auto">
<li class="nav-item"><a asp-area="" asp-controller="Home" asp-action="Index" class="nav-link">Home</a></li>
<li class="nav-item"><a asp-area="" asp-controller="Home" asp-action="About" class="nav-link">About</a></li>
<li class="nav-item"><a asp-area="" asp-controller="Home" asp-action="Contact" class="nav-link">Contact</a></li>
</ul>
<form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="#Url.Action("Index", "Home", new { area = "" })" method="post" id="logoutForm" class="navbar-right">
<ul class="nav navbar-nav navbar-right">
<li class="nav-item">
<a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage" class="nav-link">Hello #UserManager.GetUserName(User)!</a>
</li>
<li class="nav-item">
<button type="submit" class="btn btn-link navbar-btn navbar-link">Logout</button>
</li>
</ul>
</form>
}
else if (SignInManager.IsSignedIn(User) && showAll == false)
{
<ul class="nav navbar-nav mr-auto">
<li class="nav-item"><a asp-area="" asp-controller="Home" asp-action="Index" class="nav-link">Home</a></li>
<li class="nav-item"><a asp-area="" asp-controller="Home" asp-action="About" class="nav-link">About</a></li>
</ul>
<form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="#Url.Action("Index", "Home", new { area = "" })" method="post" id="logoutForm" class="navbar-right">
<ul class="nav navbar-nav navbar-right">
<li class="nav-item">
<a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage" class="nav-link">Hello #UserManager.GetUserName(User)!</a>
</li>
<li class="nav-item">
<button type="submit" class="btn btn-link navbar-btn navbar-link">Logout</button>
</li>
</ul>
</form>
}
else
{
<ul class="nav navbar-nav mr-auto">
<li class="nav-item"><a asp-area="" asp-controller="Home" asp-action="Index" class="nav-link">Home</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="nav-item"><a asp-area="Identity" asp-page="/Account/Register" class="nav-link">Register</a></li>
<li class="nav-item"><a asp-area="Identity" asp-page="/Account/Login" class="nav-link">Login</a></li>
</ul>
}
It depends a lot on what logic is behind that variable. If you can resolve it just from the login partial, you can certainly just add the logic there. For example, you could look at the current route to figure out whether you want that value to be true or not.
You could also build your own service that you inject there which then contains the logic. This can be useful if you end up doing more complicated stuff, as you should generally try to avoid too much logic inside views.
If the value is being set outside of the partial, you could also just use the ViewData dictionary to set it. This would allow you to set the value within your controllers, and then your partial view could just retrieve the value. Something like this:
#{
bool showAll = false; // default
if (ViewData.TryGetValue("NavigationShowAll", out var value) && value is bool)
{
showAll = (bool)value;
}
}
And then, in your controller, you can just do this:
public IActionResult DoSomething()
{
ViewData["NavigationShowAll"] = true;
return View();
}
I'm trying to create a custom renderer for the simple_navigation rails gem. So far, after reading through the tweaks made for the bootstrap version of the gem, I have been able to make some minor icon changes to my navigation but I'm completely stuck otherwise.
I'm trying to add some set my renderer up to accommodate the markup found at this JSfiddle:
http://jsfiddle.net/v5Yhc/
<ul class="nav navbar-collapse collapse navbar-collapse-primary">
<li class="active">
<span class="glow"></span>
<a href="dashboard.html">
<i class="icon-dashboard icon-2x"></i>
<span>Dashboard</span>
</a>
</li>
<li class="dark-nav ">
<span class="glow"></span>
<a class="accordion-toggle collapsed " data-toggle="collapse" href="#yJ6h3Npe7C">
<i class="icon-beaker icon-2x"></i>
<span>
UI Lab
<i class="icon-caret-down"></i>
</span>
</a>
<ul id="yJ6h3Npe7C" class="collapse ">
<li class="">
<a href="../ui_lab/buttons.html">
<i class="icon-hand-up"></i> Buttons
</a>
</li>
<li class="">
<a href="../ui_lab/general.html">
<i class="icon-beaker"></i> General elements
</a>
</li>
<li class="">
<a href="../ui_lab/icons.html">
<i class="icon-info-sign"></i> Icons
</a>
</li>
<li class="">
<a href="../ui_lab/grid.html">
<i class="icon-th-large"></i> Grid
</a>
</li>
<li class="">
<a href="../ui_lab/tables.html">
<i class="icon-table"></i> Tables
</a>
</li>
<li class="">
<a href="../ui_lab/widgets.html">
<i class="icon-plus-sign-alt"></i> Widgets
</a>
</li>
</ul>
</li>
<li class="">
<span class="glow"></span>
<a href="../forms/forms.html">
<i class="icon-edit icon-2x"></i>
<span>Forms</span>
</a>
</li>
<li class="">
<span class="glow"></span>
<a href="../charts/charts.html">
<i class="icon-bar-chart icon-2x"></i>
<span>Charts</span>
</a>
</li>
<li class="dark-nav ">
<span class="glow"></span>
<a class="accordion-toggle" data-toggle="collapse" href="#WLGsdJPav9">
<i class="icon-link icon-2x"></i>
<span>
Others
<i class="icon-caret-down"></i>
</span>
</a>
<ul id="WLGsdJPav9" class="in" style="height: auto;">
<li class="">
<a href="../other/wizard.html">
<i class="icon-magic"></i> Wizard
</a>
</li>
<li class="">
<a href="../other/login.html">
<i class="icon-user"></i> Login Page
</a>
</li>
<li class="">
<a href="../other/sign_up.html">
<i class="icon-user"></i> Sign Up Page
</a>
</li>
</ul>
</li>
</ul>
I can't figure out how to lay out the ruby/rails code so that it mirrors the behavior of the markup in the fiddle?
The kicker here is that the children UL/LI elements must be presented on page load, but the simple navigation GEM hides them until their parent UL/LI element is active.... frustratingly.... without fail.
Here is my custom renderer code:
class Admin < SimpleNavigation::Renderer::Base
def render(item_container)
config_selected_class = SimpleNavigation.config.selected_class
SimpleNavigation.config.selected_class = 'active'
list_content = item_container.items.inject([]) do |list, item|
li_options = item.html_options.reject {|k, v| k == :link}
icon = li_options.delete(:icon)
split = (include_sub_navigation?(item) and li_options.delete(:split))
li_content = content_tag(:span, '', class: 'glow')
li_content << tag_for(item, item.name, icon, split)
if include_sub_navigation?(item)
if split
lio = li_options.dup
lio[:class] = [li_options[:class], 'dropdown-split-left'].flatten.compact.join(' ')
list << content_tag(:li, li_content, lio)
item.html_options[:link] = nil
li_options[:id] = nil
li_content = tag_for(item)
end
item.sub_navigation.dom_class = [item.sub_navigation.dom_class, 'dropdown-menu', split ? 'pull-right' : nil].flatten.compact.join(' ')
li_content << render_sub_navigation_for(item)
li_options[:class] = [li_options[:class], 'dropdown', split ? 'dropdown-split-right' : nil].flatten.compact.join(' ')
end
list << content_tag(:li, li_content, li_options)
end.join
SimpleNavigation.config.selected_class = config_selected_class
if skip_if_empty? && item_container.empty?
''
else
content_tag(:ul, list_content, {:id => item_container.dom_id, :class => item_container.dom_class})
end
end
protected
def tag_for(item, name = '', icon = nil, split = false)
unless item.url or include_sub_navigation?(item)
return item.name
end
url = item.url
link = Array.new
link << content_tag(:i, '', :class => [icon].flatten.compact.join(' ') + ' icon-2x') unless icon.nil?
link << name
if include_sub_navigation?(item)
item_options = item.html_options
item_options[:link] = Hash.new if item_options[:link].nil?
item_options[:link][:class] = Array.new if item_options[:link][:class].nil?
unless split
#item_options[:link][:class] << 'dropdown-toggle'
item_options[:link][:class] << 'in'
#item_options[:link][:'data-toggle'] = 'dropdown'
item_options[:link][:'data-toggle'] = 'collapse'
item_options[:link][:'data-target'] = '#'
#link << content_tag(:b, '', :class => 'caret')
link << content_tag(:b, '', :class => 'icon-caret-down')
end
item.html_options = item_options
end
link_to(link.join(" ").html_safe, url, options_for(item))
end
end
Is anyone a simple_navigation whiz?
Thanks!
Regarding your two specific questions:
I can't figure out how to lay out the ruby/rails code so that it mirrors the behavior of the markup in the fiddle?
The target html structure seems pretty complicated to me. Is there any way to simplify this? In addition, it probably would be easier to help if you would fork the simple-navigation bootstrap renderer so it would be more obvious what you have changed.
The kicker here is that the children UL/LI elements must be presented on page load, but the simple navigation GEM hides them until their parent UL/LI element is active.... frustratingly.... without fail.
simple-navigation is - by default - configured that it only renders all primary items and the subnavigation of the active primary item, so this is a feature, not a bug :-). If you need to render the complete navigation independently of the active item, you need to pass the :expand_all => true option to the render_navigation call, which in turn is used to determine the return value of SimpleNavigation::Rendering::Renderer::Base#include_sub_navigation?.