Alter input type="file" label content - javascript

I was wondering if there is any way to hide or change the content of the default label:No file chosen for
<input type="file" id="myFileInput"/>
What I come up with so far is to decrease its length by half, so that it displays a tooltip.
$('input:file').css('width', parseFloat($($('input:file')).css('width'))/2 );
Any Ideas?

You cannot change input file design as its native to each browser. But you still can simulate it, sorry hacky:
See DEMO
<button id="btn_myFileInput">Choose file...</button>
<label for="btn_myFileInput">No file choosen or whatever...</label>
<input type="file" id="myFileInput" multiple />​
JS:
$(function () {
$('#btn_myFileInput').data('default', $('label[for=btn_myFileInput]').text()).click(function () {
$('#myFileInput').click()
});
$('#myFileInput').on('change', function () {
var files = this.files;
if (!files.length) {
$('label[for=btn_myFileInput]').text($('#btn_myFileInput').data('default'));
return;
}
$('label[for=btn_myFileInput]').empty();
for (var i = 0, l = files.length; i < l; i++) {
$('label[for=btn_myFileInput]').append(files[i].name + '\n');
}
});
});

You can also proceed in this way, but it is an hack:
<input type="file" id="myFileInput" name="html" style="width: 90px;" onchange="this.style.width = '100%';"/>

Chrome was giving me this problem too. I tried to set all sorts of CSS selectors, but nothing seemed to work well. However, I did find a solution by using the FORM element.
name your input[type=file] element.
name your form element and put the input[type=file] in it.
make a span and place it below the input in the form. This will be your label.
use CSS to set the input's height to 0px and opacity to 0, this will make it invisible.
make the span positioned absolutely and to the left 0px.
<style>
#file {
height:0px;
opacity:0;
}
#span {
left:0px;
position:absolute;
cursor: pointer;
}
</style>
<form name="form">
<input type="file" id="file" name="file"/>
<span id="span">My File label!!!!</span>
</form>
<script>
var span = document.getElementById("span");
span.onclick = function(event) {
document.form.file.click(event);
};
var span = document.getElementById("span");
span.onclick = function(event) {
document.form.file.click(event);
};
</script>
I tested this in Chrome and FF, not ie, but I hope this helps.
jsfiddle http://jsfiddle.net/aressler38/L5r8L/1/

Simple style with just CSS. You HTML button will read attributes from CSS. No need javascript slowing down the page.
CSS should be as below:
.editable:empty:before {
content: attr(data-placeholder);
}
.custom-file-input::before {
content: attr(placeholder);
/* content: 'Select some files'; */
}
input button should be:
<input class="custom-file-input" placeholder="#Hashtags " bind:files id="many" multiple type="file" />

Related

Drag and drop is not setting input value to be equal to files. Works if selected with the input button

