Stop the navigation bar from refreshing - Umbraco - c#

I couldn't find anything regarding my issue so I decided to post one myself.
I am using a navigation bar that has dropdown menu's. Whenever I open the dropdown and navigate to one of those pages, the navigation refreshes and closes the dropdown menu. The dropdown menu needs to stay open when I go over to one of the pages, I tried Model.Content.AncestorOrSelf().Descendants("document") to try and keep the navigation bar from refreshing but that doesn't seem to work (as people said).
Here's my menu structure:
Everything underneath "Hulp per browser" is in a dropdown and will disappear when I click on "Hulp per browser" again.
Here is my code:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
<div class="col-sm-3">
<div class="NavDigiCampuz">
<h3>Helpcentrum</h3>
<li class="NoBullet"><a class="NormalA" href="https://digicampuz.nl/">Terug naar digicampuz</a></li><br>
<ul class="nav nav-list tree">
#{
var documentRootNodeId = Model.Content.GetPropertyValue("documentRoot", true); // Fetch recursive document root id.
var selection = Umbraco.TypedContent(documentRootNodeId).Children.Where("Visible"); // Select all nodes below the document root.
}
#foreach(var item in Model.Content.AncestorOrSelf(2).Descendants("document").ToList()){
foreach (var ItemChild in #item.Children("categorieMenu")){
if(ItemChild.Children.Any())
{
<li class="MenuItems"><p>#ItemChild.Name</p></li>
foreach (var Subitem in #ItemChild.Children){
if (Subitem.Children("hoofdstuk").Any())
{
<li class="item">
#if(Subitem.GetPropertyValue("hoofdstukIcoon") != "") {
<a class="NormalA aNav" href="#"><i class="fa fa-#(Subitem.GetPropertyValue("hoofdstukIcoon")) fa-fw"></i> #Subitem.Name <i id="Arrow" class="fa fa-arrow-right" style="font-size:10px;" aria-hidden="true"></i></a>
}else{
<a class="NormalA aNav" href="#">#Subitem.Name <i id ="Arrow" class="fa fa-arrow-right" style="font-size:10px;" aria-hidden="true"></i></a>
}
#foreach (var Finalitem in #Subitem.Children){
<ul class="submenu">
#if(Finalitem.GetPropertyValue("hoofdstukIcoon") != "") {
<br><li><a class="NormalA aNav" href="#Finalitem.Url"><i class="fa fa-#(Finalitem.GetPropertyValue("hoofdstukIcoon")) fa-fw"></i>#Finalitem.Name </a></li>
}else{
<br><li><a class="NormalA aNav" href="#Finalitem.Url">#Finalitem.Name</a></li><br>
}
</ul>
}
</li>
}else
{
if(Subitem.GetPropertyValue("hoofdstukIcoon") != "") {
<li><a class="NormalA aNav" href="#Subitem.Url"><i class="fa fa-#(Subitem.GetPropertyValue("hoofdstukIcoon")) fa-fw"></i> #Subitem.Name</a></li>
}else{
<li><a class="NormalA aNav" href="#Subitem.Url">#Subitem.Name</a></li>
}
}
}
}
}
}
</ul>
</div>
</div>
<script>
$(".item").click(function(){
$(this).children(".submenu").toggle(); //it will display or hide your submenu when clicking the item.
});
</script>
<style>
.submenu{
display: none;
list-style:none;
}
</style>
I do plan on removing the script and style from the page when everything works.

First thing you have several issues in the code:
Remove the Where to filter Children and keep it like var selection = Umbraco.TypedContent(documentRootNodeId).Children("Visible");
Cast your hoofdstukIcoon to string Subitem.GetPropertyValue<string>("hoofdstukIcoon")
The first <li class="noBullet"> should be in your nav-list, not outside.
You shouldn't put <br> between your list items, if you want margins use css.
Now we'll focus on your issue with the submenus. What you are doing with your javascript is just using the display property to hide or show your submenu but when the page is rendered, Razor has no idea if that should be hidden or not. To solve this you have to create a new class like .visible that can be used by Razor and Javascript.
Yous hould also move your <ul class="submenu"> out of your #foreach (var Finalitem in Subitem.Children) because what you are doing now is creating a new list with one item for each one.
You should also include a conditional before your submenu in case there a no children and we don't want submenu #if (Subitem.Children.Any()) {
The way of telling your submenu with Razor if it has to diplay or not is doing this:
var isVisible = Model.Content.IsDescendantOrSelf(Subitem) ? "visible" : "";
<ul class="submenu #isVisible">
So in that example your submenu will show if the current page is this Subitem or one of its children.
And your JS script would become this:
$(".item").click(function () {
$(this).children(".submenu").toggleClass('visible'); //it will display or hide your submenu when clicking the item.
});
And your CSS this:
<style>
.submenu {
display: none;
list-style: none;
}
.submenu.visible {
display: block;
}
</style>

