i have to click twice, why? (JavaScript onclick event handler) - javascript

i am new to JavaScript and web development and it is the first time i see this kind of bugs. it is a very basic example, i have two divs- left and right- the left one has five images and the right one is empty , i have also two buttons copy and delete, each has an onclick event handler. the Copy button copies the entire left node (div) and appends it to the right div , the delete button should delete the last image in the right div and it does, the thing is i have to click twice on Delete button to delete one image so i have to click 10 times to delete the entire set. why this happens? what should i do to make the Delete button deletes an image by just clicking once ?
this is my entire code , tested on Microsoft Edge and Google chrome and i got the same result.
var theLeftSide = document.getElementById("leftSide");
var theRightSide = document.getElementById("rightSide");
function Copy() {
copy = theLeftSide.cloneNode(true);
theRightSide.appendChild(copy);
}
function Delete() {
copy.removeChild(copy.lastChild);
}
div {
position: absolute;
width: 670px;
height: 520px;
background: red
}
#rightSide {
position: absolute;
left: 670px;
border-left: 1px solid black;
background: black
}
<input type="button" value="Copy" onclick="Copy()">
<input type="button" value="delete" id="btn" onclick="Delete()">
<div id="leftSide" style="width:400px">
<img src="smile.png" />
<img src="smile.png" />
<img src="smile.png" />
<img src="smile.png" />
<img src="smile.png" />
</div>
<div id="rightSide">
</div>

Most browsers instert by default an empty text node between each element of your page, your code is deleting one empty node for every img, that's why it seems to work half of the times.
Try this:
function Delete(){
var imgs = document.querySelectorAll('.rightSide img');
copy.removeChild(imgs[imgs.length-1]);
}

You're removing text nodes as well as elements. What you really want is copy.removeChild(copy.lastElementChild);

Related

Resetting Image to empty when clicking upload after already setting a photo

I have a segment of code that allows for an image to be seen when uploaded but not submitted. However I found that when you hit the upload again and cancel the upload/onchange the image will stay but is actual no longer saved to submit. I wanted it so that when you click upload it sets the element with nothing inside each time and when the upload/onchange is completed the image appear. However it just overrides it and makes it so nothing can be seen
// code for loading photo
var image = document.getElementById('output1');
image.src = URL.createObjectURL(event.target.files[0]);
}
This is the code to clear the element
I had the element ID set to img.output or output1 I have been going back and forth trying to manipulate it but nothing changes both stop the image from showing now
function Empty(elementID){
document.getElementById(elementID).src = "#";
}
This is the element that I wanted to manipulate thats should add the image but always clear when the button is clicked and allow upload when open from the file loader is done.
<p id ="output1"><img id="output" width="200" /></p>
So I am unsure if maybe I am clearing the whole element and that is why it's completely deleting or if its taking precedence on the onclick vs the onchange that happens when you hit open for the upload. I would like more of an explanation of what could be going on with it since I know individually they all work fine but together they interfere.
EDIT:
Someone asked for the full code, there is quite a bit so I posted the sections that involve this part, some of the code is connected to a python file for picture upload which does not need to be changed and works fine even when the image is not seen
forgot to mention using django so that's where the csrf token comes from
<p id ="output1"><img id="output" width="200" /></p>
<form method="post" enctype="multipart/form-data"> <!--Upload Image to media file-->
{%csrf_token%}
<a><input type="file" style="display: none;" accept="image/x-png,image/jpeg" name="image" id="file" onchange="loadFile(event)" required/></a>
<button onclick = "Empty('img.output')" type="button" style="width: 100px; height: 30px; background-color: #008db1; border-radius: 10px; margin-top: 10px; margin-left: 10px;"><label for="file" style="cursor: pointer;">Upload Image</label></button>
<!--Only allow png or jpeg files, so far browse only-->
<button type="BrowseComputer" style="cursor: pointer; width: 100px; height: 30px; background-color: #008db1; border-radius: 10px; margin-top: 10px; margin-left: 10px;">Submit</button>
</form>
<script>
// add a reset to image on upload click & move it
function Empty(elementID){
document.getElementById(elementID).src = "#";
}
var loadFile = function(event) {
var image = document.getElementById('output1');
image.src = URL.createObjectURL(event.target.files[0]);
}
</script>
You are having two errors in your code.
Firstly, when you call the Empty() function, you have set its elementID parameter to img.output, which is not an id. So, you need to change it from img.output to output only.
Secondly, you had used the following code in your JavaScript:
var image = document.getElementById('output1');
image.src = URL.createObjectURL(event.target.files[0]);
Here, you are trying to set the src of the element with id = output. In your HTML, the output1 is actually the <p> element. So, you are trying to set the src of a paragraph! So, change it from
var image = document.getElementById('output1');
to
var image = document.getElementById('output');
The finalized snippet is attached below:
function Empty(elementID) {
document.getElementById(elementID).src = "#";
}
var loadFile = function(event) {
var image = document.getElementById('output');
image.src = URL.createObjectURL(event.target.files[0]);
}
.btn {
cursor: pointer;
width: 100px;
height: 30px;
background-color: #008db1;
border-radius: 10px;
margin-top: 10px;
margin-left: 10px;
}
<p id="output1"><img id="output" width="200" /></p>
<form method="post" enctype="multipart/form-data">
<!--Upload Image to media file-->
{%csrf_token%}
<a><input type="file" style="display: none;" accept="image/x-png,image/jpeg" name="image" id="file" onchange="loadFile(event)" required/></a>
<button onclick="Empty('output')" type="button" class="btn"><label for="file" style="cursor: pointer;">Upload Image</label></button>
<!--Only allow png or jpeg files, so far browse only-->
<button type="BrowseComputer" class="btn">Submit</button>
</form>

