If div in iframe has child with specific class do - javascript

I want to add a class to the parent if the child has a specific class.
The problem: It's in an iFrame and I'm not very good with jQuery. It don't really has to be jQuery, any other way would be also great. Just notice: The iFrame is on my domain, but I can't access it, because it's generated by a plugin.
If you have any ideas how to fix it, I would appreciate it
My HTML looks somewhat like this in devtools:
<iframe src="#" id="iFrameResizer0">
<div class="book-day">
<button class="disabled">Button Text</button>
</div>
<div class="book-day">
<button class="active">Button Text</button>
</div>
</iframe>
and my jQuery:
$(document).ready(function () {
$("#iFrameResizer0").contents().find(".book-day button")
if ($('.book-day button').hasClass('disabled')) {
$(".book-day button").parent().addClass('disabled');
}
});
if everything works correct I want my html looks like this afterwards:
<iframe src="#" id="iFrameResizer0">
<div class="book-day disabled">
<button class="disabled">Button Text</button>
</div>
<div class="book-day">
<button class="active">Button Text</button>
</div>
</iframe>
Devtools:

NOTE: this code has to be executed AFTER the iFrame has loaded and rendered. If you execute this in the head of the parent page without wrapping it in $(function() { ... }), it will not work
You have more than one book-day, you will need to loop:
$("#iFrameResizer0").contents().find(".book-day button").each(function() {
$(this).parent().toggleClass('disabled',$(this).is('.disabled'));
})
or perhaps
$("#iFrameResizer0").contents().find(".book-day button.disabled").each(function() {
$(this).parent().addClass('disabled');
})
PS: To remove them you do not need to give them a class:
$("#iFrameResizer0").contents().find(".book-day button.disabled").each(function() {
$(this).parent().remove;
})
If you still have issue with the timing, try this script right after the iframe tags - right after the </iframe>
<script>
$("#iFrameResizer0").on("load",function() {
$("#iFrameResizer0").contents().find(".book-day button.disabled").each(function() {
$(this).parent().remove(); // or .addClass('disabled');
})
})
</script>
UPDATE: Alternatively drop the iFrame completely:
Replace the iframe tags with <div id="iFrameResizer0"></div>
and add
<script>
$("#iFrameResizer0").load("/wp-json/ssa/v1/embed-inner?integration.../type/Reservierung",function() {
$("#iFrameResizer0").find(".book-day button.disabled").each(function() {
$(this).parent().remove(); // or .addClass('disabled');
});
});
</script>
Example pretending your iframe.content() works as expected (same origin)
$(function() { // on page load. This might STILL be too early
$("#iFrameResizer0").contents().find(".book-day button.disabled").each(function() {
$(this).parent().addClass('disabled');
})
});
.disabled {
background-color: grey
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="iFrameResizer0">
<div class="book-day disabled">
<button class="disabled">Button Text</button>
</div>
<div class="book-day">
<button class="active">Button Text</button>
</div>
<div class="book-day disabled">
<button class="disabled">Button Text</button>
</div>
</div>

You don't have to check for every button if it has disabled class or not. You can directly select those button having disabled class.
In Javascript, you have to iterate for all the buttons having disabled class, and add disabled class to it's parent. However, in jQuery, as you can see, you can achieve that, without using any loop.
For JavaScript :
$(document).ready(function() {
var all = document.querySelectorAll('#iFrameResizer0 .book-day button.disabled');
all.forEach((item) => {
item.parentElement.classList.add('disabled');
})
});
For jQuery :
$("#iFrameResizer0 .book-day button.disabled").parent().addClass('disabled');

Since the iframe is observing same-origin policy, This is possible.
First you need to select your iframe element using the following JS
var iframe = document.getElementById('iFrameResizer0');
Now you need to get the content in your iframe
var iframeContent = iframe.contentDocument;
Then select elements inside your Iframe which you wish to modify
var iframeElement = iframeContent.getElementsByClassName("book-day");
var i = 0, ilen = iframeElement.length - 1;
for (var i = 0; i < ilen; i++) {
var button = iframeElement.getElementsByTagName("button");
if(button.className == 'disabled')
{
iframeElement[i].className == 'disabled';
}
}
Then hide your element using CSS display:none property
.disabled {display:none;}

Related

how can I alter my code to hide element on load?

I'm using this js code to show/hide elements on my site:
<script>
function myFunction3() {
var x = document.getElementById("dsec-three");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
Can anyone help me to set it so the elements are hidden on load and only show once activated?
you can use class for show/hide elements same as :
function showHide(){
element = document.getElementById('element1');
showHideEle(element)
}
function showHideMulti(){
elements = document.getElementsByClassName('multi');
Array.from(elements).forEach(ele => {
showHideEle(ele)
});
}
function showHideEle(ele){
let isHide = ele.classList.contains('hide');
if (isHide) {
ele.classList.remove("hide");
} else {
ele.classList.add("hide");
}
}
.hide {
display: none
}
<p class="hide" id="element1">para 1</p>
<button onclick="showHide()">Show/Hide</button>
<br />
<p class="hide multi">para 2</p>
<p class="hide multi">para 3</p>
<p class="hide multi">para 4</p>
<button onclick="showHideMulti()">Show/Hide Multi</button>
Your function myFunction3 already does the job of hiding and showing the relevant elements. All you need to do now is invoke the function when your document loads. You can do this by adding the following line inside your <script>:
document.addEventListener("load", myFunction3);
If you need the elements to stay hidden by default and show them after the document loads, you'll need to set the display property of those elements to none either via inline CSS.
Example (if your element is a div) :
<div id="dsec-three" style="display:none">
...
</div>
what do you mean by activated?
if you mean that after the load of your page, you would need an event listener.
follow these steps:
set the initial display of your element to none.
create an event listener like load: and add your function there:
document.addEventListerer('load', function(){
myFunction3();
})
the above code is telling the browser: 'when ever the page loads, call this function'

How to hide an element in if statement?

I am making an html change to a CMS that will affect all pages when the changes are live. I would like this html alert to only affect 1 specific page. I am attempting to do an if statement for the page title.
The logic is that if the page title is Test Article Two then show the html that I have put in place, if not then display=none. With this logic in place, I am viewing the html on all pages not just the one I want it to show.
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<!--page alert -->
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
<script>
function showAlert() {
if(#pageTitle === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
}else {
document.getElementById('alert-dialog').style.display = 'none';
}
}
</script>
I'd recommend changing a class on the body element so that you can use CSS for the styling.
HTML: nothing really changed here
<body>
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
</div>
</body>
javascript: just check the document.title and add the class the the body element
<script>
if(document.title === "Test Article Two") {
document.body.classList.add("show-alert");
}
</script>
Use CSS for the styling. Always hide #alert-dialog and only show it when we add the class to the body.
<style>
#alert-dialog {
display: none;
}
.show-alert #alert-dialog {
display: block;
}
</style>
If you are making static pages or using server side rendering, you could add logic to add a class to show or hide the alert element without adding more javascript to the page. It will have the relevant class(es) when the html is generated and delivered. This way you won't have to create a function, call it and manipulate the DOM after everything is rendered.
I may have missed this in the code above, are you calling the showAlert function anywhere? If not, your alert won't be shown (or will be shown depending on the default styles).
One thing I'd caution against is the imperative nature of the code here. If you wanted to reuse this alert functionality on another page, you'd have to add another more logic to detect another page title every time you wanted to use the alert. Since you are using a CMS, you might consider adding a flag to show the alert, and on this specific page, turn that flag on.
If you wanted to use the function strategy, I'd set your default alert styles:
#alert-dialog {
display: none;
}
.show {
display: block;
}
and try something like this:
<script>
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').classList.add('show');
}
}
document.addEventListener("DOMContentLoaded", showAlert);
</script>
Another alternative is to take a look at the path of the page this is supposed to be on (window.location.pathname) and using regex to see if it matches what you want. I'd recommend that over looking at the title since it's more likely the title of the page will change rather than the url.
In JavaScript, you can access the page title with document.title. You should change the script like this:
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
} else {
document.getElementById('alert-dialog').style.display = 'none';
}
}

