I've got a form with a drag and drop file input, which I originally found here:
http://codepen.io/prasanjit/pen/NxjZMO
the form is as follows:
<form method="POST" action="{{ url('images/save') }}">
<div class="file-drop-area">
<span class="fake-btn">Choose file</span>
<span class="file-msg js-set-number">or drag and drop file here</span>
<input class="file-input" type="file" name="fileUpload">
</div>
<button>Save</button>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
the JS is unchanged from the original pen:
$(document).ready(function () {
var $fileInput = $('.file-input');
var $droparea = $('.file-drop-area');
// highlight drag area
$fileInput.on('dragenter focus click', function() {
$droparea.addClass('is-active');
});
// back to normal state
$fileInput.on('dragleave blur drop', function() {
$droparea.removeClass('is-active');
});
// change inner text
$fileInput.on('change', function() {
var filesCount = $(this)[0].files.length;
var $textContainer = $(this).prev('.js-set-number');
if (filesCount === 1) {
// if single file then show file name
$textContainer.text($(this).val().split('\\').pop());
} else {
// otherwise show number of files
$textContainer.text(filesCount + ' files selected');
}
});
});
The problem is, when I pass this through a controller, the file comes up as null when using
$file = $request->file('fileUpload');
however, when using
$file = $request->get('fileUpload');
and then die dumping $file, it turns out that the get request is actually getting the username. So it'll die dump something like "image01.jpg".
Furthermore, when adding validation to the form,
$this->validate($request, [
'fileUpload' => 'required',
]);
the form will only go through after you've attached a file.
So what's going on? Why is this coming up as null on a file request?
<form method="POST" action="{{ url('images/save') }}" enctype="multipart/form-data">
Related
I get 403 error when I submit a form with html in in request body
I want to implement a newsletter in my Laravel site, I have used grapesjs library. In create page I design newsletter and then I want to send html from this blade to next blade using forrm. But when I append that in request it gives 403 error on server, although this works on local machine. Bellow is my script
Form
<form action="{{ route('admin.newsletters.preview') }}" method="POST">
#csrf
<div class="form-group">
<label class="required">Title</label>
<input type="text" name="title" class="form-control" placeholder="Title" required>
</div>
<input type="hidden" name="newsletter">
<div id="gjs"></div>
<button class="btn btn-success mt-3">Preview & Send</button>
</form>
Script
<script src="https://unpkg.com/grapesjs"></script>
<script src="https://unpkg.com/grapesjs-preset-newsletter"></script>
<script type="text/javascript">
var editor = grapesjs.init({
container: '#gjs'
, plugins: ['gjs-preset-newsletter']
, pluginsOpts: {
'gjs-preset-newsletter': {
modalTitleImport: 'Import template',
// ... other options
}
}
, storageManager: {
type: null
}
, });
$("form").submit(function(eventObj) {
var form = $(this);
// var newsletter = editor.getHtml();
var newsletter = editor.runCommand('gjs-get-inlined-html');
form.find('input[name="newsletter"]').val(newsletter);
return true;
});
</script>
My JQuery populates $_FILES only when click on input type file but not when drop in a file.
All the examples, tutorials, documentation I have found is about using Ajax or pure JavaScript. None is what I want to do. I have found also plently of plugins, libraries, ... I just want to be able to drop a file.....
The FORM:
<form id="item-form" role="form" method="post" enctype="multipart/form-data">
<div id="image-holder" class="dropBox">
<img src="" style="width: 100%; padding: 10px;display: none;">
</div>
<div id="fileBox">
<input type="file" name="image_file_input" id="image_file_input" />
</div>
<button type="submit" name="submit">SAVE</button>
</form>
The JQUERY:
$(".dropBox").on("drop", function(e) {
e.preventDefault();
e.stopPropagation();
runUpload( e.originalEvent.dataTransfer.files[0] );
});
$(".dropBox").click(function(){
$("#image_file_input").click();
});
$('input[type=file]').on('change', function(){
runUpload( this.files[0] );
});
function runUpload( file ) {
var reader = new FileReader(), image = new Image();
reader.readAsDataURL( file );
reader.onload = function( file ) {
var image_holder = $("#image-holder");
image_holder.empty();
$("<img />", {
"src": file.target.result,
"class": ""
}).appendTo(image_holder);
$("#dropBox").hide();
$(image_holder).show();
}
The PHP:
if ( !empty($_FILES) ) {
echo '---> Files not empty ';
}else{
echo '---> Files empty ';
}
I don't want to use Ajax. I'm only showing the relevant part of the code to concentrate in the issue.
If I click on the dropBox or I drop a file (image) into the dropBox element I can see the image selected in the image_holder div.
When the form is submited if the file is from a click event it works perfectly but when is from a drop event $_FILES is empty.
I'm convinced the problem is what I pass to the runUpload function when dropping. I have tried all sort of things but unable to see what is wrong.
I want to save an image and two text field using JQuery,Ajax. here, i'm using bootstrap modal. But when I submit the modal form it's show MethodNotAllowedHttpException Exception.
My Ajax Method.
$(document).ready(function(){
$('#advisoradd').on('submit',function(){
var name=$('#adname').val();
var title=$('#adtitle').val();
var img=$('#adfile').val();
$.ajax({
url:"{{route('add.advisor')}}",
type:'post',
data:{
'_token':"{{csrf_token()}}",
'name':name,
'title':title,
'img':img,
},
success:function(data)
{
console.log(data);
}
});
});
});
My view Modal code.
<form method="POST" enctype="multipart/form-data">
{{csrf_field()}}
<div class="form-group">
<div class="img_upload_team">
<button class="btn">+</button>
<input type="file" name="myfile" id="adfile">
</div>
<h2>Add A Profile Photo</h2>
<p>Click “+” Sign to Add</p>
</div>
<div class="form-group">
<input type="text" name="adname" class="form-control" id="adname" placeholder="Name">
</div>
<div class="form-group">
<input type="text" name="adtitle" class="form-control" id="adtitle" placeholder="Title">
</div>
<button type="submit" class="btn btn_modal_submit" id="advisoradd">Add</button>
</form>
My controller and Route for this Request.
public function addadvisor(Request $request)
{
$advisor=new Advisor();
$advisor->name=$request->name;
$advisor->title=$request->title;
$file = $request->file('img') ;
$fileName = $file->getClientOriginalName();
$destinationpath=public_path().'/images/';
$file->move($destinationpath,$fileName);
$advisor->image=$fileName;
$advisor->save();
return response()->json($advisor);
}
Route::post('/advisor','ImageController#addadvisor')->name('add.advisor');
You've mixed up button and form events. Buttons don't have a submit event, forms do. Since you're adding the event on the button, change it to click.
We should also add a preventDefault() to stop the button from submitting the form.
(We could also add the type="button" attribute on the button element to stop it from submitting the form).
This should work:
$(document).ready(function() {
// Add a 'click' event instead of an invalid 'submit' event.
$('#advisoradd').on('click', function(e) {
// Prevent the button from submitting the form
e.preventDefault();
// The rest of your code
});
});
I would like to implement Dropzone in my long form. All tutorials focus on image upload ONLY, there are no tutorials if you have other stuff in your form. I am stuck in displaying dropzone. I have linked css and js files in my layout file but I still get an unstylized box for image upload and error in console: No URL provided.
This is a part of my form that should display Dropzone:
<form action="/ads/new" method="post" enctype="multipart/form-data">
<input class="input" type="text" name="name">
<input name="file" type="file" class="dropzone" multiple />
I would appreciate any help. Thanks.
UPDATE: I googled all the examples for this uploader and they all have only image upload field and nothing else. I need a solution when I have actually more fields in the form. Class dropzone can't be on whole form because I have more fields in it This is not just an image uploader!
I tried with this:
Dropzone.autoDiscover = false;
$("#pics").dropzone({
url: '/ads/new',
maxFilesize: 1
});
And there are no errors but whole dropzone functionality is gone.
Btw. If you don't know how to help then there is no need to downvote.
Try this might be help you
<form action="/ads/new" method="post" enctype="multipart/form-data" class="dropzone">
<input class="input" type="text" name="name">
<input name="file" type="file" multiple />
To make dropzone work in Laravel you can use the example below. Change it to your desired behaviour of course.
HTML
<form id="my-awesome-dropzone" class="dropzone"></form>
JQuery
<script type="text/javascript">
Dropzone.autoDiscover = false;
$(document).ready(function(){
var baseUrl = "{{ url('/') }}";
var token = "{{ Session::token() }}";
$("#my-awesome-dropzone").dropzone({
paramName: 'file',
url: baseUrl+"/ads/new",
params: {
_token: token
},
dictDefaultMessage: "Drop or click to upload images",
clickable: true,
maxFilesize: 2,
addRemoveLinks: true,
removedfile: function(file) {
// #TODO : Make your own implementation to delete a file
},
queuecomplete: function() {
// #TODO : Ajax call to load your uploaded files right away if required
}
});
});
</script>
Laravel Upload Function for route: /ads/new
use Illuminate\Support\Facades\File; // Required Dependencies
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Input;
public function upload() {
$destinationPath = public_path() . '/uploads/'; // upload folder, set whatever you like
$fileNameWithExtension = Input::file('file')->getClientOriginalName();
$upload_success = Input::file('file')->move($destinationPath, $fileNameWithExtension); // uploading file to given path
if ($upload_success) {
return Response::json('success', 200);
} else {
return Response::json('error', 400);
}
}
I have a modal containing a form and an iframe.
The form has a file field and post to the iframe.
The php controller return the uniqid (basically the name) of the uploaded file.
The upload works well and my iframe contains the uniqid.
I would like to display this uniqid on my main page.
My issue is that I don't know how to wait the end of the upload to show the uniqid.
The form and iframe :
<form id="uploadForm" enctype="multipart/form-data" action="{{ path('lesson_upload') }}" target="uploadFrame" method="post">
<label for="uploadFile">Document :</label>
<input id="uploadFile" name="uploadFile" type="file" />
<br /><br />
<input class="btn btn-primary" id="uploadSubmit" type="submit" value="Upload" />
</form>
<div id="uploadInfos">
<div id="uploadStatus">Aucun upload en cours</div>
<iframe hidden id="uploadFrame" name="uploadFrame"></iframe>
</div>
The JavaScript to fill the modal with the form :
$(document).on('click', '#computer-upload', function ()
{
var url = Routing.generate('lesson_upload_computer');
$.get(url, function (data)
{
$('#modal-various .modal-body').html(data);
return false;
});
return false;
});
The iframe at the end of an upload :
<div id="uploadInfos">
<div id="uploadStatus">Aucun upload en cours</div>
<iframe hidden="" id="uploadFrame" name="uploadFrame">
#document
<html>
<body>
<body>533ebac647b7e</body>
</body>
</html>
</iframe>
</div>
Does anyone have an idea ?
Thanks !
If you don't use an AJAX upload, after a little research, you cannot add an event that detects when the upload has finished.
You now have 2 options:
Fetch the id from the iframe every ~100ms and if it is not empty or null, the id will be in:
document.checkForId = function() {
id = $('#uploadFrame').contents().find('#idInIframeDivOrOtherContainer');
if (id) {
window.clearInterval(intervalId);
}
};
$(document).ready(function() {
intervalId = window.setInterval('document.checkForId', 100);
});
When posting data, return javascript that sets the id in the main page (if you have jquery in the iframe):
<script>
$(document).ready(function() {
$('#divInParentWindow', parent.document).text('<?php echo $id; ?>');
});
</script>
If your iFrame has its source on the same server/domain level as your main page. You could simply define a function at your main page
function iframeHasLoaded() {
var body = document.getElementById('uploadFrame').contentWindow.document.body.innerHTML;
}
And, from your iFrame
window.onload=function() { parent.iframeHasLoaded() };
This should work.