Creating ID card with HTML - javascript

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>

Related

Get Original Image Width And Height From A New Image() Object - JavaScript

I have an image uploader where I have some PHP checks that happen on the server side. What I want to do is also provide frontend validations for the user, but I am having an issue getting the values to do the maths for the image resolution in megapixels. On the server side I can just use the file's width and height properties and then multiply them.
The problem I have is on the frontend when using a new Image() object, when I get the width and height properties it gives me the values of the image file in the container, not the width and height values of the source file / original image.
I thought I could just use the .src property and get the size of that instead, but this doesn't work either.
In the code below as you can see the Image() object is assigned to a thumbnailElement variable.
If you click the Select Files button and add an image it will show the thumbnails and log the original file size to the console, but not the original width ?
Note: the updateThumbnail() function is invoked in the HTML
Codepen Link: https://codepen.io/thechewy/pen/yLjvqWe
var zone = document.getElementById("zone"),
selectedImagesContainer = document.getElementById("show-selected-images"),
fileUploader = document.getElementById("standard-upload-files");
zone.addEventListener("click", (e) => {
// assigns the zone element to the hidden input element so when you click 'select files' it brings up a file picker window
fileUploader.click();
});
fileUploader.addEventListener("change", (e) => {
// this function is further down but declared here and shows a thumbnail of the image
[...fileUploader.files].forEach(updateThumbnail);
});
function updateThumbnail(file) {
let uploadImageWrapper = document.createElement("figure"), // image wrapper <figure> element
thumbnailElement = new Image(); // image
// image thumbnail
thumbnailElement.classList.add("thumbnail");
thumbnailElement.src = URL.createObjectURL(file);
// appending elements
selectedImagesContainer.append(uploadImageWrapper); // append <figure> element
uploadImageWrapper.append(thumbnailElement); // append image thumbnail
console.log("file size is: ", file.size);
console.log("file width is: ", thumbnailElement.width);
} // end of 'updateThumbnail' function
body {
margin: 0;
display: flex;
justify-content: center;
font-family: arial;
}
form {
width: 50%;
max-width: 600px;
}
.select-files {
padding: 1rem;
background: red;
cursor: pointer;
color: #fff;
font-weight: bold;
}
#show-selected-images {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-top: 2rem;
}
figure {
width: 100%;
margin: 0;
}
img {
display: block;
width: 100%;
height: auto;
}
<form id="upload-images-form" enctype="multipart/form-data" method="post">
<h1>Upload Your Images</h1>
<div id="zone">
<p class="select-files">SELECT FILES</p>
</div>
<div class="inner-wrapper">
<div class="upload-label-wrapper">
<input id="standard-upload-files" style="display:none;" type="file" name="standard-upload-files[]" multiple>
</div>
<button id="submit-images" oninput="updateThumbnail(this.files)">SUBMIT IMAGES</button>
</div>
<div id="show-selected-images"></div>
</form>
You need the naturalWidth property to get actual image width in pixels, also to get that value reliably you should use the HTMLImageElement.decode() method that returns a promise which is resolved once the full-resolution image is fully decoded, like this:
var zone = document.getElementById("zone"),
selectedImagesContainer = document.getElementById("show-selected-images"),
fileUploader = document.getElementById("standard-upload-files");
zone.addEventListener("click", (e) => {
// assigns the zone element to the hidden input element so when you click 'select files' it brings up a file picker window
fileUploader.click();
});
fileUploader.addEventListener("change", (e) => {
// this function is further down but declared here and shows a thumbnail of the image
[...fileUploader.files].forEach(updateThumbnail);
});
function updateThumbnail(file) {
let uploadImageWrapper = document.createElement("figure"), // image wrapper <figure> element
thumbnailElement = new Image(); // image
// image thumbnail
thumbnailElement.classList.add("thumbnail");
thumbnailElement.src = URL.createObjectURL(file);
// appending elements
selectedImagesContainer.append(uploadImageWrapper); // append <figure> element
uploadImageWrapper.append(thumbnailElement); // append image thumbnail
console.log("file size is: ", file.size);
thumbnailElement.decode().then(() => {
console.log("file width is: ", thumbnailElement.naturalWidth);
}).catch((encodingError) => {
// Do something with the error.
});
} // end of 'updateThumbnail' function
body {
margin: 0;
display: flex;
justify-content: center;
font-family: arial;
}
form {
width: 50%;
max-width: 600px;
}
.select-files {
padding: 1rem;
background: red;
cursor: pointer;
color: #fff;
font-weight: bold;
}
#show-selected-images {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-top: 2rem;
}
figure {
width: 100%;
margin: 0;
}
img {
display: block;
width: 100%;
height: auto;
}
<form id="upload-images-form" enctype="multipart/form-data" method="post">
<h1>Upload Your Images</h1>
<div id="zone">
<p class="select-files">SELECT FILES</p>
</div>
<div class="inner-wrapper">
<div class="upload-label-wrapper">
<input id="standard-upload-files" style="display:none;" type="file" name="standard-upload-files[]" multiple>
</div>
<button id="submit-images" oninput="updateThumbnail(this.files)">SUBMIT IMAGES</button>
</div>
<div id="show-selected-images"></div>
</form>
Yes, .width and .height will return the computed width and height of the element when it's visible in the doc.
Since your <img> element doesn't have an srcset attribute, you can use both its naturalWidth and naturalHeight to get the actual intrinsic size of the loaded image. If you had this srcset attribute though, these values could be divided by the size multiplier of the loaded source.
If you weren't displaying the image in a thumbnail, an efficient way to get the dimensions of the image would have been to call createImageBitmap() either on the File object you have directly, and to check the .width and .height properties of the resolved ImageBitmap object.
But since you do show the image, in your case that'd be overkill. Using .naturalWidth and .naturalHeight (after the image has loaded) is just enough.