Changing HTML div's background colour when it is clicked using JavaScript without jQuery

Trying to implement a very simple feature, using only JavaScript without jQuery. I want the background of the HTML div with id='tags' to change, when I click on it.
document.getElementById('tags').addEventListener('onclick', function() {
this.style.backgroundColor = 'red';
});
<body>
<div id="tags">Item1</div>
<div id='tags'>Item2</div>
<div id='tags'>Item3</div>
</body>
Identiifiers in HTML must be unique, Use a common CSS class to instead.
Use querySelectorAll() to target them, as it will return a list, iterate it and bind event handlers
remove prefixed "on"
document.querySelectorAll('.tags').forEach(function(element) {
element.addEventListener('click', function() {
this.style.backgroundColor = 'red';
});
})
<div class="tags">Item1</div>
<div class='tags'>Item2</div>
<div class='tags'>Item3</div>
A few issues here:
your script is (or was before you edited the question) executing before the <div> elements are added to the document; the <script> needs to be placed after the <div>s in your HTML source code.
you can't have multiple elements with the same id. use class="tags" instead.
the event is "click" not "onclick"
Here's what i'd do instead:
<body>
<div class="tags">Item1</div>
<div class="tags">Item2</div>
<div class="tags">Item3</div>
<script>
for (let x of document.getElementsByClassName('tags')) {
x.addEventListener('click', function() {
this.style.backgroundColor = 'red';
});
}
</script>
</body>