Related

UL style attribute is changed to display:block from display:none but this happens in fraction of second unable to take list of li elements from ul

Dropdown - On clicking on div,Ul style attribute is changed to display:block from display:none but this happens in fraction of second unable to take list of li elements from ul
<div id="main_filter" class="drop-select-wrap">
<span data-title="Active Clinic Patients" data-value="101" class="optionValue ov-gradient">Active Clinic Patients ▼</span>
<ul class="dropSelect" id="parentFilter" style="display: none; width: 175px;">
<li id="filterTypes" data-value="102" onclick="tier1FilterChanged(this);" data-rel="My Active Patients">
<span data-title="My Active Patients">My Active Patients</span>
</li>
<li id="filterTypes" data-value="101" onclick="tier1FilterChanged(this);" data-rel="Active Clinic Patients">
<span data-title="Active Clinic Patients">Active Clinic Patients</span>
</li>
<li id="filterTypes" data-value="126" onclick="tier1FilterChanged(this);" data-rel="Inactive Patients">
<span data-title="Inactive Patients">Inactive Patients</span>
</li>
</ul>
</div>
Initial :
On page load, i am having dropdown of above code where - UL tag is having attribute style="display: none; , so all li elements are hidden . Only span value i.e. default selected value is displayed.
In this case, for dropdown on page load - Active Clinic Patients is displayed.
On Click of dropdown :
Once i click on dropdown, UL attribute is changed to style="display: block;"
and li elements are visible.
Problem Faced :
On clicking on span , dropdown values are displayed for fraction of second - so unable to handle Ul style attribute changes and selecting value from li.
I am struggling for this, it would be great if anyone can provide some solution.
Thanks in advance.
Tried Code Snippet :
private IWebElement parentFilter => driver.FindElement(By.XPath("//div[#id='main_filter'][1]/span"));
public void SelectFilter(string filterOption)
{
IWebElement elementToShow = driver.FindElement(By.XPath("//ul[#class='dropSelect']"));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].style='display: block;'", elementToShow);
IWebElement option = elementToShow.FindElement(By.XPath("//li/span[contains(text(),'" + filterOption + "')]"));
Actions action = new Actions(driver);
action.ClickAndHold(parentFilter).MoveToElement(option).Click().Build().Perform();
}
It looks like your code is attempting to directly modify the style using ExecuteScript. Instead, the code should emulate what a user does by executing a Click() method on elementToShow. This should open the list, allowing you to find your target option.

Select element from dropdown list in <ul><li>..</li><ul> tag where <ul> tag having attribute style -display:none

I want to click on div[#id='main_filter'] and then select a li element from the dropdown.
But the problem i am facing is, parent tag has attribute
style = display: none, so li items are hidden. so I am unable to get elements from the li tag.
I am creating a generic method to selectfromdropdown.
<div id="main_filter" class="drop-select-wrap">
<span data-title="Active Clinic Patients" data-value="101" class="optionValue ov-gradient">Active Clinic Patients ▼</span>
<ul class="dropSelect" id="parentFilter" style="display: none; width: 175px;">
<li id="filterTypes" data-value="102" onclick="tier1FilterChanged(this);" data-rel="My Active Patients">
<span data-title="My Active Patients">My Active Patients</span>
</li>
<li id="filterTypes" data-value="101" onclick="tier1FilterChanged(this);" data-rel="Active Clinic Patients">
span data-title="Active Clinic Patients">Active Clinic Patients</span>
</li>
<li id="filterTypes" data-value="126" onclick="tier1FilterChanged(this);" data-rel="Inactive Patients">
<span data-title="Inactive Patients">Inactive Patients</span>
</li>
</ul>
</div>
my solution :
private IWebElement parentFilter => driver.FindElement(By.XPath("//div[#id='main_filter'][1]/span"));
public void SelectFilter(string filterOption)
{
ElementHandler.Click(parentFilter);
IWebElement element = driver.FindElement(By.Id("parentFilter"));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].removeAttribute('style')", element);
IWebElement filterName = element.FindElement(By.XPath("//li/span[contains(text(),'" + filterOption + "')]"));
//driver.FindElement(By.XPath("/ul[#id='parentFilter']/li/span[contains(text(),'"+ filterOption + "')]"));
ElementHandler.SelectFromDropdown(parentFilter, filterName);
}
public static void SelectFromDropdown(IWebElement element1,IWebElement element2)
{
Actions action = new Actions(driver);
action.ClickAndHold(element1).Build().Perform();
action.ClickAndHold(element1).MoveToElement(element2).Click().Build().Perform();
}
You could try executing some Javascript on the hidden ul element to change its style attribute and display it. I see you're already trying to remove the style attribute, but let me show you an approach I've taken before that has worked:
IWebElement elementToShow = driver.FindElement(By.XPath("//ul[#class='dropSelect']"));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].style.display = 'block';", elementToShow);
If that works, then you should be able to click on the li elements.
One of the core features of Selenium is that when a Webdriver tries to interact with an element that is covered or hidden, it will fail to do so. This is a good thing, since it allows us to detect such anomalies in our testing environments instead of exposing such behaviour to our users.
This can be a bit confusing at times, though. For example, a Webdriver that tries to click a <div> that is covered by another transparent <div> will fail to do so since it is covered, although it might look like a clickable element to a human eye.

