Get content of 2 classes within 1 class - javascript

I have HTML like
<a href="/blabla" class="matchupLink">
<span class="teams"> USA</span>
<span class="teams">Brazil</span>
</a>
I want to get the HTML of the elements with class 'teams' within class 'matchupLink'
I tried
$('.matchupLink').each(function (index, obj) {
var teams = $(this).find('.teams');
console.log(teams.html())
});
But that only returns the first instance of the .teams class within each .matchupLink class. So here it only returns USA and not Brazil.
I want to calculate how many characters both teams class have within each matchupLink class. Because then if characterCount >=20, I want to display ellipses.
What should I be doing?
Thanks

You can combine selectors with the classes
$('.matchupLink .teams')
This will return you an array of objects with the class "teams".
UPDATE
Here's a fiddle that prints to the console the length
$('.matchupLink .teams').each(function(index, item){
var $item = $(item);
var teamNameLength = $item.html().length;
console.log($item.html() + ' length is: ' + $item.html().length);
// if ($item.html().length >= 20){
// ::do logic for ellipses::
// }
});
**note the USA prints out a value of 4 because you have a space before in your example.
UPDATE 2
Fiddle alerting the length of both teams
To get the length of both teams, create a variable outside of the loop and increment it appropriately.
var lengthOfBothTeams = 0;
$('.matchupLink .teams').each(function(index, item){
lengthOfBothTeams += $(item).html().length;
});
alert('Length of both team names is: ' + lengthOfBothTeams);

console.log will work on the first match in the set in your example
you should loop over the teams and not the matches
$('.matchupLink .teams').each(function () {
console.log($(this).html())
});

html() only returns the HTML content of the first matched element in the jQuery object. Use each() to iterate over the element and display their HTML content.
$('.matchupLink .teams').each(function (index, obj) {
console.log($(this).html());
});

Related

Using Jquery to dynamically create Divs with Buttons that have a function to close the div

