style multiple elements at the same time - javascript

i created four drop down select lists in html and dynamically load them from an ajax object. i made it so you could select an item in the select list and an onchange event that ran a javascript function that would get the items respective data and display in a table underneath the select list. there are four of these on the page and so that a person could select four different items and then compare their characteristics. THat all works like a charm, however im using a :hover in css to try and highlight the characteristics of the four products that match the one being hovered upon ie: if you hover over one product name it highlights all the product names. heres the code
function displayStrainInfo(event){
var eventTrigger = event.currentTarget;
Inspection::Ptr inspectionModelvar testOption = document.getElementById(eventTrigger.id);
var selectedIndex = testOption.options[testOption.selectedIndex].index;
//alert(flowerPeriod[0].firstChild.data);
//alert(eventTrigger.id.substr(6,5));
document.getElementById(eventTrigger.id.substr(6,5)).innerHTML = "<table class='strainInfoTable'><tr class='infoRow'><td id='strain_Name'>Strain Name: " + products[selectedIndex - 1].firstChild.data + "</td><td>Strain Genetics: " + genetics[selectedIndex - 1].firstChild.data + "</td></tr><tr><td class='infoRow' colspan='2'>Indica:" + raceIndica[selectedIndex - 1].firstChild.data + "&nbsp&nbsp&nbsp&nbsp&nbspSativa: " + raceSativa[selectedIndex - 1].firstChild.data + "&nbsp&nbsp&nbsp&nbsp&nbspRuderalis: " + raceRuderalis[selectedIndex - 1].firstChild.data + "</td></tr><tr><td class='infoRow'>Height: " + height[selectedIndex - 1].firstChild.data + "</td></tr><tr><td class='infoRow'>Flower Period: " + flowerPeriod[selectedIndex - 1].firstChild.data + "</td></tr><tr><td class='infoRow' id='botom'>Potency: " + potency[selectedIndex - 1].firstChild.data + "</td></tr></table>";
}
the above code is the function that creates the table that displays the choosen products information.
#strain_Name:hover{
padding-top: 20px;
padding-left: 20px;
color: blue;
font-size: 1.25em;
}
above here is the hover css for testing the effect on the name element.
it highlights just fine but it only highlights the element hovered over even though all the tables have the same .class and #id to match. just a newbie so any help would be greatly appreciated.

...even though all the tables have the same .class and #id to match
It sounds like you have duplicate IDs. IDs must be unique.
You can use the class attribute and define a class selector in CSS to match multiple elements and/or use a more elaborate CSS selector.
Simple Example of Using a Class Selector
<div class="foo">1</div>
<div class="foo">2</div>
<div class="foo">3</div>
<div class="foo">4</div>
.foo:hover { background-color: red; }
Example of Using jQuery + Class Selectors
Full working example: http://jsfiddle.net/mSWcw/
$(".parent").hover(
// fired on entry
function(){
var matchingChildren = $(".foo", this); // select all children with the class "foo" within the parent object
matchingChildren.addClass("hovered");
},
// fired on exit
function(){
var matchingChildren = $(".foo", this);
matchingChildren.removeClass("hovered");
}
);​

Related

What is the best method of changing the color of an SVG element by modifying the CSS code in a way that changes the Javascript code?