Populate Bootstrap dropdownlist dynamically

<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle " data-toggle="dropdown">
Year <span class="caret"></span>
</button>
<ul id='demolist' class="dropdown-menu" runat="server" role="menu">
</ul>
</div>
Hi All,
I am trying to populate the li items in a bootstrap dropdwnlist via code-behind. PFB the .cs code which is placed in page load.
HtmlGenericControl li;
for (int x = 3; x <= 10; x++)
{
li = new HtmlGenericControl("li");
li.Attributes.Add("class", ".dropdown p");
li.InnerText = "Item " + x;
li.Disabled = false;
demolist.Controls.Add(li);
}
PFB the js code which displays the selected value upon click.
<script type="text/javascript">
$(function(){
$(".dropdown-menu li ").click(function(){
$(".btn:first-child").text($(this).text());
$(".btn:first-child").val($(this).text());
});
});
</script>
Now, when i click on the dropdown it displays the list items,but there are 2 problems
When the mouse cursor is hovered over it
display a 'I' cursor (the one that appears when you are editing a doc or something) instead of finger pointer cursor(like how it displays for an asp:dropdown).
After clicking the list item the text of the dropdown do change, but the 'down arrow' disappears.
Could anyone please help me out on this ?
When you change the text of the button with jQuery .text(), you're overwriting the span class="caret" too.
Perhaps add another span into your button:
<button type="button" class="btn btn-default dropdown-toggle " data-toggle="dropdown">
<span class="year">Year</span> <span class="caret"></span>
</button>
Then target that with your JS:
$(".dropdown-menu li").click(function(){
var li = $(this),
btn = $('.btn:first-child'); // Maybe need a better selector?
btn.find('span.year').text(li.text());
btn.val(li.text());
});
Also the cursor won't be a pointer as you're hovering over an li, not an a etc. But you could tweak your CSS to chose the cursor style:
.dropdown-menu li {
cursor: pointer;
}

Dynamically add multiple carousel jquery sliders on a cshtml page

I would like to add multiple jquery sliders on a cshtml page using data from a database. Basically I have a collection of tabs that when active dynamically populate a slider contained within with data from a database.
cshtml code with Razor C# hooks:
<div class="tabbable">
<ul id="myTab" class="nav nav-tabs">
#foreach(var row in db.Query(queryCategory))
{
<li>#row.Food_Category</li>
}
</ul>
<div class="tab-content">
#{bool first = true;}
#foreach(var row in db.Query(queryCategory))
{
var ids= #row.Food_Category;
<div class="#{if (first){<text>tab-pane active</text> first = false;}else{<text>tab-pane</text>}}" id=#ids>
<p>I'm in #row.Food_Category.</p>
<div class="list_carousel">
<ul id="foo">
#foreach(var row1 in db.Query("SELECT * FROM Food WHERE Food_Category = #0", ids))
{
<li>#row1.Food_ID</li>
}
</ul>
<div class="clearfix"></div>
<a id="prev2" class="prev" href="#"><</a>
<a id="next2" class="next" href="#">></a>
<div id="pager2" class="pager"></div>
</div>
</div>
}
</div>
</div><!--tabbable-->
The bit I think needs focus:
The rest of the code is dynamic except this bit. I'm not sure how to go about getting a unique id for each un-ordered list (e.g foo1, foo2, foo3 dynamically) depending on the number of items in a database column.
<ul id="foo">
#foreach(var row1 in db.Query("SELECT * FROM Food WHERE Food_Category = #0", ids))
{
<li>#row1.Food_ID</li>
}
</ul>
The Jquery bit:
Here Im not sure, but I think I'll need to set this options true for a range of #id specified dynamically.
<script>
//Carousel
$('#foo').carouFredSel({
width: '100%',
scroll: 2,
auto: false,
prev: '#prev2',
next: '#next2',
pagination: "#pager2",
mousewheel: true,
swipe: {onTouch: true}
});
</script>
I'm just starting out with webmatrix & jquery please bear with me. Thanks
If you just want to get the unique ID for each unorder list you can do somethink like this
#int inc=0;
#foreach(var row in db.Query(queryCategory))
{
var ids= #row.Food_Category;
<div class="#{if (first){<text>tab-pane active</text> first = false;}else{<text>tab-pane</text>}}" id=#ids>
<p>I'm in #row.Food_Category.</p>
<div class="list_carousel">
<ul id="foo#inc++">
#foreach(var row1 in db.Query("SELECT * FROM Food WHERE Food_Category = #0", ids))
{
<li>#row1.Food_ID</li>
}
</ul>
<div class="clearfix"></div>
<a id="prev2" class="prev" href="#"><</a>
<a id="next2" class="next" href="#">></a>
<div id="pager2" class="pager"></div>
</div>
</div>
}
but if you just want to get carousal dynamically for-each under list you can use for each function in jquery foreach
$('ul').each(function(index) {
$('this').carouFredSel({
width: '100%',
scroll: 2,
auto: false,
prev: '#prev2',
next: '#next2',
pagination: "#pager2",
mousewheel: true,
swipe: {onTouch: true}
});
});

