JQuery: create array from element's name and create list - javascript

I would like to getElement's names => make an array => create a menu as list => add some clickbehaviour CSS. When exercising I already found a way to get all elements but could not reach their names.
The elements I am aiming for look like this <a class="jqsubmenu" name="ELEMENTSNAME"></a>.
The HTML-Code to be produced needs to be like <div id="#submenu"><ul>...</ul></div>. The <li> needs to look like <li>ELEMENTSNAME</li>. When a menu item is clicked any "active" classes in #submenu need to be removed and the clicked Anchor gets class="active".
Here are my results where I got stuck:
1) Get elements:
var optionTexts = [];
$("A.jqsubmenu").each(function() { optionTexts.push($(this).text()) });
2) make list (once I hopefully have an array) and write into DOM
var SubmenuArray = ['One', 'Two', 'Three'];
// GENERATE SUBMENU
var ObjUl = $('<div id="submenu"><ul></ul></div>');
for (i = 0; i < SubmenuArray.length; i++)
{
var Objli = $('<li></li>');
var Obja = $('ARRAYITEM');
} // WRITE INTO DOM
$('#submenuwrap').append(ObjUl);
}
3) CSS-Gimmick
$( document ).ready(function() {
$( "#submenu A" ).click(function( event ) {
$( "#submenu A" ).removeClass("active");
$( this ).addClass("active");
});
});
Thanks for your answers and all the best!

To access element's name attribute use
$("A.jqsubmenu").each(function() { optionTexts.push($(this).attr("name")) });

Related

how to get the index of the li clicked in javascript

Just using javascript, need to get the index of the li that's clicked with the following listener:
var ulList = document.getElementById('todo-list');
ulList.addEventListener('click', function(e){
if( e.target.nodeName == "BUTTON") {
//IS THERE A WAY INSIDE HERE TO GET THE INDEX OF THE li clicked
e.target.parentNode.remove();
}
});
each li looks like:
<li>
<input type="checkbox" value="1" name="todo[]">
<span class="centerSpan" style="text-decoration: none;">abc</span>
<button class="rightButton">X</button>
</li>
From the target (button, in this case) call closest() to get a reference to your li element
var li = e.target.closest('li');
Then get an array reference of your UL's children by using Array.from() and passing in the children HTMLCollection
var nodes = Array.from( ulList.children );
//or if you want to not depend on externally defined variables
var nodes = Array.from( li.closest('ul').children );
Finally call indexOf() to get the index
var index = nodes.indexOf( li );
If wanting to support old browsers will need to polyfill for methods like Array.from()

jquery random element id for every loop

sorry i'm new in jquery and i need help :-(
i want to traverse all elements on html page with class parts
then go inside to two children and pass them a random number ( the same for them both)
for every element new random number is passed ( no repeat on page)
children classes are :
anot-head
anot-body
this is a sample code:
$(document).ready(function() {
$.each($('.parts'), function(){
var ran=Math.floor(Math.random()* 1000000);
$( ".anot-head" ).attr( "data-toggle","collapse" ).attr( "href","#s"+ran );
$( ".anot-body" ).attr( "id","s"+ran );
});
});
$(".anot-body") does a search of the whole document, if you want to find a particular element in another element you need to do a search from that parent element.
In your case you would do a search on the particular .parts element that is currently being iterated over in your $.each() callback
$('.parts').each(function(index,element){
var parent = $(element);
var ran=Math.floor(Math.random()* 1000000);
parent.find('.anot-head').attr( "data-toggle","collapse" ).attr( "href","#s"+ran );
parent.find('.anot-body').attr( "id","s"+ran );
});
No need to use random.... use index of each
$('.parts').each(function(index){
var $part = $(this);
$part.find('.anot-head').attr({"data-toggle":"collapse","href":"#s"+index});
$part.find('.anot-body').attr("id","s"+ index);
});

Jquery class for list elements

I'm trying to adapt a JS plugin and I need to give numerical classes to a series of li items
This is the code at the moment and I would like to add a class or a data attribute in order to be able to select them individually
var li = '<li><span></span>';
Try with JQuery addClass() to add class on based on its position.
For example
$( "ul li" ).addClass(function( index ) {
return "item-" + index;
});
This example adds the class "item-0" to the first <li> and "item-1" to the second.
In the same way you can add class on <a> under each <li>.
$( "ul li" ).each(function( index1 ) {
$(this).find('a').addClass(function( index2 ) {
return "item-" + (index1 * 10 + index2) ;
});
});

