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
}
Related
I have a form that has three separate divs within it.
<form method="post">
<div id = "f1">
<div class="label">Value 1:</div>
<input type="text" name="name"/>
<button id = "next1" type="button" onclick="checkValue()">Next</button>
</div>
<div id ="f2">
<div class="label">Value 2:</div><br>
<input type="text" name="name"/>
<button type="button" onclick="checkValue()">Next</button><br>
</div>
<div id ="f3">
<div class="label">Value 3:</div><br>
<input type="text" name="name"/>
<button type="button" onclick="checkValue()">Next</button><br>
</div>
</div>
</form>
In my javascript function. I have a fadein and fadeout attached to each div when the next button is pressed. When the "next1" button is pressed the first div will be faded out and the second div will fade in. I want to check the values inputted in the first div when the user presses the first next button. I know how to do this if i just passed in the whole form into my javascript function on the final submit button, but I would like to know how to do this after each next button is pressed.
I also will have more than one value in each of the divs (f1, f2, f3) but for simplicity I only included one value.
EDIT*: further explaintaion
If i did this by passing in the form into checkValue. I could just do an onsubmit = "checkValue()". And then in my JS file, I would just include checkValue(form) as its parameter. If i want to do a check after every single button is pressed, I am not sure how to do this or what to pass in as its parameter.
Simple mock up hopefully to get you one your way.
Fiddle: http://jsfiddle.net/AtheistP3ace/krr3tgLx/1/
HTML:
<form method="post">
<div id="f1" style="display: block;">
<div class="label">Value 1:</div>
<input type="text" name="name" />
<button id="next1" type="button" onclick="checkValue(this)">Next</button>
</div>
<div id="f2">
<div class="label">Value 2:</div>
<br>
<input type="text" name="name" />
<button type="button" onclick="checkValue(this)">Next</button>
<br>
</div>
<div id="f3">
<div class="label">Value 3:</div>
<br>
<input type="text" name="name" />
<button type="button" onclick="checkValue(this)">Next</button>
<br>
</div>
</div>
</form>
JS:
function checkValue (button) {
// Finds the sibling input of the button
var input = $(button).siblings('input');
// Gets input value
var value = input.val();
// Stops showing next div if no value
if (value == '') {
return false;
}
else {
// Finds the parent div holding button and input
var div = $(button).closest('div');
// Fades out current div
div.fadeOut();
// Gets next div and fades it in
div.next().fadeIn();
}
}
CSS:
form > div {
display: none;
}
From my assumptions this is what you are looking for :
Multipart form handler
Basically I wired up each button with a class
<button id = "next1" type="button" class="check-btn">Next</button>
Then I used Jquery to get all those buttons and find the parent div (based on your structure) and then get all the child inputs (can include selects etc). From here you can continue to tweak to perform a check on each type of input etc.
$(document).ready(function(){
$('.check-btn').on('click',function(){
var parent = $(this).parent('div');
var elems = parent.find('input');
alert(elems.length);
//DO checks here for each element
});
});
I have an HTML template consisting of a DIV that contains three buttons.
<template ID="template3buttons">
<div ID="container3buttons" class="boxes">
<div ID= "sunShadeUp" class="boxes">
<input type="button"
id="SunshadeButtonUp"
class="SunshadeSmallButton"
onclick="GenericAction('ENO_ShutterStop($all)', 'all')"
value=""/>
</div>
<div ID= "sunShadeStop" class="boxes">
<input type="button"
id="SunshadeButtonStop"
class="SunshadeSmallButton"
onclick="GenericAction('ENO_ShutterStop($all)', 'all')"
value=""/>
</div>
<div ID= "sunShadeDown" class="boxes">
<input type="button"
id="SunshadeButtonDown"
class="SunshadeSmallButton"
onclick="GenericAction('ENO_ShutterStop($all)', 'all')"
value=""/>
</div>
</div>
</template>
I use JS to generate many copies of the template, which are eventually inserted into appropriate DIVs.
function create3Button(cellButtonId) //create boxes with 3 buttons each
{
var template3buttons = document.querySelector('#template3buttons');
var insertionPoint= document.getElementById(cellButtonId);
var clone = document.importNode(template3buttons.content, true);
insertionPoint.appendChild(clone);
}
Now, i need to manipulate the content of the 'onclick' tag for each copy of the template depending on the insertion point. I understand that getElementById() does not work for DOM nodes. What are the alternatives?
If you use jQuery you can do this:
$("[id*=sunShade]").children().click(function() {
alert( "Handler for .click() called." );
});
This is my code:
Javascript:
$(".test").on("focusout", function (e) {
$("#output").append("Lost focus<br>");
});
HTML:
Inputs inside div:
<div class="test">
<input type="text" />
<input type="text" />
</div><br>
Inputs outside div:<br>
<input type="text" />
<div id="output">
</div>
I want to detect if user leaves "div.test". Unfortunately, "focusout" works also when I move focus to other object inside this div.
Look at this fiddle: http://jsfiddle.net/Piotrek1/wfukje3g/6/
Click on first input and use Tab to switch through textboxes. "
Lost focus" should appear only if user move out from the div, but it happens always. Why is that and how to change it?
The $ operator returns a collection. You have two inputs inside the <div class="test">. So it matches all elements and children with the .test class.
I think what you want two divs with separate input elements and two different classes OR, use an ID on the actual input element so the $ operator only matches the input id you want this event to fire on. http://jsfiddle.net/wfukje3g/7/
$("#test").on("focusout", function (e) {
$("#output").append("Lost focus<br>");
});
<div class="sometest">
<input id="test" type="text" />
<input type="text" />
</div><br>
Inputs outside div:<br>
<input type="text" />
<div id="output">
</div>
I have implemented piece of code to handle div focus out
$(document).ready(function () {
var count = 1;
$("#name").focusout(function (e) {
if($(this).has(e.relatedTarget).length === 0) {
$("#output").append("<label style='width:100%;'>"+ count++ +" Name div focus out </label>");
}
});
});
Inputs inside div:
<div id="name" class="test">
<input type="text" id="firstname"/>
<input type="text" id="lastname"/>
</div>
Inputs outside div:<br>
<input type="text" id="dob"/>
<div id="output" style="width:100%"></div>
In this piece of code I have used relatedTarget.
relatedTarget will provide the next focused element If next element is not the child of this div then it is div focus out.
Try this in your code.
I hope this will be helpful.
Thanks
JSFIDDLE LINK - Sample code
I have an div element ("main") on my page who's contents changes back and forth between two different screens (their id's are "readout" and "num"), the contents of which are stored as hidden div elements (using display:none). Each screen has a button which sets mainto the other hidden div.
Since I struggled to get javascript to put num.innerHTML into main on load, I've ended up putting virtually identical content to num (with a different form name) into main:
<p>Number of Passengers per Carriage:</p>
<form method="post" action="javascript:void(0);" name="applesForm" onSubmit="setPassengers();">
<input type="text" name="numApples" id="numPassengers" />
<br/><br/>
<input type="submit" name="Submit" value="OK!"/>
</form>
setPassengers() successfully sets main's contents to readout. readout successfully sets main's contents to num (virtually identical to the original content of main). But then it won't go back to readout.
Here are setPassengers() and setPassengersAgain(), which is the same but for a different form name:
function setPassengers()
{
passengers=document.applesForm.numPassengers.value;
document.getElementById('main').innerHTML=readout.innerHTML;
}
function setPassengersAgain()
{
passengers=document.applesFormAgain.numPassengers.value;
document.getElementById('main').innerHTML=readout.innerHTML;
}
So my question is:
1)Why isn't num changing to readout?
2)Is there a way to load num straight away on page load so as to simplify the code?
EDIT: I can use onload, which means that num is the only bit that's broken...
EDIT 2: Here are the hidden div's:
<div id="readout" style="display:none">
<p>Throughput per hour:</p>
<p id="output">--</p>
<p>Average Dispatch Time:</p>
<p id="avDisTime">--</p>
<form method="post" action="javascript:void(0);" name="dispatchForm" onSubmit="dispatch();i++;">
<input type="submit" name="Submit" value="Press on Dispatch!"/>
</form>
<br/>
<form method="post" action="javascript:void(0);" name="resetTimesForm" onSubmit="resetTimes();">
<input type="submit" name="Submit" value="Reset Times"/>
</form>
<form method="post" action="javascript:void(0);" name="resetAllForm" onSubmit="resetAll();">
<input type="submit" name="Submit" value="Reset All"/>
</form>
</div>
<!--back to default page-->
<div id="num" style="display:none">
<p>Number of Passengers per Carriage:</p>
<form method="post" action="javascript:void(0);" name="applesFormAgain" onSubmit="setPassengersAgain();">
<input type="text" name="numApples" id="numPassengers" />
<br/><br/>
<input type="submit" name="Submit" value="OK!"/>
</form>
</div>
You didn't post your HTML code, so I don't know how it looks like, but you could use somethin like:
HTML:
<button id="changeMain">Change #main</button>
<div id="main">
<div id="readout" class="screen show">
Readout
</div>
<div id="num" class="screen">
Num
</div>
</div>
CSS:
#main>.screen{display:none;}
#main>.screen.show{display:block;}
JavaScript:
var els=[document.getElementById('readout'),document.getElementById('num')],current;
function addClass(el,c){
var arr=el.className.split(' ');
if(arr.indexOf(c)>-1){return;}
arr.push(c);
el.className=arr.join(' ');
}
function delClass(el,c){
var arr=el.className.split(' ');
var i=arr.indexOf(c);
if(i===-1){return;}
arr.splice(i,1);
el.className=arr.join(' ');
}
document.getElementById('changeMain').onclick=function(){
if(!current){
for(var i=0,l=els.length;i<l;i++){
if(els[i].className.indexOf('show')>-1){
current=i;
break;
}
}
}
delClass(els[current],'show');
current=(current+1)%els.length;
addClass(els[current],'show');
}
DEMO: http://jsfiddle.net/CUgqh/
Explanation:
If you want some content insode #main, you should place inside it (hidden or shown). Then, we hide all .screen with #main>.screen{display:none;} except .screen.show: #main>.screen.show{display:block;}.
Then, JavaScript code:
First we create an array with the elements:
var els=[document.getElementById('readout'),document.getElementById('num')],current;
And a function which adds/removes a class c to the element el:
function addClass(el,c){
var arr=el.className.split(' ');
if(arr.indexOf(c)>-1){return;}
arr.push(c);
el.className=arr.join(' ');
}
function delClass(el,c){
var arr=el.className.split(' ');
var i=arr.indexOf(c);
if(i===-1){return;}
arr.splice(i,1);
el.className=arr.join(' ');
}
And we create an event to the button:
document.getElementById('changeMain').onclick=function(){
if(!current){
for(var i=0,l=els.length;i<l;i++){
if(els[i].className.indexOf('show')>-1){
current=i;
break;
}
}
}
delClass(els[current],'show');
current=(current+1)%els.length;
addClass(els[current],'show');
}
The code above does:
If it's the first time the current els' index (current) is undefined, we search which element has the class show by default.
It removes the class show to the current shown element, so it disappears.
It adds 1 to current (or it becomes 0 if it was the last els' element
It add class show to the current element, so it appears.
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.