I have uploaded an image to the server without page load. My question is that what is the best way to display it after successful upload in the browser without page load ??
html part---->
<form method="post" data-remote="true" accept-charset="UTF-8" action="/update_profile_image" enctype="multipart/form-data" id="edit_user_72" class="edit_user">
<div>
<input type="file" id="user_avatar" name="user[avatar]" as="file">
</div>
<input type = "button" value ="Update" id= "update-img"
onclick ="AjaxUpdateImage($('form').attr('action'),$('form').attr('id'))" />
</form>
ajax part--->
function AjaxUpdateImage(url,id) {
var formData = new FormData($('#'+id)[0]);
$.ajax({
type: "POST",
url: url,
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
data: formData, // serializes the form's elements.
success: function(data)
{
console.log(data);
},
error: function (data)
{
console.log(data)
}
})
server part (ruby on rails)---->
def update_profile_image
id = params[:user][:attr].to_i
#user = User.find(id)
#response = #user.update_attribute(:avatar, params[:user][:avatar])
respond_to do |format|
format.json { render json: #response }
end
end
Related
I'm trying to create a form that submits pictures to database using Ajax.
The form is defined in function "new_pic" that is neither accepted nor returning errors when a picture is submitted.
After clicking submit button the flash message "please fill the form" is returned.
Please tell what did I do wrong?
db.py:
db.define_table('input_images', \
Field('action_id', type='string', unique=False, compute=lambda r: action_id ),\
Field('picture', 'upload', uploadfield='picture_file')),\
Field('picture_file', 'blob'),\
primarykey=['action_id']\
)
default.py:
import uuid
action_id = str(uuid.uuid4())
def index:
return dict()
def new_pic():
form = SQLFORM(db.input_images, buttons=[])
if form.process(session=None, formname='test').accepted:
response.flash = 'form accepted'
elif form.errors:
response.flash = 'form has errors'
else:
response.flash = 'please fill the form'
return dict(form=form)
index.html:
<div class="inner">
<form id="myform" action="#" enctype="multipart/form-data" method="post">
{{=LABEL('Upload picture', _for='picture', _class='button-25')}}
{{=INPUT(_id='picture', _name='picture', _type='file')}}
<div id="sbmt_picture">
{{=INPUT(_id='submit_btn', _name='submit_btn', _type='submit', _class='button-25')}}
</div>
<input type="hidden" name="_formname" value="test" />
</form>
</div>
<script>
jQuery('#myform').submit(function() {
ajax('{{=URL('new_pic')}}', ['picture'], 'trgt');
return false;
});
</script>
<div id="trgt"></div>
The problem was in the JS. I just found another kind of this element here: https://stackoverflow.com/a/28386477/13128766
That works for me:
<script>
jQuery(document).on("submit", "form", function(event)
{
event.preventDefault();
jQuery.ajax({
url: "{{=URL('new_pic')}}",
type: jQuery(this).attr("method"),
dataType: "JSON",
data: new FormData(this),
processData: false,
contentType: false,
success: function (data, status)
{
},
error: function (xhr, desc, err)
{
}
});
});
</script>
My Vue component to display a modal is like this :
<template>
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
...
<a href="javascript:">
<img v-if="image == ''" :src="'https://myshop.co.id/img/no-image.jpg'" alt="" class="img-responsive">
<img v-else :src="image" alt="" class="img-responsive" />
</a>
...
<input type="file" v-on:change="changeImage">
...
</div>
</div>
</div>
</template>
<script>
export default{
...
data() {
return {
image: '',
...
}
},
methods: {
changeImage($event) {
const selectedImage = $event.target.files[0]
const form = new FormData();
form.append('file', selectedImage);
// define the done handler
const onDone = (data) => {
if (!$.trim(data)) {
alert('No response');
}
else {
var files = $event.target.files || $event.dataTransfer.files
if (!files.length)
return;
this.createImage(files[0])
this.imageChanged = data
this.disabled = 0
}
}
// define th post options
const options = {
url: window.Laravel.baseUrl+'/product/addImage',
type: "POST",
data: form,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}
// submit the image
$.ajax(options).done(onDone);
},
createImage(file) {
var image = new Image()
var reader = new FileReader()
var vm = this
reader.onload = (e) => {
vm.image = e.target.result
};
reader.readAsDataURL(file)
},
}
}
</script>
When the modal shows, it will display a file input.
If I upload image using the file input, it will display that image in the HTML.
When I close the modal and re-open it, the image is still displayed.
I want to reset the input data in the modal so that when I open the modal again, the image will disappear.
How can I do it?
Set this.image='' when the modal closes.
In bootstrap you can do this automatically when the modal closes by listening to the hidden.bs.modal event. You can clear file inputs by setting their value to null.
Add a ref attribute to your modal
<div ref="modal" class="modal" tabindex="-1" role="dialog">
...
<input ref="imageInput" type="file" v-on:change="changeImage">
And add code to listen to the event.
mounted(){
$(this.$refs.modal).on('hidden.bs.modal', () => {
this.image = ''
this.$refs.imageInput.value = null
})
}
Running into a weird problem with Angular forms (running 1.2 rc.2). If I leave the form without a name and prepend each model with a common name, the form sends fine. If I remove the prepended name from each model and give the form that name, the submit action doesn't bind the data and the form tries to send an empty request payload.
This model works fine, except Angular's form validation doesn't instantiate
<form ng-submit="sendForm()">
<input type="text" ng-model="my_form.fullname">
<button type="submit">Submit</button>
<form>
.
app.controller("MyCtrl", function($scope, $http) {
$scope.sendForm = function() {
$http({ method:'POST', url: '...', data: $scope.my_form; })
.then(function(result) { alert("The form was sent"); },
function(reason) { alert("There was a problem"); });
}
}
So now if I add a name attribute to my form and remove it from the models, the form tries to send empty data...
<form name="my_form" ng-submit="sendForm()">
<input type="text" ng-model="fullname">
<button type="submit">Submit</button>
<form>
It seems like my_form no longer exists. In fact, if I don't initialize $scope.my_form = {} on the controller the form won't even send an empty object.
Any advice on how to get the second method to work?
When you give the form a name, that name becomes a variable with meta-data about the fields... dirty flags, errors, etc. It doesn't actually hold the data.
So, when you set ng-model to fullname, the value isn't being set on the my_form object, it is being set directly on your $scope.
Personally, I prefer to do it this way:
<form name="my_form" ng-submit="sendForm(formData)">
<input type="text" ng-model="formData.fullname">
<button type="submit" ng-disabled="my_form.$invalid">Submit</button>
<form>
Then your code looks like this:
app.controller("MyCtrl", function($scope, $http) {
$scope.sendForm = function(formData) {
$http({
method:'POST',
url: '...',
data: formData
})
.then(
function(result) {
alert("The form was sent");
},
function(reason) {
alert("There was a problem");
}
);
}
}
I've this form
<form id="frm_main" action="#" method=POST>
<input type=hidden name="MAX_FILE_SIZE" value="100000" />
<input id='file' name="file" type="file">
<input type=submit id='btn_import' name='btn_import' value='Importar' />
<input type=hidden id="uploadResponseType" name="mimetype" value="html" />
<input type=hidden id="func" name="func" value="upload" />
<div id="uploadOutput"></div>
</form>
So, the problem became when I try to post the upleaded file. If I use ajaxSubmit function the form is submited but it doesn't return to the page; and if I use $.ajax function, it doesn't sent the uploeade file. The thing is that I need to return to the same page because I've to do some stuff with the file content. I've already tried lot of combinations but I'm still having the same results. The code to handle submit look like this
$( '#frm_main' ).bind( 'submit', function( e ) {
// e.preventDefault(); // <-- important
$( this ).ajaxSubmit({
target: '#uploadOutput', // <-- div container
type: "POST", // <-- override, just in case.
url: "/process.php", // <-- server-side handler
data: "func=upload", // <-- parameter for post purpouse
beforeSubmit: function(a,f,o) {
o.dataType = $('#uploadResponseType').val(); // should be 'html'.
$('#uploadOutput').html('Submitting...');
},
success: function(data) {
var $out = $('#uploadOutput');
$out.html('Form success handler received: <strong>' + typeof data + '</strong>');
$out.append('<div><pre>'+ data +'</pre></div>');
}
});
return false;
});
And I've already tried with next code
$('#frm_main').bind('submit', function() {
var formdata = $(this).serialize();
$.ajax({
url: '/process.php',
data: formdata,
dataType: 'html',
success: function(data){
var $out = $('#uploadOutput');
$out.html('Form success handler received: <strong>' + typeof data + '</strong>');
}
});
return false;
});
And process.php code looks like this
switch($_POST['func']) {
case 'upload' :
$output = upload_file ();
echo $output;
break;
default :
echo "<BR/>INVALID";
break;
}
?>
Can somebody help me with this situation, please? Any help will be gratefully appreciated
Don't you need form enctype="multipart/form-data" to upload files?
I have a form with two input fields, one text and one send button. I want to submit via jQuery .ajax() without reloading the document.
It works as long as the button is clicked, but not when you press return/enter, then it submits without ajax methodology. I tried onEnter() or onSubmit(), but that didn't work either.
These are the code bits:
//HTML
<div id="search_form">
<form method="POST" action="search.php">
<input id="search_text" type="text" name="query"/>
<input id="search_button" type="button" value="send"/>
</form>
</div>
<div id="results"></div>
//Javascript
jQuery(function(){
$("#search_button").click(function(){
var query = "query="+$("input[name=query]").val();
$.ajax({
type: "GET",
url: "request.php",
data:query,
cache:false,
success: function(result){
$('#results').fadeIn();
},
error:function(xhr,err){
alert("readyState: "+xhr.readyState+"\nstatus: "+xhr.status);
alert("responseText: "+xhr.responseText);
}
});
});
});
Instead of a click on the button, rig up to the submit event on the <form>, like this:
$(function() {
$("#myFormId").submit(function() {
$.ajax({
type: "GET",
url: "request.php",
data: $(this).serialize(),
cache: false,
success: function(result){
$('#results').fadeIn();
},
error:function(xhr,err){
alert("readyState: "+xhr.readyState+"\nstatus: "+xhr.status);
alert("responseText: "+xhr.responseText);
}
});
return false;
});
});