In javascript (jquery), I'm retrieving a list of elements that start with "#error-". This works correctly. The problem I have is that I can't assign a value to elements of the array while looping through it.
I'm using this function:
function HideErrorMessages(){
var errors = $('*[id^="error-"]');
for (var i = 0; i < errors.length; i++) {
errors[i].css('display', none);
}
}
As you can see, I tried this "css" possibility. Doesn't work.
I also tried:
errors[i].hide();
errors[i].style.display = 'none';
But when using " alert(errors[i]) ", I get a response which indicates that it contains a list of "span" elements (which is correct).
So how can I do to hide elements in this loop?
Thanks!
Try to invoke .hide() over the jquery object,
$('[id^="error-"]').hide();
You don't need to iterate over that elements one by one. If you fetch elements from a jquery object by bracket notation, then it will return native javascript DOM node. So .css() will cause error as it is not a part of a DOM node.
errors[i] makes reference to a property inside the jQuery object which is a selected DOM object. There's no css function for those objects, it's a jQuery thing. But you can use jQuery eq to select the object and have access to jQuery methods:
errors.eq(i).css('display', 'none');
You can also use each to iterate each element of the jQuery object:
$('*[id^="error-"]').each(function(){
$(this).css('display', 'none');
});
I would go like this.
$('#buttonClick').on('click', function() {
var showing = $(this).closest('.thumbBrowser').find('ul li:visible');
var next = showing.last().next();
if( next.length === 0 ) {
next = $(this).closest('.thumbBrowser').find('ul li').first();
}
next.toggleClass('hidden').next().toggleClass('hidden');
showing.toggleClass('hidden');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="thumbBrowser">
<ul>
<li class="thumbLeft caseStudy tint tintWhite">
<img src="images/argus_thumb.jpg" alt="one">
</li>
<li class="thumbRight caseStudy tint">
<img src="images/adr_thumb.jpg" alt="two">
</li>
<li class="hidden thumbLeft caseStudy tint tintWhite">
<img src="images/dd_thumb.jpg" alt="three">
</li>
<li class="hidden thumbRight caseStudy tint">
<img src="images/cdp_thumb.jpg" alt="four">
</li>
<li class="hidden thumbRight caseStudy tint tintWhite">
<img src="images/pm_thumb.jpg" alt="five">
</li>
<li class="hidden thumbLeft caseStudy tint tintWhite">
<img src="images/argus_thumb.jpg" alt="six">
</li>
</ul>
<div class="cycleButton" id="buttonClick"><img src="images/cycleIcon.png"></div>
</div>
.hidden {
display:none;
}
Related
In my project, there are so many jQuery toggles needed for changing text and icons. Now I’m doing that using:
$("#id1").click(function () {
//Code to toggle display and change icon and text
});
$("#id2").click(function () {
//Same Code to toggle display and change icon and text as above except change in id
});
The problem is that I got so many to toggle, the code is quite long but all I change for each one is the id. So I was wondering if there is any way to make this simple.
Below is a sample pic. I got so many more in single page.
There are two issues here.
How to run the same action on multiple elements
How to know which element you've clicked so that you can run a relevant action on it. (most of the existing answers skip this part).
The first is to use a class for each of the elements you want to click, rather than wire up via an id. You can use a selector similar to [id^=id] but it's just cleaner to use a class.
<div id="id1" class="toggler">...
which allows you to:
$(".toggler").click(function() ...
the second is it associate the clickable with the item you want to toggle. There are many ways to do this, my preferred option is to associate them with data- attributes, eg:
<div class="togger" data-toggle="#toggle1">...
which allows you to:
$(".toggler").click(function() {
$($(this).data("toggle")).toggle();
});
The key here is that this is the element being clicked, so you can do anything else with this such as show/hide an icon inside or change colour.
Example:
$(".toggler").click(function() {
$($(this).data("toggle")).toggle();
$(this).toggleClass("toggled");
});
.toggler { cursor: pointer }
.toggled { background-color: green }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="toggler" data-toggle="#t1">T1</div>
<div class="toggler" data-toggle="#t2">T2</div>
<div class="toggler" data-toggle="#t3">T3</div>
<hr/>
<div id="t1" style='display:none;'>T1 content</div>
<div id="t2" style='display:none;'>T2 content</div>
<div id="t3" style='display:none;'>T3 content</div>
Oh,Can you use a class instead of id?
<ul>
<li class="idx">A</li>
<li class="idx">B</li>
<li class="idx">C</li>
</ul>
$(".idx").click(function(e){
//Code to toggle display and change icon and text
let target = e.target;
//You can do all what you want just base on the `target`;
});
You can store the queries in an array, and iterate over them to perform the same JQuery operation on all of them
let ids = ["#id1", "#id2", "#id3", "#randomID"]
ids.forEach((id) => {
console.log($(id).html())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li id="id1">A</li>
<li id="id2">B</li>
<li id="id3">C</li>
<li id="randomID">D</li>
</ul>
Or (If like your example) and all of the id's are actually id1, id2, id3, ... etc.
let id = "id";
let n = 3; //amount of id's
for (let i = 1; i <= n; i++) {
console.log($("#" + id + i).html())
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li id="id1">A</li>
<li id="id2">B</li>
<li id="id3">C</li>
</ul>
You can try the below code.
var num = $("#myList").find("li").length;
console.log(num)
for(i=0;i<num;i++){
$("#id"+ i).click(function(e){
let target = e.target;
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<ul id="myList">
<li id="id1">A</li>
<li id="id2">B</li>
<li id="id3">C</li>
</ul>
Is it possible to get the .nextUntil() to work on split lists, or get the same functionality?
So I am trying to implement the ever so popular shift select for my items, and since they are ordered in a list in my application I want to be able to select across <ul> borders.
I have the following set of DOM elements:
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
And using something like this:
$('li.clicked').nextUntil('li.selected');
I'd like a list containing the following elements
[ <li class="item">third</li>,
<li class="item">fourth</li>,
<li class="item">fifth</li> ]
However all I get is the elements leading up to the split </ul>. Is there any way of doing this? I have also tried to first selecting all items with $('.item')and then using .nextUntil() on them without any luck.
Is this what you are looking for?
$('li').slice($('li').index($('.clicked'))+1,$('li').index($('.selected')));
For reference
Jquery.Index
Jquery.Slice
Edit
So if you do
$('li')
you will get an array of all elements 'li' getting:
[<li class="item">first</li>,
<li class="item clicked">second</li>,
<li class="item">third</li>,
<li class="item">fourth</li>,
<li class="item">fifth</li>,
<li class="item selected">sixth</li>,
<li class="item">seventh</li>]
Since it is an array you can slice him to get an sub array you just need two positions, where to start and here to finish.
//start
$('li').index($('.clicked'))+1 // +1 because you dont want to select him self
//end
$('li').index($('.selected'))
For better preformance you should before create an array with all li so it will not search all dom 3 times for the array of 'li'
var array = $('li');
var subarray = array.slice(array.index($('.clicked'))+1,array.index($('.selected')));
Assuming these lists cannot be merged into one, it is impossible using the nextUntil method. This is because of how jQuery performs traversing. According to the documentation,
Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed.
fifth is not a sibling of the clicked element, but rather it is a child of the sibling of the element's parents.
I came up with two possible solutions.
Solution 1: Combine NEXT and PREV traversals
Assuming that .clicked is always in the first list and .selected is always in the second list, combining prevAll() with nextAll() should do the trick. This assumes that the order is the same.
var siblings = $("li.clicked").nextAll()
Get all siblings of the current element AFTER the element itself.
var distantSiblings = $("li.selected").prevAll();
Get all distant siblings after the first element, but before the second one.
siblings.push(distantSiblings);
Combine them into two and then iterate over each element.
var siblings = $("li.clicked").nextAll()
var distantSiblings = $("li.selected").prevAll();
siblings.push(distantSiblings);
siblings.each(function() {
$(this).addClass("blue");
});
.blue { color: blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
http://jsfiddle.net/r15z10o4/
Note:
You will notice that the above code works, however it might not be the optimal solution. This is only confirmed to work for your example above. There may also be a less verbose solution.
Solution 2 (Find index of all list items)
Another idea is to find the index of all items, and collect the elements that are sandwiched between those two indices. You will then want to use the 'slice' selector to get the range in between.
var items = $(".item");
var clicked = $(".clicked");
var selected = $(".selected");
var clickIndex = items.index(clicked);
var selectIndex = items.index(selected);
$("li").slice(clickIndex + 1, selectIndex).addClass("blue");
var clicked = $(".clicked");
var selected = $(".selected");
var clickIndex = $("li").index(clicked);
var selectIndex = $("li").index(selected);
$("li").slice(clickIndex+1, selectIndex).addClass("blue");
.blue { color: blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
You can do it manually by selecting all these items at once, and using loops.
Consider the parent element, let's say "container":
<div id="container">
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
</div>
Now, you can select all these items:
var $items = $("#container > ul > li.item"); // or simply $("#container .item");
And iterate through them:
var $items = $(".item"), $result = $(), found = false;
for (var i = 0; i < $items.length; i++)
{
$currentItem = $items.eq(i);
if ($currentItem.is('.clicked')) {
found = true;
continue;
}
if ($currentItem.is('.selected'))
break;
if (found)
$result = $result.add($currentItem);
}
console.log($result);
Here is the working JSFiddle demo.
In any case it feels like you will need to define groups of li.
I think the easiest is to create a function getting a list of lis that you can request any way you want then to filter the el you are interested in.
function elRange(elList, start, end){
// we do not use indexOf directly as elList is likely to be a node list
// and not an array.
var startI = [].indexOf.call(elList, start);
var endI = [].indexOf.call(elList, end);
return [].slice.call(elList, startI, endI + 1);
}
// request the group of *ordered* elements that can be selected
var liList = document.querySelectorAll('ul.current > li, ul.later > li');
var selectionEnd = document.querySelector('.selected');
[].forEach.call(liList, function(li){
li.addEventListener('click', function(){
var selected = elRange(liList, li, selectionEnd);
selected.forEach(function(el){
el.classList.add('red');
})
});
});
.selected {
color: blue;
}
.red {
color: red;
}
<ul class="current">
<li class="item">first</li>
<li class="item">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
I have a banner which is something like this:
<ul id="carousel">
<li id="item1">
<div onclick="window.open('mylinkhere.com,'_blank')" style="cursor:pointer;margin-left:-436px;width:996px;height:100%">
</div>
</li>
<li id="item2">
<div onclick="window.open('myotherlinkhere.com,'_blank')" style="cursor:pointer;margin-left:-436px;width:996px;height:100%">
</div>
</li>
</ul>
I need to access the links written in onclick attribute i.e. mylinkhere.com
I tried
var banners = $($("#carousel")[0]).children().filter("li");
var b_items = $(banners[0]).children().filter("div");
attr_val = $(".b_items")[0].attr("onclick");
But i couldn't. By the way i don't know from the start that which item will be in the carousel because it's randomized by another function. So i cannot access them with item1 item2 ect.
Thanks.
You can set the url in a data attribute and read easily like this:
<ul id="carousel">
<li id="item1">
<div data-url="mylinkhere.com" onclick="window.open($(this).data('url'),'_blank')" style="cursor:pointer;margin-left:-436px;width:996px;height:100%">
</div>
</li>
<li id="item2">
<div data-url="myotherlinkhere.com" onclick="window.open($(this).data('url'),'_blank')" style="cursor:pointer;margin-left:-436px;width:996px;height:100%">
</div>
</li>
</ul>
To read:
var b_items = $(banners[0]).children().filter("div");
var link = $(b_items).data('url');
See this fiddle:
http://jsfiddle.net/Pontual/pugytfwu/
For me, the following code works as expected (Chrome 44, jQuery 2.1.3):
var s = jQuery('#carousel li div');
s.each(function(i,node) {
alert(jQuery(node).attr('onclick'));
});
http://jsfiddle.net/aavf1450/
Possible problem is that in your code, you do not wrap the element into $(...), so .attr() is not a valid function, as using indexers on a jQuery object returns raw HTML elements.
I have multiple divs (class="profile") wich are hidden by default. Each div is only shown when targeted. I want all divs with class="employeeul" to be hidden when one of the profile divs is targeted. I don't get this working with css, does anyone know why? A JS solution is good as well. (I think I can't use something like onclick, because the divs must hide when the anchors are accessed from other sites.)
This is my code (I removed the divs content):
<div class="narrow_content">
<div class="profile" id="m_empfang0"></div>
<div class="profile" id="m_empfang1"></div>
<div class="profile" id="m_mitarbeiter0"></div>
<div class="profile" id="m_mitarbeiter1"></div>
<div class="profile" id="m_mitarbeiter2"></div>
<div class="profile" id="m_mitarbeiter3"></div>
<div class="profile" id="m_mieter0"></div>
<div class="profile" id="m_mieter1"></div>
<div class="profile" id="m_mieter2"></div>
<div class="employeeul">
<ul> <!-- Empfang -->
<li class="employee"></li>
<li class="employee"></li>
</ul>
</div>
<div class="employeeul">
<ul> <!-- Mitarbeiter -->
<li class="employee"></li>
<li class="employee"></li>
<li class="employee"></li>
<li class="employee"></li>
</ul>
</div>
<div class="employeeul">
<ul> <!-- Mieter -->
<li class="employee"></li>
<li class="employee"></li>
<li class="employee"></li>
</ul>
</div>
</div>
It seems like you just need the syntax for displaying/hiding items dynamically when the page has a specific url. In that case, here is a simple JS solution:
//get an array of elements with the class we're interested in working with
var employeeuls = document.getElementsByClassName("employeeul");
//get the current url
var url = window.location.href;
//if the current url is equal to example.php#profile, hide some elements
if(url == "example.php#profile")
{
//iterate over the array and apply the style to hide the elements
for(i=0; i < employeeuls.length; i++)
{
employeeuls[i].style.display = "none";
}
}
//otherwise, the elements should be hidden
else
{
//iterate over the array and apply the style to hide the elements
for(i=0; i < employeeuls.length; i++)
{
employeeuls[i].style.display = "block";
}
}
NOTE: "block" is the default display property for unordered lists.
I understand you're not using jQuery, but I'm going to include the jQuery equivalent for anyone viewing this post in the future:
//variable assigned to all elements with class "employeeul"
var employeeuls = $(".employeeul");
//get the current url
var url = $(location).attr("href");
//apply the style change
if(url == example.php#profile)
{
employeeuls.hide();
}
else employeeuls.show();
If by targeting, you mean the hash value in the URL, you just need to write some JS to grab that hash value and toggle the css. Then toggle show/hide (or a visibility class via jQuery).
$(document).ready(function(){
var $profiles = $('.profile'); // Store all the profiles in a query
var hashTarget = location.hash.replace('#', ''); // Returns hash value
function showTargetedDiv(){
$profiles.hide(); // Hide any divs that may previously be showing
$('#' + hashTarget).show();
}
showTargetedDiv();
$(window).on('hashchange', showTargetedDiv); // Event handler
});
I have a li element parented to a div with id holder. I need to clone the li multiple times, have all the clones parented to the holder div and change their data-ids. My hierarchy looks like this:
<div id="holder">
<li data-id=0 class="element">
//other nodes
</li>
</div>
How can I clone the li element and than change it's data-id so I get:
<div id="holder">
<li data-id=0 class="element">
//other nodes
</li>
<li data-id=1 class="element">
//other nodes
</li>
<li data-id=2 class="element">
//other nodes
</li>
<li data-id=3 class="element">
//other nodes
</li>
<li data-id=4 class="element">
//other nodes
</li>
<li data-id=5 class="element">
//other nodes
</li>
</div>
-- David
Just use clone and attr:
var holder, li, clone, counter;
holder = $("#holder");
li = holder.find("li:first");
counter;
for (counter = 1; counter <= 5; ++counter) {
clone = li.clone();
clone.attr("data-id", counter);
clone.appendTo(holder);
}
Here's a quick and dirty solution:
http://jsfiddle.net/Epzt9/7/
Also - and I'm surprised no-one else has mentioned this - your containing element for the list items should be a <ul>, not a <div> - <li> tags don't stand on their own, they should belong to a list.
Something along these lines should work:
var clone = $("#holder > li").last().clone();
clone.data("id", parseInt(clone.data("id"), 10) + 1);
$("#holder").append(clone);
It gets a reference to the last li child of #holder and clones that. It then adds 1 to the current value of the data-id attribute, and appends the clone back into #holder.
However, this won't actually change the value of the attribute on the element (if you inspected the DOM, clones would appear to have the same data-id value as the element from which they came). The new value is associated with the element, which is fine if you are using the jQuery data method to obtain this value later. If not, you would need to use attr instead of data to set the value.