I have created text area that allows user to type in their text as shown below:
<!DOCTYPE html>
<html>
<body>
<textarea rows="4" cols="50">
Please type your favourite foods here and upload attachments if you want!</textarea>
</body>
</html>
I want to allow the user to allow be able to drag/drop or upload file attachments to the textarea but I am not quite sure how I can achieve this. I am quite new to web development and I am not sure what such feature would even be called. I have created a screenshot of what I would like, see below - something along the lines of gmail compose window. Please can someone help me, thanks.
Once the user has written and uploaded the files, I will be saving them to a database.
I suggest using the DropzoneJS library.
Create Dropzone object with the options you need and use the sending event to add textarea text to the POST request.
Change the default template and add your HTML inside div with template-container id. Then add previewTemplate property to myDropzone options
with value
document.querySelector('#template-container').innerHTML
Dropzone.autoDiscover = false;
$(document).ready(function() {
Dropzone.options.myDropzone = {
url: $('#my-dropzone').attr('action'),
paramName: "file",
maxFiles: 5,
maxFilesize: 20,
uploadMultiple: true,
thumbnailHeight: 30,
thumbnailWidth: 30,
init: function() {
this.on('sending', function(file, xhr, formData) {
formData.append('favouriteFoodText', document.getElementById('favourite-food-text').value);
}),
this.on("success", function(file, response) {
console.log(response);
})
}
}
$('#my-dropzone').dropzone();
});
#b-dropzone-wrapper {
border: 1px solid black;
}
#b-dropzone-wrapper .full-width {
width: 100%
}
#b-dropzone-wrapper textarea {
resize: none;
border: none;
width: 99%;
}
#my-dropzone {
top: -5px;
position: relative;
border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.0/min/dropzone.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.0/min/dropzone.min.css" rel="stylesheet" />
<div id="b-dropzone-wrapper">
<textarea rows=5 id="favourite-food-text" placeholder="please write some text here"></textarea>
<form action="file-upload.php" id="my-dropzone" class="dropzone full-widht" method="post" enctype="multipart/form-data"></form>
<input type="submit" value="Submit your entry" class="full-width" />
</div>
After submitting the form on the server side the transferred data will be parsed by PHP and saved in $_POST and $_FILES super global arrays.
Related
Am able to upload an image to the first web page using file input tag in a form. But I want to display that same image on another page when I click Submit button.
`
`<div class="profile-pic-div" id="input_field">
<input type="file" class="myfile" id="imgfile" accept="image/png, image/jpg">
</div>`
Here is a functional version of what I described in my comment.
You can use a FileReader() to read the value of the file input and use the readAsDataURL method to convert the image to a DataURL. This can then be stored in localStorage and read later on a different page (assuming all pages are on the same domain/site).
Unfortunately StackSnippets have limitations on things like reading files and localStorage. The same applies to places like CodePen and jsfiddle. Because of this I cannot post a live demo, but I can give you the source code.
NOTE: Again, this StackSnippet demo DOES NOT WORK HERE on StackOverflow. StackOverflow restricts access to things like localStorage and file readers. You will need to try this in a .html file you save.
<!doctype html>
<html>
<head>
<title>Save Uploaded Image in LocalStorage</title>
<style>
input[type="file"] {
vertical-align: middle;
padding: 1em 2em;
border: 1px solid #CCC;
border-radius: 0.4em;
}
.save {
font-size: 1.2em;
vertical-align: middle;
padding: 0.6em 1em;
}
img {
max-width: 10em;
max-height: 10em;
}
</style>
</head>
<body>
<div id="status">Waiting...</div>
<input type="file" id="file" onchange="_ReadImage()">
<br>
<br>
<img id="img">
<br>
<input type="button" value="Load Image" onclick="_LoadImage()">
<br>
<br>
<br>
<br>
<p>Clicking this link just reloads the page, but should <i>simulate</i> going to a new page where you could load the image data via localStorage.</p>
<script>
const _ReadImage = () => {
document.querySelector("#status").innerText = `Reading File...`;
let f = document.querySelector("#file");
if(f.files && f.files[0]) {
var reader = new FileReader();
reader.onload = e => {
_SaveImage(e.target.result);
}
reader.readAsDataURL(f.files[0]);
}
}
const _SaveImage = img => {
localStorage.setItem("img", img);
document.querySelector("#status").innerText = `Saved!`;
}
const _LoadImage = () => {
if(localStorage.getItem("img")) {
document.querySelector("#img").src = localStorage.getItem("img");
document.querySelector("#status").innerText = `Image Loaded!`;
} else {
document.querySelector("#status").innerText = `No Image!`;
}
}
</script>
</body>
</html>
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>
I am working on a resume generator and I want to be able to save the
input form data into a .yml file but I can't seem to find any article
to give me some clues. I want that once the submit button is clicked, the data is automatically written in the .yml file
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div class="biography">
<h2>Fill in your education information</h2>
<label for="degree">Degree</label>
<input id="degree" type="text">
<br/>
<label for="from">From</label>
<input id="from" type="date">
<br/>
<label for="to">To</label>
<input id="to" type="date">
<br/>
<button id="submit" type="submit">Submit</button>
</div>
</template>
<script>
export default {
name: "Education"
}
</script>
<style scoped>
input {
margin-left: 100px;
margin-bottom: 10px;
border: 2px;
width: 300px;
height: 3em;
display: inline-block;
}
button {
font-size: 16px;
padding: 10px;
background-color: #004d4d;
color: white;
border-radius: 6px;
}
button:active {
background-color: #00e6e6;
}
label {
position: absolute;
}
</style>
If you write a function that will turn the input values into a string that represents valid YAML text, you can use the Blob API to turn it into a file.
As media type, use the same type as the other YAML files your company uses ( text/yaml, application/yaml, text/vnd.yaml, etc ) since we ( afaik ) do not have a standard type yet for YAML files.
To actually save the file, you'll need to create a url from that Blob the user can click to download. ( See the multitude of other questions about that here on SO or any JS blob-to-url tutorial. )
If you are actually submitting a form to a serverside script, there's probably a bunch of server libraries that can create a YAML file you can return as the response to a form POST request.
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>
The question might not be clear, so i will explain further.
I saw some page like wordpress new post tag, they have something like
[input]
x tag | x tag | x tag
or Facebook Notes when you post a image...
the when you input a tag and press enter, a new tag is insert in to element in the page...
I don't quite understand how can you parse that out and then submit to the form.
if anyone know please give me an idea.
Thanks
If I am getting it right, you are talking about sending AJAX-based post requests "under the hood" and get "dynamic reflections" back on the same page.
Well, if this is the case, there are actually more than just submitting data to the server.
Here is the big picture:
You need a javascript which is loaded in the page that has the form to submit.
Inside that script, you need to define the event which will trigger the AJAX-based post request. Basically you would love trigger such an event when the content in that particular field has been just changed (an onChange event, that is).
Then you can use script like the following:
$.ajax
({
type: 'POST',
cache: false,
async: false,
timeout: 10000,
url : '/path/to/your/serverside/function',
dataType : 'json',
data:
{
'tag' : //whatever you want to be used as the tag
},
success : function(message)
{
//this will be called when this post was successfully been carried out.
//you should update the view (the same page) here using some jQuery script.
//such as : $('#tag').html(message.tag);
},
error : function(message)
{
//this is for displaying error messages (perhaps due to networking problems?)
}
});
Since there are really a lot to write about. I suggest you post whatever you have finished up here so we can give it a check.
At least from my consideration, this scenario require the following knowledge to get everything right(though you can always choose to use less tech):
onChange event triggered
|
|
jQuery =====sending JSON formatted tag info ======> serverside function
|
|
decode JSON tag info
|
|
process(saving it into database?)
|
|
encode feedback info
|
jQuery callback function <===== JSON info==================
|
|
update the view(the same page)
.
.
.
.
.
aforementioned process is before form is submitted via normal POST/GET.
One way is to keep track of the tags you add in a hidden form field, but actually display using divs or spans or whatever UI you want. In the case of facebook, I'd imagine they're doing something somewhat similar, though I guess they could actually be adding form elements dynamically. Forgive the nasty code/css - just tossed it together. If you add tags and then hit submit, you'll see the querystring that all the values are there.
<!doctype html>
<html lang="en">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#btnSuggest").click(function(){
var $tagSuggest = $("#tagSuggest");
if($tagSuggest.val() != "")
AddTag($tagSuggest.val());
});
$("#tagSuggest").keyup(function(e){
if(e.keyCode == 13 && $(this).val() != "")
AddTag($(this).val());
});
});
function AddTag(tag){
$("<div>").text(tag).appendTo("#tags").click(function(){
$(this).remove();
UpdateTags();
}).hover(function(){
$(this).addClass("over");
},function(){
$(this).removeClass("over");
});
UpdateTags();
}
function UpdateTags(){
var allTags = "";
$("#tags div").each(function(){
allTags += "," + $(this).text();
});
$("#hidTags").val(allTags.substring(1));
$("#tagSuggest").val("");
}
</script>
<style type="text/css">
.main
{
width: 400px;
padding: 10px;
margin: auto;
border: 1px solid black;
background-color: #e6e6e6;
height: 600px;
}
#tags div
{
padding: 3px;
border: 1px solid black;
background-color: #e6e6e6;
margin: 3px;
height: 15px;
width: auto;
float: left;
cursor: pointer;
}
#tags div.over
{
background-color: red;
}
</style>
</head>
<body>
<div class="main">
<form action="" method="get">
<input type="hidden" name="hidTags" id="hidTags">
<textarea name="Wallpost" style="width: 390px; height: 100px;"></textarea>
<br />
<input type="text" id="tagSuggest" style="width: 280px;" />
<input type="button" id="btnSuggest" value="Add Tag" style="float: right;"/>
<br />
<input type="Submit" name="cmdSubmit" value="Share" style="float: right;"/>
</form>
<div id="tags">
</div>
</div>
</body>
</html>