Hide/show child element onClick - javascript

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();
});

Related

If div in iframe has child with specific class do

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;}

jquery - click, append, load, slideDown not displaying as expected

I'm trying to implement, what I thought would be a simple click, load, slideDown scenario. But I can't get the slideDown part to display.
I have the following two buttons:
<div>
<fieldset id="btn">
<input class="databasebtn" type="submit" name="nameDatabaseBtn" id="db1" data-id=1" VALUE="DB1"/></br>
<input class="databasebtn" type="submit" name="nameDatabaseBtn" id="db2" data-id="2" VALUE="DB2"/></br>
</fieldset>
</div>
I then have the following jQuery:
$(document).ready(function()
{
$('.databasebtn').on('click',function()
{
$(this).append("<div id='btnlist'></div>");
$('#btnlist').slideDown("200",function()
{
$('#btnlist').load("test78b.php");
});
})
});
The idea being that I click the button, I append the #btnlist div to the button, and fill the new div with the contents of test78b.php, which should generate a list of checkboxes.
It all works fine, except that I can't see the checkboxes. If I look at the code in the background it is all there, it just wont show up.
If I include 'test78b.php' separately it displays as expected.
Is there something I am missing?
You can not append div to a button, you can append div to a parent in this case fildset with this code
<script type="text/javascript">
$(document).ready(function() {
$('.databasebtn').on('click',function(){
$(this).parent().append("<div id='btnlist'></div>");
$('#btnlist').slideDown('slow',function(){
$('#btnlist').load("your page");
})
})
});
</script>
or you can use insertBefore to append div before butoon clicked with this code
<script type="text/javascript">
$(document).ready(function() {
$('.databasebtn').on('click',function(){
$("<div id='btnlist'></div>").insertBefore($(this))
$('#btnlist').slideDown('slow',function(){
$('#btnlist').load("your page");
})
})
});
</script>
or append div to the body tag with this other code
<script type="text/javascript">
$(document).ready(function() {
$('.databasebtn').on('click',function(){
$("<div id='btnlist'></div>").appendTo('body')
$('#btnlist').slideDown('slow',function(){
$('#btnlist').load("your page");
})
})
});
</script>
and then, for a correct html code,you shouldn't have multiple items on the same page with the same id. The div added via script should not have id btnlist but class="btnlist"
DEMO http://jsfiddle.net/TWQbD/4/
$('.databasebtn').on('click',function() {
$(this).next('.databasetext').append("<div class='btnlist'>test78b.php</div>");
$(this).next('.databasetext').find('.btnlist').last().slideDown("1000");
});

traverse element inside the div

html:
<div style="width: 260px;margin:25px 0 0 30px">
<input type="checkbox" name="send_email" class="delete_followup" />Send email alerts
<input type="checkbox" value="delete" type="checkbox" />Send SMS alerts <button type="submit" name="delete" value="{{follower.id}}" class="delete_follower">Delete</button>
</div>
js:
$(".delete_followup").click(function(){
var $this = $(this);
$(this).find(".delete_follower").show();
});
I want to show the hidden button on clicking the delete_followup class.i TRIED WITH ABOVE jQuery but not working.
Or try .nextAll:
$(this).nextAll(".delete_follower").show();
Working here: http://jsfiddle.net/tw5XK/
The delete_follower element is not a decedent of delete_followup element, it is a sibling element so instead of find() you need to use siblings()
$(".delete_followup").click(function(){
var $this = $(this);
$this.siblings(".delete_follower").show();
});
You are trying to search downward into the div, when you already have a reference to the element you want. Making it way more complicated than it needs to be lol
$(".delete_followup").click(function(){
$(this).show();
});
Whenever you trigger off a click event, the actual element clicked on is passed through as the scope of the function. Since you are triggering off the click of ".delete_followup", that div is your element scope
Try this:
$(".delete_followup").click(function () {
if (this.checked) {
$(this).siblings(".delete_follower").show();
} else {
$(this).siblings(".delete_follower").hide();
}
});
Demo here

Selecting <li> item using jQuery after doubleclick

