I have created a simple jQuery toggle function which adds and removes the class formVisablethe toggle function is adding the class how in the wrong place CLICK HERE.
I want to add the class to the following element <div id="hide-overlay"> however at the moment the class is being added to my button element <a id="show-form">. Below is a snippet of my code
HTML
<div class="row promo-image responsive">
<figure>
<figcaption class="caption">
<a id="show-form" class="promo-button" href="#">
<span>Be More Productive</span>
<i class="fa fa-download"></i>
</a>
<h4>Download the 8 steps for successful collabration</h4>
</figcaption>
</figure>
</div>
HIDDEN ELEMENT
<div id="hide-overlay">
<a id="hide-form-close" href=""><i class="fa fa-times fa-2x"></i></a>
<div class="col-sm-6 col-sm-offset-3 form-container">
<h2 class="business">Register</h2>
<form class="main-contact submit-fade ajax-form" action="process.php" method="POST">
<ul class="small-block-grid-2 medium-block-grid-2 hide-form">
<li>
<label for="name">Name</label>
<input type="text" class="form-control" name="name" placeholder="Name" required>
</li>
<li>
<label for="email">Email</label>
<input type="text" class="form-control" name="email" placeholder="Email">
</li>
</ul>
<input type="submit" class="btn btn-success">
</form>
</div>
</div>
JQUERY
var $hideOverlay = $("#hideOverlay").hide();
$("#show-form").on("click", function(e){
$(this).toggleClass("formVisable");
});
It's because you are using this which represents the object that is calling the function, in this case #show-form. You should use $('#hide-overlay').toggleClass("formVisible");
Here's the fiddle for it: http://jsfiddle.net/norg5k2o/4/
"This" represents the object that an action is being applied to. In this case, it's your button. You want the class to be applied to your overlay, rather than to the button. Therefore, try this:
Also, you had some spelling errors.
$("#hide-overlay").hide()
$("#show-form").on("click", function(e){
$("#hide-overlay").toggleClass("formVisible");
});
WORKING DEMO HERE
You did not properlay declare the variable. You had $(#hideOverlay) when your HTML id attribute was actually id='hide-overlay'. As such, I have re-written the jQuery to properly target and hide the form as was your original intent. I also, disabled the link so that it will only do the show/hide function and not the go to href='#' action.
As the other answers suggest, when using the $(this) selector in jQuery, it will target the parent selector of the current iteration of the function.
I also updated your CSS as it was hiding the form.
View working example
var $hideOverlay = $("div#hide-overlay");
$hideOverlay.toggle();
$hideOverlay.css("border", "solid 1px black");
$("a#show-form").on("click", function(e){
e.preventDefault();
$hideOverlay.slideToggle(300);
});
The $(this) inside a JQuery event handler is the DOM element that has the handler attached. If we attached the handler to something else, like the containing <div>, we will get the DIV DOM element doesn't matter which inside elements of the DIV we clicked.
So, in this case you would need something like this, since $("#hideOverlay") is already cached, the correct way to do it is:
var $hideOverlay = $("#hideOverlay").hide();
$("#show-form").click(function(e){
$hideOverlay.toggleClass("formVisible");
//Prevent default behavior for links and buttons
e.preventDefault();
});
Related
I have input and I suggest autocomplete list of words from my database using Ajax.
I use bootstrap 4 to design the list, but use <a></a> tag instead of the <li></li> tag, because bootstrap 4 provides hover effect when using <a> instead of <li> element for my list.
Everything is working the list of words is displaying, but I don't know how to fill the value of the input when, the user clicks on the desired word.
My HTML looks like this:
<form action="index.html" method="post">
<div class="form-group">
<label for="team1">First Team</label>
<input id="team1" type="text" name="team1">
<div id="autoFil" class="list-group col-sm-12"></div>
//Here I generate the list using Ajax which looks like this
<a class="list-group-item list-group-item-action ">Keyword 1</a>
<a class="list-group-item list-group-item-action ">Keyword 2</a>
<a class="list-group-item list-group-item-action ">Keyword n</a>
</div>
</form>
you can add a clickHandler to your anchors, see this for more information.
The clickHandler would then basically use the innerHTML of the clicked a-element and fill any other element's content.
<form action="index.html" method="post">
<div class="form-group">
<label for="team1">First Team</label>
<input id="team1" type="text" name="team1">
<div id="autoFil" class="list-group col-sm-12"></div>
//Here I generate the list using Ajax which looks like this
<a class="list-group-item list-group-item-action " onclick="fillInput('Keyword 1')">Keyword 1</a>
<a class="list-group-item list-group-item-action " onclick="fillInput('Keyword 2')">Keyword 2</a>
<a class="list-group-item list-group-item-action " onclick="fillInput('Keyword n')">Keyword n</a>
</div>
</form>
<script>
function fillInput(val){
document.getElementById('team1').value = val;
}
If you are having issue in setting the value of input field then you should check val()
It is used like:
$('#team1').val('whatever value you want to set');
If you are having issue in attaching a click handler for dynamically generated links, then you should be checking this existing question: Event binding on dynamically created elements?
The field Description is optional and only appears when the user clicks on the + Description button. However when another div is generated the code loses the focus of the element it should hide and the button doesn't work anymore.
<script>
$(document).ready(function(e){
$(document).on('click', '#hide-desc', function(e) {
$("#description").slideToggle();
});
});
</script>
I have a button to remove and add the following div:
<div class="item-wrapper">
<div class="item-inner-wrapper">
<!-- Among other stuff -->
<div id="description" class="item-child-desc">
{{ form }}
</div>
</div>
<div class="item-action-button">
<!-- Deletes item-wrapper and another button adds it -->
<a id="delete" href="#" class="button alt small special">Remove</a>
<a id="hide-desc" class="button alt small">+ Description</a>
</div>
</div>
I know the function must be able to identify which description I am talking about, but I don't know how to do that. I tried to get the parent div of the button and specify the div with method find() but I could not make it work.
I have the same problem happening with an autocomplete function. I believe I will get both working if I can figure out what I have to do.
Based on your comments, I assume your html sort of looks like this (note that we use .description rather than #description since those are not unique elements):
<div class="item-wrapper">
<div class="item-action-button">
<a id="delete" href="#" class="button alt small special">Remove</a>
<a id="hide-desc" class="button alt small">+ Description</a>
</div>
<div class="description" class="item-child-desc">
blergh
</div>
</div>
We just have to look for the parent .item-wrapper using e.target to reference the source of the event then search the child .description:
$(e.target).parents(".item-wrapper").find(".description").slideToggle();
Based on the sample html you've added, the following should also work without modification:
$(e.target).parents(".item-wrapper").find(".item-child-desc").slideToggle();
It's also possible to just use this:
$(this).parents(".item-wrapper").find(".item-child-desc").slideToggle();
In all cases, the crucial part is parents(".item-wrapper").
I'm not entirely certain of the question, but if my understanding is correct I believe I may have found a solution for you. Using jQuery Event Delegation, it's relatively simple!
Run this code snippet and see if I'm close to a solution:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item-action-button"> Remove
<a class="hide-desc button alt small">+ Description</a>
<div class="item-child-desc">{{ form }}</div>
</div>
<div class="item-action-button"> Remove
<a class="hide-desc button alt small">+ Description</a>
</div>
<div class="item-action-button"> Remove
<a class="hide-desc button alt small">+ Description</a>
<div class="item-child-desc">{{ form }}</div>
</div>
<div class="item-action-button"> Remove
<a class="hide-desc button alt small">+ Description</a>
</div>
<script>
$(document).ready(function (e) {
$(".item-action-button").on('click', '.hide-desc', function (e) {
$(e.delegateTarget).find(".item-child-desc").slideToggle();
});
});
</script>
<style>
.item-child-desc {
display: none;
}
</style>
The problem with using ids for event handling is that they are only ever registered with the last element with that matching id. If you want one event handler for all elements of a certain type, register an event handler with elements of a certain class or tag. You'd be doing yourself a disservice otherwise.
Hope this helps!
This question already has answers here:
How do I detect a click outside an element?
(91 answers)
Closed 7 years ago.
I have a search suggestion box that appears when a user types in the search box. I want to close that box when the user clicks outside of the parent div. I tried this method below using .not() to omit the parents div but it did not omit it and still closes it when clicked on the parent div.
I have looked at solutions using event propagation but those have their own perils so I'd really like to use a simple function like .not() to accomplish this.
JS
// close search suggestions
$("body").not('#searchbox').mousedown(function() {
$('.search-suggestions').fadeOut();
});
HTML
<section id="searchbox">
<div class="container">
<div class="row">
<div class="col-md-12">
<form class="form-inline clearfix">
<div class="form-group pull-left">
<input type="text" class="form-control" id="search-input" placeholder="Search">
</div>
<button type="submit" class="btn btn-default pull-right"><i class="fa fa-search"></i></button>
</form>
</div>
<div class="col-md-12 search-suggestions">
<ul class="list-unstyled">
<li><h4>Browse:</h4></li>
<li class="suggestion-new-homes"><span class="suggestion-result">result</span> in New Homes</li>
<li class="suggestion-renovation"><span class="suggestion-result">result</span> in Renovation</li>
<li class="suggestion-interior-living"><span class="suggestion-result">result</span> in Interior Living</li>
</ul>
</div>
</div>
Attach a click handler to the document when the search dropdown is open, remove it when closed. Prevent propagation of the click when user clicks inside the open dropdown.
I know there are tons of posts out here about this but I have yet to find anything that works. I think because how deep my button is nested versus the postion of the div I am trying to effect.
Most of this is generated dynamically so I can't target IDs but I can target classes.
I have tried a number of approaches. Including:
$('div.hold:first').addClass('skinSelected');
AND
$(this).parent.parent.parent.prev('.hold').addClass('skinSelected')
AND
$(this).parent.prev('.hold').addClass('skinSelected')
This does the job to the first div with class hold but I have numerous divs with class "hold"
Here's my HTML:
<li>
<a>...</a>
<div style="display:none" class"hold">current selection</div>
<div>
<div>
<span>....</span>
<div>....</div>
<div>
<h3>...</h3>
<p>...</p>
select
</div>
</div>
</div>
</li>
Here's my javascript:
<script type="text/javascript">
function passSkinID() {
$('div.skinSelected').removeClass('skinSelected');
$(this).prevAll('.hold:first').addClass('skinSelected')
}
</script>
And here is my css
<style>
.skinSelected {
background-size:cover;
width:100%;
background:#2d67a3;
color:#FFFFFF;
display:block !important;
}
</style>
Thanks in advance for any insight!
First of all, you cannot use $(this) as it reffers to the jQuery's window object. You should pass this on click, and then wrap it into jquery object.
HTML:
select
Script:
function passSkinID(el) {
$('div.skinSelected').removeClass('skinSelected');
// use passed element instead of $(this):
$(el).closest('li').find('.hold').addClass('skinSelected');
}
DEMO
I would however do it this way:
<a href="#" class="my-btn btn btn-primary" >select</a>
Script:
$('.my-btn').click(function(e) {
e.preventDefault();
$('div.skinSelected').removeClass('skinSelected');
$(this).closest('li').find('.hold').addClass('skinSelected');
});
DEMO
Because the event is triggered on a child of a <li> tag that also contains the elements you want to manipulate, you have to travel up the DOM to that parent with closest() then find all children that have the required class:
$(this).closest('li').find('.hold').addClass('skinSelected')
This will only work if between <li> and the link you don't have other <li>'s, and if the other .hold elements that you don't want to add the class to are outside this particular <li> tree. I imagine that your DOM structure is like this:
<li>
<a>...</a>
<div style="display:none" class"hold">current selection</div>
<div>
<div>
...
<div>
...
select
</div>
</div>
</div>
</li>
<li>
<a>...</a>
<div style="display:none" class"hold">current selection</div>
<div>
<div>
...
<div>
...
select
</div>
</div>
</div>
</li>
...
For the first you need and equl in you div elemnt with class "hold"
You can do this as i have done in this jsBin http://jsbin.com/lujekojami/1/edit?html,css,js,output
I hope it helps :)
So I am building a comment system and have loaded a bunch of comments to a page, then have generated a reply box for each. Below is what my reply box looks like, but there are many identical ones on each page. As you can see, the first portion is a div that contains a toggle (show/hide) for the reply box.
I am posting because I cannot get the reply toggle to fire.
Here is my html:
<div class="col-sm-offset-1 col-sm-11">
<a href="#" id="reply-toggle">
<span class="text">Reply</span>
<i class="toggle-icon fa fa-angle-down"></i>
</a>
</div>
<div id="reply-div" class="col-sm-12">
<form class="form-horizontal" role="form" accept-charset='UTF-8' data-parsley-validate novalidate>
<fieldset>
<div class="form-group">
<label for="ticket-message" class="col-sm-1 control-label"></label>
<div class="col-sm-11">
<textarea class="form-control" name="post-body" id="new_post_textarea" rows="5" cols="30" placeholder="Try to be as specific as possible when posting!"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-1 col-sm-11">
<button id="submit_reply_button" type="submit" class="btn btn-primary btn-block">Submit Reply</span></button>
</div>
</div>
</fieldset>
</form>
</div>
Here is my jquery:
$("#reply-toggle a").click(function() {
alert("running");
$('#reply-div').slideToggle("slow");
)};
I recognize I am not very good in jquery, so I am sure it's something simple, however, I also recognize that I will have to use jquery(closest) to only toggle the reply box associated with the proper comment thread. I have not gotten to this step yet, but it would be greatly appreciated If I could receive some guidance in regards to that as well.
Sincere thanks for any help!
$(document).on('click', '#reply-toggle', function() {
$(this).closest('.col-sm-offset-1').next('#reply-div').slideToggle('slow');
});
edit:added a period to the col-sm-offset-1 class
Your link selector does not match anything. $("#reply-toggle a") will return all <a> tags that have a parent with ID reply-toggle.
You should change this to simply $("#reply-toggle").
Edit: As an aside, you say you have multiple of these Reply buttons - I would strongly recommend you change the ID selector to a class selector as browsers expect only one element with a specific ID per page.
"#reply-toggle a" looks for <a> elements within an element that has id "reply-toggle". Maybe $("a#reply-toggle") would fix your firing issue?
You might want to generate a specific id for each reply toggle and div, say reply-toggle-1and reply-div-1. However, this approach needs a click()defined for each toggle. Use class declarations instead (i.e. not id="reply-toggle", but class="reply-toggle").