Toggle up and down arrows as images

I have two images of arrows, up and down. My problem is when I use slideToggle(), it toggles up and down, but the image stays the same rather then changing. For instance, if I toggle up, the image should automatically change to the downward arrow and vice versa. Also, these arrows should be moved to the top of the page once the toggle happens. The current code displays two arrows, I would like that to be one arrow that changes based on the toggle.
What I have so far..
HTML:
<div id="toggleParam">
<input type="image" class="upArrow" src="~/Content/Images/Reserved.ReportViewerWebControl.png" name="Show / Hide Parameters" />
<input type="image" class="downArrow" src="~/Content/Images/downArrow.png" name="Show / Hide Parameters" />
</div>
CSS:
.upArrow{
display: block;
margin-left: 690px;
margin-top: 0px;
border-width: 5px;
padding-bottom: 0px;
cursor: pointer;
height: 7pt;
}
.downArrow{
display: block;
margin-left: 760px;
margin-right: 70px;
margin-top: -10px;
border-width: 5px;
padding-bottom: 0px;
cursor: pointer;
height: 7.5pt;
}
JavaScript/JQuery:
$(document).ready(function () {
$('#toggleParam').on("click", function () {
$('.dropdown').slideToggle();
});
What I need is shown in these two pictures..
I realize missing a lot of code on the JS part.. I am working on it while asking this question. Thanks for the help!
You need to simply include the arrows' elements in the toggle function accordingly:
$('#toggleParam').on("click", function () {
$('.downArrow, .upArrow').toggle();
$('.dropdown').slideToggle();
});
Also in the beginning you need to hide one of the arrows (not sure which one in your case):
.downArrow{
display: none;
...
.upArrow{
display: block;
Try this (note - there's n-ways to do this; this is just how i'd do it).
<!--index.html-->
<div id="toggleParam" class="toggle-param--up">
<input type="image" class="up-arrow" src="~/Content/Images/Reserved.ReportViewerWebControl.png" name="Show / Hide Parameters" />
<input type="image" class="down-arrow" src="~/Content/Images/downArrow.png" name="Show / Hide Parameters" />
</div>
/* app.css */
.toggle-param--up .down-arrow { display; none;}
.toggle-param--down .up-arrow { display; none;}
//app.js
$('#toggleParam').on("click", function (e) {
// the rest of your logic goes here....
var isUp = $(e.target).hasClass("toggle-param--up"),
directionClass = { true: "toggle-param--up", false: "toggle-param--down"};
$(e).target.removeClass(directionClass[isUp]).addClass(directionClass[!isUp];
});

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");
}
}

Background image disappears on hover/mouseover and menu doesn't work in IE

I have 5 diffrent backgrounds which change from one to another when mouseover menu links like that:
3 different screenshots out of 5
I want that the web site works properly in all browsers, but I get very different results. In firefox, background image dissapears and reappears on each menu link, but only first time when I go over a link with a cursor, other times works fine. In chrome backgrounds disappear and reappear on every onmouseover. And in IE onmouseover doesn't work at all nor the menu.
So I'm asking you to help me fix this, both things, dissapearing and the menu in IE. I found out that this disappearing and reappearing happens because of slow image loading, but I have no idea how to repair my code to fix this.
I just wrote my code in jsFiddle and menu doesn't work in it as well. And I noticed that when I downscale windows into the size smaller than div, the whole thing starts to deform. I thought I already fixed it, but it seems that I don't know how to that as well. You can see my code here:
My Code in jsFiddle
CSS
body
{
background-image:url(Slike/Ozadja/Osnova.png);
background-repeat:no-repeat;
background-position:center;
background-attachment:local;
background-color: #FFFAF0;
background-size:794px;
}
#layoutWidth div
{
width:628px;
margin:auto;
display:table;
overflow:hidden;
}
div .header
{
height:85px;
text-align:center;
display:table-row;
}
div .menu
{
height:173px;
display:table-row;
}
#ddm
{ margin-top: 30px;
padding: 0;
z-index: 30}
#ddm li
{ margin-left:12px;
margin-top:10px;
padding: 0;
list-style: none;
float: left;
font: bold 100% arial}
#ddm li a
{ display: block;
margin: 0 6px 0 0;
padding: 4px 4px;
width: 130px;
background: transperent;
color: #FFF;
text-align: center;
text-decoration: none}
#ddm li a:hover
{ background: transparent;
color: #C0C0C0;
}
#ddm div
{ position: absolute;
visibility: hidden;
margin-top:10px;
padding: 0;
background: transparent;
}
#ddm div a
{ position: static;
display: block;
margin-left: -16px;
padding: 5px 10px;
width: 150px;
white-space: normal;
text-align: center;
text-decoration: none;
background: transperent;
color: #000;
font: bold 11px arial;
}
#ddm div a:hover
{ background: transparent;
color: #696969}
div .body
{
height:650px;
text-align: left;
display:table-row;
}
div .footer
{
display:table-row;
}
HTML
<html>
<head>
<title>Drop-Down Menu</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta http-equiv="Content-Type"
content="text/html;charset=UTF-16">
<link rel="stylesheet" type="text/css" href="Stil.css">
<!-- dd menu -->
<script type="text/javascript">
<!--
var timeout = 500;
var closetimer = 0;
var ddmenuitem = 0;
var myImage = {};
myImage.m1 = 'Prvi_predal.png';
myImage.m2 = 'Drugi_predal.png';
myImage.m3 = 'Tretji_predal.png';
myImage.m4 = 'Cetrti_predal.png';
function mopen(id)
{
mcancelclosetime();
if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
ddmenuitem = document.getElementById(id);
ddmenuitem.style.visibility = 'visible';
document.body.style.backgroundImage = 'url(Slike/Ozadja/'+myImage[id]+')';
}
function mclose()
{
if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
document.body.style.backgroundImage = 'url(Slike/Ozadja/Osnova.png)'
}
function mclosetime()
{
closetimer = window.setTimeout(mclose, timeout);
}
function mcancelclosetime()
{
if(closetimer)
{
window.clearTimeout(closetimer);
closetimer = null;
}
}
document.onclick = mclose;
// -->
</script>
</head>
<body>
<div id="layoutWidth">
<div class="header">
<a href="Domov.html">
<img src="Slike/Logo/Logo.png" alt="Mankajoč logotip" width="279" height="80"></a>
</div>
<div class="menu">
<ul id="ddm">
<li>Obdelava lesa
<div id="m1" class="prvi" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
Izdelki iz iverala
Izdelki iz masive
Obnova pohištva
</div>
</li>
<li>Talne obloge
<div id="m2" class="drugi" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
Laminat
Parket
</div>
</li>
<li>Ostale storitve
<div id="m3" class="tretji" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
Uporaba mavčnih plošč
Lažja zidarska dela
Fotografiranje dogodkov
Video zajem dogodkov
</div>
</li>
<li>Informacije
<div id="m4" class="cetrti" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
O podjetju
Kontakt
Kje se nahajamo
Galerija
</div>
</li>
</ul>
<div style="clear:both"></div>
<div style="clear:both"></div>
</div>
<div class="body">
<p>Brez pomena.</p>
<br />
<p> Tole tudi! </p>
</div>
<div class="footer">
Brez pomena.
</div>
</div>
</body>
</html>
For blinking background images, and other images which you want to use from JS, you need to preload, or it will be blinking. How to preload an image? Click here
(It's blinking, because when the page was loaded, the image wasn't. So, that image which you want to use, isn't at the user. The browser download it, but until that time, theres no image what it can show for him/her. This is the reason.)
IE is blocking JS in default (like IE 10). You need to enable it. I've got a warning bubble an the bottom, which say, I've blocking everything... or something like that. You can't enable this from script. Only you can create a warning message for the user, which you remove if JS is enabled.
An extra thing, in jsFiddle it will work the page if you select the "no warp - in <head>" option from the second drop down list at top left. After that you need to click run at top.

Hitting 'Cancel' during file upload in Chrome clears value

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.

Categories