I've been writing a codepen for the game Simon and I was asked to rewrite it so that if somebody like an artist that was working with me had access to the html and css but didn't know how javascript worked (or didn't have access to the .js files) wanted to change the colors of the buttons they could do so w/o changing the javascript code. So my plan is to write the js code such that it adds/removes classes that affect the path elements. The path elements are like this:
<path class="outer arc1default" id="arc1"/>
with these css classes:
.outer {
stroke: black;
stroke-width: 10;
}
.arc1default {
fill: red;
}
if the color changes on click by design, this class gets added:
.arc1flash {
fill: pink;
}
On line 73 of the .js code I'm using the following:
function buttonFlash(button) {
console.log("button is: " + button);
//$("#" + button).attr("class", button + "flash outer");
//$("#" + button).removeClass(button + "default");
$("#" + button).addClass(button + "flash");
//$("#" + button).css({ fill: buttonDict[button].flash });
buttonDict[button].sound.play();
setTimeout(function() {
$("#" + button).attr("class", button + "default outer");
//$("#" + button).css({ fill: buttonDict[button].color });
buttonDict[button].sound.pause();
buttonDict[button].sound.currentTime = 0;
}, 300);
}
The code in // notation is what I was trying before and wasn't working at the time but I've left it in for reference in case I missed something and used it incorrectly but was on the right path.
Anyway, here's the results I've observed:
If I start the element w/ fill:red using the id in CSS, it starts red and stays red when classes get added/removed.
If I remove that part of the code but start the path element w/ a class that says fill:red then it starts red again (which is good) but when classes get removed/added nothing changes.
If I remove the fill:red from the element and do NOT add the class in question, it starts as if it has fill:black, probably because the outer class does a stroke: black for the border.
Here's the link to my codepen in case that helps: https://codepen.io/glennqhurd/pen/EQqxKe
To reiterate, I'm not asking about how to use Javascript to change the CSS. I'm asking how to use Javascript to change the classes of the HTML objects in such a way to change the properties of the objects w/o changing the classes themselves.
You have to use .attr() on a svg... Since .addClass() and .removeClass does not work. See this other answer about it.
Now you have to use the same class "name structure" on the 4 colors (like arc1default and arc1flash) if you want to concatenate default/flash to the button.
I updated your CodePen
function buttonFlash(button) {
console.log("button is: " + button);
$("#" + button).attr("class", "outer " + button + "flash");
buttonDict[button].sound.play();
setTimeout(function() {
$("#" + button).attr("class", "outer " + button + "default");
buttonDict[button].sound.pause();
buttonDict[button].sound.currentTime = 0;
}, 300);
}

jQuery .text() including button's text

I am using select2 for one of my dropdownlists and I have a jquery event listener for when a selection is made. Basically, once a selection is made, that selection is then populated into an ul element. The text part of the li element in the ul will have a button for removing that option from the ul. If that option is removed from the ul then it is populated back into my select list.
Here is my jQuery for adding selected options to the ul:
$("#My-DDL").on("select2:select",
function (evt) {
console.log(evt.params);
$("#My-UL-Element").append("<li class='list-group-item list-group-item-info text-dark' data-id='" +
evt.params.data.id +
"' ><small>" +
evt.params.data.text +
"</small> <button type='button' class='close remove-button'>×</button></li>");
$("#My-DDL option[value='" + evt.params.data.id + "']").remove();
$("#My-DDL").val("").change();
});
Here is my jQuery for when an option is removed from the ul element and populated back into My-DDL:
function removeCapability() {
$("#My-UL-Element").on("click",
".remove-button",
function () {
console.log($(this).parent().text());
console.log($(this).parent().data("id"));
var elementId = $(this).parent().data("id");
$("#My-DDL").append(new Option($(this).parent()
.text(),
elementId)); // add item back to dropdownlist
/* sort the dropdownlist options back to the original way */
var selectList = $("#My-DDL option");
selectList.sort(function (a, b) {
a = a.value;
b = b.value;
return a - b;
});
$("#My-DDL").html(selectList);
/* End of Sort */
$(this).parent().remove(); // remove item from ul element
});
}
Now, my problem deals with the second part of when an item is removed from the ul and populated back into the select. When an item is removed.. the $(this).parent().text() includes the × from the button.. which I can understand because it is the text of the that element, but how do I ignore the button text?
UPDATE
The question above can be answered by focusing on the text inside the small element. Let me rephrase with a different scenario.. how would I accomplish this if the text didn't have a small element?
$("#My-DDL").on("select2:select",
function (evt) {
console.log(evt.params);
$("#My-UL-Element").append("<li class='list-group-item list-group-item-info text-dark' data-id='" +
evt.params.data.id +
"' >" +
evt.params.data.text +
" <button type='button' class='close remove-button'>×</button></li>");
$("#My-DDL option[value='" + evt.params.data.id + "']").remove();
$("#My-DDL").val("").change();
});
Since you are removing the LI from the list in that case anyway, you could remove the button from the LI first, and then get the LI text content ...
But preferably, you would rather store the info you need in a custom data attribute or using https://api.jquery.com/data/, so that you can retrieve it again from there - so that the “pollution” of the text value by additional buttons etc. doesn’t matter any more.
That way you separate the actual data more from the presentation. Whatever else you might apply/add to that text shown in the LI at a later point won’t affect your script in that regard any more.
A quick vanilla JS function to get the text nodes within a parent, and concatenate them into one string:
function getText(el) {
return Array.from(el.childNodes).filter(e =>
e.nodeType == 3 // text node
).map(e =>
e.nodeValue
).join(" ");
}
console.log(getText(document.getElementById("demo")));
<div id='demo'>
Part 1
<button>Button!</button>
Part 2
</div>

How can I access the attributes of an element cloned via jquery within a javascript function?

I need to permit my users to dynamically create new categories and then branches and sub-branches within categories. To facilitate this I've built an html table that contains multiple nested tables. Each nested table is surrounded by its own div. The base category displays on the left and branches and sub-branches grow out to the right.
To allow the user to create the branches I call jquery clone() within a javascript function. Like this:
function elementCopy(targetTable, targetDiv)
{
var clone = $('.' + targetTable).clone(true).appendTo($("." + targetDiv));
}
This creates the requested clone and places it in the correct table. But I have not discovered how to access the clone's attributes to edit them.
In a previous iteration of this functionality, I called jquery clone() from within document.ready().
$('button[name="newTasks"]').click(function()
{
//Create the cloned block and keep the event listener so the newly displayed plus icon
// also creates a new block.
var clone = $(".tasksTable").eq(0).clone(true).appendTo(".tasksDiv");
//
clone.find( ".tasksTable" ).attr('name', 'Tasks' + '_' + countTaskBlocks);
});
I abandoned this iteration because I was unable to send parameters to the document.ready() version. Without the parameters, I could not position the clone within its proper table and sub-table. However, this version DID allow me to edit the clone's attributes.
This line edits all of the elements with the same class name:
$('.' + targetTable).attr('class', 'tasksTable' + '_' + countTaskBlocks);
How can I edit the 'name', 'id', and 'class' attributes of the specific clone created in the call to 'elementCopy' function?
JQuery methods are chainable, so you can do something like this.
function elementCopy( targetTable, targetDiv ) {
var clone = $( '.' + targetTable )
.clone( true )
.appendTo( $( "." + targetDiv ) )
.attr( {
'name': 'Tasks' + '_' + countTaskBlocks,
'id': 'Tasks' + '_' + countTaskBlocks,
'class': 'Tasks' + '_' + countTaskBlocks
} );
return clone;
}
Check out the demo below.
$('a').clone( true ).appendTo( $('body') ).attr( { 'class': 'Goodbye', 'href': 'http://www.example.com' } );
a::before { margin-right: .5em; content: attr(href); } a::after { margin-left: .5em; content: attr(class); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="hello" href="#">Link</a>
Search the children of the DIV you appended the clone to by the class name of the element you cloned.

associate number field with hidden div

I have a set of number input fields, labeled small & medium.., and a set of div's with the label small and medium. In my actually project there will be more sizes than just small and medium. When you add a number to the small number input field a text input insertsAfter the div labeled small. When you subtract a number from the small number input field, the text input field that was recently added is removed.
If the small number field is 0, I want
<div class="name-number-field-container" data-size="Small">
to be hidden, if the small number field is greater than 0 I want the
<div class="name-number-field-container" data-size="Small">
to show. Same goes for medium.
http://jsfiddle.net/7PhJZ/63/
the hidden and shown is correct, but they are not associated to their proper size and product. all class="name-number-field-container" show
i tried this:
$('.product-quantity').on('change', function(){
var select = $(".name-number-field-container").closest('[id^="product"]').find('[data-size="' + this.name + '"]')
if($(this).val()>=1){
$(select).show();
} else {
$(select).hide();
}
});
Is this what you meant?
http://jsfiddle.net/9kXLC/4/
Replace your show/hide code with this:
$('.product-quantity').on('change', function () {
var select = ".name-number-field-container[data-size=" + $(this).attr('name') + ']'
if ($(this).val() >= 1) {
$(this).parents('div[id^=product-]').find(select).show();
} else {
$(this).parents('div[id^=product-]').find(select).hide();
}
});
http://jsfiddle.net/fenderistic/Q4bFB/
Basically you have a custom name for each product-quantity that correlates to a specific name-number-field-container's data-size. I had to add the data-output-id attribute to distinguish between the different divs. So you use that information to hide or show the correlating divs.
$('.product-quantity').on('change', function () {
if ($(this).val() >= 1) {
$(".name-number-field-container[data-size='" + $(this).attr("name") + "'][data-output-id='" + $(this).attr("data-product-id") + "']").show();
} else {
$(".name-number-field-container[data-size='" + $(this).attr("name") + "'][data-output-id='" + $(this).attr("data-product-id") + "']").hide();
}
});
I just added a class to your fiddle that explicitly set the width for the .name-field input class like this: .name-field {width:50px;} and got the results you were looking for.

Javascript mouse over on dynamic amount of elements

My goal is on hover a p element contained inside an a tag gets bigger on hover. I have achieved this via css3 transitions, however this is not the issue.
A loop creates a variable amount of elements in the form below on each iteration.
anchorElement = "<a id='anchor" + countWide + "' class=\"boxOPT oneplustwo\" alt=\'"+ image_website +"' style=\"cursor:pointer;width:"+ itemWidth + "px"+";height:"+anchorHeight+";position:absolute;left:"+ locationLeft + "px"+";top:0.3%;\" ><p id=\"test\" class=\"popupDynamic\"> " + popupImageTitles[i] + "</p>";
anchorElement += '</a>';
I would love to be able to add a mouse in/out effect whenever the user scrolls on the relevant anchor. each p tag contains unique information that needs to be conveyed and on hover only the relevant one should react.
I dont want to it it the below way, making two each of the methods every time a new element is created above. is there a way to have the following below which will work for a dynamic amount of elements?
$("#anchor" + etc).mouseover(function() {
document.getElementById("test").style.height="1.1em";
});
$("#anchor" + etc).mouseout(function() {
document.getElementById("test").style.height="1.1em";
});
My version of suggestions. the console logs works.
.popupHighlight {
color: red;
}
..
$('.boxOPToneplustwo').mouseover(function (e) {
console.log("in");
$(e.target).next('p').addClass("popupHighlight");
});
$('.boxOPToneplustwo').mouseout(function (e) {
$(e.target).next('p').removeClass("popupHighlight");
});
What about selecting all a elements?
$('a').mouseout(function() {
//do stuff in here
});
or better yet, have a class selector:
$('.mySpecialRolloverClass').mouseover(function (e) {
$(e.target).next('p').addClass("highlight");
});
$('.mySpecialRolloverClass').mouseout(function (e) {
$(e.target).next('p').removeClass("highlight");
});
which would go hand in hand with
An anchor
and
.highlight {
color:red;
}
Here's a jsfiddle demo:
http://jsfiddle.net/8J6kM/
The #yochannah answer is correct, however if you want to add more links dynamically, you then need to use on method instead of mouseover and mouseout, otherwise it won't work. See the demo and jQuery documentation for further details.
// I assumed that links are placed inside of a container element: #links
$('#links').on('mouseover', '.mySpecialRolloverClass', function (e) {
$(e.target).next('p').addClass("highlight");
});

Categories

Resources