Apply class to neighbor div when div gets class - javascript

I have a div containing all my content, and then I have a div containing pop-up windows. So basically something like this:
<div class="content">
Some content
</div>
<div class="popup-wrapper">
Popup content
</div>
Then at some point a class is added to the popup-wrapper due to some button click, that in Angular would look something like:
<button (click)="popup = !popup">Click me</button>
<div class="popup-wrapper" [ngClass]="popup ? 'is-active' : ''">
Popup content
</div>
My question is: Are there some way (CSS wise. JS would probably also do if no other alternative is available) that when popup-wrapper has the class is-active I can also target content as well ?
The issue for me not just putting the same JS into the content div, i.e. [ngClass]="popup ? 'is-active' : ''" is because there are several instances that can activate a popup, and other popup wrappers as well. So if I were to do this I would have to go through every page that has this kind of popup-wrapper, and paste similar code into every content div, but with different state names.
So I just thought it would be much easier, if I could target the content div whenever the popup-wrapper div had the is-active class.

For my understanding, you'll need something like that:
function anyName () {
let x = document.getElementByClassName('is-active');
if (x === true) {
// do something
}
}
Depending on what ever you want to do next, you can either go for an identifier like your div's className ('content') or you try to target it by its position, like 'previousElementSibling'

Related

Accordion closing onClick anywhere in container

I am trying to create an accordion for a project I'm working on. For the sake of argument, lets assume this accordion only has one container. So far, I've got it all working, however when I expand the accordion, which will only expend if I click on the header, I am then able to close the open container by clicking anywhere in the container, rather than just the header.
I've tried a few different things resulting in null .toggle errors so far. Below is a snippet of the accordion itself, along with the JS I'm using with it. Please bare in mind the accordion functions correctly and displays correctly, its the click function that's the issue (meaning my CSS is fine so no point sharing):
JS:
const accordion = document.getElementsByClassName('container1');
for (i=0; i<accordion.length; i++) {
accordion[i].addEventListener('click', function () {
this.classList.toggle('active');
});
}
Accordion HTML:
<div class="accordion-body">
<div class="accordion">
<hr>
<div class="container1" id="container1">
<div class="label" id="linkId">Generate a payment link</div>
<div class="content">
<div class="form">
</div>
</div>
</div>
<hr>
</div>
</div>
Essentially, I only even want the accordion to open/close if the 'label' div is pressed. This is because within my accordion there are buttons, so at the moment when a button is pressed when accordion is open, it changes the class which closes the accordion back up. Right now I understand that the clickable area is 'container1' but I've not been able to make it work against the label div.
I can also provide a link to the webpage where it is happening, happy to provide this via PM.
I tried changing the JS to the below:
const accordion = document.getElementsByClassName('container1');
const linkId = document.getElementById('linkId');
for (i=0; i<accordion.length; i++) {
document.getElementById('linkId').addEventListener('click', function () {
accordion.classList.toggle('active');
});
}
However the above produces the following error:
Uncaught TypeError: Cannot read properties of undefined (reading 'toggle')
at HTMLDivElement. (txninfo.php:825:25)
LINE 825 is the following:
accordion.classList.toggle('active');
Any help would be massively appreciated
accordion in that case is instance of HTML-Collection and not Element as you assume.
So you correctly iterate over the collection of elements, you now just want to select the current element (where key == i) of iteration instead of the whole collection.
accordion[i].classList.toggle('active');
then you should have an Element and should be able to access it´s properties like classList
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName

Running if/each statement to select divs and alter background image position independently

I am currently trying to change the position of a background image within a div depending on the text within a span.
My problem is multiple divs have the same class which are not changeable.
For example. Every cell where I want to change the image position looks like:
<td class="js-gridBlock js-Pre-order" data-attvalue1="3XL" data-attvalue2="Plum">
<div class="js-gridImage">
<div class="prodpageGridText" id="gridtext-gridbox34">
<span class="status">Due in 4 weeks</span><br>
<div class="prodpageGridTextArrow">
</div>
</div>
</div>
</td>
Where the Span class Status value changes anywhere between 1-10.
My jQuery currently looks like;
jQuery(document).ready(function() {
if (jQuery('span.status:contains("4")')) {
jQuery('.js-Pre-order .js-gridImage').css("background-position", "-4px -213px");
}
if (jQuery('span.status:contains("5")')) {
jQuery('.js-Pre-order .js-gridImage').css("background-position", "-4px -242px");
}
if (jQuery('span.status:contains("10")')) {
jQuery('.js-Pre-order .js-gridImage').css("background-position", "-4px -387px");
}
});
My issue is when the jQuery is run every js-gridImage then changes to ("background-position", "-4px -387px") where as I need them to change dependent on their spanvalues.
I have seen the .each() function but am unsure how best to incorporate it into my code.
Thanks in advance.
You can use the relationship between elements, Here .closest(selector) can be used to traverse up to fetch the desired element and set the CSS rules.
jQuery(document).ready(function() {
jQuery('span.status:contains("4")').closest('.js-gridImage').css("background-position", "-4px -213px");
jQuery('span.status:contains("5")').closest('.js-gridImage').css("background-position", "-4px -242px");
jQuery('span.status:contains("10")').closest('.js-gridImage').css("background-position", "-4px -387px");
});

