HTML file input — "accept" attribute not working - html

After reading through the comments on this post, I came up with the following syntax for the accept attribute:
Images
<input type="file" accept="image/jpeg, image/png, image/gif, .jpeg, .png, .gif">
Audio
<input type="file" accept="audio/mpeg, audio/x-wav, .mp3, .wav">
This works perfectly on desktop browsers, but does not appear to filter files at all on iOS or Android.
Are there any cross-browser solutions available?

I was unable to get the accept attribute to work for mobile. Ultimately I had to add an onchange handler to the input (general idea shown below).
Keep in mind, you'll still want to use the accept attribute as shown in my question, because it will work on desktop.
const supportedExtensions = ['jpeg', 'jpg', 'png', 'gif'];
const handleChange = ({ target }) => {
const path = target.value.split('.');
const extension = `${path[path.length - 1]}`;
if (supportedExtensions.includes(extension)) {
// TODO: upload
} else {
// TODO: show "invalid file type" message to user
// reset value
target.value = '';
}
}

The detail listing of browser support for "accept" attribute is listed in w3 schools. Have a look. It may help you.

I got the same problem, found this page, here is my workaround using onChange event.
I know this isn't true filtering and this is pretty ugly (I don't it), but it works indeed. I tested on my iOS and Android devices.
<script type="text/javascript">
let file;
function checkFile() {
file = document.querySelector('input[type=file]').files[0];
if (file.type != "image/png") {
file = null;
document.getElementById('image').remove();
let div = document.getElementById('div');
let image = document.createElement('input');
image.setAttribute('type', 'file');
image.setAttribute('id', 'image');
image.setAttribute('accept', 'image/png');
image.setAttribute('onchange', 'checkFile()');
div.appendChild(image);
window.alert('unsupported file type');
}
}
</script>
<div id="div">
<input type="file" id="image" accept="image/png" onchange="checkFile()">
</div>

Related

form tag in html not posting/hitting website

so im trying to create a link shortener for me and my friend
to use on our small service center
but im having a small problem.
i set up an express server to get this done, whilst creating a fileuploader
which i used postman to test.
both work fine, but this is where im getting the problem.
whenever i use the snippet below to try and send data to the 'api'
it doesnt even post/touch the website yes i debugged to see if it touched
its only when i use form post/get method that the code doesnt work
HTML code snippet
<form method="POST" action="/shorten" enctype="application/x-www-form-urlencoded">
<label for="fUrl" class="sronly">URL</label>
<input class="input"
required
placeholder="URL"
type="url"
name="fUrl"
id="fUrl"
/>
<button type="submit">Shrink This!</button>
</form>
ive tried many things, i dont know if its because im rendering it with EJS or what
i tested it on its own with an HTML file but to no avail
if theres anything in this post i missed to go over let me know!
It looks like there is some issue with mapping between client and server. Try changing action value to the your API endpoint.
<form method="POST" action="http://myserver.com/shorten" enctype="application/x-www-form-urlencoded">
<label for="fUrl" class="sronly">URL</label>
<input class="input"
required
placeholder="URL"
type="url"
name="fUrl"
id="fUrl"
/>
<button type="submit">Shrink This!</button>
</form>
It was a problem of browsers being a tad too fast/slow
fix is here
// thanks to Vikasdeep Singh for this oddly specific url regex test
function isValidURL(string) {
var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9#:%_\+.~#?&//=]*)/g);
return (res !== null)
};
var el = document.getElementById("yourButtonID");
el.addEventListener("click", avoidNSErrorWithFirefox, false); //Firefox
function avoidNSErrorWithFirefox() {
ElementInterval = setInterval(function() {
var url = document.getElementById("inputURL").value; // input tag
if (isValidURL(url)) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://your-url.com/shorten", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
"url": url
}));
}
clearInterval(ElementInterval);
}, 0);
};
works like a charm on all browsers ive tested
edge chrome opera firefox
Hopefully me and my friends fix saves you some trouble with form / express problems!