So I am trying to create new divs of a fruit, but I am added an X to help call a special function that will delete it. My only problems is when I dynamically create my div+span I end up with problems when I try to use the onclick function
Here is my HTML code
<html>
<div id="listContents">
</div>
</html>
Also below is my script code
list = ["apple", "strawberry", "banana"]
for(var i = 0; i < list.length; i++){
$("#listContents").append('<div>' + list[i] + '<span class="picker" id="close" onclick="removeFruit(list[i].toString())"> (X)</span></div>');
}
function removeFruit(fruit){
console.log("Here is the fruit you selected");
}
Obviously I want to be able to delete these when the X button is clicked but right now I am having trouble getting the onclick function to work correctly. Also here is a jsfiddle I quickly made
You are creating an span with id close for each item in your list. Ids should be unique throughout the whole document. Since you are not using the id attribute, I suggest you delete it.
Also, you are appending an onclick event in all your span items. I would use event delegation.
Furthermore, since you are converting the elements in your array into HTML elements, you could use map method to do the transformation and generate all the HTML for your items.
Lastly, you can add a data attribute to account for the item index. You can then read that attribute using jQuery data method.
Having that into account, the code could look like:
var list = ["apple", "strawberry", "banana"];
var $list = $("#listContents");
$list.on('click', '.picker', function(ev) {
var idx = $(ev.target).data('idx');
removeFruit(list[idx]);
});
$list.append(list.map(function(item, idx) {
return '<div>' + item + '<span class="picker" data-idx="' + idx + '"> (X)</span></div>';
}).join(''));
function removeFruit(fruit) {
console.log("Here is the fruit you selected");
}
Similar to what others are saying, id should be reserved for only one-time use.
Also, when you are dynamically creating the items you give each onClick the string "removeFruit(list[i].toString())" so it is not actually looking for a function called removeFruit but instead it has the actual string "removeFruit".
When creating the html you could instead give each item a fruitName attribute equal to the fruit name like so.
list = ["apple", "strawberry", "banana"]
for (var i = 0; i < list.length; i++) {
$("#listContents").append('<div>' + list[i] + '<span class="picker" fruitName='+ list[i] + '>(X)</span></div>');
}
and then we can target these using a click listener rather than an onClick and use what fruitName is equal to by using the $(this).attr('fruitName').
$("#listContents").on('click', '.picker', function(e) {
removeFruit($(this).attr('fruitName'))
})
function removeFruit(fruit) {
console.log('You clicked ' + fruit);
}
$(this) will reffer to whichever span you clicked on and the .attr() will look for the fruitName and find what it is equal to.
you could add the id while you are doing the map.
["apple", "strawberry", "banana"].map(x => {
$("#listContents").append(`<div id="${x}">
${x}
<span
class="picker"
onclick="(() => document.getElementById('${x}').remove())()">
(X)
</span>
</div>`)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="listContents">

Sorting divs based on array order

I have a drag and drop design that, when you rearrange the draggable items, pushes their ids to an array. So i’ll have an array like:
["#fake-block_1","#fake-block_3","#fake-block_2"]
Behind the scenes, I want to rearrange some corresponding divs that share the same numeric value as these blocks, e.g., #fake-block_1 maps on to #real-block_1. I can’t quite seem to grasp how I would get this rearrangement to happen. Heres what I currently have:
$('.js-fake-block’).each(function(i){
$this = $(this);
$array = new Array();
$delimiter = '_';
$array.push($this.attr("id").split($delimiter)[1]);
$array.forEach(function(item,index){
$realBlockId = "#real-block_”+[item];
});
});
So I loop through every “fake block”, split their ID by an underscore (I match fake and real with the same numeric value), add them into an array, and then have the real Ids made up again… but after that I’m lost. No idea how I’d sort the “real blocks” based on this "fake blocks" arrays order.
Here is a simple example of what you're trying to do JSFiddle
function sortDom(selectorArray) {
while (selectorArray.length) {
let $el = $(selectorArray.pop());
$el.parent().prepend($el);
}
}
//Usage//
$('.ordinal').on('click', function() {
sortDom(['#_01', '#_02', '#_03', '#_04', '#_05', '#_06', '#_07', '#_08', '#_09', '#_10']);
});
$('.reversed').on('click', function() {
sortDom(['#_10', '#_09', '#_08', '#_07', '#_06', '#_05', '#_04', '#_03', '#_02', '#_01']);
});
$('.jumbled').on('click', function() {
sortDom(['#_07', '#_01', '#_10', '#_04', '#_02', '#_03', '#_06', '#_05', '#_09', '#_08']);
});
Note this method does not enforce the array elements reference dom elements attached to the same parent and it does not enforce that all child elements of the parent must be referenced in the array. Unreferenced child elements will be pushed to the bottom of the list.
One solution is to use the sort method to describe how to the sort elements and then re-set the html of the parent:
var sortedDivs = $divs.sort(function (a, b) {
// If referring to your array of IDs, you can use indexOf($(a).attr("id"))
return $(a).attr("id") > $(b).attr("id");
});
$("#container").html(sortedDivs);
JsFiddle
I don't know why you need to save numbers in array and loop again to create a new array .. you can just use the next code
$array = []; // use array outside the loop
$('.js-fake-block').each(function(i){
var $this = $(this);
var $delimiter = '_';
var SplitNum = $this.attr("id").split($delimiter);
$array.push("#real-block_" + SplitNum[1]);
});
console.log($array);
Working example
$array = []; // use array outside the loop
$('.js-fake-block').each(function(i){
var $this = $(this);
var $delimiter = '_';
var SplitNum = $this.attr("id").split($delimiter);
$array.push("#real-block_" + SplitNum[1]);
});
console.log($array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="js-fake-block" id="fake-block_1"></div>
<div class="js-fake-block" id="fake-block_3"></div>
<div class="js-fake-block" id="fake-block_5"></div>
<div class="js-fake-block" id="fake-block_4"></div>
<div class="js-fake-block" id="fake-block_2"></div>

Making part of an Id name into a variable

I have a bunch of divs with matching ids (#idA_1 and #idB_1, #idA_2 and #idB_2, etc). In jquery I wanted to assign click functions, so that when I click an #idA it will show and hide an #idB.
Basically I want to make this:
$(".idA_x").click(function(){
$("idB_x").toggleClass("hide")
});
X would be a variable to make #idA and #idB match. I could write each individually, but that would take too much code, is there a way to make the number in the id into a variable?
Sure, you can do:
var num = 13;
addButtonListener(num);
function addButtonListener(num){
$("#idA_"+num).click(function(){
$("#idB_"+num).toggleClass("hide")
});
}
Try JQuery solution :
var x = 1;
$(".idA_" + x ).click(function(){
$(".idB_" + x ).toggleClass("hide")
});
Hope this helps.
There are many ways to achieve that, but what you probably want is to create a shared CSS class, e.g. .ids, and bind the event listener to that one:
$('.ids').click(function () {
//...
});
Then you can handle your logic in a cleaner way within the function body.
In order to make it dynamic, and not have to repeat the code for each one of your numbers, I suggest doing as follows:
First, add a class to all the div's you want to be clickable .clickable, and then use the id of the clicked event, replacing A with B in order to select the element you what to toggle the class:
$(".clickable").click(function(){
var id = $(this).attr('id');
$("#" + id.replace('A', 'B')).toggleClass("hide");
});
Or, you can also select all divs and use the contains wildcard:
$("div[id*='idA_']").click(function(){
var id = $(this).attr('id');
$("#" + id.replace('A', 'B')).toggleClass("hide");
});
This solution won't have the need to add a class to all clickable divs.
You can use attribute selector begins with to target the id's you want that have corresponding elements.
https://api.jquery.com/attribute-starts-with-selector/
Then get the value after the understore using split on the id and applying Array.pop() to remove the 1st part of the array.
http://jsfiddle.net/up9h0903/
$("[id^='idA_']").click(function () {
var num = this.id.split("_").pop();
$("#idB_" + num).toggleClass("hide")
});
Using regex would be your other option to strip the number from the id.
http://jsfiddle.net/up9h0903/1/
$("[id^='idA_']").click(function () {
var num = this.id.match(/\d+/g);
$("#idB_" + num).toggleClass("hide")
});

Checkboxes that display results with jQuery

I am trying to have the user check the boxes they are interested in getting resources for and then click the button to get a list of those resources that are hyperlinked to those resources. The hyperlinks (ul id="results” in HTML) are hidden until they called upon by the button “Get Resources”.
Plus I would like to add text to it before results saying “You have indicated an interest in:” (line break) then a listing the hyperlinks (line break) “Please click on the links to learn more”. If no check box is selected the div id=“alert” displays, which I got to work.
I think I am very close, I just can’t seem to get the list of resources.
Here is a link to my coding:
JSFiddle Code sample
$(document).ready(function() {
$('#alert').hide();
$('#results > li').hide();
/* Get the checkboxes values based on the parent div id */
$("#resourcesButton").click(function() {
getValue();
});
});
function getValue(){
var chkArray = [];
/* look for all checkboxes that have a parent id called 'checkboxlist' attached to it and check if it was checked */
$("#checkBoxes input:checked").each(function() {
chkArray.push($(this).val());
});
/* we join the array separated by the comma */
var selected;
selected = chkArray.join(',') + ",";
/* check if there is selected checkboxes, by default the length is 1 as it contains one single comma */
if(selected.length > 1){
// Would like it to say something before and after what is displayed
$('#results > li.' + $(this).attr('value')).show();
} else {
$('#alert').show();
}
}
I'd ditch the selected variable and just check the chkArray contents against the list item classes like:
function getValue() {
var chkArray = [];
/* look for all checkboxes that have a parent id called 'checkboxlist' attached to it and check if it was checked */
$("#checkBoxes input:checked").each(function () {
chkArray.push($(this).val());
});
$('#results li').each(function () {
if ($.inArray($(this).attr('class'), chkArray) > -1) $(this).show()
else($(this).hide())
})
/* check if there is selected checkboxes, by default the length is 1 as it contains one single comma */
if (!chkArray.length) {
$('#alert').show();
//alert("Please at least one of the checkbox");
}
}
jsFiddle example
I found a straightforward way of achieving what you want. DEMO: https://jsfiddle.net/erkaner/oagc50gy/8/
Here is my approach: I looped through all checkboxes. This way I could get the index of the current item in the original list, i, and use this index to display the corresponding item in the second list. I filter the checked items by using .is(':checked') condition, and then added them item to the array:
function getValue() {
var chkArray = [];
$("#checkBoxes input").each(function (i) {//now we can get the original index anytime
if($(this).is(':checked')){//is the item checked?
chkArray.push($(this).val());//if so add it to the array
var selected;
selected = chkArray.join(", ");
if (selected.length) {
$('#results').find('li').eq(i).show();//show the corresponding link by using `i`
} else {
$('#alert').show();
}
}
});
}
Last thing in your $(document).ready function, add:
$("#checkBoxes input:checkbox").click(function() {
$('li.' + $(this).val().replace(/ /g, '.')).show()
});
JSFiddle
Explanation:
On document ready, add a click handler to the checkboxes that shows the corresponding hidden list item below. The tricky thing here is the spaces in the list names. This makes each word a separate classname, so simply combine the list names with a dot . which results in a sequential classname call in jQuery.
By using <li class="Fitness & Recreation"> as a list item classname, you are giving this item 3 classnames: Fitness, &, and Recreation. In jQuery you select elements with multiple classnames by including each name preceded by a dot .. For example, selecting a list item element with the classnames foo, bar, and baz:
$('li.foo.bar.baz').show()
In the case of <li class="Fitness & Recreation">:
$('li.Fitness.&.Recreation').show()
Since these values are stored in the value attribute of the checkboxes we use jQuery to pull these values: $(this).val(), replace the spaces with dots: .replace(/ /g, '.'), and concatenate the result to the li. portion to access the appropriate list item.

jQuery each array index append to div

I'm trying to append the values of array I've made into another div but when I append the array value its appending all the values of the array not just the one I've added(by click), any suggestions would be great, thanks in advance!
HTML
<div id="products">
<ul>
<li><p>Lorem 1</p><button class="target">Add</button></li>
<li><p>Lorem 2</p><button class="target">Add</button></li>
</ul>
</div>
<div id="cart">
<ul>
</ul>
</div>
jQuery
$(document).ready(function(){
var array = Array();
$(".target").click(function() {
array.push($(this).siblings('p').text());
$.each(array, function(index, value) {
$("#cart ul").append("<li>"+value+"</li>");
});
});
});
When I click Add on say the first button its displays
Lorem 1
but when I then click the add on the second button it displays
Lorem 1
Lorem 1
Lorem 2
You are adding the items to the array, which makes sense if you want to keep a list of added items, but then you are looping through the array when adding items to the list, which will make it add all items to the items already existing there.
You can just add the last item:
array.push($(this).siblings('p').text());
$("#cart ul").append("<li>" + array[array.length - 1] + "</li>");
or you can clear the list before adding the items:
array.push($(this).siblings('p').text());
$("#cart ul").empty();
$.each(array, function(index, value) {
$("#cart ul").append("<li>" + value + "</li>");
});
Because you loop on each element of the array, so you get all your elements.
Try without the $.each in your click function, it will be better.
If you want to only add one value when the selector $(".target") is clicked, you should do something like
// assuming you want the last value in the array.
var value = array[array.length-1]; // could also do $(this).siblings('p').text()
$("#cart ul").append("<li>"+value+"</li>");
It seems like you might not even need your array, (unless it is being used by some other functions as well).
LIVE DEMO
$(function(){
var array = [];
$(".target").click(function() {
array.push( $(this).siblings('p').text() );
$("#cart ul").append("<li>"+ array[array.length -1] +"</li>");
});
});

Categories