UL toggle working in FF and not in IE 7

I have an list that toggles with no problem in FF. I need this working IE for it to be production ready.
It seems (IE) to apply the js to the first #orderItem and the first #familiy only. The rest of the items in the list are ignored.
Any help would be great.
A piece of the HTML (large list):
<div class="classificationContainer">
<ul class="classification" id="orderUL">
<li id="orderItem" class="ordrheading">
<div class="order">
<a href="?nav=search_recherche&lang=en">
<img src="http://dev.ncr.ec.gc.ca/publications/bba-aob/images/node_closedc.gif" alt="By Classification" id="OrdListImage" />
Apodiformes (Swifts and Hummingbirds)
</a>
</div>
<ul class="classification" id="FamilyList">
<li id="familiy">
<div class="family">
<a href="?nav=search_recherche&lang=en">
<img src="http://dev.ncr.ec.gc.ca/publications/bba-aob/images/node_closedc.gif" alt="Family" id="FamListImage" />
Apodidae (Swifts)
</a>
</div>
<ul class="classification" id="SpiecesList">
<li>
<img src="http://dev.ncr.ec.gc.ca/publications/bba-aob/images/node_leafc.gif" alt="Species" />
Chimney Swift (Chaetura pelagica)
</li>
</ul>
</li>
<li id="familiy">
<div class="family">
<a href="?nav=search_recherche&lang=en">
<img src="http://dev.ncr.ec.gc.ca/publications/bba-aob/images/node_closedc.gif" alt="Family" id="FamListImage" />
Trochilidae (Hummingbirds)
</a>
</div>
<ul class="classification" id="SpiecesList">
<li>
<img src="http://dev.ncr.ec.gc.ca/publications/bba-aob/images/node_leafc.gif" alt="Species" />
Ruby throated Hummingbird (Archilochus colubris)
</li>
<li>
<img src="http://dev.ncr.ec.gc.ca/publications/bba-aob/images/node_leafc.gif" alt="Species" />
Rufous Hummingbird (Selasphorus rufus)
</li>
</ul>
</li>
</ul>
</li></ul></div>
I have the following jquery functions:
<script type="text/javascript">
$(document).ready(function () {
// toggle action for the order to familiy
$("li#orderItem").click(function (event) {
// toggle the image
var src = ($("#OrdListImage", this).attr("src") == "/images/node_closedc.gif")
? "/images/node_openc.gif"
: "/images/node_closedc.gif";
$("img#OrdListImage", this).attr("src", src);
//toggle the ul
$('ul#FamilyList', this).toggle($('ul#FamilyList', this).css('display') == 'none');
// stop all link actions
return false;
});
//toggle action from familiy to speices
$("li#familiy").click(function () {
// toggle the image
var src = ($("#FamListImage", this).attr("src") == "/images/node_closedc.gif")
? "/images/node_openc.gif"
: "/images/node_closedc.gif";
$("img#FamListImage", this).attr("src", src);
//toggle the ul
$('ul#SpiecesList', this).toggle($('ul#SpiecesList', this).css('display') == 'none');
// stop all link actions
return false;
});
});
Also check if id's are not repeated (there is only one #orderItem, only one #familiy and etc.). "id" attribute must be unique in html document, "class" can be repeated.
The toggle function provided by jQuery is not guaranteed to work. I lost the reference where I read this (was on jQuery's homepage). I encountered the same problem and (as suggested by jQuery) implemented my own toggle function. I'd suggest trying this, as it's not much work and could provide you a solution.

Categories

Resources