Prevent chrome autosuggest list

I'm using a bootstrap date-picker and with a recent update to Chrome, it started super-imposing a suggestion dropdown on top of the date-picker like this:
I've tried the
autocomplete="nope"
and
autocomplete="new-password"
suggestions for disabling auto-fill, but neither worked. Mind you, there is no autofill happening, it's only the suggestion list that is popping up and only after clicking on the input, so I don't know if this would even be governed by autocomplete.
Try adding this to each input field that you have:
role="presentation" autocomplete="nope"
For me it works. Tested on Chrome Version 66.0.3359.181 (Official Build) (64-bit)
Adding autocomplete="off" attribute will disable autocomplete for an input that isn't a username or password field
<input type="text" autocomplete="off"/>
MDN
Note: This link states that turning off autocomplete breaks WCAG 1.3.5 but I'm not sure that is entirely true. Going to discuss with them.
Workaround :
$('#Name').on('mouseup keyup', function () {
var val = $('#Name').val();
val = val.length;
if (val === 0) {
$('#Name').attr('autocomplete', 'on');
}
else {
$('#Name').attr('autocomplete', 'new-password');
}
}).on('mousedown keydown', function () {
var val = $('#Name').val();
var length = val.length;
if (!length) {
$('#Name').attr('autocomplete', 'new-password');
}
})

Using file-input with accept image to access webcam on laptop

This most probably is a duplicate, please point me in the right direction:
I know how to use a file-upload input type=file with accept=image to allow fileupload of images from mobile devices.
<input type="file" name="myImage" accept="image/*" />
I would like to make this work on a Laptop just like on any other mobile device. Browser-Vendors still open up a Choose-File-Dialog where I would expect a "Choose-Source"-Dialog on mobile-devices.
I know that this is a thing that Browser-Vendors will have to solve, but in the meantime the question is: Is there any framework that emulates such a behaviour?
UPDATED ANSWER
<input type="file" accept="image/*" capture>
http://anssiko.github.io/html-media-capture/ for other media capture examples.
If you don't need IE support then you could try the MediaDevices.getUserMedia()
// A lot of other options are available - check out the constraints.
const constraints = { audio: true, video: { width: 1280, height: 720 } };
const video_stream = document.createElement('video');
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
video_stream.srcObject = mediaStream;
video_stream.onloadedmetadata = function(e) {
document.body.appendChild(video_stream);
video_stream.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); });
You can capture a frame and then append it to a canvas for preview and from there export it to .png/.jpg

Manually Triggering Form Validation using jQuery