I've been trying to create a drag and drop component. We have a working example without using a form or submit button (it is done on user input, or drag/drop).
I am modifying the component now so it will work with a form wrapper and send data to another page.
Here is the js:
const $fileUploader = $('.fileUploader');
const $input = $fileUploader.find('input[type="file"]');
const $label = $fileUploader.find('label');
const showFiles = files => {
if (files) {
$label.text(files[0].name);
}
};
const uploadBulkReports = () => {
$input.on('change', e => {
showFiles(e.target.files);
});
$fileUploader
.on('drag dragstart dragend dragover dragenter dragleave drop', e => {
e.preventDefault();
e.stopPropagation();
})
.on('dragover dragenter', () => {
$fileUploader.addClass('is-dragover');
})
.on('dragleave dragend drop', () => {
$fileUploader.removeClass('is-dragover');
})
.on('drop', e => {
droppedFiles = e.originalEvent.dataTransfer.files;
$input.files = e.originalEvent.dataTransfer.files;
showFiles(droppedFiles);
});
};
uploadBulkReports();
Our HTML (I have simplified this from C#/Razor)
<form mvc-action="/BulkUpload/Brand" action="/BulkUpload/Brand" enctype="multipart/form-data">
<div class="fileUploader" data-action="/BulkUpload/Brand" data-method="post">
<div class="fileUploader__input">
<input class="fileUploader__file" type="file" name="file" id="file" accept=".csv" />
<label for="file">Click to select a file</label>
<p class="fileUploader__dragndrop"> or drag it here</p>
<ul class="small">
<li>Id: Technical id of the Brand (leave blank to create new)</li>
<li>Name: Name of the Brand</li>
</ul>
</div>
<button class="btn btn-primary mt-2" type="submit">Submit</button>
</div>
</form>
My understanding is that on drop, the $input.files = e.originalEvent.dataTransfer.files; should set the input files value to the FileData information as is with the input selection. For some reason it does not work on submission.
We are only sending a single file, so I did try accessing the file here e.originalEvent.dataTransfer.files[0]; but it does not seem to work. (e.dataTransfer.files also does not work for me, I had to pass the originalEvent method).
I have made this jsfiddle https://jsfiddle.net/lharby/75m8ocva/ although I don't think it's possible to test a form submission in jsfiddle.
I want to know if setting the $input.files to the dropped files is identical to setting the file input via the regular method. When I try to console.log $input.files after the input has changed, I get undefined so I assume it is a different method.
I hope someone can help, if you need more information please let me know.
I want to know if setting the $input.files to the dropped files is identical to setting the file input via the regular method
No, there only one way to populate files in file upload control <input type="file"> and that is the regular way - You click on it ; it opens you OS file browser and you select file(s)
Programatically setting files on the file upload control is not allowed due to security reasons. So that means you will have to use AJAX only.
.on('drop', e => {
droppedFiles = e.originalEvent.dataTransfer.files;
$input.files = e.originalEvent.dataTransfer.files; //<--this won't update file input's internal state
showFiles(droppedFiles);
});
var ajaxData = new FormData($form.get(0));
$.each( droppedFiles, function(i, file) {
ajaxData.append( 'file_'+i, file );
});
$.ajax({
data: ajaxData,
cache: false,
contentType: false,
processData: false,
success: function(data) { }
});
But wait.. there is another sorta "hack" that many online services use when you load the page in HTML only layout or with javascript disabled. The reason why it works is that you can natively drag and drop files over a file control without any code at all giving same result had you went through the "regular way"
What they do is increase the width and height on the file control and make it look big with a label.
$('form').submit(function(e){
e.preventDefault();
console.log($('#file')[0].files)
});
input[type='file'] {
border: 2px dashed #aaa;
padding: 100px 50px 20px 130px;
position: relative;
background-color: yellow
}
input[type='file']:before {
content: "drag & drop here";
display: block;
position: absolute;
text-align: center;
top: 50%;
left: 50%;
width: 200px;
height: 100px;
margin: -25px 0 0 -100px;
font-size: 20px;
font-weight: bold;
}
#submit { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<form>
<input type="file" id="file" />
<input type="submit" id="submit">
</form>

Dynamically Adjust HTML Text Input Width to Content

I can't quite find a clear answer on this, and excuse me if there is one I've missed.
I want my text input widths to automatically adjust to the size of the content within them. First with placeholder text than the actual text someone inputs.
I've created the below as an example. Currently, the boxes are far bigger than my placeholder text, causing huge amounts of white space, and it's obviously the same thing when I type in something.
I've tried width auto, some jQuery, and twine and bubble gum I found on the internet. But nothing has worked yet. Any thoughts? Thanks!
HTML:
<span><p>Hello, my name is </p></span>
<span><input type="text" id="input" class="form" placeholder="name"></span>
<span><p>. I am </p></span>
<span><input type="text" id="input" class="form" placeholder="age"></span>
<span><p> years old.</p></span>
CSS:
.form {
border: 0;
text-align: center;
outline: none;
}
span {
display: inline-block;
}
p {
font-family: arial;
}
Fiddle
One possible way:
[contenteditable=true]:empty:before {
content: attr(placeholder);
color:gray;
}
/* found this online --- it prevents the user from being able to make a (visible) newline */
[contenteditable=true] br{
display:none;
}
<p>Hello, my name is <span id="name" contenteditable="true" placeholder="name"></span>. I am <span id="age" contenteditable="true" placeholder="age"></span> years old.</p>
Source for CSS: http://codepen.io/flesler/pen/AEIFc.
You'll have to do some trickery to pick up the values if you need the values for a form.
Use onkeypress even
see this example :http://jsfiddle.net/kevalbhatt18/yug04jau/7/
<input id="txt" placeholder="name" class="form" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';"></span>
And for placeholder on load use jquery and apply placeholder
size in to input
$('input').css('width',((input.getAttribute('placeholder').length + 1) * 8) + 'px');
Even you can use id instead of input this is just an example so that I
used $(input)
And in css provide min-width
.form {
border: 1px solid black;
text-align: center;
outline: none;
min-width:4px;
}
EDIT:
If you remove all text from input box then it will take placeholder value using focusout
Example: http://jsfiddle.net/kevalbhatt18/yug04jau/8/
$("input").focusout(function(){
if(this.value.length>0){
this.style.width = ((this.value.length + 1) * 8) + 'px';
}else{
this.style.width = ((this.getAttribute('placeholder').length + 1) * 8) + 'px';
}
});
input.addEventListener('input', event => event.target.style.width = event.target.scrollWidth + 'px');
Unfortunately this will only increase the size of the input. If you delete characters the size will not decrease. For some use cases this is perfectly fine.
Kevin F is right, there is no native way to do it.
Here is a one way to do it if you really want it to happen.
In the code, there is an invisible span where the text is placed. Then we retrieve the width of the span.
https://jsfiddle.net/r02ma1n0/1/
var testdiv = $("#testdiv");
$("input").keydown( function(){
var ME = $(this);
//Manual Way
//var px = 6.5;
//var txtlength = ME.val().length;
//$(this).css({width: txtlength * px });
testdiv.html( ME.val() + "--");
var txtlength = testdiv.width();
ME.css({width: txtlength });
});
Try with 'size' attribute.
This will work even when you clear the text .
Need jQuery to work this
<div>
<input id="txt" type="text" style="max-width: 100%;" placeholder="name">
</div>
<script>
$(document).ready(function() {
var placeholderLen = $('#txt').attr('placeholder').length;
// keep some default lenght
placeholderLen = Math.max(5, placeholderLen);
$('#txt').attr('size', placeholderLen);
$('#txt').keydown(function() {
var size = $(this).val().length;
$(this).attr('size', Math.max(placeholderLen, size));
});
});
</script>

Custom <input type="file"> not working in IE

I'm trying to use a custom < input type="file" > button. This works in chrome and FF. How do I make it work in IE 10 and above?
The problem in IE is that the browse box is not opening.
html:
<button type="button" id="fileT"><input type="file" id="file"></button>
css:
#fileT{
overflow: hidden;
position: relative;
}
#fileT input {
position: absolute;
opacity: 0.1
}
I've got what you mean: since <input type="file"/> is hard to style, you need a container.
Then try using a <div> instead of a <button>.
Just ensure you specify height and width since the div content will be absolutely positioned (and hence stripped from the flow).
Running demo:
<div id="fileT">
<input type="file" id="file" />
</div>
#fileT{
overflow: hidden;
position: relative;
width: 75px;
height: 50px;
}
#fileT input {
position: absolute;
opacity: 0.5;
}
I think this approach is wrong. The input field <input type="file"> should not include inside the <button>.
This will work.
<input type="file" id="file">
Just remove that button and try with just input tag.. It works..
Like this
<input type="file" id="file" value="Browse"/>
if you want to have your custom button then you have to remove position:absolute and keep opacity:0
You do not need to surround the input tags with button tags, as the input for file upload automatically creates a browse button for you. When you click it in IE you are just clicking the empty button and not the browse one created by the input which is why it is not doing anything.
So instead of:
<button type="button" id="fileT"><input type="file" id="file"></button>
Replace simply with:
<input type="file" id="fileT">
Try this way:-
<input type="file" id="file" multiple="true"/>
<button type="button" id="fileT">Upload</button>
OR
It might be version problem.
Updated1:-
This is bug from IE 10 Desktop.To be more specific here's the IE 10 Desktop version:
Version: 10.0.9200.16540
Update Versions: 10.0.4 (KB2817183)
Product ID: 00150-20000-00003-AA459
Refer This
Updated2:-
Html:
<div id="wrapper">
<div id="button">Upload</div>
<input type="file" id="file" multiple="true"/>
</div>
<div id="notice">Nothing to upload</div>
Css:
#button
{
width: 100px;
height: 50px;
background-color: #0f0;
}
#wrapper
{
width: 200px;
height: 50px;
overflow: hidden;
cursor: pointer;
}
Fiddler
var input = document.getElementById('Selectfile');
if (!input) {
input = document.createElement('input');
input.type = 'file';
input.id = "Selectfile";
document.body.appendChild(input);
}
input.onchange = function (e) {
var file = e.target.files[0];
};
input.click();

