scriptData not being passed when there are multiple instances of uploadify - javascript

I've got two instances of uploadify in my form. You'll find the definitions below.
And two buttons that trigger the uploads. The image button is the only one relevant to the question:
$( "#btnimageupload" ).button().click(function()
{
$('#picbrowse').uploadifySettings( 'scriptData', ({ 'isSelected': $( '#selectImage' ).val() }));
$('#picbrowse').uploadifyUpload();
});
Now, here's the issue:
When I click btnimageupload button, the image doesn't upload. The progressbar goes to 100 and stops. No errors, javascript or otherwise.
But, when I disable the vdobrowse file input box, and its corresponding script, everything works fine. The images are uploaded and the data is transferring.
Here's the tricky part... if I don't pass the scriptData on the btnimageupload click handler, images will upload even with vdobrowse file input box on the page.
So it seems to me like scriptData is breaking uploadify when there's more than one instance of uploadify on the page.
Anyone know how I could solve this?
Uploadify definitions
$('#picbrowse').uploadify(
{
uploader : 'script/uplodify/uploadify.swf',
script : '../../dopost.php',
cancelImg : 'script/uplodify/cancel.png',
folder : '/images',
queueID : 'picqueue',
auto : false,
multi : true,
fileDesc : 'Image Files',
fileExt : '*.gif;*.jpg;',
queueSizeLimit: 5,
scriptData:
({
'action': 'upload_image',
}),
onComplete: function( event, queueID, fileObj, response, data )
{
console.log( reponse)
}
});
.
$('#vdobrowse').uploadify(
{
uploader : 'script/uplodify/uploadify.swf',
script : '../../dopost.php',
cancelImg : 'script/uplodify/cancel.png',
folder : '/video',
queueID : 'vdoqueue',
auto : false,
multi : true,
fileDesc : 'Video Files',
fileExt : '*.avi;*.mpg;*.mov;*.mp4;*.mpeg;*.flv;*.mkv;*.wmv',
queueSizeLimit: 5,
scriptData:
{
action: 'upload_video'
},
onComplete: function( event, queueID, fileObj, response, data )
{
console.log( response );
}
});

The plugin appears to be putting the
options into global space, which is
why when you are using two or more
uploadify's with scriptData it is
picking up the last stored value in
scriptData.
I see running two uploadify's on one
page a pointless exercise and as such
I never test the functionality with
multiple uploadify's.
uploadifySettings works perfectly with
one uploadify. Multiple uploadify's
are the demo page to demonstrate the
different setups possible.
That said, it is still obviously a
problem for users and we will need to
fix it for those that wish to use
multiple uploadify's on the same page.
Forum
I suggest to use swfUpload. I am use in at my project and tested with multiple instances and it's work perfect. So swfUpload easy to understand and api looks like as uploadify api.

Given that there seems to be a limitation with scriptData and multiple Uploadifys on a page, what you could do is skip the scriptData and folder attributes and parse out the file types inside dopost.php and take an action based on that.
For example:
$fileParts = pathinfo($_FILES['Filedata']['name']);
$extension = strtolower($fileParts['extension']);
switch($extension){
case "gif" | "jpg":
// Do Image Upload Action
break;
case "avi" | "mpg" | "mov" | "mp4" | "mpeg" | "flv" | "mkv" | "wmv":
// Do Video Upload Action
break;
}

I'm receiving the scripData just fine, I've made an example on my website
I've limited the upload size to 500KB for obvious reasons and corrected the code:
$('#picbrowse').uploadify(
{
uploader : 'uploadify.swf',
script : 'uploadify.php',
cancelImg : 'cancel.png',
folder : 'uploads/images',
queueID : 'picqueue',
auto : false,
multi : true,
removeCompleted : false,
fileDesc : 'Image Files',
fileExt : '*.gif;*.jpg',
sizeLimit : 512000,
queueSizeLimit: 5,
scriptData: {action: 'upload_image'},
onComplete: function( event, queueID, fileObj, response, data )
{
$ul.html('');
var json = jQuery.parseJSON(response);
$.each(json,function(k,v){
var li = "<li>"+k+": "+v+"</li>";
$ul.append(li);
});
},
onError: function (event,ID,fileObj,errorObj) {
console.log(errorObj.type + ' Error: ' + errorObj.info);
}
});
$('#vdobrowse').uploadify(
{
uploader : 'uploadify.swf',
script : 'uploadify.php',
cancelImg : 'cancel.png',
folder : 'uploads/video',
queueID : 'vdoqueue',
auto : false,
multi : true,
sizeLimit : 512000,
fileDesc : 'Video Files',
fileExt : '*.avi;*.mpg;*.mov;*.mp4;*.mpeg;*.flv;*.mkv;*.wmv',
queueSizeLimit: 5,
scriptData: {action: 'upload_video'},
onComplete: function( event, queueID, fileObj, response, data )
{
$ul.html('');
var json = jQuery.parseJSON(response);
$.each(json,function(k,v){
var li = "<li>"+k+": "+v+"</li>";
$ul.append(li);
});
}
});
And I'm using the standard uploadify.php and echoing the POST variable instead:
echo json_encode($_POST);