Hide/show child element onClick

I am building a "edit profile" page.
Here is what I want to do:
In each section, the employer will be shown and the edit form will be hidden.
When I click the "edit employer" button, the edit form will be shown and the employer will be hidden.
Here is what I did using jQuery. It does not work when I click on the "edit employer" button. I do not know why this does not work.
<!DOCTYPE html>
<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div class="edit">
<form class="editForm">
employer: <input type="text" value="Citigroup" />
</form>
<div class="contents">Employer: Citigroup</div>
<button class="editButton">Edit Employer</button>
</div>
<script>
$('div.edit').each(function(i) {
$(this).children('.editForm').hide();
})
$('div.edit').each(function() {
$(this).children('.editButton').click(function() {
$(this).children('.editForm').show();
$(this).children('.contents').hide();
});
})
</script>
</body>
</html>
The $(this) inside the click function contains the local instance of the $(this).children('.editButton'). For that reason your code is not finding any .editForm elements.
For this to work you could do something like this:
<script>
$('div.edit').each(function(i) {
$(this).children('.editForm').hide();
})
$('div.edit').each(function() {
var $this = $(this);
$(this).children('.editButton').click(function() {
$this.children('.editForm').show();
$this.children('.contents').hide();
});
})
</script>
If I may I would improve the code with some more changes:
<script>
$('.edit .editForm').hide(); // this will hide all instances of .editForm
$('.edit .editButton').click(function() { //assign 1 handler for all cases
$(this).siblings('.editForm').show(); // show the sibling edit form
$(this).siblings('.contents').hide(); // hide the sibling contents element
});
</script>
Reference:
Sibling Selector: https://api.jquery.com/siblings/#siblings-selector
The problem is the this inside the click handler referring to the button, not the div.edit. Here's one way to fix this:
$('div.edit').each(function(i) {
$(this).children('.editForm').hide();
});
$('div.edit').each(function() {
var $self = $(this);
$(this).children('.editButton').click(function() {
$self.children('.editForm').show();
$self.children('.contents').hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="edit">
<form class="editForm">
employer:
<input type="text" value="Citigroup" />
</form>
<div class="contents">Employer: Citigroup</div>
<button class="editButton">Edit Employer</button>
</div>
You don't need to use .each() at all. Just do an .click() event on the class of .editButton and use this to find its parent. If you want to make a toggle, you're going to have to make use of a new class or something of that nature to make a conditional statement off of.
//This will hide *ANY* .editForm elements
$('.editForm').hide();
//This will fire off of *ANY* editButton clicks.
$('.editButton').click(function() {
var form = $(this).closest('.edit'); //Get the wrapper
if(form.hasClass('open')) { //Check to see if it is open or not
form.removeClass('open').addClass('close'); //Toggle Classes
form.find('.editForm').show();
form.find('.contents').hide();
} else {
form.removeClass('close').addClass('open');
form.find('.editForm').hide();
form.find('.contents').show();
}
});
I like to use closest and find more than parent and children (respectively). They can go 1-many layers up or down and search the hierarchy for whatever you're looking for, rather than parent and children going up or down a single layer.
If you are inserting your .edit form after the DOM loads, you're going to need to bind your click event to the document
$(document).on('click', '.editButton', function() {
var form = $(this).closest('.edit');
form.find('.editForm').hide();
form.find('.contents').show();
});

Showing/Hiding Divs with the same class name - Javascript

I am trying to replicate something similar to what the Google Javascript from the Ground up Accomplishes
http://code.google.com/edu/submissions/html-css-javascript/#javascript
Basically have multiple div classes with the same name and show/hide those based on adding removing classes to the original class name.
Heres my markup
<div class="vidItem" id="vidItem">
<div class="vidTitle">
<h2></h2>
</div>
<div class="vidContain" id="vidContain">
<iframe class="testtt" width="560" height="315" src="-----" frameborder="0" allowfullscreen> </iframe>
</div>
</div>
<div class="vidItem" id="vidItem">
<div class="vidTitle">
<h2></h2>
</div>
<div class="vidContain" id="vidContain">
<iframe width="560" height="315" src="----" frameborder="0" allowfullscreen></iframe>
</div>
</div>
Heres my javascript
var toggleExpando = function() {
var expando = this.parentNode;
if (hasClass(expando, 'hide')) {
removeClass(expando, 'hide');
addClass(expando, 'show');
} else {
removeClass(expando, 'show');
addClass(expando, 'hide');
}
};
var expandos = getElementsByClass('vidContain');
for (var i=0; i < expandos.length; i++) {
addClass(expandos[i], 'hide');
var expandoTitle = document.getElementById('vidItem');
addEventSimple(expandoTitle, 'click', toggleExpando);
}
}
Onload both of the divs seem to set their classes to hide just fine but when I click on the top one everything disappears but when I click on the bottom one nothing happens. I am assuming there is a problem with my for loop and also where it says (expando = this.parentNode). I have no idea where to go from here.
Any help or ideas would be appreciated.
Javascript assumes that there is only one element with specific id (and this is what standard say). So when you say..
var expandoTitle = document.getElementById('vidItem');
here the variable contains only first item with id vidItem and attaches event to that element only.
This can be corrected by using class names instead of id.
jQuery might be a good option for this. ID needs to be unique but classes don't, so you can query for all element with a class name in the same way you would with id's in straight javascript by using jQuery. Not sure on what you want the initial state to be so i'm hiding all on inital load. Something along the lines of below is what i mean. (code is untested. place it in the html head)
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.vidItem').addClass('hide');
$('.vidItem').click(function(){
$('.vidItem').addClass('hide');
$(this).removeClass('hide');
$(this).addClass('show');
});
});
</script>
If you want to make it look nice with transition effects you can use some of the build in jQuery ones such as:
$('.vidItem').fadeOut();
$(this).fadeIn();
or
$('.vidItem').slideUp();
$(this).slideDown();

Categories