stopImmediatePropagation() of sibling not working

I show a search field on some text click, and hide it on search input blur.
But if I click on the search button I don’t want to hide the input field, and prevent it from being hidden (because of the blur). I tried to stopImmediatePropagation() without any luck.
Here’s some code:
// Not working. when search button is pressed, disable hiding the search input
$('.search-contacts-container > button').on('click touchstart', function(e) {
alert('xxx');
e.stopImmediatePropagation();
})
// when search input is blurred, hide it
$('#search-contacts').on('blur', function() {
$('.search-contacts-container').addClass('visuallyhidden');
$('#search-contacts').attr('required', 'false').blur();
})
// when search input is focused, show it
$('#search-contacts').on('focus', function() {
$('.search-contacts-container').removeClass('visuallyhidden');
$('#search-contacts').attr('required', 'true');
})
// on search text click, show the search input
$('.js-show-search').on('click touchstart', function() {
if ($('.search-contacts-container').is('.visuallyhidden')) {
$('.search-contacts-container').removeClass('visuallyhidden');
$('#search-contacts').attr('required', 'true').focus();
} else {
$('.search-contacts-container').addClass('visuallyhidden');
$('#search-contacts').attr('required', 'false').blur();
}
})
HTML:
<span class="js-show-search" title="Search for contacts">Search</span>
<form action="search" method="post" class="form-search search-contacts-container visuallyhidden">
<input type="text" id="search-contacts" placeholder="Search" required="false" />
<button type="submit" class="form-search__button" title="Search"></button>
</form>
Demo: http://jsfiddle.net/un775/
Any ideas?
Check out my new JsFiddle. I use this method on day to day tasks. I hope it helps you.
Basically what you are doing is adding a background that masks everything behind it, and then adding a click even listener to it that hides everything. The form/input is in front of the background allowing you to interact with it.
HTML
<div id="js-show-search">...</div>
<form id="search-contacts" class="hide">...</form>
<div id="background" class="hide"></div>
JavaScript
var searchContact, background;
searchContact = $('#search-contacts');
background = $('#background');
$('#js-show-search').on('click', function(){
//remove .hide to show elements
});
$('#background.close').on('click', function(){
//add .hide to hide elements
});
CSS
html, body {
height: 100%;
}
#background {
height: 100%;
width: 100%;
position: absolute;
top:0;
left: 0;
z-index: 0;
}
#search-contacts {
position: relative;
z-index: 1;
display: inline-block;
}
.hide {
display: none!important;
}
http://jsfiddle.net/un775/7/

