Hitting 'Cancel' during file upload in Chrome clears value - javascript

I'm working with a simple html type="file" input, and I'm having an issue in Chrome. Specifically, when you browse to and choose a file, it saves the value. However, if you re-browse, then press cancel it will clear out the value.
The html is simple:
<input type="file">
Here is a simple fiddle- http://jsfiddle.net/78ghn/.
This doesn't happen in other browsers -- is there a way to force Chrome to retain the value??

function f()
{
document.getElementById("b").appendChild(document.getElementById("a"));
document.getElementById("d").innerHTML = document.getElementById("c").innerHTML
document.getElementById("alert").innerHTML = 'Your last file was '.concat(document.getElementById("b").lastChild.value.slice(12))
}
function g()
{
if(document.getElementById("b").lastChild.value)
{
document.write("You have submitted ".concat(document.getElementById("b").lastChild.value.slice(12)));
}
else
{
document.write("You have submitted nothing.");
}
}
#a
{
opacity: 0;
width: 100%;
height: 100%;
}
#c
{
display: none;
}
#d
{
width: 100%;
height: 100%;
}
#e
{
background-color: green;
border: 2px solid black;
color: white;
font-size: 16pt;
width: 180px;
height: 90px;
}
#f
{
position: relative;
left: 25%;
bottom: 70%;
}
<form>
<div id='e'>
<span id='d'>
<input type="file" onchange='f();' id='a'>
</span>
<span id='f'>Select File</span>
</div>
<input type='button' value='Submit' onclick='g();'>
</form>
<span id='alert'>You have chosen no files.</span>
<ul id='b'>
</ul>
<form id='c'>
<input type="file" onchange='f();' id='a'>
</form>
I was unable to find a native implementation for this, so I tried my own workaround. It takes input from a custom CSS button overlay, then adds the actual input element to a list and replaces it with an empty one. The value is read and displayed, as it would be with a normal input. It is not included, but submitting it would involve moving the original input (last element of ul with id='b') to a form and submitting it via JavaScript. It is not optimal, but it does work.

Related

Creating ID card with HTML

I'm trying to create a simple ID card template with HTML but I got stocked for days looking for how to make passport photograph appear in the photograph box. I also noticed that the print preview of the ID card is not the same as what I see on screen, how can I fix this too please? Below is the code...
function printDiv(divName) {
var printContents = document.getElementById(divName).innerHTML;
w = window.open();
w.document.write(printContents);
w.print();
w.close();
}
body {
background-image: url("id-template.jpg");
background-attachment: fixed;
background-repeat: no-repeat;
background-position: center;
}
#media print {
#print {
display: none;
}
}
#print {
position: fixed;
bottom: -4px;
}
div {
padding-top: 204px;
}
<div id="identity"> <span style="padding-left: 436px;">
<form style="display: inline;"><input type="file" accept="image/jpeg"
placeholder="PASSPORT PHOTO" style="border-color: grey; border-radius: 90px; height: 155px; width: 155px; text-align: center; font-family: monospace; font-size: 10px; margin-bottom: 7px" /></form></span>
<br>
<span style="padding-left: 370px">
<form style="display: inline;"><input placeholder="YOUR NAME" style="border-color: grey; border-radius: 5px; height: 25px; width: 280px; text-align: center; font-family: monospace; font-size: 20px;" /></form></span>
</div><br>
<center><input type="button" id="print" onclick="print()" value="Print" /></center>
The two helps I need
I want the photograph to appear when selected from the user's device.
I want the print preview to show exactly what on the page.
This is the id-template.jpg I'm working with.
Thanks.
The html in your question has lots of noise and was relying on odd strategies for positioning.
For the sake of showing the core of the issue you are meant to solve, I stripped it down to the bare minimum. It won't perfectly match with your expectations but the css is well commmented so it will be easy for you to restyle it according to your needs.
Displaying the picture loaded by user in an <input type=file>
Anyway the main problem there was how to show the picture in the file just loaded inside an input type="file" element.
The key is having a change event handler on your input file element so that when the user loads a new file, it will attempt to read it using a FileReader and will change the src attribute of an <img> element existing in the dom.
.noprint class to style elements when #media print
I also added a class noprint to add to all the elements that will be hidden by the media query #media print. Such class is given to the <input type="file"> and to the <button> for printing.
References
https://developer.mozilla.org/en-US/docs/Web/API/FileReader
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file
Demo
I did a very small demo to show the point:
function printDiv(divName) {
var printContents = document.getElementById(divName).innerHTML;
w = window.open();
w.document.write(printContents);
w.print();
w.close();
}
/*shows inside #preview the picture loaded in the #photo element*/
function previewImage() {
var preview = document.getElementById('preview');
var file = document.getElementById('photo').files[0];
//creates a FileReader with the onLoadEnd event handler
var reader = new FileReader();
reader.onloadend = function () {
//..that will change the src attribute of the preview element to show the picture loaded
preview.src = reader.result;
}
//if there's a file loaded
if (file) {
//unhide the #preview element
preview.style.display = "block";
//lets the FileReader reads the file loaded
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
body {
font-family: monospace; /* <----- here I set the font/size for all children in body */
font-size: 18px;
}
/*hides the .noprint elements when printing*/
#media print {
.noprint {
display: none !important;
}
}
/*flex container*/
#identity{
display: flex;
flex-direction: column;
gap: 1em; /* <----- here I set space between elements in the container */
}
/*flex items*/
#identity > *{
margin: 0 auto; /*horizontally centered*/
}
/*all input elements*/
input{
border-color: grey;
text-align: center;
}
/*name input*/
#name{
width: 30ch; /* <----- here I chose the name input to have 30ch*/
}
/*preview*/
#preview{
width: 30%; /* <----- here I chose the preview to have 30% container width*/
}
#print{
display: block;
margin: 1em auto 0 auto;
cursor: pointer;
}
<body>
<form id="identity">
<input
id="photo"
class="noprint"
name="photo"
type="file"
accept="image/jpeg"
placeholder="PASSPORT PHOTO"
onchange="previewImage()">
<img id="preview" src="#" alt="Image preview" style="display:none;">
<input
id="name"
name="name"
placeholder="YOUR NAME">
</form>
<button type="button" id="print" class="noprint" onclick="print()">Print</button>
</body>

