Javascript onfocus / onblur issues - javascript

So I am making a little searchbar that shows results underneath of it like such:
<div id='searchWrapper'>
<div id='Search'>
<input id="inputSpn" type="input" value="" />
<input id="searchBtn" type="image" src="/search.png" />
<br clear='all'/>
</div>
<div id='Results'>
</div>
</div>
I am basically doing a livesearch with through AJAX. The <div id='Results'> is initially hidden until you type and it populates some results. My issue however is getting it to hide when the user clicks away. having it disappear through onblur does not work either as I need to be able to click on the results and not have them disappear on me. Unfortunately I have not been able to find a good non jQuery method on the internet yet. Simplest way to put it is: I want the results to disappear if anything but the <div id='searchWrapper'> is clicked. Thanks!

Here is a non-optimised but working non-jQuery solution
<script>
document.onclick=function(e) {
var elem = e?e.target:event.srcElement;
var id = elem.id;
document.getElementById("inputSpn").value=id+" clicked"; // debug - remove when happy
// the following could be done by looping over the searchWrapper and its children
if (id !="searchWrapper" && id!="Search" && id != "inputSpn" && id != "searchBtn" && id != "Results") {
document.getElementById("Results").style.display="none"
}
}
</script>
<div id='searchWrapper'>
<div id='Search'>
<input id="inputSpn" type="input" value="" />
<input id="searchBtn" type="image" src="TekTP/icons/search.png" />
<br clear='all'/>
</div>
<div id='Results'>hello
</div>
</div>
UPDATE:
Toggle if clicked on the wrapper div
var hide= (id !="searchWrapper" && id!="Search" && id != "inputSpn" && id != "searchBtn" && id != "Results");
document.getElementById("Results").style.display=(hide)?"none":"block";

Add a listener to the document (using addEventListener) - JSFiddle Example
<style>
#Results {
display: none;
}
</style>
<script type="text/javascript">
window.onload = function(){
document.addEventListener('click', function(event){
if(document.getElementById('searchBtn') != (event.target) ? event.target : event.srcElement) {
document.getElementById('Results').style.display = 'none';
} else {
document.getElementById('Results').style.display = 'block';
}
});
};
</script>
<div id='searchWrapper'>
<div id='Search'>
<input id="inputSpn" type="input" value="" />
<input id="searchBtn" type="button" value="Search"/>
<br clear='all'/>
</div>
<div id='Results'></div>
</div>
But if you are going to be using a significant amount of Javascript in your site, you might consider using jQuery - it will make your life much easier.

Related

jQuery toggle won't work for checkbox, div remains display:block

