Blueimp fileupload() callbacks not called - file-upload

I am using Blueimp fileupload() to post image files to a django-tastypie API.
The code below works correctly as far as the file is being uploaded:
$("#image").fileupload({
dataType: 'json',
start: function() {
console.log("start fileupload");
},
progress: function(e, data) {
console.log(data.loaded + " " + data.total);
},
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
},
done: function(e, data) {
console.log("done uploading file.");
}
});
$("#image").bind('fileuploadfinished', function (e, data) {
console.log("fileuploadfinished");
});
However, the done callback is never called. I tried binding the fileuploadfinished and that is also never called.
start and progress are both called as expected.
beforeSend is undocumented, but is needed by django-tastypie for SessionAuthentication - removing it doesn't change that done and fileuploadfinished is never called.

As it turns out, django-tastypie correctly returns a 201 status code. However, this status code is not considered a success by fileupload.
This code handles the status code manually:
$("#image").fileupload({
dataType: 'json',
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
},
complete: function(xhr) {
if (xhr.readyState == 4) {
if (xhr.status == 201) {
console.log("Created");
}
} else {
console.log("NoGood");
}
},
});
That means, the complete callback is called whether success or failure, and checking the readyState and status together can tell whether it succeeded.
There are some other ways to get this to work, however I think this is the best. More details here:
Data inserted successful but jquery still returning error

I was having the same problem. it is because you set your datatype 'json'.
Just leave this out or put it to plain and it will work.
Your server , or uploadhandler isn't return a json answer.

Related

Updating release field with Rally API fails, what's wrong and how to fix it?

I'm trying to update some release fields with the Rally API, but the requests fails when trying to save, I've tried with normal and custom fields. I can't figure out why this is happening.
Here's my portion of the code that attempts to do this:
launch: function() {
this._getReleaseModel().then({
success: function(model) {
console.log('release model: ', model)
return this._getReleaseRecord(model, 72984315568);
},
scope: this
}).then({
success: function(releaseRecord) {
console.log('release record:', releaseRecord);
this._updateReleaseRecord(releaseRecord, 'Name', 'Test Release Modified by API');
},
scope: this
});
}
_getReleaseModel: function() { // returns model promise
return Rally.data.ModelFactory.getModel({
type: 'Release'
});
},
_getReleaseRecord: function(model, objectID) { // returns record promise
return model.load(objectID);
},
_updateReleaseRecord: function(record, fieldToChange, newField) {
console.log('gonna update this record:', record);
record.set(fieldToChange, newField);
record.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log('record saved successfully');
}
else {
console.log('failed to save record');
}
}
})
}
Note I'm not pasting the whole app code for simplicity. Thank you.
So, the problem was that I was testing the rally code from a cloud9 server through app-debug.html. Apparently the save method can't access the Rally CA central from outside rally. I tested the code inside an actual rally custom html app and it worked fine. Thanks to Kyle for answering promptly either way.

Tooltipster not working in a ajax content

While searching in stack overflow .I find an old issue that i am facing too.But no one answered it.
So just wants to know anyone have any idea about it
How to get jquery Tooltipster Plugin to work for newly created DOM elements?
Following is my code
$(document).ready(function() {
$('.test_link').tooltipster({
interactive:true,
content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
continueTooltip();
// next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'POST',
url: 'example.php',
success: function(data) {
// update our tooltip content with our returned data and cache it
origin.tooltipster('content', $(data)).data('ajax', 'cached');
}
});
// }
}
});
});
My problem solved.
Just add the instantiation script in the ajax content too.
also set the option multiple:true
ie
$(document).ready(function() {
$('.test_link').tooltipster({
interactive:true,
multiple:true,
content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
continueTooltip();
// next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'POST',
url: 'example.php',
success: function(data) {
// update our tooltip content with our returned data and cache it
origin.tooltipster('content', $(data)).data('ajax', 'cached');
}
});
// }
}
});
});
It worked for me in Firefox.But didn't tested in other browser
I know this is an old post, and the problem was solved, but i recently needed something similar.
Adding the initialization on every ajax function was not a solution since we had several content dynamically loaded on the page, so the simplest solution found was:
$(document).on('mouseenter', '[data-toggle="tooltip"]', function(){
if ($(this).is('.tooltipstered')) {
// Do nothing
} else {
$(this).tooltipster({
delay: 50,
// Your other Tooltipster options
});
$(this).mouseover();
}
});
$('[data-toggle="tooltip"]') being the OP's $('.test_link').
The if deter the repeated initialization of document mouseenter.