Related

Re-bind calendar to get new data

I am using the "events" elements of fullcalendar to get data dynamically. This works fine and I'm happy with it, however, I need to be able to pass a GET / POST parameter to the PHP page, and I'm unsure how to refresh the call to include the changed variable... My code is like this:
function redrawMe() {
var resource_array = get_resources();
$("#calendar").fullCalendar({
"cache" : true,
"editable" : true,
"events" : {
"url" : "/ajax/get_calendar_entries.php",
"data" : function() {
return { "resources" : resource_array }
}
}
});
}
function get_resources() {
let view_id = $("#view_id").val();
let promise = $.ajax({
"url" : "/ajax/get_resources.php",
"data" : { "view_id" : view_id },
"dataType" : "json"
});
promise.done(function(data) {
return data;
});
}
Tl;Dr:
I have a dropdown ("view_id") that just needs to fire redrawMe() and redraw the calendar dynamically.
Currently, I can see in the network tab of the developer tools, that the "events" url isn't being fired, and I think its probably because the #calendar div is "already" a calendar?
Make sense?
As recommended by #ADyson - I pass the view_id in the ajax call and use that, rather than multiple calls.
function redrawMe() {
$("#calendar").fullCalendar({
"cache" : true,
"editable" : true,
"eventClick" : function(calEvent, jsEvent, view) {
showJob(calEvent.job_id);
},
"data" : function() {
return {
"view_id" : $("#view_id").val(),
});
});
}
The above works fine
When I want to force a refresh I use this:
$("#calendar").fullCalendar("refetchEvents");

Using CodeMirror as elFinder editor

CodeMirror with elFinder! Wasn't able to find an example anywhere so had to figure it out. It turns out to be really simple in the end, but it took a bit to figure out so I'm posting this because someone out there is bound to need it eventually.
$().ready(function() {
var elf = $('#elfinder').elfinder({
url : 'elfinder-2.0-rc1/php/connector.php',
commandsOptions: {
edit : {
// list of allowed mimetypes to edit
// if empty - any text files can be edited
mimes : ['text/plain', 'text/html', 'text/javascript', 'text/css'],
// you can have a different editor for different mimes
editors : [{
mimes : ['text/plain', 'text/html', 'text/javascript', 'text/css'],
load : function(textarea) {
this.myCodeMirror = CodeMirror.fromTextArea(textarea, {
lineNumbers: true,
theme: "xq-dark"
})
},
close : function(textarea, instance) {
this.myCodeMirror = null;
},
save : function(textarea, editor) {
textarea.value = this.myCodeMirror.getValue();
this.myCodeMirror = null;
}
} ] //editors
} //edit
} //commandsoptions
}).elfinder('instance');
});
The answer is above!
I should really have asked this as a question and then answered it. Sorry.

issue with pagingtoolbar on a livesearchgridpanel

i'm trying to set a pagingtoolbar on my livesearchgridpanel.i'm getting the data over a Httpproxy ,so here is my store :
tempStore = new Ext.data.Store
({
groupField : default_groupby_s,
model : 'reportWorkspace',
allowFunctions : true,
autoSync : false,
pageSize : 20,
autoLoad : true,
remoteSort : false,
proxy : new Ext.data.HttpProxy
({
url : url_s,
actionMethods :
{
read : 'POST'
},
reader :
{
type : 'json',
root : 'workspace_report',
successProperty : 'success'
}
})
});
return tempStore ;
}
and here is my pagingtoolbar ,it will be included in my LivesearchgridPanel:
{
xtype: 'pagingtoolbar',
store: tempStore ,
dock: 'bottom',
pageSize:20,
displayInfo: true
}
the problem,it's that the pagingtoolbar is displaying pages correctly,but in the case of my grid,it displays ALL the data at the same time (in every page) . is it possible to do it without setting any starting point or limit in the autoload param ??
i just want to download all my data and then display it Correctly with pages
Any suggestion Please ?
I see several incosistencies:
LiveGrid was not built for paging at all but as an alternative to it.
ExtJS 4.1x no longer uses HTTP Proxy class but instead uses type: 'ajax' proxy config.
If you are going to page your data, you need to remote sort it, otherwise it won't make sense.
You have to make sure your grid panel and your pagingtoolbar refer to the same store instance. A common config for that in a grid panel is:
.
this.dockedItems = [
{
xtype:'pagingtoolbar',
store:this.store, // same store GridPanel is using
dock:'bottom',
displayInfo:true
}
];

Extjs 4 gridrow draws blank after model save