I have an input checkbox field and when the checkbox changes (user clicks or unclicks) the div below should toggle. In my style sheet I have the div paypalInputArea as display:none and when the checkbox in clicked, it should toggle, however I can't seem to get it to work. Can anyone see what is wrong with my code?
Here is my html:
<div class="checkbox-row" id="paypalCheckbox">
<input type="checkbox" maxlength="2147483647" value="true" name="paypalPaymentCheckbox" id="paypalPaymentCheckbox" class="checkinput styled" />
<label class="paymentMethodTitle"></label>
</div>
<div class="paypalInputArea">
<isinclude template="includes/paymentmethodsinclude" />
</div>
And here is my jQuery:
$("#paypalCheckbox.checkbox-row .areaExpander").on('change', function() {
$(".paypalInputArea").toggle();
if ($('.paypalInputArea').is(':visible')) {
app.paymentAndReview.setCOContinueBtn(true);
$("#paypalPaymentCheckbox").attr('checked','true');
$('#paypalCheckbox.checkbox-row .areaExpander').addClass('open');
} else {
$("#paypalPaymentCheckbox").removeAttr('checked');
$('#paypalCheckbox.checkbox-row .areaExpander').removeClass('open');
app.paymentAndReview.setCOContinueBtn(false);
}
});
$("#paypalCheckbox.checkbox-row input").attr('checked') && app.paymentAndReview.setCOContinueBtn(true);
$("#paypalCheckbox").on('change', function() {
$(".paypalInputArea").toggle();
if ($('.paypalInputArea').is(':visible')) {
//app.paymentAndReview.setCOContinueBtn(true);
$('#paypalCheckbox.checkbox-row .areaExpander').addClass('open');
} else {
$('#paypalCheckbox.checkbox-row .areaExpander').removeClass('open');
//app.paymentAndReview.setCOContinueBtn(false);
}
});
$("#paypalCheckbox.checkbox-row input").attr('checked') && app.paymentAndReview.setCOContinueBtn(true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="checkbox-row" id="paypalCheckbox">
<input type="checkbox" maxlength="2147483647" value="true" name="paypalPaymentCheckbox" id="paypalPaymentCheckbox" class="checkinput styled" />
<label class="paymentMethodTitle"></label>
</div>
<div class="paypalInputArea" style="display:none">
blabla
</div>
just replace the line:
$("#paypalCheckbox.checkbox-row .areaExpander").on('change', function() {
with:
$("#paypalCheckbox").on('change', function() {
As you have an ID (which has to be unique) you dont have to use other classes or else to reach it!
you can also remove those lines as the attrribute checked is set as the user clicks on the checkbox
$("#paypalPaymentCheckbox").attr('checked','true');
$("#paypalPaymentCheckbox").removeAttr('checked');
Hope this helps!
It looks like you're missing the class areaExpander from your checkbox

Unable to attach Event to an Submit button in a form

On the following page "https://www.capgemini.com/new-ways-to-accelerate-innovation". there are multiple sections with "Expand" button and when you click on expand button a form gets exposed. the issue here is am not able to attach click event to the "Submit" button.
I have tried using addeventlistener but the event is not getting assigned.
How do I do that, please advise.
https://www.capgemini.com/new-ways-to-accelerate-innovation
Expand Button is in the below code.
<div class="exp_article-header-bg">
<div class="exp_article-header-inner">
<h2 class="exp_article-header-title">TechnoVision 2017</h2>
<div class="exp_article-header-author"></div>
<div class="exp_article-header-lead">
<p>
TechnoVision 2017 gives you a framework to create a new digital story to solve problems and grasp new opportunities. Our 37 technology building blocks will help you to navigate the technology maze and give a clear direction to your business.
</p>
</div>
<div class="exp_article-header-expand">
**
<div class="exp_link exp_link--white exp_link--expand">
<span class="exp_link-label">EXPAND</span>**
<span class="exp_button-arrow exp_button-arrow--down"></span>
</div>
</div>
</div>
</div>
Form gets exposed when you click the above Expand button. The Submit button is in the form as highlighted below.
<form accept-charset="UTF-8" method="post" action="https://go.pardot.com/l/95412/2017-08-09/2tfbfg" class="form" id="pardot-form">
<style type="text/css">
form.form p label {
color: #000000;
}
</style>
<p class="form-field email pd-text required ">
<label class="field-label" for="95412_59459pi_95412_59459">Email Address</label>
<input type="text" name="95412_59459pi_95412_59459" id="95412_59459pi_95412_59459" value="" class="text" size="30" maxlength="255" onchange="piAjax.auditEmailField(this, 95412, 59459, 44072473);">
</p>
<div id="error_for_95412_59459pi_95412_59459" style="display:none"></div>
<p style="position:absolute; width:190px; left:-9999px; top: -9999px;visibility:hidden;">
<label for="pi_extra_field">Comments</label>
<input type="text" name="pi_extra_field" id="pi_extra_field">
</p>
<!-- forces IE5-8 to correctly submit UTF8 content -->
<input name="_utf8" type="hidden" value="☃">
<p class="submit">
<input type="submit" accesskey="s" value="Submit Now">
</p>
<script type="text/javascript">
//<![CDATA[
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
if (anchor.getAttribute("href") && !anchor.getAttribute("target")) {
anchor.target = "_top";
}
}
//]]>
</script>
<input type="hidden" name="hiddenDependentFields" id="hiddenDependentFields" value="">
</form>
Have CSS display:none; for the element which needs to be expanded. when expand is clicked call a javascript function which checks if the element is hidden , if hidden change the CSS display: block;.
Check the below working code.
<body>
<div class="exp_article-header-bg">
<div class="exp_article-header-inner">
<h2 class="exp_article-header-title">TechnoVision 2017</h2>
<div class="exp_article-header-author"></div>
<div class="exp_article-header-lead"><p>TechnoVision 2017 gives you a framework to create a new digital story to
solve problems and grasp new opportunities. Our 37 technology building blocks will help you to navigate the
technology maze and give a clear direction to your business.</p>
</div>
<div class="exp_article-header-expand">
**
<div class="exp_link exp_link--white exp_link--expand">
<button onclick="myFunction()" class="exp_link-label">EXPAND</button>
**
<span class="exp_button-arrow exp_button-arrow--down" id="expandDiv"
style="color: #000066; background-color: gainsboro;display: none;">I Got Expanded</span></div>
</div>
</div>
</div>
</body>
Javascript function:-
<script>
function myFunction() {
var x = document.getElementById('expandDiv');
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
</script>
check on plnkr: https://plnkr.co/edit/MWKYxmV6Jk2eId3Owt2u?p=preview
where is ur form opening? if u're usingjquery, just target the form id and do .submit()
You're going to want to use the 'onsubmit' event listener, most likely with a preveninstead of a click event.
document.querySelector("#submit-button").addEventListener("submit", function(event) {
//your stuff here
event.preventDefault();
}, false);

jQuery targeting element inside a div with only unique data-field

I get the following HTML of which I have no control:
<div class="form-wrap">
<div class='input-wrap' data-field='start-set'>
<input type='radio' name='participant[0][start-set][value]' value='Information centre' class='participant-form--input-radio'/>
<span>Information centre</span>
<input type='radio' name='participant[0][start-set][value]' value='Terminal' class='participant-form--input-radio'/>
<span>Terminal<span>
</div>
<div class='input-wrap' data-field='delivery'>
...
</div>
</div>
And this might be repeated multiple times in the same page, for different participants.
What needs to be done is to capture the radio input change and if the radio value is 'terminal', to display the sibling div with data-field='delivery'.
I am really bad at front end, so would appreciate any help or guidance.
You can use tree traversal#next() method
$("input[type='radio'].participant-form--input-radio").on('change', function() {
var currentRadio = $(this);
if (currentRadio.val() == "terminal") {
currentRadio.parent().next().show();
}
})
$('input[type=radio]').change(function() {
if ($(this).val() == 'Terminal') {
$(this).parents('.input-wrap').next('[data-field=delivery]').show();
} else {
$(this).parents('.input-wrap').next('[data-field=delivery]').hide();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="form-wrap">
<div class='input-wrap' data-field='start-set'>
<input type='radio' name='participant[0][start-set][value]' value='Information centre' class='participant-form--input-radio' />
<span>Information centre</span>
<input type='radio' name='participant[0][start-set][value]' value='Terminal' class='participant-form--input-radio' />
<span>Terminal<span>
</div>
<div class='input-wrap' data-field='delivery' style="display:none;">
...
</div>
</div>
First, you'll need to bind a change event to your radio button, I've used the name starts with ... selector.
$('input[name^=participant]').on('change', function() {
Alternatives are:
$('input:radio') /* all radiobuttons */
$('.form-wrap input:radio') /* all radiobuttons inside .form-wrap */
$('.participant-form--input-radio') /* class selector */
After that we need to find the element we want to show and hide. I prefer to travel up the tree to the elements parent and the find the child we are looking for
$(this).closest('.form-wrap').find('[data-field="delivery"]')
Then I use toggle(statement) to either hide or show it. The statement in this case will be "is the value 'Terminal'"
.toggle( $(this).val() == 'Terminal' )
All together, it looks like this:
$(function() {
$('input[name^=participant]').on('change', function() {
$(this).closest('.form-wrap').find('[data-field="delivery"]').toggle( $(this).val() == 'Terminal' );
});
});
[data-field="delivery"] { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-wrap">
<div class='input-wrap' data-field='start-set'>
<input type='radio' name='participant[0][start-set][value]' value='Information centre' class='participant-form--input-radio' />
<span>Information centre</span>
<input type='radio' name='participant[0][start-set][value]' value='Terminal' class='participant-form--input-radio' />
<span>Terminal</span>
</div>
<div class='input-wrap' data-field='delivery'>
...
</div>
</div>

hide a checkbox in function another and disabled all elements to the checkbox disabled

<script type="text/javascript">
function CheckBox(checkerbox, div) {
if (checkerbox.checked) {
document.getElementById(div, Urbanoo).style.display = "block"
} else {
document.getElementById(div, Rurall).style.display = "none"
$("#Rurall").find("*").prop("disabled", true);
}
}
function CheckBox1(checkerbox1, div) {
if (checkerbox1.checked) {
document.getElementById(div, Rurall).style.display = "block"
} else {
document.getElementById(div, Urbanoo).style.display = "none"
$("#Urbanoo").find("*").prop("disabled", true);
}
}
</script>
How to hide a checkbox in function another and disabled all elements to the checkbox disabled?
<input name="Rural" type="checkbox" onclick="CheckBox1(this,'Rurall');" />
<input name="Urbano" type="checkbox" onclick="CheckBox(this,'Urbanoo');" /> Urbanoo </center>
<div id="Urbanoo" style="display:none" >
<g:render template="../DomUrbano/form"/>
</div>
The problem is that when I turn on a check box not the other box is not disabled
<div id="Rurall" style="display:none">
</br>
<g:render template="../DomRural/form"/>
</div>
I think I see what you are attempting but frankly it's less than super clear.
SO what I think you want is;
Hide other checkboxes if I check one
If I do uncheck a box, show the other one again
Show a "partner" area if I check a box
Disable other NOT partner area inputs if I check a box
I modified your markup some to make it easier and also added some additional to clearly show what is happening. I also added a data element for the partner to the input so we can make this all simpler and only have one function; now called via an event handler and NOT with inline code in markup.
Revised markup:
<span class="myinputs"><input class="mycheck" name="Rural" type="checkbox" data-partner="#Rurall" /> Rurall</span>
<span class="myinputs"><input class="mycheck" name="Urbano" type="checkbox" data-partner="#Urbanoo" /> Urbanoo</span>
<div id="Urbanoo" class="hidden others">the Urbannoo
<g:render template="../DomUrbano/form" />
<input type="textbox"/>
</div>
<div id="Rurall" class="hidden others">the Rurall
<g:render template="../DomRural/form" />
<input type="textbox"/>
</div>
Code:
$('.mycheck').on('change', function() {
var amIChecked = $(this)[0].checked;
$(this).parent().siblings('.myinputs').toggle(!amIChecked);
var pt = $(this).data('partner');// get the partner selector
$(pt).toggle(amIChecked);// show the partner in the others list
//do the enable in the partner
$('.others').filter(pt).toggle(amIChecked).find("*").prop("disabled", !amIChecked);
//do the disable in the othes list not the partner
$('.others').not(pt).find("*").prop("disabled", amIChecked);
});
Play with it all here: https://jsfiddle.net/MarkSchultheiss/cLyb103x/1/

find form id div is in

Bit of a weird question. I have got a form and inside this form the controls are div's with onClick events instead of buttons. I can't use buttons as I can't use page reloads, instead I have to send all data using ajax.
Plus half of the buttons just increase counters, below is my code. How would I go about using JavaScript to find the form ID that the element clicked on is in. So as an example:
<form id="20">
...
<div onClick="doSomething(this)">
...
</form>
The doSomething will then keep moving up levels of parents or something like that until it finds the form, and then a variable will have the form id assigned to it.
<form id="50">
<div class="image_container background">
<div style="text-align:center; font-size:12px;">image1</div>
<input type="hidden" id="imgId" value="50" />
<div class="image" style="background-image:url(images/image3.JPG);"></div>
<div class="selected_product">
<span>KR</span>
</div>
<input type="hidden" id="applied_products" value="KR" />
</div>
<div class="controls_container background">
<div id="selected">KR</div>
<a class="button arrow expandProducts">
<span>
<div class="products">
<span>KR</span>
<span>A5</span>
<span>CC</span>
</div>
</span>
</a>
<hr />
<span class="button plus" onClick="sale(this)"></span>
<input type="text" id="amount" disabled="disabled" value="0"/>
<span class="button minus"></span>
<hr />
<input type="text" id="total" disabled="disabled" value="£0"/>
</div>
</form>
Your doSomething function could continue navigating through it's parents until it finds a form, like so:
function doSomething( elem )
{
var parent = elem.parentNode;
if( parent && parent.tagName != 'FORM' )
{
parent = doSomething(parent);
}
return parent.id;
}
Also, if you use <button type="button">...</button> it won't cause a page refresh, since the default button type is submit.
If you are going straight javascript and not jquery or some other library. Each DOM Element has a parentNode Property
var elm = document.getElementById(yourDivId);
var parent = elm.parentNode;
From there you can cycle through each parent, until you get back to the form element and then pull out the id.
How about something like that:
function handler(target) {
var parent = target.parentNode;
// loop until parent is a form or browser crashes :)
while (parent.tagName != 'FORM') {
parent = parent.parentNode;
}
var formId = parent.id; // the id you wanted
// do stuff
}

Categories