How does CasperJs bind variables?

I have the following code which does not post data as expected
var casper = require('casper').create();
var myData;
var utils = require('utils');
casper.start();
casper.then(function () {
myData = {"source":"casperjs"};
utils.dump(myData);
});
casper.thenOpen('http://my-api/api/upload/', {
method: "post",
data: JSON.stringify(myData),
headers: {
"Content-Type":"application/json"
}
}, function () {
utils.dump(myData);
});
casper.run();
The message was sent to my server but without valid data. However, if I move the thenOpen(...) into the then(...) like this
casper.then(function () {
myData = {"source":"casperjs"};
utils.dump(myData);
this.thenOpen('http://my-api/api/upload/', {
method: "post",
data: JSON.stringify(myData),
headers: {
"Content-Type":"application/json"
}
}, function () {
utils.dump(myData);
});
});
Then the post would succeed. Or If i change the thenOpen part in the original code (i.e., without moving it in to the casper.then(...) part, like this
casper.thenOpen('http://my-api/api/upload/', {
method: "post",
data: JSON.stringify({"source":"casperjs"}),
headers: {
"Content-Type":"application/json"
}
}, function () {
utils.dump(myData);
});
Then the post would also be successful. So it looks like myData has to be initialized when the thenOpen(...) is seen. So is this expected or I have done something wrong? I could not find reference about this behavior. Thanks!
This is expected behavior as casperjs schedules the steps before running them. This means for your first listing that JSON.stringify(undefinded) will be sent to the server. The reason is that your first casper.then block was not yet executed when the object is evaluated for your casper.thenOpen block. Therefore your data was not yet assigned properly to myData, which happens inside the step.
The evaluation of the POST data on the other hand is done for the thenOpen call and not inside, so it is executed synchronously.
You already provided some good alternatives.

Why success callback is not called in extjs form submission?

I'm trying to upload a file using Ext JS forms and in case of success or failure, show appropriate messages. But I'm not able to get the desired result. I'm not able to make success or failure callbacks work in form.submit action.
What I've done till now is:
Creating a form with this script:
new Ext.FormPanel({
fileUpload: true,
frame: true,
url: '/profiler/certificate/update',
success: function() {
console.log(arguments);
},
failure: function() {
console.log(arguments);
}
}).getForm().submit()
​/*
The response Content-Type is text/html (with charcode=utf8);
The response JSON is: { "success": true }
*/​​
Setting the response Content-Type to text/html based on this answer.
Sending an appropriate JSON result back, based on Ext JS docs. The response captured via Fiddler is:
{"success":false}
or
{"success":true}
I even set the response Content-Type to application/json. But still no success.
I've read links like this and this, but none of them helped. Please note that I also tried another script which creates a form, with an upload field in it, and a save button, and I submitted the form in the handler of the save button. But still no callback is fired.
Here's a working example - Javascript code:
Ext.onReady(function () {
Ext.define('ImagePanel', {
extend: 'Ext.form.Panel',
fileUpload: true,
title: 'Upload Panel',
width: 300,
height: 100,
onUpload: function () {
this.getForm().submit({
url: 'upload.php',
scope: this,
success: function (formPanel, action) {
var data = Ext.decode(action.response.responseText);
alert("Success: " + data.msg);
},
failure: function (formPanel, action) {
var data = Ext.decode(action.response.responseText);
alert("Failure: " + data.msg);
}
});
},
initComponent: function () {
var config = {
items: [
{
xtype: 'fileuploadfield',
buttonText: 'Upload',
name: 'uploadedFile',
listeners: {
'change': {
scope: this,
fn: function (field, e) {
this.onUpload();
}
}
}
}
]
};
Ext.apply(this, Ext.apply(this.initialConfig, config));
this.callParent(arguments);
}
});
var panel = Ext.create('ImagePanel', {
renderTo: Ext.getBody()
});
});
And PHP code:
<?php
if (isset($_FILES)) {
$temp_file_name = $_FILES['uploadedFile']['tmp_name'];
$original_file_name = $_FILES['uploadedFile']['name'];
echo '{"success": true, "msg": "'.$original_file_name.'"}';
} else {
echo '{"success": false, "msg": "No Files"}';
}
I have been struggling with this for quite some time now as well. Here's my code:
Ext.getCmp('media-upload-form').getForm().doAction('submit', {
url: './services/recordmedia/upload',
method: 'post',
waitMsg: 'Please wait...',
params: {
entityId: this.entityId,
},
failure: function(form, action){
alert(_('Error uploading file'));
this.fireEvent('file-upload');
this.close();
},
success: function(form, action){
this.fireEvent('file-upload');
this.close();
},
scope: this
})
The response was always wrapped in <pre> tags by the browser, what caused the Extj lib not to call the callbacks. To fix this:
make sure your server returns the correct json: {"success":true}
make sure that the content-type is set to text/html
Actually, this is well covered by docs for Ext.form.Panel and Ext.form.Basic. The problem with your code not working is that there are no config options "success", "failure" for the form panel. You should put them in the config object passed to the submit action. So your code should look like:
new Ext.FormPanel({
fileUpload: true,
frame: true
}).getForm().submit({
url: '/profiler/certificate/update',
success: function() {
console.log(arguments);
},
failure: function() {
console.log(arguments);
}
});
Note the difference: In Ext 4, there is a form component (Ext.form.Panel) which is basically a view component concerned with how you form looks, and then there is the underlying form class (e.g. Ext.form.Basic) concerned with the functionality. Form submissions are handled by Ext.form.Basic (or whatever returned by your form.getForm()).

Read ExtJS message from ajax store

I have an ExtJS store with an ajax proxy and json reader:
Ext.create('Ext.data.Store', {
proxy: {
type: 'ajax',
url: '...',
reader: {
type: 'json',
root: 'data',
totalProperty: 'totalCount',
messageProperty: 'message',
successProperty: 'success'
},
...
This is what I get from the server:
data: [...]
message: "I want to read this string after the store is loaded"
success: true
totalCount: x
Now I want to access the 'message' when the store is loaded - where do I get it? I looked a lot but I can't find a place to hook in? The only listener in the proxy is exception, that doesn't really help me.
use store load event:
Ext.create('Ext.data.Store', {
listeners: {
'load': function(store, records, successful, operation) {
alert(operation.resultSet.message);
}
},
proxy: {
// ...
UPDATE
It appears that documentation for load event is wrong. The correct list of arguments is (store, records, successful) (no operation argument). Therefore the solution above wouldn't work.
However there is reader's rawData property which can help:
Ext.create('Ext.data.Store', {
listeners: {
'load': function(store, records, successful) {
alert(store.getProxy().getReader().rawData.message);
}
},
proxy: {
// ...
My answer applies to ExtJs 4.1.x. I spent some time reading the code and it seems that one way to do this is to provide a callback in the store beforeload event instead of handling the load event. The callback is passed the operation object which will contain the original request parameters and in case of success it will contain the response object and the data (parsed) under the resultSet property.
In other case:
myStore.load({
callback : function(object, response, success) {
// on error response: success = false
if(!success) {
// i don't remember de correct path to get "message" or "responseText"
console.log(response.response.responseText);
} else {
...
}
});
Cya!
I get the message in the following way although I load manually and do not use events here:
var initData = Ext.create('My.data.SomeAjaxStore');
initData.load(function(records, operation, success) {
if (!success || operation.hasException()) {
// Here is your message from server
// In case of HTTP error you get:
// {
// status: 404,
// statusText: "Not Found"
// }
var error = operation.getError();
Ext.log({msg:[Ext.getClassName(me), ": Command failure: ", error].join(""), level:"error"});
}