I have a couple of grids, divided in an accordion layout. They basicly show the same kind of data so an grouped grid should do the trick, however it looks really good this way and so far it works good too.
Left of the grids there is a form panel which is used to edit grid records, when I click on a record in the grid the appropriate data shows up in the form. I can edit the data, but when I click the save button, which triggers an 'model'.save() action, the related grid row draws blank and a dirty flag appears. I checked the model and the 'data' attribute doesn't contain any data but the id, the data is present in the 'modified' attribute.
I read that the red dirty flag means that the data isn't persisted in the back-end, but in this case it is. The request returns with a 200 status code and success : true.
The onSave method from the controller:
onSave : function() {
// Get reference to the form
var stepForm = this.getStepForm();
this.activeRecord.set( stepForm.getForm().getValues() );
this.activeRecord.save();
console.log( this.activeRecord );
}
The step store:
Ext.define( 'Bedrijfsplan.store.Steps', {
extend : 'Ext.data.Store',
require : 'Bedrijfsplan.model.Step',
model : 'Bedrijfsplan.model.Step',
autoSync : true,
proxy : {
type : 'rest',
url : 'steps',
reader : {
type : 'json',
root : 'steps'
},
writer : {
type : 'json',
writeAllFields : false,
root : 'steps'
}
}
} );
Step model:
Ext.define( 'Bedrijfsplan.model.Step', {
extend : 'Ext.data.Model',
fields : [ 'id', 'section_id', 'title', 'information', 'content', 'feedback' ],
proxy : {
type : 'rest',
url : 'steps',
successProperty : 'success'
}
} );
Step grid
Ext.define( 'Bedrijfsplan.view.step.Grid', {
extend : 'Ext.grid.Panel',
alias : 'widget.stepsgrid',
hideHeaders : true,
border : false,
columns : [ {
header : 'Titel',
dataIndex : 'title',
flex : 1
} ]
} );
I spend a couple of hours searching and trying, but I still haven't found the solution. Some help on this matter would be appreciated :)
Your model updating code:
this.activeRecord.set( stepForm.getForm().getValues() );
Should work, but I might try splitting it into two lines and setting a breakpoint to verify that getValues() is returning what you're expecting.
Also ensure that you have the name attribute set for each field in your form and that it matches exactly to the names of fields in your model.
Finally, it's better to call .sync() on the store rather than .save() on the model when you're working with a model that belongs to a store. They option autoSync: true on the store will make this happen automatically each time you make a valid update to one of its models.
The BasicForm.loadRecord and BasicForm.updateRecord methods provide a nice wrapper around the functionality you're seeking that may work better:
onRowSelected: function(activeRecord) {
stepForm.getForm().loadRecord(activeRecord);
}
onSaveClick: function() {
var activeRecord = stepForm.getForm().getRecord();
stepForm.getForm().updateRecord(activeRecord);
activeRecord.store.sync();
}
The only oddity I see is with your: this.activeRecord.set( stepForm.getForm().getValues() );
I've always used .set() on the store never on the record. e.g.:
myDataStore.set( stepForm.getForm().getValues() );

ExtJS 4 - How to download a file using Ajax?

I have a form with various textfields and two buttons - Export to Excel and Export to CSV.
The user can provide the values to different fields in the form and click one of the buttons.
Expected behaviour is that an Ajax request should be fired carrying the values of fields as parameters and the chosen file (Excel/CSV as per the button click) should get downloaded (I am not submitting the form as there needs to be done some processing at the values before submit).
I have been using the following code in success function of Ajax request for the download:
result = Ext.decode(response.responseText);
try {
Ext.destroy(Ext.get('testIframe'));
}
catch(e) {}
Ext.core.DomHelper.append(document.body, {
tag: 'iframe',
id:'testIframe',
css: 'display:none;visibility:hidden;height:0px;',
src: result.filename,
frameBorder: 0,
width: 0,
height: 0
});
The above code has been working fine in the case when the file is created physically at the server. But in my current project, the file is not created at the server, rather the contents are just streamed to the browser with proper headers.
Thus, is there a way to download a file using Ajax when the file is not present at the server physically? Just to add that I have a long list of parameters which I need to send to the server and hence can not add them all to the src of iframe.
Could anyone guide at this?
Thanks for any help in advance.
You may use component like this:
Ext.define('CMS.view.FileDownload', {
extend: 'Ext.Component',
alias: 'widget.FileDownloader',
autoEl: {
tag: 'iframe',
cls: 'x-hidden',
src: Ext.SSL_SECURE_URL
},
stateful: false,
load: function(config){
var e = this.getEl();
e.dom.src = config.url +
(config.params ? '?' + Ext.urlEncode(config.params) : '');
e.dom.onload = function() {
if(e.dom.contentDocument.body.childNodes[0].wholeText == '404') {
Ext.Msg.show({
title: 'Attachment missing',
msg: 'The document you are after can not be found on the server.',
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
})
}
}
}
});
Put it somewhere in viewport, for example:
{
region: 'south',
html: 'South',
items: [
{
xtype: 'FileDownloader',
id: 'FileDownloader'
}
]
}
Do not forget to require it in your viewport class:
requires: [
'CMS.view.FileDownload'
]
Action handler may look like this:
var downloader = Ext.getCmp('FileDownloader')
downloader.load({
url: '/attachments/' + record.get('id') + '/' + record.get('file')
});
It's very important to have Content-Disposition header in response, otherwise nothing is downloaded.
Regards go to http://www.quispiam.com/blog/post.php?s=2011-06-09-download-a-file-via-an-event-for-extjs4
This thing works for me.

Categories

Resources