Retaining state of navigation problems - javascript

Hi I am trying to retain the state of a navigation accros multiple pages pages.I have managed to get the indexes of each element I want to retain , the problem is setting them.For some reason only some of the elements seem to be set.
I have debugged the code and it seems as if only one element gets taken into consideration sometimes.I can not figure out what am I doing wrong here.Here is my code:
<ul id="ProductNav">
<li>
<h2>#category.Key.ToUpper()</h2>
<ul>
<li>
<img src="#Url.Content("~/Content/Images/arrow.gif")" class="arrow"/>
#Html.ActionLink(subcategory,"Index" , "Products" , new { subcat = subcategory} , null)
</li>
</ul>
</li>
</ul>
......
var menuState = JSON.parse(sessionStorage["navigation"]);
for (var i = 0; i < menuState.length; i++) {
var menuIndex = menuState[i].eq;
$("ul#ProductNav li").eq(menuIndex).children("ul").css("display", "block");
}
menuState will we an object containing an array of indexes
From what I understand so far the problem begins here:
$("ul#ProductNav li").eq(menuIndex).children("ul").css("display", "block");

Related

materialize collapsible: how to determine which section is open?

I have a materialize collapsible which works as expected. Something similar to:
<ul class="collapsible">
<li>
<div class="collapsible-header">Title1</div>
<div class="collapsible-body" />
</li>
<li>
<div class="collapsible-header">Title2</div>
<div class="collapsible-body" />
</li>
</ul>
In a later process, when pressing a button I need a javascript function to modify its behavior depending on which section is open.
How can I determine which section is open?
I guess one possibility would be to store in a hidden element the index of the section when it is selected but I don't know how to do it.
Materializecss add an active class to an open collapsible item by itself. So you can use it to understand which collapsible item is open.
You can use this jquery code :
$(document).on("click","ul.collapsible li", function(){
var elem = document.querySelectorAll("ul.collapsible li");
var index = "none"
for (var i = 0; i < elem.length; i++) {
if (elem[i].className == "active") {
index = i;
}
document.getElementById("show").innerHTML = index;
}
})
This code show index of opened collapsible item for you.
Here is complete example : jsFiddle

Click on li with specific "rel" : Pure javascript, no jquery

I have to do a fully JavaScript (jQuery forbidden) script. I only can use the 'click()' function.
I have to simulate a click on a "li" which has a random attribute for a sneakers website.
For showing you :
The user click on a "mega menu" which display (on the click) the different sizes.
The user choose his size in that menu
I show you the "code" of the html big menu. On this article, "LZAE31" is the ID product.
<ul class="theUlClass" style="display:none">
<li class="theLiClass" rel="LZAE31:40">EU 40</li>
<li class="theLiClass" rel="LZAE31:41">EU 41</li>
<li class="theLiClass" rel="LZAE31:42">EU 42</li>
<li class="theLiClass" rel="LZAE31:43">EU 43</li>
</ul>
Imagine that the user has already buy something on the website, and his size is 42 EU.
The script is 90% ok (the part that the user has already buy something), but now i need to "simulate" a click.
For exemple, the end of the script works and it is :
document.getElementsByClassName("addtocart")[0].click();
So I really need you, to understand how can i click on the "rel="RANDOM:42" in the li.TheLiClass for exemple...
Try with:
First select element:
With Selector:
document.querySelector("[rel='LZAE31:40']")
// try like: console.log(document.querySelector("[rel='LZAE31:40']"));
Or with this function :
function specificRel( rel )
{
var items = document.getElementsByTagName('li');
for (var i=0; i<items.length; i++) {
if (items[i].getAttribute("rel") == rel) {
return items[i];
}
}
}
// try like: console.log(specificRel("LZAE31:40"));
And two, click :
With selector:
document.querySelector("[rel='LZAE31:40']").click();
Or with the function:
specificRel("LZAE31:40").click();
It's a tad bit unclear what you're asking, but I'll give it a shot. To get the LI element with rel=LZAE31:43 is trivial.
for( var a= document.getElementsByTagName('li'),i= 0; i < a.length; ++i )
if( a[i].getAttribute('rel') == 'LZAE31:43' )
break;

Jquery to copy first link to second ul and then change class of first link

