Method to select matching data elements using jQuery - javascript

I'm new to jQuery and have a question that goes beyond my knowledge. I have a link with a unique data-number and a div with a matching data-number. The goal is to hide all divs and when each link is clicked by the user the div would be displayed with the matching data-number.
The part that's difficult for me to figure out is how to iterate through all of the links and divs matching them up so when each link is clicked ONLY the matching div with the same data-number will be displayed.
Here is what I have so far in Coffeescript:
$('#task-item').on('click', (event) ->
n = $(#).data('number')
if (n > 0)
event.preventDefault()
$('#task-info').fadeToggle(600)
)
Sample html link:
<li id="task-item" data-number="3">
<span class="label label-purple"> Task</span>
<i class="icon-angle-right"></i>
<span class="label label-success">Open</span>
NEW SAVE METHOD FOR TASKS
..... additional HTML....
</li>
Sample div html:
<div id="task-info" data-number="3" class="span8">
..... #MORE HTML HERE ....
</div>
If there is a better way to accomplish this I'm open to any suggestions.

Firstly, I assume the li and div in your example are repeated multiple times, so you should be using a class to identify them. Secondly, you can use filter to find the element by the required data attribute. Try this:
$('.task-item').on('click', (event) ->
var $item = $(this);
$('.task-info').filter(function() {
return $(this).data('number') == $item.data('number');
}).fadeToggle(600);

Look into jQuery attribute selectors
http://api.jquery.com/attribute-equals-selector/
You should be able to select the div you want like this:
$("div[data-value='3']")

First thing I would recommend is change the li ids to class like <li class="task-item">
Then
<div class="task-info" data-number="3" class="span8">
JS
$(".task-item").click(function(e){
var itemNumber=$(this).data('number');
$('.task-info').filter(function() {
return $(this).data('number') == itemNumber
}).fadeToggle(600);
});

Related

How to use CSS selector not to exclude span text

I'm having some problems figuring out how to use the :not selector correctly.
I have a menu which contains menuitems, where one menu-item has an "is-selected"class to show the user what the current page is that he is visiting.
I would like to retrieve the text of this item, without the badge.
Div Structure
<div class="a-TreeView-content is-selected is-current--top">
<a class="a-TreeView-label">
Orderinvoer
<span class="cb-Menu-badge">25</span>
</a>
</div>
And the following code:
var activeMenuItem = $('div.a-TreeView-content.is-selected > a').text();
Which returns something like: "Orderinvoer25"
I've tried the following to retrieve only the text 'Orderinvoer' but I don't really know what I'm doing wrong:
$('div.a-TreeView-content.is-selected > a span:not(".cb-Menu-badge")').text()
$('div.a-TreeView-content.is-selected > a :not(span)').text()
$('div.a-TreeView-content.is-selected > a:not(".cb-Menu-badge")').text()
$('div.a-TreeView-content.is-selected :not(".cb-Menu-badge")').text()
You can use replace() to remove the .cb-Menu-badge text and trim() to remove extra space.
Stack Snippet
var activeMenuItem = $('div.a-TreeView-content.is-selected > a').text().replace($('.cb-Menu-badge').text(), '').trim();
console.log(activeMenuItem);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a-TreeView-content is-selected is-current--top">
<a class="a-TreeView-label">
Orderinvoer
<span class="cb-Menu-badge">25</span>
</a>
</div>
Try this
$('div.a-TreeView-content.is-selected > a')
.clone()
.children()
.remove()
.end()
.text();
FIDDLE HERE
.clone() clones the selected element.
.children() selects the children from the cloned element
.remove() removes the previously selected children
.end() selects the selected element again
.text() gets the text from the element without children
Pick the first text node in .is-selected a.
$(".is-selected a").contents().get(0).nodeValue
var selected = $(".is-selected a").contents().get(0).nodeValue;
console.log(selected);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a-TreeView-content is-selected is-current--top">
<a class="a-TreeView-label">
Orderinvoer
<span class="cb-Menu-badge">25</span>
</a>
</div>
By using :not() selector, you are trying to select an anchor tag which is not a span type or not having cb-Menu-badge class. So, it always select the anchor tag and gives you the text it has inside. You can be leaving the span inside the anchor tag by selecting its first content alone as follows. Read more about contents()
$($('div.a-TreeView-content.is-selected > a').contents()[0]).text();
The above link has lot more examples which will help you if you have your text inside like 'text1<span>text2'

How do I move these elements in DOM

I don't want to change HTML because I want to leave the display the way it is for default view and want to move them in second view. I want to know how I can dynamically order the class of a div.
I want to do this via button click. I have adEventListener() for 'click' where I am doing something and the move logic would go inside this event listener.
I understand that I can get these divs, remove from their parents and place it where I want. But I do not know how to do these for each of them since I have multiple lis. I am struggling with the loop so that I can do these for each li. I need to do this using pure JS and not jQuery.
<ul>
<li>
<div>
<div class="a">
<div class="b">
<a class="c">
<div class="d"></div>
<div class="e">
<div class="f"></div> // this is the first item that I want to move
</div>
<div class="g"></div> // this is the second item that I want to move
</a>
</div>
<div class= "h"></div> // I want above mentioned divs to be before this div
</div>
</div>
</li>
//There are multiples lis
<li></li>
Assuming you would like to do this on load of the page, you could solve your problem with the following JQuery DOM manipulations:
$(document).ready(function(){
$("ul .a").each(function(index, element){
$current_div_a = $(element);
$div_h = $current_div_a.find(".h");
$div_f = $current_div_a.find(".f");
$div_f.clone().insertBefore($div_h);
$div_f.remove();
$div_g = $current_div_a.find(".g");
$div_g.clone().insertBefore($div_h);
$div_g.remove();
})
});
You can test it out on this demo.
I strongly advise against this way of doing it though. I guess it's also the reason why your question got some downvotes too. Just modifying your HTML keeps your code clean, maintainable and clearer for anyone else starting to work on your project. Keeping backwards compatibility for your code as much as possible will cause maintainability problems later.
I ended up using
var list = document.querySelectorAll("ul li");
for (var item of list) {
let fClass = item.querySelector(".f");
fClass.parentNode.removeChild(fClass);
let parentOfFirstChildAfterWhichIwantMyF = item.querySelector(//selector for parentOfFirstChildAfterWhichIwantMyF);
parentOfFirstChildAfterWhichIwantMyF.insertAdjacentElement("beforeend", fClass);
}

Getting html data from template generated list - JQuery

I am generating a list from a template engine (Template7) and adding a userID to the data tag in each list item. For example
<li>
<a id='user' data-user-id='5'>
<div>content here</div>
</a>
</li>
<li>
<a id='user' data-user-id='6'>
<div>content here</div>
</a>
</li>
I am trying to get the "user-id" data of the list item clicked on using jQuery, but what I seem to be doing instead is getting the user-id of the first list item - in this case always 5.
$(document).on("touchend", "#user", function(e) {
e.preventDefault();
var userItem = $("#user");
var userID = userItem.data("user-id");
console.log(matchID);
});
Where am I going wrong? A unique ID for each item would work, but then it would need to be parsed etc so there must be a better way! Is there a best practice for this kind of thing?
try replacing #user with this should work in your case
Id selector always selects first element with matching Id. it is advisable not to have multiple element with same id. try to use class name instead.
any ways for your query you can use below code.
$(document).on("touchend", "#user", function(e) {
e.preventDefault();
var userID = $(this).data("user-id");
console.log(userID);
});
Use a css class on each anchor item, like this:
<li>
<a class='user' data-user-id='5'>
<div>content here</div>
</a>
</li>
Id attributes are meant to be unique to that element.
To get the content of the attribute **data-user-id** like in <a id='user' data-user-id='5'> you have to use
$(this).attr("data-user-id") // will return the string "5"
or .data() (if you use newer jQuery >= 1.4.3)
$(this).data("user-id") // will return the number 5

Add class to a particular element when second child of list clicked

I want to add class on particular element which already have class when second child of list item clicked then remove that class if any other list item clicked.
i can add class onclick of link but don't understand how to add condition when other list item clicked rather then 2nd child so i can remove that added class.
<ul class="acf-hl acf-tab-group">
<li>tab1</li>
<li class="active">tab2</li>
<li>tab3</li>
</ul>
<div class="single-item ae0fgf0c hidden-by-tab"></div>
<div class="single-item ae0fgf0b hidden-by-tab"></div>
<h3 class="submit-button">Budget</h3>
<div class="single-item ae0fgf045"></div>
<div class="single-item ae0fgf0e"></div>
<div class="single-item ae0fgf0cf hidden-by-tab"></div>
<div class="single-item ae0fgf0t hidden-by-tab"></div>
Basically its a wordpress custom field plugin so it added ".hidden-by-tab" class when item is clicked to the other items related element and i added a html code h3 before certain class like above
<h3 class="submit-button">Budget</h3>
Now this h3 will showing up on other tab content part i want to make this hide on other tab content, i just want to show this on 2nd list content.
jQuery(document).ready(function($){
$(".acf-field-54f5a4c9a71b0").before('<h3 class="submit-head">BUDGET</h3>');
$(".acf-field-54f5a4c9a7497").before('<h3 class="submit-head">FUNDING</h3>');
});
Above is the jquery code i use to add h3 before particular classes is there any solution to hide this like the related class hide on other tab, if you see above code add ".active" class above i tried to target the by that class but not succesfull.
if($(.acf-tab-group li:nth-child(2)).hasClass('active')){
$(.submit-button).addClass("selected");
}
In jsfiddle it add class but in real code it doesn't. please help me out or let me know if there is need of further explaination.
I guess this is what you want:
$('.acf-hl').on('click', 'li', function () {
if ($(this).index() == 1 && $(this).hasClass('active')) $('h3.submit-button').addClass('active');
else $('.active').removeClass('active');
return false;
});
Demo: https://jsfiddle.net/tusharj/amrq3bf4/4/
Another Demo: https://jsfiddle.net/tusharj/amrq3bf4/5/
I hope this is what you are looking for.
$('.acf-tab-group > li').click(function(){
var flag=$(this).hasClass('active');
if(flag){$('.submit-button').addClass("selected")}
else{$('.submit-button').removeAttr('class').addClass('submit-button')}
})
removeAttr will remove entire class attribute so i have added .submit-button class again.

Use same div to toggle different parts of the page

Hello I have the following code:
Javascript/jQuery:
$(document).ready(function() {
$(".clickMe").click(function() {
$(".textBox").toggle();
});
});
Html code printed with a for loop:
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 2</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 3</div>
I would like to be able:
When the page loads I want the to be hidden and toggle on click.
Using the same ids for <a class="clickMe"> and <div class="textBox"> to be able to toggle or hide the correct/equivalent <div> element.
jsFiddle code:
http://jsfiddle.net/A7Sm4/3/
Thanks
Edit 1: Class instead of Id
Edit 2: Fixed jsfiddle link
id are supposed to be unique
you should use class to do this
[EDIT] updated the jsfiddle to fit Marko Dumic's solution: http://jsfiddle.net/SugvH/
Something like this should do the trick:
$(document).ready(function() {
var divs = [];
$(".textBox").each(function(index) {
divs[index] = this;
});
$(".clickMe").each(function(index) {
$(this).click(function() {
$(divs[index]).toggle();
});
});
});
ID must (as per spec) be unique on the page. You can easily rewrite this to use class attribute:
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 2</div>
...
Initially, you need to either hide div.textBox when DOM becomes ready, or hide it using CSS.
Then you attach click handlers to a.clickMe:
$(function () {
$('a.clickMe').click(function () {
// find first of following DIV siblings
// with class "textBox" and toggle it
$(this).nextAll('div.textBox:first').toggle();
});
});
However, maybe you don't control the markup but desperately need this done, you can keep your markup as it is and still make it work due to the fact that jQuery uses Sizzle framework to query the DOM which can be forced around the limitation of document.getElementById() (which returns only one element).
E.g. suppose you used id instead of class, if you write $('#clickMe'), you'll get the jQuery collection of only one element (jQuery internally used .getElementById() to find the element), but if you write $('#clickMe'), you get the collection of all elements with the id set to "clickMe". This is because jQuery used document.getElementsByTagName('a') to find all anchors and then filtered-out the elements (by iterating and testing every element) whose attribute value is not "clickMe".
In that case (you used your original markup), this code will work:
$(function () {
$('a#clickMe').click(function () {
$(this).nextAll('div#textBox:first').toggle();
});
});
Again, don't do this unless you absolutely need to!
$(document).ready(function() {
$("a").click(function() {
$(this).parent().find("div").toggle();
});
});
Use something similar to this.
Try appending an index to each pair of a/div's ids (clickme1 and textbox1, etc). Then when an a is clicked, read the id, take the index off the end, and show/hide the textbox with the same index.

Categories

Resources