onSubmit Adding a Second Javascript Action After Form Validation

I have a form that uses very basic input validation using javascript onSubmit before the server side processing begins in PHP.
However, due to the time the PHP script takes to process (uploading images etc) I am trying to use the same onSubmit function to display a "please wait" notice if it passes validation. Or is there a better way? I tried in PHP, but the processing has to complete before I can echo any output. Anything I have tried from other SO posts stops the validation process.
<form id="form" method="post" action="" onsubmit="return Validate(this)" autocomplete="off">
Current Javascript Example
function Validate(myForm) {
var error = '';
// Example Filed
if(myForm.name.value == '') {
error += '- Please enter your Name.\n';
}
// Show Error Notice
if(error != '') {
error = 'The form has not been completed correctly, please check the following:\n\n' + error;
alert(error); // Displays Error
return false;
} else {
// Allows the form to move on to PHP Processing
// Need to Show Waiting Notice here
return true;
}
}
CSS & HTML Waiting Notice (Initially Hidden)
<style>
#processing {
display:block;
position: fixed;
top: 0;
left: 0;
background: rgba(255,255,255,0.8);
width: 100%;
height: 100%;
}
#popup {
width: 300px;
min-height: 160px;
padding:20px;
background-color: #fff;
border: 5px solid #06C;
text-align: center;
color: #202020;
position: absolute;
left: 50%;
top: 50%;
margin-left: -150px;
margin-top: -100px;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
}
#popup img {
height:60px;
width:60px;
}
</style>
<div id="processing">
<div id="popup">
<img width="60" height="60" src="../waiting.gif" />
<h3>Please Wait!</h3>
<p>The form is processing...</p>
</div>
</div>
Any help would be appreciated
All you need to do is have the "...Please Wait..." element already present in the document, but hidden and then show it when the submit takes place. You do this by applying a CSS class to the element in the HTML, which hides it initially and then remove that class when the form is valid.
A couple of side notes...
Don't use inline HTML event attributes (onsubmit, onclick, etc.). That is how events were registered 20 years ago and there are many drawbacks to using them. Unfortunately, because most people just copy what others have done, the use of this approach just will not die. Instead, follow modern standards and use .addEventListener().
Also, don't ever name an element or a variable name as name is a property of the Global window object and the use of that name can cause problems in the code.
// Get references to the DOM elements that your code will need
var frm = document.getElementById("form");
var wait = document.getElementById("processing");
var userName = document.getElementById("txtName");
frm.addEventListener("submit", validate); // Set up events the modern, standards-based way
// All event handlers will automatically be passed a reference
// to the event object for that event
function validate(evt) {
var error = '';
// Example Filed
if(userName.value == '') {
error += '- Please enter your Name.\n';
}
// Show Error Notice
if(error != '') {
error = 'The form has not been completed correctly, please check the following:\n\n' + error;
alert(error); // Displays Error
evt.preventDefault(); // Stop the event
} else {
// Allows the form to move on to PHP Processing
// Need to Show Waiting Notice here
wait.classList.remove("hidden"); // Remove the hidden class
}
}
#processing {
display:block;
position: fixed;
top: 0;
left: 0;
background: rgba(255,255,255,0.8);
width: 100%;
height: 100%;
}
#processing.hidden { display:none } /* This hides the message by default */
#popup {
width: 300px;
min-height: 160px;
padding:20px;
background-color: #fff;
border: 5px solid #06C;
text-align: center;
color: #202020;
position: absolute;
left: 50%;
top: 50%;
margin-left: -150px;
margin-top: -100px;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
}
#popup img {
height:60px;
width:60px;
}
<form id="form" method="post" action="#" autocomplete="off">
<input type="text" id="txtName">
<input type="submit">
</form>
<div id="processing" class="hidden">
<div id="popup">
<img width="60" height="60" src="../waiting.gif" />
<h3>Please Wait!</h3>
<p>The form is processing...</p>
</div>
</div>
On your javascript validation, you could let the user know the image is loading by showing a simple message.
<div class="loading" style="display:none;">Loadin ...</div>
function Validate(myForm) {
var error = '';
// Example Filed
if(myForm.name.value == '') {
error += '- Please enter your Name.\n';
}
// Show Error Notice
if(error != '') {
error = 'The form has not been completed correctly, please check the following:\n\n' + error;
alert(error); // Displays Error
return false;
} else {
// Allows the form to move on to PHP Processing
// Need to Show Waiting Notice here
// show the user the image is loading
$('#form .loading').show();
return true;
}
}
After it loads you may remove the message once you get a response from the server.
$('#form .loading').hide();