Short question:
http://jsfiddle.net/wF4FH/2/
What I want is for Page1 to be right above Page2 and Page10 above Page 20 before I change the classes. This should work for any number of elements.
The code provided gives an "Uncaught TypeError: Object # has no method 'append' ".
Long question:
I'm having problem finding the correct way to insert an li element based on the first link. The problem is I cant use id's on my markup so I have to "walk through" each class and check for names. I might just make this a lot more complicated than it is because my first two solutions didn't work the way I thought they would.
html
<ul class="nav">
<li class="active">
Start
</li>
<li class="has-child">
page1
<ul class="">
<li>
page2
</li>
</ul>
</li>
<li class="has-child">
page10
<ul class="">
<li>
page20
</li>
<li>
page30
</li>
</ul>
</li>
javascript
//Copy first link to child ul li
var pageLinks = $("li.has-child > a:first-child");
if (pageLinks != null) {
//var dropdownMenus = $("li.dropdown > a:first-child");
for (var i = 0; i < pageLinks.length; i++) {
for (var x = 0; x < pageLinks.length; x++) {
if (pageLinks[i].innerHTML === pageLinks[x].innerHTML) {
pageLinks[x].childNodes.append(pageLinks[i]);
}
}
}
}
//Change css classes
$("li.has-child").attr('class', 'dropdown');
$(".dropdown ul").addClass("dropdown-menu");
$(".dropdown a").attr("href", "#").addClass("dropdown-toggle").attr('data-toggle', 'dropdown');
strong text
What I want is for Page1 to be right above Page2 and Page10 above Page 20 before I change the classes. This should work for any number of elements.
When they are copied to the inner ul I change the top level menu item to a different class to work as a clickable dropdown men item.
The code provided gives an "Uncaught TypeError: Object # has no method 'append' ".
It is the navigation of a cms I cant change the markup on.
try this:
$links = $('li.has-child').children('a:first-child');
if($links.length > 0){
$links.each(function(i,link){
$(link).next().prepend($('<li></li>').append($(link)))
})
}
http://jsfiddle.net/wF4FH/6/
You need .clone() method to copy elements..
UPDATED
$links = $('li.has-child').children('a:first-child');
if($links.length > 0){
$links.each(function(i,link){
$(link).next().prepend($('<li></li>').append($(link).clone()))
})
}
http://jsfiddle.net/wF4FH/7/
When you have a jQuery object and you access it by numeric index, you're left with an HTML element. So $('body')[0] == document.body. This means that when you access pageLinks[x], you're really getting a raw element. This means that you want pageLinks[x].appendChild(pageLinks[i]);, not pageLinks[x].childNodes.append(pageLinks[i]);

How to get the current ul li's length in javascript , when i tried to sort them?

<ul id="types" style="list-type:none;">
<li id="categories" style="list-type:none;">1
<ul>
<li style="list-type:none;">1</li><br/>
<li style="list-type:none;">1</li>
</ul>
</li>
<li id="categories" style="list-type:none;">2
<ul>
<li style="list-type:none;">2</li><br/>
<li style="list-type:none;">2</li>
</ul>
</li>
<li id="categories" style="list-type:none;">3
<ul>
<li style="list-type:none;">3</li><br/>
<li style="list-type:none;">3</li>
</ul>
</li>
</ul>
i am moving the li up and down ,when i am doing like this i have written the code for calling one jquery _mouseStop function(event,noPropagation))
in this function i am writing
var tagetNode = this.currentItem[0].parentNode.id
if (this.element[0].id == "categories") {
var targetlistlength = document.getElementById(targetListId).getElementsByTagName("li").length;
// var targetlistlength = this.parentNode.getElementsByTagName("li").length;
var PageIds = "";
for (var i = 0; i < targetlistlength; i++) {
PageIds += document.getElementById(targetListId).getElementsByTagName("li")[i].getAttribute("value") + ",";
}
}
when i am sorting the child li's the above function get called but it is always getting the first child ul of first li length only.. i want the current ul li's length which i am trying to sort
i have tried with the commented line also to get the length of li's but iam getting error as this.parentNode is undefined
anyone please suggest me what can i do
As there is no working demo available, you can check what you get when you use console.log($(this)); inside that function when mouseStop event occurs in console. If you get the expected li in the console then you can executing the following code to get the length of its parent's childs.
alert($(this).parent().children().length);
There mustn't be multiple elements with the same id.
Try to replace them with classes or make them unique.
The if-condition could be the following if you have unique id's (e.g. categories-1, categories-2, ...)
if (this.element[0].id.match("^categories") != null) { ... }
Or if you use classes the if-condition could be:
if (this.element[0].className.match("(^| )categories( |$)") != null) { ... }

javascript looping through li attributes and changing values per item

I want to loop through a bunch of <li> elements and update the value held in it, and show this on the document.
The reason i'm doing this is because I want to sort a list of elements in an order. I do this using Sortable in JQuery.
<li> 1 </li>
<li> 2 </li>
<li> 3 </li>
<li> 4 </li>
<li> 5 </li>
the order may become:
<li> 3 </li>
<li> 1 </li>
<li> 4 </li>
<li> 2 </li>
<li> 5 </li>
Then clicking a button i would like my JS function to change the value of the li items back to 1,2,3,4,5. Its worth noting i am not looking for a solution to revert back to how the list was before.
Thanks.
This should work (as of jQuery 1.4):
$('.your_list li').text(function (index) {
return index + 1;
});
I think you would rather reorder the list items than their contents. This way, you don't lose any of the li's attributes/classes/... And you can keep the DOM's elements intact, only change the order of some ul's children.
I found a nice little snippet do do it:
http://www.onemoretake.com/2009/02/25/sorting-elements-with-jquery/
The only thing you still need to do is remember the initial order
function mysortA( a, b ) {
var compA = $(a).text().toUpperCase();
var compB = $(b).text().toUpperCase();
return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
}
function mysortB( a, b ) {
return a.originalindex < b.originalindex ? -1
: a.originalindex > b.originalindex ? 1
: 0;
}
You have to initialize:
var ul = $('ul');
var listitems = ul.children('li').get();
// remember original index
listitems.each( function(index, li){ li.originalindex=index; } );
Then you can sort one way:
// sort them using your sort function
listitems.sort( mysort )
// rebuild the list container
listitems.each( function(idx, itm) { mylist.append(itm); });
And sort back:
var ul=$('ul');
ul.children('li').get().sort(mysortB).each(function(i,li){ ul.append(li); });
Note: untested - grab the idea.

Categories

Resources