"Incremented" CSS class in element

Let us suppose that we have a div element #a-node and a javascript method create one or more other div's called .b-node (not need inside this first) and it too add an #a-node class .b-node-enabled.
Exists a way to toggle/turn on the .b-node-enabled only if exists .b-node's connected specifically to #a-node?
Example:
If no one .b-node is connected with #a-node, so turn class off;
If one or more .b-node is connected with #a-node, so turn class on;
I can use jQuery, if need and -webkit features.
REAL PROBLEM
I have a div popup that create a background, and I need turn on a classe on the main content body (that not inside this popup, and vice-versa, just appended to body too), and I can have more than one popup enabled at same time. I only need turn off the .b-node-enabled if no one popup is showing.
<body>
<!-- MAIN CONTENT -->
<div id="a-node" class="b-node-enabled">...</div>
<!-- POPUPS -->
<div class="b-node">...</div>
<div class="b-node">...</div>
<div class="b-node">...</div>
</body>
I don't know if I really understood your question, but maybe this code snippet can help you (jQuery needed).
function updateANodeClass() {
if ($(".b-node").length) {
$("#a-node").addClass("b-node-enabled");
} else {
$("#a-node").removeClass("b-node-enabled");
}
}
After you've added or removed one .b-node you'll have to call that function to update the class.

Javascript show/hide - I don't want it to hide the entire element

This is probably a fairly easy question, but I'm new to JavaScript and jquery....
I have a website with a basic show/hide toggle. The show/hide function I'm using is here:
http://andylangton.co.uk/articles/javascript/jquery-show-hide-multiple-elements/
So here's my question..... I would really like the first 5-10 words of the toggled section to always be visible. Is there some way I can change it so that it doesn't hide the entire element, but hides all but the first few words of the element?
Here's a screenshot of what I would like it to do:
http://answers.alchemycs.com/mobile/images/capture.jpg
There are many different implementation possibilities:
You can divide the contents up into the first part and the second part (two separate spans or divs inside your main object) and hide only the child object that represents the second part, not hide the parent object.
Rather than hide the object at all, you can set its height to only show the first part (with overflow: hidden)
Change the contents of the main object to only have the first part as the contents (requires you to maintain the full contents somewhere else so you can restore it when expanded again).
Here's a working example of option 1: http://jsfiddle.net/jfriend00/CTzsP/.
You'd need to either:
Put in a span/etc. after the first n words, and only hide that part, or
Change the viewable region, or
Replace or toggle the span/etc. with the "collapsed" view.
The last is a bit more customizable; using two separate elements allows trivial games to be played (showing an image, for example, like a little curly arrow) without modifying adding/removing DOM elements.
I tend towards the last because it's simple and obvious, but that's a personal preference, and really isn't as true as it used to be.
You can do some plugin authoring,I did a sample demo here ,based on your screenshot
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
here is javascript/jquery code
jQuery.fn.myToggle = function(selector, count) {
var methods = {
toggle: function(selector, count) {
if ($(selector).is(':visible')) {
var span = $('<span>');
span.text($(selector).text().substr(0, count) + "...");
span.insertAfter($(selector));
$(selector).hide();
}
else {
$(selector).show();
$(selector).next('span').hide();
}
}
};
$(this).each(function() {
methods.toggle($(this).next(selector), count);
$(this).click(function(evt) {
methods.toggle($(this).next(selector), count);
});
});
};
$(function() {
$('.toggle').myToggle('.content', 3);
});
Here is a solution using css properties only instead of mangling the dom.
http://jsfiddle.net/AYre3/4/
Now if you want some sort of animation happening as well you'll probably need to do a bit of measurement along the way.

TinyMCE Remove DIVs with a specific class

I would like to remove a div from the TinyMCE editor content that has a specific class.
In the ideal world I'd like to be able to do this via the valid_elements option but I don't know if it's achievable.
Here is a sample of editor content:
<div class="content">
Some html content here
<div class="anotherclass"></div>
</div>
I would like the
<div class="content">
stripping out so the editor will only show this:
Some html content here
<div class="anotherclass"></div>
Cheers guys.
First get the innerHTML of the div, and then append that content to the div, after which you can remove it.
In jQuery:
var contentHtml = $(".content").html();
$(".content").after(contentHtml);
$(".content").remove();
Of course, if you have multiple divs with these classes its more complicated because then you would have to work with parents etc.
Problem here will that by default your editor will have a root_block element (in your case div) and all content gets wrapped inside that kind of root_block element. This is done for styling purposes, but can be deactivated using this initialization params
force_p_newlines : false,
force_br_newlines : false,
convert_newlines_to_brs : false,
remove_linebreaks : true,
Once that is done you can use this code to easily get rid tof your divs.
var $elements_to_be_removed = $(".content");
$elements_to_be_removed.each(function(index) {
$(this).replaceWith(this.innerHTML);
});

Categories