click all buttons on page except when parent has a specific class

I want to click all buttons on a page that have the attribute data-capture='noiseClicked'
This is my code so far:
javascript: (function() {
var followButtons = $("li.js-profile-card button[data-capture='noiseClicked']");
var index = followButtons.length - 1;
follow();
function follow() {
if (index >= 0) {
$(followButtons[index--]).click();
setTimeout(follow, 1);
}
}
})();
However I want to exclude buttons that have a parent of li.noise--active or li.friend--active
So the following would be clicked:
<li class="js-profile-card noise--active"><button data-capture="noiseClicked" type="button"></button></li>
but the following would not be clicked...
<li class="js-profile-card noise--active"><button data-capture="noiseClicked" type="button"></button></li>
or
<li class="js-profile-card friend--active"><button data-capture="noiseClicked" type="button"></button></li>
I thought that jquery's not selector would be helpful here, but I'm not sure how to use it to exclude a parent element with a specific attribute and I don't know how to exclude two different attributes (noise--active and friend--active)
Thanks.
You can use parent & hasClass methods for this:
var indexToSet = index--;
if( !$(followButtons[indexToSet]).parent().hasClass( 'noise--active' ) && !$(followButtons[indexToSet]).parent().hasClass( 'friend--active' )) {
$(followButtons[indexToSet]).click();
}
EDIT:
to travel up in the node list better to use closest() method:
var indexToSet = index--;
if( !$(followButtons[indexToSet]).closest( 'noise--active' ).length && !$(followButtons[indexToSet]).closest( 'friend--active' ).length ) {
$(followButtons[indexToSet]).click();
}
:not selector might come handy:
var followButtons = $("li.js-profile-card:not(.noise--active,.friend--active) button[data-capture='noiseClicked']");

can this JavaScript function be refactored?

I need to use prototype JavaScript library on a project and wanted to add tabbed box to HTML.
The click handler has a simple task - set selected on parent <li> element and show linked DIV id element (rel tag on <li> has element id name)
<div class="tabInterface">
<ul class="tabSelector">
<li class="selected" rel="searchLast">Popularna iskanja</li>
<li rel="searchMine">Moje zadnje iskanje</li>
</ul>
<div class="tabContent selected" id="searchMine">
box 1 content
</div>
<div class="tabContent" id="searchLast">
box 2 content
</div>
</div>
Final result after 1 hour of hard labour.
initTabInterface = function() {
//requires prototype
var tabClick = function(event){
Event.stop(event);
var $el = Event.element(event);
var $menu = $el.up('.tabSelector');
var liList = $menu.descendants().filter(function(el){return el.match('li')});
liList.invoke('removeClassName', 'selected');
$el.up().addClassName('selected');
var rel = $el.up().readAttribute('rel');
var $interface = $menu.up('.tabInterface');
var tabList = $interface.descendants().filter(function(el){return el.match('.tabContent')});
tabList.invoke('removeClassName', 'selected');
$interface.down('#'+rel).addClassName('selected');
};
$$('.tabInterface .tabSelector li a').each(function(el){
var $el = $(el);
Event.observe($el, 'click', tabClick);
});
};
Event.observe(window,"load", function(){
initTabInterface();
});
Is there an easier way of traversing in prototype than with the bunch of up, down, filter, match, invoke and each?
This is pretty much you can get:
initTabInterface = function() {
//requires prototype
var tabClick = function(event){
Event.stop(event);
var $el = Event.element(event);
var rel = $el.up().readAttribute('rel');
// remove old selected classes
$el.up('.tabInterface').select('.selected')
.invoke('removeClassName', 'selected');
// add new selected classes
[ $(rel), $el.up() ].invoke('addClassName', 'selected');
};
$$('.tabSelector li a').each(function(el){
Event.observe($(el), 'click', tabClick);
});
};
Event.observe(window,"load", function(){
initTabInterface();
});​
I do not know Prototype well enough to quickly refactor your code, but you can use Element.siblings instead of going up and then descending down. Alternatively, you can just enumerate by class names (doesn't work well if you have more than one tab control).
$el.siblings().invoke('removeClassName', 'selected');
Also
$interface.down('#'+rel).addClassName('selected');
is unnecessary because you can only have one element with an id in the whole document. Can change it to:
$(rel).addClassName('selected');

Categories