PDA

View Full Version : Using forms for file uploads



Ex_Soft
18 Jun 2010, 12:31 AM
I test this (http://www.javabeat.net/articles/163-ext-js-30-cookbook-7.html) example (from Ext JS 3.0 Cookbook):


Ext.BLANK_IMAGE_URL = "../images/s.gif";

Ext.onReady(function() {
Ext.QuickTips.init();

var
picBox = {
columnWidth: "100 px",
bodyStyle: "padding: 10px",
items: [{
xtype: "box",
autoEl: {
tag: "div",
html: '<img id="pic" src="' + Ext.BLANK_IMAGE_URL + '" class="img-contact" />'
}
}]
},
picFiles = {
columnWidth: .65,
layout: "form",
labelAlign: "top",
items: [{
xtype: "textfield",
fieldLabel: "Current",
labelSeparator: "",
name: "currPic",
id: "currPic",
readOnly: true,
disabled: true,
anchor: "100%"
}, {
xtype: "textfield",
fieldLabel: "New (JPG or PNG only)",
labelSeparator: "",
name: "newPic",
id: "newPic",
style: "width: 300px",
inputType: "file",
allowBlank: false
}]
},
pictUploadForm = new Ext.FormPanel({
frame: true,
title: "Change Picture",
bodyStyle: "padding: 5px",
width: 420,
layout: "column",
url: "contact-picture.aspx",
method: "POST",
fileUpload: true,
items: [picBox, picFiles],
buttons: [{
text: "Upload Picture",
handler: function() {
var
theForm = pictUploadForm.getForm();

if (!theForm.isValid())
{
Ext.MessageBox.alert("Change Picture", "Please select a picture");
return;
}

if (!validateFileExtension(Ext.getDom("newPic").value))
{
Ext.MessageBox.alert("Change Picture", "Only JPG or PNG, please.");
return;
}

theForm.submit({
params: { act: "setPicture", id: "contact1" },
waitMsg: "Uploading picture"
})
}
}, {
text: "Cancel"
}]
});

pictUploadForm.on({
actioncomplete: function(form, action) {
if (action.type == "load")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
}

if (action.type == "submit")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
Ext.getDom("newPic").value = "";
}
}
});

pictUploadForm.render(document.body);
pictUploadForm.getForm().load({ params: { act: "getPicture", id: "contact1" }, waitMsg: "Loading" });
});

function validateFileExtension(fileName)
{
var
exp = /^.*\.(jpg|JPG|png|PNG)$/;

return exp.test(fileName);
}
1. In IE7 error is occured "Invalid argument" at ext-all-debug.js


setWidth : function(width, animate){
var me = this;
width = me.adjustWidth(width);
==> !animate || !me.anim ?
==> me.dom.style.width = me.addUnits(width) :
==> me.anim({width : {to : width}}, me.preanim(arguments, 1));
return me;
}
2. In IE7 only buttons "Upload picture" && "Cancel" are visible.
3. Load. Server send


{"success":"true","data ":{"contactId":"contact id","file":"./img/27265.gif"}}
but


actioncomplete: function(form, action) {
if (action.type == "load")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
}
isn't occured and pic.src isn't changed.
4. Upload. Server send


{"success":"true","data ":{"contactId":"contact id","file":"./download/user.png"}}
but
4.1. Browser (FF 3.6.3) offer me to save contact-picture.aspx
4.2.

actioncomplete: function(form, action) {
if (action.type == "submit")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
Ext.getDom("newPic").value = "";
}
isn't occured and pic.src isn't changed.
Is this example incorrect?

P.S. ExtJS ver.3.2.1

Condor
18 Jun 2010, 12:55 AM
1. columnWidth:"100 px" is invalid. You want width:100
2. picBox is overnested. Why put a BoxComponent inside a Panel when all you need is a BoxComponent?
3. For a file upload the response needs to have Content-type:text/html and should either be HTML encoded JSON or plain JSON in a textarea tag, e.g.

<html><body><textarea>{"success":"true","data ":{"contactId":"contact id","file":"./download/user.png"}}</textarea></body></html>
4. Due to security reasons Firefox doesn't include the path in the filename, so setting the image src won't work.

Ex_Soft
18 Jun 2010, 1:23 AM
1. columnWidth:"100 px" is invalid. You want width:100
+1 THNX


2. picBox is overnested. Why put a BoxComponent inside a Panel when all you need is a BoxComponent?

This isn't my code.