How to remove "no file selected" from type=file inputs?

I can't seem to figure out any way to remove the "No file selected" text that shows up next to inputs of type "file".
Do you guys know any way how to remove this text?
input[type='file'] {
color: transparent;
}
Enjoy
There is no cross-browser way to do this. The "no file selected" text is in the implementation-defined part of the widget, and I don't believe that most browsers offer much in the way of browser-specific customization. On the other hand, you could simply use CSS to cover the text with something when the value attribute is empty.
You can do this by defining a width to the input and hiding the exceeding content (the undesired "No file selected" text).
input {
width: 132px;
overflow:hidden;
}
Here is the demonstration on jsfiddle.
Beware: each language has its own default text and it may render different input sizes. In brazilian portuguese that 132px width is fine!
My answer was based on this similar question on stackoverflow.
You can replace the file field with a button with the answer to this question: file upload button without input field?
CSS
<style>
#image_file{
position: relative;
width: 188px;
border: 1px solid #BBB;
margin: 1px;
cursor: pointer;
float: left;
}
</style>
HTML
<input id="image_file" onclick="getFile()" onfocus="this.blur()" value=""/>
<div style='height: 0px;width: 0px; overflow:hidden;'>
<input type="file" id="PinSpot_file">
</div>
<input type="button" onclick="getFile()" style="background-color: #DDD;" value="Browser" >
JAVASCRIPT
function getFile(){
document.getElementById("PinSpot_file").click();
}
// Event when change fields
$('#PinSpot_file').live('change', function(e) {
var file = this.value;
var fileName = file.split("\\");
document.getElementById("image_file").value = fileName[fileName.length-1];
//AJAX
}
This is a really good hack and its a lot cleaner.
HTML
<div id="file_info' style='display:inline;'>Browse</div>
<input type="file" name='file[]' multiple style='opacity: 0;' onchange='displayFileName()'/>
JS
function displayFileName() {
var files = $('input[type="file"]')[0].files;
document.getElementById('file_info').innerHTML = files.length + " images to upload";`
}
Well, since there is no way to completely disable the text, I'd suggest either placing an element over the text or try the following solution..
CSS
input[type="file"] {
width: 90px; /* Keep it under 100px in order to hide the unwanted text. */
}
and add an html inline-title attribute to the element to hide the "No File Chosen" hover text.
HTML
<input type="file" id="FileId" title="">
or, you could do it all with JavaScript.
JS
document.addEventListener('DOMContentLoad', myFunction);
function myFunction() {
const FilePicker = document.getElementById('FileId');
FilePicker.style.width = "90px";
FilePicker.title = ""; // Leave This Empty
}
You can try this. Its work for me firefox browser
<style type="">
input[type='file'] {
color: transparent;
}
</style>

Categories

Resources