I am currently uploading a file to the server in Django as follows (For some unrelated reasons, I cannot use models for this form):
<div class="input-group" style="padding-top: 10px">
<div><input class="form-control" id="filename" value="Select a ZIP file to upload..." disabled></div>
<div class="input-group-btn"><input type="button" id="get_file" class="btn btn-primary" value="Browse"
style="margin-right: 3px;margin-left: 3px"></div>
<div class="input-group-btn"><input type="submit" id="upload"
class="btn btn-success" value="Upload" style="display: none"></div>
<input type="file" id="upload_file" name="upload_file" accept=".zip">
</div>
And then I some JavaScript as:
document.getElementById('get_file').onclick = function() {
document.getElementById('upload_file').click();
};
$('input[type=file]').change(function (e) {
document.getElementById('filename').value = ($(this).val());
document.getElementById('upload').style.display = "inline"
});
document.getElementById('upload').onclick = function() {
};
This works fine and I can upload the file just fine. However, now along with a file, I also want to send a string identifier. I am not sure how I can insert another request parameter on submit from this template?
The Django side looks like:
def upload(request):
"""
if request.method == 'POST' and request.FILES['upload_file']:
# Do things
So I need to add another parameter, so that I can do something like: request.GET.get('identifier') and this identifier key/value is inserted in the template code.
Does adding a hidden input inside the form work?
<input type="hidden" name="identifier" value="..."/>
Related
I'm trying to load forms in modal dynamically using jquery and ajax in python but when i submit the form i get the error werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'title'.
Mentioning that I recently started using jquery and ajax with python, could you help me please?
I want to reuse modal section to load multiple forms with jquery.
The code is as below.
HTML: lockbox.html
<input class="btn add" type="button" value="New">
<!--Modal-->
<dialog class="modal">
<div class="modal-header">
<h4 class="modal-title"></h4>
<button class="close-modal">X</button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button class="close-modal">Cancel</button>
</div>
</dialog>
Javascript
$('.add').on('click', function () {
$.ajax({
type: "get",
url: "/newentry",
success: function (data) {
$('.modal-body').html(data);
$('.modal-header').css('background-color', '#0688fa');
$('.modal-title').text('New register');
$('.modal-footer').css('background-color', '#0688fa');
modalBox.showModal();
}
});
});
Python route
#app.route('/newentry')
def newentry():
return render_template('app/addpass.html')
HTML: addpass.html
<form method="post" class="addPass" action="/addPassReg">
<div class="field-block">
<label for="title">Title: </label>
<input type="text" id="title" value="">
</div>
<div class="field-block">
<label for="user">User: </label>
<input type="text" id="user" value="">
</div>
<div class="field-block">
<label for="passw">Password: </label>
<input type="text" id="passw" value="">
</div>
<div class="field-block">
<input type="submit" value="Save" class="btn save">
</div>
</form>
Python route
#app.route('/addPassReg', methods = ['POST', 'GET'])
def addPassReg():
#cur = mysql.connection.cursor()
if request.method == 'POST':
print('is post')#for debug
print(request.args.listvalues)#trying to know the error
title = request.form['title']
user = request.form['user']
passwd = request.form['passw']
if title and user and passwd:
return json.dumps({'message' : 'OK.'})
else:
print('After')
return redirect(url_for('lockbox'))#json.dumps({'html' : 'Complete please.'})
if request.method == 'GET':
print('is get')#for debug
else:
print('whats up?')#for debug
return redirect(url_for('lockbox'))
When I reuse the modal just to see data it's OK, but for forms I realize that it doesn't work and I don't know if it doesn't recognize the form data or I'm doing something wrong.
I am looking for a way to receive parameters sent by .JS as .JSP.
The file receiving the parameter is JSP, but it is the script that must be used.
sendParameter.jsp
<form name="frm" action="adminGNB.jsp" method="POST" >
<div class="form-line">
<input type="text" class="form-control" name="admin_id" id="admin_id" onkeyup="enterkey()">
</div>
<div class="form-line">
<input type="password" class="form-control" name="admin_password" id="admin_password" onkeyup="enterkey()">
</div>
<div class="btn-wrap">
<button type="button" class="btn btn-block btn-primary" id="login" onClick="loginbutton()">login</button>
</div>
</form>
receive Parameter.jsp
<%
request.setCharacterEncoding("UTF-8");
String name = (String)request.getSession().getAttribute("admin_id");
System.out.println("admin_id :" + name);
%>
<script>
$(function(){
changeYourPassword();
latestNoticeCheck();
});
....
</script>
I'm using Java to receive parameters sent by JSP, as you can see by the code. But where I have to use the parameters in <script>. How can I get the parameters?
I don't use the GET method.
getParameter("admin_id") is don't work
Thanks in advance
this code should be working .....
<script>
$(function(){
var myVar = '<%= request.getSession().getAttribute("admin_id") %>';
changeYourPassword();
latestNoticeCheck();
});
....
</script>
Actually I load the picture on the server. But once we do this, the page refreshes. My goal is to do this without refreshing the page. How can I do that? Is there anyone who can help?
In the code below I write onsubmit = "return false" in the form. But the picture is not uploaded to the server because the page is not refresh in this way.
VIEW
#using (Html.BeginForm("create_conference", "Home", FormMethod.Post, new { enctype = "multipart/form-data", id = "registerFormValidation", onsubmit = "return false" }))
{
<div class="form-group">
<div class="input-group">
<span class="btn btn-default btn-wd btn-info btn-fill btn-file input-group-addon">
<i class="fa fa-image"></i> <input type="file" name="file" id="imgInp" accept="image/*">
</span>
<input type="text" class="form-control" readonly id="image-path" value="">
</div>
</div>
<div id="enter-room-name">
<div class="form-group">
<input type="text" placeholder="Enter Name of Room" class="form-control" required="true" id="room-name" autocomplete="false" style="text-transform:uppercase">
</div>
<button type="submit" name="add-room-submit" class="btn btn-info btn-round btn-wd">Save</button>
</div>
}
CONTROLLER
[HttpPost]
public ActionResult create_conference(HttpPostedFileBase file)
{
var path = "";
if (file != null)
{
if (file.ContentLength > 0)
{
//for checking uploaded file is image or not
if(Path.GetExtension(file.FileName).ToLower()==".jpg"
|| Path.GetExtension(file.FileName).ToLower()==".png"
|| Path.GetExtension(file.FileName).ToLower()==".gif"
|| Path.GetExtension(file.FileName).ToLower()==".jpeg")
{
path = Path.Combine(Server.MapPath("~/assets/img/conference-img"), file.FileName);
file.SaveAs(path);
ViewBag.UploadSuccess = true;
}
}
}
return View();
//return Redirect("rooms");
}
Don't read it as base64 using the fileReader or using a iframe...
Simply turn the form element into a FormData and send that to the server.
A good idea is not trying to specify method/url in the javascript keep it as general as possible and have the html markup do what it was meant to do (defining things) then you can use this function for more forms and it got a more graceful degration if javascript where turned of
function turnFormToAjax(evt) {
evt.preventDefault()
var form = evt.target
var fd = new FormData(fd)
fetch(form.target, {method: form.method, body: fd})
.then(function(res) {
// done uploading
})
}
document.querySelector('form').onsubmit = turnFormToAjax
Convert to base64 and ajax call it. Make sure the backend converts it back to an image file before saving it.
I've done it with jquery in the past.
This is the important part:
I've done it with jquery. This is the important part.
$(document).ready(function() {
$('#imageFile').change(function(evt) {
var files = evt.target.files;
var file = files[0];
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById('preview').src = e.target.result;
};
reader.readAsDataURL(file);
// console.log(file.name)
var filename = file.name
console.log(filename);
}
});
make sure filename sends.
You can upload image using iframe, using iframe and ajax image will upload without page refresh.
You can try using my sample.
HTML:
<form id="registerFormValidation" name="registerFormValidation" action="" method="POST" enctype="multipart/form-data" >
<div id="main">
<input name="imgInp" id="imgInp" size="27" type="file" />
<input type="button" name="action" value="Upload" onclick="upload()"/>
<iframe id='my_iframe' name='my_iframe' src="">
</iframe>
</div>
</form>
This is my JS:
function upload()
{
//'my_iframe' is the name of the iframe
document.getElementById('registerFormValidation').target = 'my_iframe';
document.getElementById('registerFormValidation').submit();
}
And For Server side you can use simple Ajax method or Custom method.If you use ajax method then action will be action="javascript:submitForm();" and if you use custom method then you can use your function name.
I have a form with multiple fields but also a file upload. I am able to upload multiple files.
I also know that it is possible to upload files with AJAX.
So I would like to upload my files using ajax while i'm filling in every other field. But how would I link the already uploaded images then? And also prevent the images to be uploaded again?
This is the form:
<form id="form_validation" method="POST" action="{{route('storeexpense')}}" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group form-float">
<div class="form-line">
<input type="text" class="form-control" name="description" required>
<label class="form-label">Omschrijving</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="number" class="form-control" name="amount" required>
<label class="form-label">Bedrag</label>
</div>
</div>
<div class="form-group form-float">
#foreach ($types as $type)
#if ($type->id === 1)
<input name="transactiontype" type="radio" id="rdio{{$type->id}}" value="{{$type->id}}" checked />
<label for="rdio{{$type->id}}">{{$type->description}}</label>
#else
<input name="transactiontype" type="radio" id="rdio{{$type->id}}" value="{{$type->id}}" />
<label for="rdio{{$type->id}}">{{$type->description}}</label>
#endif
#endforeach
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" class="datepicker form-control" name="date" placeholder="Please choose a date..." required>
<!-- <label class="form-label">Datum</label> -->
</div>
</div>
<div class="form-group demo-tagsinput-area">
<div class="form-line">
<input type="text" class="form-control" id="tagsinput" data-role="tagsinput" placeholder="Labels" name="tags" required>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
#if (count($errors) > 0)
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
<input type="file" name="attachments[]" multiple class="custom-file-control"/>
</div>
</div>
<button class="btn btn-primary waves-effect" type="submit">SAVE</button>
</form>
This is the PHP code that saves the information from the form:
public function store(UploadRequest $request)
{
// Save new transaction in database
$transaction = new Transaction;
$transaction->description = $request->description;
$transaction->amount = $request->amount;
$input = $request->date;
$format = 'd/m/Y';
$date = Carbon::createFromFormat($format, $input);
$transaction->date = $date;
$transaction->transactiontype_id = $request->transactiontype;
$transaction->user_id = Auth::id();
$transaction->save();
// Put tags in array
$inputtags = explode(",", $request->tags);
// Loop through every tag exists
// EXISTS: get ID
// NOT EXISTS: Create and get ID
foreach ($inputtags as $inputtag)
{
$tag = Tag::firstOrCreate(['description' => $inputtag]);
$transaction->tags()->attach($tag->id); //Put the 2 ID's in intermediate table ('tag_transaction')
}
//Check if there are files
if (!is_null($request->attachments))
{
//Loop through every file and upload it
foreach ($request->attachments as $attachment) {
$filename = $attachment->store('attachments');
// Store the filename in the database with link to the transaction
Attachment::create([
'transaction_id' => $transaction->id,
'path' => $filename
]);
}
}
Thanks,
Bart
It sounds like you want to make a fancy form that starts uploading the file as soon as you choose it and meanwhile the user can continue filling the rest of the form. If so, I'd do it like this:
Implement your main text/data form, eg.
<form method="POST" action="/save-data-endpoint.php">
<input name="email" type="text" />
<button type="submit>Submit</button>
</form>
Next to it, a form for the images. eg.
<form method="POST" class="file-upload-form" action="/save-file.php">
<input name="my-file" type="file" />
<!-- note that we wont show a submit button -->
</form>
For the user, it all looks like the same form but clicking the submit button will send only the data to the save-data-endpoint.php. Now we need some js to control this madness (I'll use jQuery for brevity). But you can use FileReader api in js, ajax progress tracking to make it even fancier. See https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications for more.
$(function(){ // run when document is ready
// listen when the input changes (when a file is selected)
$('.file-upload-form').on('change', function(e){
// file has been selected, submit it via ajax
// show some kind of uploading indication, eg. a spinner
$.ajax({
type:'POST',
url: $(this).attr('action'),
data: new FormData(this),
cache:false,
contentType: false,
processData: false,
success:function(data){
// the save-file.php endpoint returns an id and/or a url to the saved/resized/sanitized image
console.log(data.id, data.url);
// we then inject this id/url, into the main data form
var $hiddenInput = $('<input type="hidden" name="uploads[]" value="'+data.id+'">');
$('.main-form').append($hiddenInput);
// show a thumbnail maybe?
var $thumbnail = $('<img src="'+data.url+'" width="20" height="20" />');
$('.main-form').append($thumbnail);
// hide spinner
// reactivate file upload form to choose another file
$('.file-upload-form').find('input').val('');
},
error: function(){
console.log("error");
}
});
});
});
Your backend will get the images as they are selected, one by one. You then save them and return an id and/or a url to the image to be used in the success handler in js. After adding some images your main form should look something like this:
<form method="POST" action="/save-data-endpoint.php">
<input name="email" type="text" />
<button type="submit>Submit</button>
<input type="hidden" name="uploads[]" value="x">
<img src="...x.jpg" width="20" height="20" />
<input type="hidden" name="uploads[]" value="y">
<img src="...y.jpg" width="20" height="20" />
</form>
Now when the user fills the remaining fields and clicks submit, your server will get all the data along with an array called uploads which contains all the image ids/paths you have already saved. You can now store this data and relate it to the files.
I wont go deeper on the backend side as it can be implemented on any language. In summary the basic flow would be:
send files one at a time to a save file endpoint that returns a file identifier (can be an id, hash, full path to image, etc)
js injects those ids into the main form
the main form is submitted to a save data endpoint that returns a success or error message and stores + relates all the data in your preferred method of storage.
Hope it helps!
This is a form that will go to the javascript page and will upload the photo to the server
<div class="col-sm-5" style="border-right: 1px solid #ccc">
<div class="subStyle" ng-show="showDiv1">
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "/api/photo"
method = "post">
<input type="file" name="userPhoto" />
<input type="submit" value="Upload Image" name="submit">
</form>
</div>
</div>
This is the JavaScript function
function confirmUploaded() {
res.end("File was successfully uploaded -- " + outText);
}
How would i call this function from the JavaScript file to the HTML page
res.end is not a client side, It is a server side code and need to be send from the server end(NodeJS).
Make use of $http.success in angular and then on success attach the result to a particular div or header tags and use css for formatting.