I test this (http://www.javabeat.net/articles/163-ext-js-30-cookbook-7.html) example (from Ext JS 3.0 Cookbook)


3. For a file upload the response needs to have Content-type:text/html and should either be HTML encoded JSON or plain JSON in a textarea tag, e.g.

<html><body><textarea>{"success":"true","data ":{"contactId":"contact id","file":"./download/user.png"}}</textarea></body></html>


Notice that after a successful upload, the JSON-encoded response will have the following structure: (http://www.javabeat.net/articles/163-ext-js-30-cookbook-7.html)


"{success:true,data:{contactId:'contact id',file:'[picture path]'}}



4. Due to security reasons Firefox doesn't include the path in the filename, so setting the image src won't work.
Hm...


<html>
<head>
<title>&laquo;Test &lt;img&gt; src&raquo;</title>
</head>
<body onload="document.getElementById('ImgVictim').src='./pix/SmthPix.gif'">
<img id="ImgVictim" />
</body>
</html>
works fine. (FF 3.6.3)
and

actioncomplete isn't occured

Ex_Soft
18 Jun 2010, 1:49 AM
3. For a file upload the response needs to have Content-type:text/html and should either be HTML encoded JSON or plain JSON in a textarea tag, e.g.

<html><body><textarea>{"success":"true","data ":{"contactId":"contact id","file":"./download/user.png"}}</textarea></body></html>
+1 THNX


actioncomplete: function(form, action) {
if (action.type == "submit")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
Ext.getDom("newPic").value = "";
}works fine in FF && Chrome. In IE7


Ext.getDom("newPic").value = "";
doesn't work.
When I send this for load:


8272 doDecode = function(json){
8273 return eval("(" + json + ')');
}

error in ext-all-debug.js is occured. So, for load response should be JSON?

Condor
18 Jun 2010, 2:38 AM
1. I said that the response could also be HTML encoded JSON. Since the JSON doesn't contain <, > or & it is already HTML encoded.

Example: If you wanted to return the following JSON:

{success: true, message: '<span class="info">AT&T</span>'}
then for a fileUpload:true you would need to return:

{success: true, message: '&lt;span class="info"&gt;AT&amp;T&lt;/span&gt;'}

2. If you want to change the value of a field then you should not modify the element, but the component.

Ext.getCmp('newPic').setValue('');

3. Does the following line really work in Firefox (if you select an image from a different directoy)?

Ext.getDom("pic").src = pic.file;

Ex_Soft
18 Jun 2010, 5:55 AM
1. I said that the response could also be HTML encoded JSON. Since the JSON doesn't contain <, > or & it is already HTML encoded.

Example: If you wanted to return the following JSON:

{success: true, message: '<span class="info">AT&T</span>'}then for a fileUpload:true you would need to return:

{success: true, message: '&lt;span class="info"&gt;AT&amp;T&lt;/span&gt;'}
You don't understand me. (BTW, I'm so sorry for my English) After upload file all works fine.


actioncomplete: function(form, action) {
if (action.type == "load")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
}
doesn't work.


2. If you want to change the value of a field then you should not modify the element, but the component.

Ext.getCmp('newPic').setValue('');
In IE7 error:

Microsoft JScript runtime error: Object doesn't suppurt this property or methodIn FF


Error: Ext.getDom("newPic").setValue is not a function


3. Does the following line really work in Firefox (if you select an image from a different directoy)?

Ext.getDom("pic").src = pic.file;
Yes. After upload


if (action.type == "submit")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
Ext.getDom("newPic").value="";
}
set img.src.

Condor
18 Jun 2010, 6:40 AM
1. I said:

Ext.getCmp('newPic').setValue('');

2. OK, so you are showing a server image after upload. Yes that works.

Ex_Soft
18 Jun 2010, 6:56 AM
Ext.getCmp('newPic').setValue('');
I'm confused... However even
Ext.getCmp('newPic').setValue(''); doesn't work in IE7.


2. OK, so you are showing a server image after upload. Yes that works.
But img.src wasn't set after first page load.

Condor
18 Jun 2010, 7:05 AM
Please be clearer. What exactly doesn't work?

Ex_Soft
18 Jun 2010, 7:15 AM
Please be clearer. What exactly doesn't work?
1. After


Ext.onReady(function() {
...
==> pictUploadForm.getForm().load({ params: { act: "getPicture", id: "contact1" }, waitMsg: "Loading" });
});
Server send

{"success":"true","data ":{"contactId":"contact id","file":"./img/27265.gif"}}but actioncomplete isn't occured and


pictUploadForm.on({
==> actioncomplete: function(form, action) {
==> if (action.type == "load")
==> {
==> var
==> pic = action.result.data;
==>
==> Ext.getDom("pic").src = pic.file;
==> Ext.getCmp("currPic").setValue(pic.file);
==> }
doesn't work.

2. After upload file actioncomplete is occured, but


pictUploadForm.on({
actioncomplete: function(form, action) {
if (action.type == "submit")
{
var
pic = action.result.data;

Ext.getDom("pic").src = pic.file;
Ext.getCmp("currPic").setValue(pic.file);
==> //Ext.getDom("newPic").value = "";
==> Ext.getCmp("newPic").setValue("");
}
doesn't clear newPic.value in IE7.

Condor
18 Jun 2010, 7:26 AM
1. Is actionfailed executed instead of actioncomplete (for load)?
2. newPic is an type="file", so you can only clear it with:

pictUploadForm.getForm().getEl().dom.reset();
(but that clears the entire form!)

Ex_Soft
18 Jun 2010, 7:43 AM
1. Is actionfailed executed instead of actioncomplete (for load)?
+1 Yes!!! So, why is it occured?


2. newPic is an type="file", so you can only clear it with:

pictUploadForm.getForm().getEl().dom.reset();
Hm... Ext.getDom("newPic").value = "" works fine in FF && Chrome...

Condor
18 Jun 2010, 7:46 AM
1. What is action.failureType in the actionfailed handler?
2. IE simply doesn't support changing an <input type="file"> field. The only way to work around this is to reset the form (as described) or by recreating the field.

Ex_Soft
18 Jun 2010, 7:56 AM
1. What is action.failureType in the actionfailed handler?
action.failureType="load"


2. IE simply doesn't support changing an <input type="file"> field. The only way to work around this is to reset the form (as described) or by recreating the field.
OK

Condor
19 Jun 2010, 5:16 AM
action.failureType="load" means that:
1. There is no data returned by the server
or
2. The returned JSON doesn't contain 'success':true.
or
3. The returned JSON doesn't contain a 'data' object with field names/values.

Animal
19 Jun 2010, 5:47 AM
4. The returned Content-Type is not text/html as described in the documentation.