Here's what I'm trying to do:
I have an input field one can use to add entries to a todo list. I use JQuery to display a sorted list of entries after the user clicks 'Add'. I also made the list sortable (You can change the order by mouse drag using jQuery.) Now what I want to bold an individual list item when it is double-clicked. Somehow I'm not getting the jQuery to select the right item...
Here's my code.
HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
<script type="text/javascript" src='script.js'></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<title>Tadum</title>
</head>
<body>
<h2>Tadum - The ToDo List</h2>
<h3>Enter New ToDos</h3>
<form id="addForm">
<input type="text" name="ToDoListItem"></input>
</form>
<div id="button">Add!</div>
<h3>Your ToDos</h3>
<ol class="todolist"></ol>
</body>
</html>
CSS:
.todolist li{
font-weight: normal;
}
.todolist {
font-family:garamond;
color:#cc0000;
}
Javascript
$(document).ready(function() {
$('#button').click(function(){
var toAdd = $('input[name=ToDoListItem]').val();
$('.todolist').append('<li class="item">'+toAdd+'</li>');
$('#addForm')[0].reset();
});
$('ol').sortable();
$('ol').css('cursor', 'pointer');
$('.todolist li').dblclick(function(){
$(this).css('font-weight', 'bold');
});
});
NOTE:
Somehow what works is if I replace the .list li in jQuery and in the CSS stylesheet with a simple ol. Then a doubleclick displays all items in the list (which is, of course, not what I want). But somehow I can't figure out how to only select the individual <li> that is doubleclicked with jQuery...
(I also tried a bunch of variations on this. For example, only use 'li' to select the doubleclicked item or use 'ol li', or '.item li'. None of them work.)
You need to bind the dblclick event handler to the newly added list items, like this:
$(document).on('dblclick', '.todolist li', function(){
$(this).css('font-weight', 'bold');
});
Please note that this doesn't toggle the style, but just makes them bold on double click. If you double click again it won't do anything.
Also if I may suggest some other changes to your JavaScript code: Your form can be normally submitted like any other form, for the purposes of this to do list anyways. I've also added a label to the HTML <form> for accessibility purposes.
$(document).ready(function() {
$('#addForm').submit(function(e){
e.preventDefault();
$('.todolist').append('<li class="item">' + $('#ToDoListItem').val() + '</li>');
$(this)[0].reset();
});
$('ol').sortable().css('cursor', 'pointer');
$(document).on('dblclick', '.todolist li', function() {
$(this).css('font-weight', 'bold');
});
});
HTML
<form id="addForm">
<label for='ToDoListItem'>Item:</label>
<input type="text" id="ToDoListItem" />
<button type='submit'>Add!</button>
</form>
You are adding the li items after the document was created. So you need to use "on" method so that you can trigger the click on the newly created items afterwards.
$(document).ready(function() {
$('#addForm').submit(function(e){
e.preventDefault();
var toAdd = $('#ToDoListItem').val();
$('.todolist').append('<li class="item">'+toAdd+'</li>');
$('#ToDoListItem').reset();
});
$('ol').sortable().css('cursor', 'pointer');
$(document).on('dblclick','li.item',function(){
$(this).css('font-weight', 'bold');
});
});

Bind a jquery function to elements

I am very new to jquery and need some help. I am trying to change a css element when I enter a textbox. I have applied a css class to my textboxes and I have a couple of div tags around my textboxes.
When a user selects the textbox I want to change the desired div tag.
This is how the html looks
<div class="left">
<div class="right">
<input name="myTextBoxID" type="text" id="myTextBoxID" class="myTextBox" />
<span id="rfInput"></span>
</div>
</div>
my jquery looks like this
<script language="javascript" type="text/javascript">
$(function () {
$('.myTextBox').focus(function () {
$('.box.left').addClass("active");
}).blur(function () {
$('.box.left').removeClass("active");
});
});
</script>
Now the jquery is working and changes the class on focus and blur however it effects all elements witht he class="myTextBox" how can I get jquery to attach to all elements however only fire the css change to the selected textboxes outside elements class?
Any help would be great!
<script language="javascript" type="text/javascript">
$(function () {
$('.myTextBox').focus(function () {
$(this).closest('.left').addClass("active");
})
.blur(function () {
$(this).closest('.left').removeClass("active");
});
});
</script>
this refers to the element that received the event.
So you wrap this into a jQuery object, $(this) and access the closest() ancestor with the class you designate.
.closest() - http://api.jquery.com/closest/
you were not that clear, so, here,s my guess...
$(function () {
$('.myTextBox').focus(function () {
$(this).closest('.left').addClass("active");
}).blur(function () {
$(this).closest('.left').removeClass("active");
});
});

Categories