jQuery to check for multiple strings with HTML textarea

Im working on a 'what you see is what you get' application. You code in one box and the output is displayed in another. I need to check if a user has typed specific text within an HTML textarea, and if it's correct is will make a button visible.
So far, when the user types text-align:center; the button is made visible. I can't work out so the user HAS to type 2 sets of text.
So far i have this:
$(document).ready(function(){$(".textArea").keyup(function() { // directed at the textArea div tag
if ($(this).val().indexOf('text-decoration:underline;' && 'text-align:center;') != -1) { // if the text matches those 2 strings
$(".continue").css("visibility", "visible"); // make button visible
}
else {
$(".continue").css("visibility", "hidden"); // keep it hidden if strings haven't been produced
$(".correct").css("display", "block");
}
});
});
.continue{
background-color: #ef6d3b;
width: 6em;
text-align: center;
font-size: 15px;
border: none;
height: 25px;
color: #000000;
outline: none;
cursor: pointer;
border-radius: 5px;
text-transform: uppercase;
position: relative;
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="codeArea">
<div class="correct">
<textarea class="textArea">
<html>
<body>
</body>
</html>
</textarea>
</div>
</div>
<button class="continue" type="button">Continue</button>
You are using wrong expression for your if statement..
if ($(this).val().indexOf('text-decoration:underline;' &&
'text-align:center;') != -1)
which is evaluated same as
$(this).val().indexOf('text-align:center;') != -1
what you should really do is
$(this).val().indexOf('text-decoration:underline;')!=-1 &&
$(this).val().indexOf('text-align:center;')!=-1

Why does the javascript css style works for first condition but not for second?

I have a progress bar that should react to input if the input is blank or equals 0 the inner progress div should have no background. For all other inputs it should be fill. It does work for the condition that the input is blank however after the input is entered there is no change reflected.
var first = document.getElementById("first");
if (a.innerHTML == '') {
first.style.background = "none";
} else {
first.style.background = "#e91b23";
}
.progress_bars_vertical_holder {
display: inline-block;
width: 100%;
position: relative;
}
.progress_bars_vertical {
display: inline-block;
position: relative;
float: left;
margin: 0px 2% 0px 0px;
}
.progress_bars_vertical:last-child {
margin: 0px;
}
.progress_bars_vertical .progress_content_outer {
height: 200px;
position: relative;
}
<input id="a" onkeypress="return tisNumberKey(event)" type="text" style="height: 250px; margin-top: 10px; width: 75%; text-align: center; font-size: 100px;" type="text" data-in="" />
<div class="progress_bars_vertical_holder vertical">
<div class="progress_bars_vertical background_color" style="width: 99.7%;">
<div class="progress_content_outer">
<div data-percentage="30" id="first" class="progress_content" style="height: 50%; background-color: rgb(22, 146, 159);"></div>
</div>
</div>
</div>
http://codepen.io/georgiemathews/pen/mJGBOV
It should be:
first.style.background = "#e91b23";
^---
The # marks that string as a hex value. Otherwise it's just seen as some random garbage.
You had a few typos. I grabbed a copy of your CodePen demo and here is a working version you can play with.
HTML
I got it working and the red progress bar is added when you type into the box. But, when you clear the input range, the indicator stayed red because it was simply looking for a keypress. I changed it to oninput to get the desired behavior.
You also had a typo in your function - it said tisNumberKey - changed to isNumberKey.
<input id="a" oninput="return isNumberKey(event)" type="text" style="height: 250px; margin-top: 10px; width: 75%; text-align: center; font-size: 100px;" type="text" data-in="" />
JavaScript
You weren't calling the function with anything. The HTML was trying to call the script, but there was no named function. Adding function isNumberKey(event) to the script allows it to run when you type in the input range.
Finally, I changed the logic for adding the class. If the field is not empty, make it red. Ran more consistently with the other changes. Working script is below:
function isNumberKey(){
var first = document.getElementById("first");
var a = document.getElementById("a");
if (a.value !== '') {
first.setAttribute("class", "red-bg");
} else {
first.setAttribute("class", "no-bg");
}
}

Radio buttons becoming misaligned due to addition of logos

I am a newbie to CSS and HTML5 and JavaScript. The codes that you see below are not mine. I ran the codes on a browser and there was an image of three cars and textboxs beneath the cars and submit buttons. When I tried to add more cars to the existing code, for example I added Chrysler, Dodge, etc, the submit buttons became misaligned. What I am trying to do is to spread these cars out so that they cover the WHOLE page. At the moment, you will see three cars concentrated in the middle of your screen. What I would like to do is add 6 more cars to the existing 3 cars, so that there will be a total of 9 cars -- 3 cars per row, and there will be three rows in all. And these nine cars will be evenly spread out throughout the page. Also, if I don't want the logo of a car, but a box with the NAME of individual cars, how do I go about doing that? In other words, there will be 9 boxes in all, each box containing the actual name of the car, and beneath each box you have a textbox into which the user adds his comments, and below the textbox you have the submit radio button. My problem (as a result of inexperience) is tat when I'm adding more and more cars, the textboxes remain in place but the submit radio buttons become seriously misaligned.
Also, the background turquoise color only covers the area immediately surrounding the three cars. How can I have the color cover the whole page?
<!DOCTYPE html>
<html>
<head>
<style>
#form {
background-color: rgb(0,255,255);
position: absolute;
overflow: hidden;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
}
.car {
float: left;
margin: 2% 2% 5% 2%;
}
.car label img {
transform: scale(0.8);
transition-duration: 0.2s;
}
.car label img:hover {
cursor: pointer;
transform: scale(1);
}
.comment {
position: absolute;
visibility: hidden;
}
.comment input {
width: 128px;
font-size: 1em;
}
.car label img {
width: 128px;
display: block;
}
#button {
position: relative;
left: 66%;
margin: 2%;
visibility: hidden;
}
</style>
</head>
<body>
<div id="form">
<form method="post" action="furiousindex.php">
<div class="car">
<label for="Mercedes">
<img src="http://tinyurl.com/on964r9" />
</label>
<div class="comment">
<input type="text" id="Mercedes" placeholder="Mercedes"
/>
</div>
</div>
<div class="car">
<label for="BMW">
<img src="http://tinyurl.com/on964r9" />
</label>
<div class="comment">
<input type="text" id="BMW" placeholder="BMW" />
</div>
</div>
<div class="car">
<label for="Audi">
<img src="http://tinyurl.com/on964r9" />
</label>
<div class="comment">
<input type="text" id="Audi" placeholder="Audi" />
</div>
</div>
<input id="button" type="submit" name="submit" value="Submit">
</form>
</div>
<script type='text/javascript' src='//code.jquery.com/jquery-2.1.0.js'>
</script>
<script>
$('.car').click(function() {
$('.comment').css("visibility", "hidden");
$('#button').css("visibility", "hidden");
var id = $(this).children('label').attr('for');
var buttonOffset;
switch (id) {
case 'Mercedes':
buttonOffset = '0';
break;
case 'BMW':
buttonOffset = '33%';
break;
case 'Audi':
buttonOffset = '66%';
break;
}
$(this).children('.comment').css("visibility", "visible");
$('#button').css("left", buttonOffset);
$('#button').css("visibility", "visible");
});
$('.comment').mouseleave(function() {
setTimeout(function() {
$('.comment').css("visibility", "hidden");
$('#button').css("visibility", "hidden");
}, 5000);
});
</script>
</body>
</html>
Add this to #form. It will restrict the size of the box around the cars to fit a max of three cars wide (based on other variables) and you can add as many rows as you like.
#form {
width: 450px;
}
To make the entire background turquoise:
body {
background-color: rgb(0,255,255);
}
I think this covers everything. If not, let me know what I missed.

Categories