Add onmouseover controls

would like to add a play/stop button to an image onmouseover. I have several images in the same div that are called separately. If Image A is called I would like to have a arrow icon/button appear on the image. And onmouseout, the arrow/icon button to disappear from the image. I do not need this on all my images.
The functionality of the icon/button will be to change Image A to it's loop form and back.
Thanks for any help.
Here's what I have used so far: Not sure this is the most efficient way, but I have the main chart and call other charts as overlays, some are transparent layers some are not. When the main map is displayed, I want to call the buttons that float on top of the map. these will utilize the onmouseover/mouseout. And when clicked I want to change the main map to its loop version.
#chart
{
width: 1000px;
height:700px;
border: solid 1px #d9d9d9;
vertical-align: middle;
position: relative;
z-index: 1;
float: left;
}
<div id="chart">
<img name="mymap" src="http://www.dalta.com/still_image.gif"
width="1000px" height="700px" alt="Map" align="middle" />
<div class="basemap" id="HI_basemap" >
<img src="WEB_HI_BASEMAP.gif" width="1000" height="700"></div>
<div class="basemap" id="HI_etp" >
<img src="WEB_HI_ETP_BASEMAP.gif" width="1000" height="700"></div>
<div class="basemap" id="HI_vor" >
<img src="WEB_VOR_HAWAII.gif" width="1000" height="700"></div>
<div class="basemap" id="HI_route" >
<img src="WEB_ROUTES_HI.gif" width="1000" height="700"></div>
</div>
Tried this instead, but need a way to make infinite loop between 2 images.
intImage = 2;
function swapImage() {
switch (intImage) {
case 1:
IMG1.src = "http://ftpweb.delta.com/weather/WEB0HR.gif"
intImage = 2
return(false);
case 2:
IMG1.src = "http://ftpweb.delta.com/weather/WEB.gif"
intImage = 1
return(false);
}
}
I call this with an onClick but it only lets me do the function 1 time. Any ideas?
Then you can add the id attribute, to the image A. Such as this:
<img src="link/to/file.png" alt="photo" id="a" />
Now the JS would be as:
$('#a').hover(function () {
// do what so ever,
}
$('#a').mouseleave(function () {
// do what so ever,
}
There are many other events in the API. You can use them, and execute the code. However to play/stop you can do this:
$('#a').hover(function () {
$('.audioFile').play();
}
This can be achieved by giving a unique id to each of the images .
Then use getElementById("some id") to get a reference to that image. Then attach the onMouseOver and onMouseOut events to these refernces. This task will become very simple if you give a systematic id to the images like img1,img2 etc since you can use a for loop in this case.

Displaying HTML elements on an image with the fade-in and the fade-out effects

I'm displaying two buttons and a checkbox on an image as can be seen in the following
These buttons and the checkbox are shown only when the mouse pointer is positioned over the image. They disappear when the mouse pointer is moved away.
This effect is achieved by the following simple jQuery code.
jQuery(function(){
jQuery(".the-buttons").hide();
jQuery('.show-image').hover(function(){
jQuery(this).find('.the-buttons').fadeIn(600);
},function(){
jQuery(this).find('.the-buttons').fadeOut(300);
});
});
The associated HTML/CSS is as follows.
<span class="show-image" style="position: relative;float:left;margin:5px;">
<a href="../product_images/large/3562298873030291049_Winter.jpg">
<img src="../product_images/medium/3562298873030291049_Winter.jpg" alt="The image is not available"/>
</a>
<input type="button" class="the-buttons" name="btnEdit" value="" style="background-image:url(../css/layout/site/tables/action2.gif);height: 12px; width: 14px; border: none; cursor: pointer; background-color: transparent;position:absolute;top:0;left:0;" title="Click to edit this image." />
<input type="checkbox" class="the-buttons" id="chk" name="chk" title="Check to mark for multiple deletion at once." style="position:absolute;bottom:0;right:0;" value="662"/>
<input type="submit" class="the-buttons" name="btnDeleteSingle" value="" style="background-image:url(../css/layout/site/tables/action4.gif);height: 12px; width: 14px; border: none; cursor: pointer; background-color: transparent; text-align:right;position:absolute;top:0;right:0;" title="Click to delete this image." />
</span>
The static CSS stype as with the buttons and the checkbox is unrelated. The CSS classes show-image with the given <span> tag, the-buttons with the given buttons and the checkbox are interacting with the jQuery code that gives this effect.
I have one additional requirement. When the given checkbox on the bottom-right corner of the image is checked/selected, it should be displayed permanently ignoring the fade-in and the fade-out effects. The two other buttons displayed on the image should however have that effect (when the checkbox is unchecked again, it should have that effect as it is meant). I have tried someway but didn't succeed. Is this possible somehow?
When it's checked, give it a certain class defined as this:
.always-visible {
display: inline !important;
}
And use this code:
$("#chk").on("click", function () {
var $this = $(this);
if ($this.is(":checked")) {
$this.addClass("always-visible");
} else {
$this.removeClass("always-visible");
}
});
(of course, replace $ with jQuery if necessary)
Now I think it might also be necessary to use this code for your fading:
jQuery(this).find('.the-buttons').not('.always-visible').fadeIn(600);
// and
jQuery(this).find('.the-buttons').not('.always-visible').fadeOut(300);
Make a function that checks if the checkbox is checked.
You can then execute this when the picture's hovered.
if($('#chk').is(':checked')) {
get only two of them fading in and out
}
else {
all of them fading in and out
}
Hope this helps.

Hide input button

Here is the code I have: http://jsfiddle.net/Draven/rEPXM/23/
I'd like to know how I can hide that Add submit button until I click the + image to add input boxes to the form.
I don't want to add the submit button next to the input box because I want to be able to add multiple input boxes and submit them all when I click Add.
HTML
<div id="left">
<div class="box">
<div class="boxtitle"><span class="boxtitleleftgap"> </span><span class="boxtitlebulk"><span class="boxtitletext">Folders</span><div style="float: right; margin-top: 4px;"><div class="addplus"> </div></div></span></div>
<div class="boxcontent">
<form method="post" id="folderform" action="page.php?action=list-volunteer-apps" name="folderform">
<a class="even" href="page.php?action=list-volunteer-apps&folder=2">Folder 2 <span class="text">(1)</span></a><a class="even" href="page.php?action=list-volunteer-apps&folder=1">Folder 1 <span class="text">(0)</span></a>
<div id="foldercontainer"><input type="submit" value="Add"></div>
</form>
</div>
</div>
</div>
jQuery
function AddFolder() {
$('#foldercontainer').append('<input name="folder[]" type="text" size="20" />');
}​
Just give the button an ID, and make it start hidden
<input type="submit" id="addButton" value="Add" style="display: none;">
Then use the show() jQuery method:
$("#addButton").show();
http://jsfiddle.net/TcFhy/
Here's a way you could do this... also, cleaned up the method used for making these input boxes a bit:
http://jsfiddle.net/mori57/4JANS/
So, in your html you might have:
<div id="foldercontainer">
<input id="addSubmit" type="submit" value="Add">
<input id="folderName" name="folder[]" type="text" size="20" style="" />
</div>
and your CSS might be:
#foldercontainer #addSubmit {
display:none;
}
#foldercontainer #folderName {
display:none;
width: 120px;
background: #FFF url(http://oi47.tinypic.com/2r2lqp2.jpg) repeat-x top left;
color: #000;
border: 1px solid #cdc2ab;
padding: 2px;
margin: 0px;
vertical-align: middle;
}
and your script could be:
// set up a variable to test if the add area is visible
// and another to keep count of the add-folder text boxes
var is_vis = false,
folderAddCt = 0;
function AddFolder() {
if(is_vis == false){
// if it's not visible, show the input boxes and
$('#foldercontainer input').show();
// set the flag true
is_vis = true;
} else {
// if visible, create a clone of the first add-folder
// text box with the .clone() method
$folderTB = $("#folderName").clone();
// give it a unique ID
$folderTB.attr("id","folderName_" + folderAddCt++);
// and append it to the container
$("#foldercontainer").append($folderTB);
}
}​
I moved the button out of the folder wrap, and I am showing it when you add a new folder. This way the button will stay at the bottom when adding new folders. I also removed the inline style, and replaced it with a class.
This is used to display the button, just add it to the AddFolder() function:
$('#addBtn').show();
I am hiding it with CSS like this:
#addBtn { display: none;}
I moved the button out of the #foldercontainer, this way it will always stay at the bottom when you add multiple folders, as you wanted:
<div id="foldercontainer"></div>
<input id="addBtn" type="submit" value="Add">
Look here for the jsFiddle: http://jsfiddle.net/kmx4Y/1/
$('form#folderform input[type=submit]').hide();
Then show the add button after you click the submit
http://jsfiddle.net/SQh8L/

Can each new click produce a new image?

I know how to make an image appear using onclick or onMouseOver but how can I make each click produce the appropriate image not just in the same place but, for example, in a row, next to it's previous apperance? My idea is this: I click on reference1 and a picture1 shows up. Then I click on reference2 and a picture2 shows up next to the picture1 already displayed. Now I click on reference1 again, and I want to see pictures 1,2,1 in a row. How can I do that? My ideal would be to see the row rolling when filled, and a delete button deleting the last image in that row, even making the pictures jump out being called from the text field, but I can search for these myself. My greatest concern for now is new click=new image. Thank you.
Assuming this is relatively simplistic- you could keep track of the current position in a list of images, afterwards create a function that deals with the current image then increments this position. Have the onClick event call this function, and there you are.
An example of this in action, using JQuery, can be viewed here:
http://jsfiddle.net/8Q4LQ/
Here's an example.
<html>
<head>
<style>
.refimg { width: 100px; height: 100px; }
.choices a { margin-right: 2ex; }
.choices img { display: none; }
#target { display:block; width: 500px; overflow-x: scroll; border: 1px solid black; }
</style>
</head>
<body>
Choices:
<div class="choices">
ref1
ref2
<image id="image1" src="image1.gif" class="refimg" />
<image id="image2" src="image2.gif" class="refimg" />
</div>
<br />
Selections: <input type="button" value="Delete" onclick="delImage()" />
<nobr id="target">
</nobr>
<script>
function putImage(src) {
var a = src.cloneNode(true);
a.id = ''; //clear id to prevent duplicate id
target.appendChild(a);
a.scrollIntoView(true);
return false;
}
function delImage() {
var a=target.children;
if (a.length>0) target.removeChild(a[a.length-1]);
}
target.style.height=((target.offsetHeight-target.clientHeight)+100)+'px'; //extend height for scroll bar
</script>
</body>
</html>

Categories

Resources