I have a form with several different fieldsets. I have some jQuery that displays the field sets to the users one at a time. For browsers that support HTML5 validation, I'd love to make use of it. However, I need to do it on my terms. I'm using JQuery.
When a user clicks a JS Link to move to the next fieldset, I need the validation to happen on the current fieldset and block the user from moving forward if there is issues.
Ideally, as the user loses focus on an element, validation will occur.
Currently have novalidate going and using jQuery. Would prefer to use the native method. :)
TL;DR: Not caring about old browsers? Use form.reportValidity().
Need legacy browser support? Read on.
It actually is possible to trigger validation manually.
I'll use plain JavaScript in my answer to improve reusability, no jQuery is needed.
Assume the following HTML form:
<form>
<input required>
<button type="button">Trigger validation</button>
</form>
And let's grab our UI elements in JavaScript:
var form = document.querySelector('form')
var triggerButton = document.querySelector('button')
Don't need support for legacy browsers like Internet Explorer? This is for you.
All modern browsers support the reportValidity() method on form elements.
triggerButton.onclick = function () {
form.reportValidity()
}
That's it, we're done. Also, here's a simple CodePen using this approach.
Approach for older browsers
Below is a detailed explanation how reportValidity() can be emulated in older browsers.
However, you don't need to copy&paste those code blocks into your project yourself — there is a ponyfill/polyfill readily available for you.
Where reportValidity() is not supported, we need to trick the browser a little bit. So, what will we do?
Check validity of the form by calling form.checkValidity(). This will tell us if the form is valid, but not show the validation UI.
If the form is invalid, we create a temporary submit button and trigger a click on it. Since the form is not valid, we know it won't actually submit, however, it will show validation hints to the user. We'll remove the temporary submit button immedtiately, so it will never be visible to the user.
If the form is valid, we don't need to interfere at all and let the user proceed.
In code:
triggerButton.onclick = function () {
// Form is invalid!
if (!form.checkValidity()) {
// Create the temporary button, click and remove it
var tmpSubmit = document.createElement('button')
form.appendChild(tmpSubmit)
tmpSubmit.click()
form.removeChild(tmpSubmit)
} else {
// Form is valid, let the user proceed or do whatever we need to
}
}
This code will work in pretty much any common browser (I've tested it successfully down to IE11).
Here's a working CodePen example.
You can't trigger the native validation UI (see edit below), but you can easily take advantage of the validation API on arbitrary input elements:
$('input').blur(function(event) {
event.target.checkValidity();
}).bind('invalid', function(event) {
setTimeout(function() { $(event.target).focus();}, 50);
});
The first event fires checkValidity on every input element as soon as it loses focus, if the element is invalid then the corresponding event will be fired and trapped by the second event handler. This one sets the focus back to the element, but that could be quite annoying, I assume you have a better solution for notifying about the errors. Here's a working example of my code above.
EDIT: All modern browsers support the reportValidity() method for native HTML5 validation, per this answer.
In some extent, You CAN trigger HTML5 form validation and show hints to user without submitting the form!
Two button, one for validate, one for submit
Set a onclick listener on the validate button to set a global flag(say justValidate) to indicate this click is intended to check the validation of the form.
And set a onclick listener on the submit button to set the justValidate flag to false.
Then in the onsubmit handler of the form, you check the flag justValidate to decide the returning value and invoke the preventDefault() to stop the form to submit. As you know, the HTML5 form validation(and the GUI hint to user) is preformed before the onsubmit event, and even if the form is VALID you can stop the form submit by returning false or invoke preventDefault().
And, in HTML5 you have a method to check the form's validation: the form.checkValidity(), then in you can know if the form is validate or not in your code.
OK, here is the demo:
http://jsbin.com/buvuku/2/edit
var field = $("#field")
field.keyup(function(ev){
if(field[0].value.length < 10) {
field[0].setCustomValidity("characters less than 10")
}else if (field[0].value.length === 10) {
field[0].setCustomValidity("characters equal to 10")
}else if (field[0].value.length > 10 && field[0].value.length < 20) {
field[0].setCustomValidity("characters greater than 10 and less than 20")
}else if(field[0].validity.typeMismatch) {
field[0].setCustomValidity("wrong email message")
}else {
field[0].setCustomValidity("") // no more errors
}
field[0].reportValidity()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="email" id="field">
Somewhat easy to make add or remove HTML5 validation to fieldsets.
$('form').each(function(){
// CLEAR OUT ALL THE HTML5 REQUIRED ATTRS
$(this).find('.required').attr('required', false);
// ADD THEM BACK TO THE CURRENT FIELDSET
// I'M JUST USING A CLASS TO IDENTIFY REQUIRED FIELDS
$(this).find('fieldset.current .required').attr('required', true);
$(this).submit(function(){
var current = $(this).find('fieldset.current')
var next = $(current).next()
// MOVE THE CURRENT MARKER
$(current).removeClass('current');
$(next).addClass('current');
// ADD THE REQUIRED TAGS TO THE NEXT PART
// NO NEED TO REMOVE THE OLD ONES
// SINCE THEY SHOULD BE FILLED OUT CORRECTLY
$(next).find('.required').attr('required', true);
});
});
I seem to find the trick:
Just remove the form target attribute, then use a submit button to validate the form and show hints, check if form valid via JavaScript, and then post whatever. The following code works for me:
<form>
<input name="foo" required>
<button id="submit">Submit</button>
</form>
<script>
$('#submit').click( function(e){
var isValid = true;
$('form input').map(function() {
isValid &= this.validity['valid'] ;
}) ;
if (isValid) {
console.log('valid!');
// post something..
} else
console.log('not valid!');
});
</script>
Html Code:
<form class="validateDontSubmit">
....
<button style="dislay:none">submit</button>
</form>
<button class="outside"></button>
javascript( using Jquery):
<script type="text/javascript">
$(document).on('submit','.validateDontSubmit',function (e) {
//prevent the form from doing a submit
e.preventDefault();
return false;
})
$(document).ready(function(){
// using button outside trigger click
$('.outside').click(function() {
$('.validateDontSubmit button').trigger('click');
});
});
</script>
Hope this will help you
For input field
<input id="PrimaryPhNumber" type="text" name="mobile" required
pattern="^[789]\d{9}$" minlenght="10" maxLength="10" placeholder="Eg: 9444400000"
class="inputBoxCss"/>
$('#PrimaryPhNumber').keyup(function (e) {
console.log(e)
let field=$(this)
if(Number(field.val()).toString()=="NaN"){
field.val('');
field.focus();
field[0].setCustomValidity('Please enter a valid phone number');
field[0].reportValidity()
$(":focus").css("border", "2px solid red");
}
})
$('#id').get(0).reportValidity();
This will trigger the input with ID specified. Use ".classname" for classes.
When there is a very complex (especially asynchronous) validation process, there is a simple workaround:
<form id="form1">
<input type="button" onclick="javascript:submitIfVeryComplexValidationIsOk()" />
<input type="submit" id="form1_submit_hidden" style="display:none" />
</form>
...
<script>
function submitIfVeryComplexValidationIsOk() {
var form1 = document.forms['form1']
if (!form1.checkValidity()) {
$("#form1_submit_hidden").click()
return
}
if (checkForVeryComplexValidation() === 'Ok') {
form1.submit()
} else {
alert('form is invalid')
}
}
</script>
Another way to resolve this problem:
$('input').oninvalid(function (event, errorMessage) {
event.target.focus();
});

How to allow <input type="file"> to accept only image files?

I need to upload only image file through <input type="file"> tag.
Right now, it accepts all file types. But, I want to restrict it to only specific image file extensions which include .jpg, .gif etc.
How can I achieve this functionality?
Use the accept attribute of the input tag. To accept only PNG's, JPEG's and GIF's you can use the following code:
<label>Your Image File
<input type="file" name="myImage" accept="image/png, image/gif, image/jpeg" />
</label>
Or simply:
<label>Your Image File
<input type="file" name="myImage" accept="image/*" />
</label>
Note that this only provides a hint to the browser as to what file-types to display to the user, but this can be easily circumvented, so you should always validate the uploaded file on the server also.
It should work in IE 10+, Chrome, Firefox, Safari 6+, Opera 15+, but support is very sketchy on mobiles (as of 2015) and by some reports, this may actually prevent some mobile browsers from uploading anything at all, so be sure to test your target platforms well.
For detailed browser support, see http://caniuse.com/#feat=input-file-accept
Using this:
<input type="file" accept="image/*">
works in both FF and Chrome.
Use it like this
<input type="file" accept=".png, .jpg, .jpeg" />
It worked for me
https://jsfiddle.net/ermagrawal/5u4ftp3k/
Steps:
1. Add accept attribute to input tag
2. Validate with javascript
3. Add server side validation to verify if the content is really an expected file type
For HTML and javascript:
<html>
<body>
<input name="image" type="file" id="fileName" accept=".jpg,.jpeg,.png" onchange="validateFileType()"/>
<script type="text/javascript">
function validateFileType(){
var fileName = document.getElementById("fileName").value;
var idxDot = fileName.lastIndexOf(".") + 1;
var extFile = fileName.substr(idxDot, fileName.length).toLowerCase();
if (extFile=="jpg" || extFile=="jpeg" || extFile=="png"){
//TO DO
}else{
alert("Only jpg/jpeg and png files are allowed!");
}
}
</script>
</body>
</html>
Explanation:
The accept attribute filters the files that will be displayed in the
file chooser popup. However, it is not a validation. It is only a
hint to the browser. The user can still change the options in the
popup.
The javascript only validates for file extension, but cannot
really verify if the select file is an actual jpg or png.
So you have to write for file content validation on server side.
This can be achieved by
<input type="file" accept="image/*" />
But this is not a good way. you have to code on the server side to check the file an image or not.
Check if image file is an actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
}
else {
echo "File is not an image.";
$uploadOk = 0;
}
}
For more reference, see here
http://www.w3schools.com/tags/att_input_accept.asp
http://www.w3schools.com/php/php_file_upload.asp
Using type="file" and accept="image/*" (or the format you want), allow the user to chose a file with specific format. But you have to re check it again in client side, because the user can select other type of files.
This works for me.
<input #imageInput accept="image/*" (change)="processFile(imageInput)" name="upload-photo" type="file" id="upload-photo" />
And then, in your javascript script
processFile(imageInput) {
if (imageInput.files[0]) {
const file: File = imageInput.files[0];
var pattern = /image-*/;
if (!file.type.match(pattern)) {
alert('Invalid format');
return;
}
// here you can do whatever you want with your image. Now you are sure that it is an image
}
}
Just as an addition: if you want to include all modern image file types with the best cross-browser support it should be:
<input type="file" accept="image/apng, image/avif, image/gif, image/jpeg, image/png, image/svg+xml, image/webp">
This allows all image file types that can be displayed in most browsers while excluding less commons formats like TIFF or formats that are not suitable for the web like PSD.
you can use accept attribute for <input type="file"> read this docs http://www.w3schools.com/tags/att_input_accept.asp
You can add specific type of image or other file type and do validation in your code :
<input style="margin-left: 10px; margin-top: 5px;" type="file" accept="image/x-png,image/jpeg,application/pdf"
(change)="handleFileInput($event,'creditRatingFile')" name="creditRatingFile" id="creditRatingFile">
handleFileInput(event) {
console.log(event);
const file = event.target.files[0];
if (file.size > 2097152) {
throw err;
} else if (
file.type !== "application/pdf" &&
file.type !== "application/wps-office.pdf" &&
file.type !== 'application/pdf' && file.type !== 'image/jpg' && file.type !== 'image/jpeg' && file.type !== "image/png"
) {
throw err;
} else {
console.log('file valid')
}
}
In html;
<input type="file" accept="image/*">
This will accept all image formats but no other file like pdf or video.
But if you are using django, in django forms.py;
image_field = forms.ImageField(Here_are_the_parameters)
If you want to upload multiple images at once you can add multiple attribute to input.
upload multiple files: <input type="file" multiple accept='image/*'>
Simple and powerful way(dynamic accept)
place formats in array like "image/*"
var upload=document.getElementById("upload");
var array=["video/mp4","image/png"];
upload.accept=array;
upload.addEventListener("change",()=>{
console.log(upload.value)
})
<input type="file" id="upload" >
Other people's answers refactored for ReactJS (hooks)
import React from 'react';
const ImageUploader = () => {
const handleImageUpload = (e) => {
// If no file selected, return
if (e.target.files.length === 0) return false;
const file = e.target.files[0];
// If no image selected, return
if (!/^image\//.test(file.type)) {
alert(`File ${file.name} is not an image.`);
return false;
}
// ...
};
return (
<>
<input type='file' accept='image/*' onChange={(e) => handleImageUpload(e)} />
</>
);
};
export default ImageUploader;