I am using Ext JS 3.4 and having an issue getting files to upload from a form
The PHP script is failing to receive the file data (even trying just with a print_r($_FILES) which should show any file or error received).
this is my code
var editOrganisationForm = new Ext.FormPanel({
url: 'appsrv/users_json.php',
labelWidth: 75,
border:false,
width: 350,
items: {
xtype:'tabpanel',
layoutOnTabChange: true,
deferredRender:true,
border: false,
activeTab: 0,
defaults: {autoHeight:true, bodyStyle:'padding:10px; border: 0', bodyBorder: false},
items:[{
title:'Organisation Info',
layout: 'form',
fileUpload: true,
defaults: {width: 230},
defaultType: 'textfield',
items: [
{xtype: 'hidden', name: 'id'},
{fieldLabel: 'Organisation', name: 'organisation', allowBlank:false},
{
fieldLabel: 'Logo',
name: 'org_logo',
id: 'org_logo',
inputType: 'file',
allowBlank:true
},
{
fieldLabel: 'Theme',
name: 'org_theme',
id: 'org_theme',
store: [['val1', 'First Value'], ['val2', 'Second Value']],
xtype: 'combo',
allowBlank: false,
forceSelection: true,
valueField:'id',
displayField:'name'
}
]
}]
}
});
and
var winOrg = new Ext.Window({
title: 'Edit Organisation',
layout:'fit',
width:400,
height:215,
closeAction: 'hide',
plain: false,
modal: true,
shadow: true,
items: [editOrganisationForm],
buttons: [{
text:'Save',
handler: function() {
editOrganisationForm.getForm().submit({
method: 'POST',
waitTitle: 'Please Wait...',
waitMsg: 'Saving Changes',
url: 'appsrv/users_json.php',
params: {cmd: "addOrg"},
success: function() {
Ext.Msg.alert('Complete','Your changes have been saved');
tree.root.reload();
winOrg.hide();
},
failure: function(form, action) {
if (action.failureType == 'server') {
obj = Ext.util.JSON.decode(action.response.responseText);
Ext.Msg.alert('Oops!', obj.errors.reason);
} else if (action.failureType == 'client') {
Ext.Msg.alert('Sorry', 'Please ensure all required fields have been completed');
} else {
Ext.Msg.alert('Sorry','An error occurred');
}
}
});
},
disabled: false
}]
});
That's me solved it
fileUpload: true was correct but I had it in the wrong object, it should have been in the form config object and not in the form>panel>items object
include isUpload: true in the form config object
Related
I'm trying to put a GridPanel powered by an ArrayStore in a Window, but no matter what I do, it just looks like this with no data rows inside:
Here's my code:
var ticketsStore = new Ext.data.ArrayStore
(
{
autoDestroy: false,
remoteSort: false,
data: result,
fields:
[
{ name: 'articleId', type: 'int' },
{ name: 'heatTicketRef', type: 'string' },
{ name: 'username', type: 'string' },
{ name: 'dateLinked', type: 'date' }
]
}
);
var ticketsGrid = new Ext.grid.GridPanel({
store: ticketsStore,
id: this.id + 'ticketsGrid',
viewConfig: {
emptyText: 'No data'
},
autoShow: true,
idProperty: 'heatTicketRef',
columns: [
{ id: 'heatTicketRef', header:"Ticket ID", width: 100, dataIndex: 'heatTicketRef', sortable: false },
{ header: "User", width: 100, dataIndex: 'username', sortable: false },
{ header: "Date Linked", width: 100, dataIndex: 'dateLinked', xtype: 'datecolumn', format: 'j M Y h:ia', sortable: false }
]
});
var window = new Ext.Window
(
{
renderTo: Ext.getBody(),
id: this.id + 'linkedHeatTickets',
closable: true,
modal: true,
autoHeight: true,
width: 500,
title:'Linked Heat Tickets',
resizable: false,
listeners:
{
close: function () { // do something }
},
items:
{
style: 'padding:5px;',
items: ticketsGrid
},
buttons:
{
text: 'Close',
handler: function () {
window.close();
}
}
}
);
window.show();
When I debug, I can see that my "result" object is healthy and the ArrayStore is of the right length:
But the GridPanel doesn't like the data because it's not in its items (although it's in the store) array:
What little thing have I done wrong?
Thanks!
Because I'm an idiot... I used an ArrayStore instead of a JsonStore!
I am creating the form below, but for some reason the select button handler doesn't
get executed. Everything else is working properly (loading data into the grid).
Is there something I'm missing?
Ext.Loader.setConfig({enabled:true});
Ext.define('Project', {
extend: 'Ext.data.Model',
fields: ['PID', 'ProjectName']
});
var projectsStore = Ext.create('Ext.data.Store',
{
model: 'Project',
autoLoad: true,
proxy:{
type: 'ajax',
url : 'projects.php?action=read',
reader:{ type:'json', root:'projects', successProperty:'success' } }
});
Ext.onReady(
function()
{
var simple = Ext.create('Ext.form.Panel', {
url:'projects.php?action=select',
frame:true,
title: 'Projects',
bodyStyle:'padding:5px 5px 0',
width: 350,
fieldDefaults: {
msgTarget: 'side',
labelWidth: 75
},
defaultType: 'textfield',
defaults: {
anchor: '100%'
},
items: [{
columnWidth: 0.60,
xtype: 'gridpanel',
store: projectsStore,
height: 400,
title:'General',
columns: [
{header: 'Id', dataIndex: 'PID', flex: 1},
{header: 'Project Name', dataIndex: 'ProjectName', flex: 1},
]
}],
buttons: [{
text: 'Select',
handler: function() {
Ext.Msg.alert('Selecting', action.result.msg);
}
}]
});
simple.render('proj-form');
projectsStore.load();
}
);
Your code is crashing when it's running the handler because action.result.msg doesn't exist.
You can look in Firebug/Chrome Dev Tools and it would have shown you the problem.
I'm beginning going crazy with extjs4 and form loading.
In my struts application, I have a simple form and i want to load JSON data.
The problem is that the data are correctly loaded from the server but never displayed.
Here is the code :
Ext.onReady(function(){
var formPanel = Ext.create('Ext.form.Panel', {
renderTo: Ext.get('categoryForm'),
width: 340,
bodyPadding: 5,
waitMsgTarget: true,
url: '<s:url value="json/save" />',
method: 'POST',
loader: {
type: 'json',
root: 'category',
successProperty: 'success'
},
fieldDefaults: {
labelAlign: 'right',
labelWidth: 85,
msgTarget: 'side'
},
defaultType: 'textfield',
items: [{
name: 'category.id',
hidden: true
}, {
fieldLabel: "<s:text name="category.label"/>",
name: 'label',
allowBlank: false,
maxLength: 35
}, {
fieldLabel: "<s:text name="category.description"/>",
name: 'description',
xtype: 'textarea',
maxLength: 250
}, {
fieldLabel: '<s:text name="category.creationDate"/>',
name: 'creationDate',
xtype: 'datefield',
readOnly: true
}],
buttons: [{
text: "<s:text name="action.modify"/>",
handler: function() {
formPanel.getForm().submit();
}
}, {
text: "<s:text name="action.cancel"/>",
handler: function() {
formPanel.getForm().reset();
}
}]
});
formPanel.show();
formPanel.load({
url: '<s:url action="json/load"/>',
params: {
categoryId: <s:property value="categoryId"/>
}
});
});
The JSON data (intented) response :
{
"category":
{
"creationDate": "2012-04-14T22:29:52",
"description":"description",
"id":1,
"label":"Toto"
},
"errorMessage":null,
"success":true
}
Finally I found where was the problem.
The JSON response must contains the 'data' property instead of 'category'.
Replacing the property fill the form.
I have an Editor Grid and a store with a custom type in it.
store :
var sourceStore = new Ext.data.JsonStore({
url: hp,
storeId: 'labels-data-store',
idProperty: 'ID',
root: 'results',
fields: [{
name: 'ID',
type: 'int'
}, {
name: 'LanguageID',
type: 'int'
}, {
name: 'KeyID',
type: 'int'
}, {
name: 'Value',
type: 'string'
}, {
name: 'ToolTip',
type: 'string'
}, {
name: 'LanguageName',
type: 'string'
}, {
name: 'KeyInfo',
type: 'LanguageKeyInfo'
},
CUSTOM TYPE HERE !! !{
name: 'ServerComments',
type: 'string'
}]
});
Editor Grid :
var sourceGrid = new Ext.grid.EditorGridPanel({
id: 'source-grid',
region: 'center',
title: localize.sourceView,
iconCls: 'source-view-title',
store: sourceStore,
trackMouseOver: true,
disableSelection: false,
loadMask: true,
split: true,
stripeRows: true,
border: true,
autoExpandColumn: 'label',
cm: sourceColModel,
// customize view config
viewConfig: {
forceFit: true,
enableRowBody: true,
showPreview: false,
emptyText: localize.noRecordsFound
},
sm: new Ext.grid.RowSelectionModel({
singleSelect: false,
moveEditorOnEnter: true
})
});
Custome Type implementation:
LanguageKeyInfo = function () {
this.ID = arguments[0];
this.Value = arguments[1];
this.Description = arguments[2];
}
Ext.data.Types.LANGUAGEKEYINFO = {
convert: function (v, data) {
if (!data) {
return null;
}
if (!data.KeyInfo) {
return null;
}
return new LanguageKeyInfo(
data.KeyInfo.ID,
data.KeyInfo.Value,
data.KeyInfo.Description);
},
sortType: function (key) {
return key.ID;
},
type: 'LanguageKeyInfo'
}
Source Column Model:
var sourceColModel = new Ext.grid.ColumnModel({
columns: [{
header: 'ID',
dataIndex: 'ID',
width: 50,
hidden: true,
sortable: true
}, {
header: 'Language ID',
dataIndex: 'LanguageID',
width: 50,
hidden: true,
sortable: true
}, {
header: 'Language',
dataIndex: 'LanguageName',
width: 20,
hidden: true,
sortable: true
}, {
header: 'Key ID',
dataIndex: 'KeyID',
width: 30,
hidden: true,
sortable: true
}, {
header: 'Key',
dataIndex: 'KeyValue',
width: 40,
sortable: true,
editor: new Ext.form.TextField({
allowBlank: false,
maxLength: 200
})
}, {
header: 'Label',
dataIndex: 'Value',
sortable: true,
editor: new Ext.form.TextField({
allowBlank: false,
maxLength: 500
}),
renderer: function (sc) {
var lanID = getSelectedLanguageID() ? getSelectedLanguageID() : 1;
switch (parseInt(lanID)) {
case 2:
return '<div class="rtl">' + sc + '</div>';
default:
return sc;
}
}
}, {
header: 'Description',
dataIndex: 'KeyDescription',
width: 30,
editor: new Ext.form.TextField({
allowBlank: true,
vtype: 'englishOnly',
maxLength: 100
})
}, {
header: 'Tool Tip',
dataIndex: 'ToolTip',
width: 80,
sortable: true,
editor: new Ext.form.TextField({
allowBlank: true,
maxLength: 200
})
}]
});
When I start editing the first column row the text field value is [object,object] which mean the grid is passing the KeyInfo object to the textbox value.
How can I send one of KeyInfo properties to the textbox and have it mapped to the store record ??
For starters your dataIndex does not reference a valid record mapping:
dataIndex: 'KeyValue', should probably be dataIndex: 'KeyInfo',
Secondly I don't think there is any support for custom types on grid editors. I might be wrong of course.
I'd be grateful for any help please. I've just started to build my first ever sencha app and am pleased with the results so far, but am now stuck on one thing. I've built a search form and want to be able to display the results on the same page, but this is where I'm stuck. The form works and sends the results using GET, but it doesn't send it to the correct place. I want to show it on the same page (I've built a php file called search.php to handle the results), but it reloads the whole app with the variables in the url.
I've tested all of the code away from the app and it works perfectly so I know the problem isn't with the code, but more with my lack of understanding of Sencha so would be extremely grateful for any help.
Code:
searchForms = new Ext.TabPanel({
fullscreen: true,
title: 'Search',
displayField: 'text',
store: searchForm,
iconCls: 'search',
items: [{
id: 'searchSubmit',
xtype: 'form',
standardSubmit : true,
scroll: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Keywords',
defaults: {
// labelAlign: 'right'
labelWidth: '35%'
},
items: [{
xtype: 'textfield',
name: 'keywords',
id: 'keywords',
placeHolder: 'EG: Music, TV',
autoCapitalize : true,
required: true,
useClearIcon: true
}]
}, {
xtype: 'fieldset',
title: 'Advanced Search',
items: [{
xtype: 'selectfield',
name: 'genre',
id: 'genre',
label: 'Genre',
options: [{
text: 'All',
value: ' '
text: 'Country',
value: '1'
text: 'Sci-Fi',
value: '2'
text: 'Western',
value: '3'
}]
}, {
xtype: 'selectfield',
name: 'media',
id: 'media',
label: 'Media',
options: [{
text: 'All',
value: ' '
text: 'Music',
value: '1'
text: 'TV',
value: '2'
text: 'Movie',
value: '3'
}]
}]
}, {
layout: 'vbox',
defaults: {xtype: 'button', flex: 1, style: 'margin: .5em;'},
items: [{
text: 'Search',
ui: 'confirm',
scope: this,
hasDisabled: false,
handler: function(){
searchForms.submit({
url: 'search.php'
});
}
}, {
text: 'Reset',
ui: 'decline',
handler: function(){
searchForms.reset();
}
}]
}]
}]
});
I've then tried to use this to display the results on the same page, but as I say this just doesn't work. It doesn't call the search.php page at all.
I've made sure all of the files (except the index.js file which is in a js folder) are in the same directory as the index.html file.
I've also tried to load the file in the app seperately by using:
Ext.regModel('mobile', {
fields: [
{name: 'text', type: 'string'}
]
});
var searchForm = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'search.php?keywords=test',
reader: {
type: 'tree',
root: 'items'
}
}
});
and that works perfectly so I know that all of the php stuff is working and does work with Sencha Touch, but I'm just not sure how to get it to only work when somebody clicks 'search'
I'd be grateful for any help with this as I've spent days searching the web to get this fix, but nothing seems to be working :(
I don't know if this is of help, but the main javascript file is:
var tabPanel;
var homePanel = new Ext.Panel({
title: 'Home',
iconCls: 'home',
fullscreen: true,
scroll:{direction:'vertical',threshold:7},
items: [{
html: '<center><p>Home</p></center>'
}]
});
var servicePanel = new Ext.Panel({
title: 'Services',
iconCls: 'team',
fullscreen: true,
items: [{
html: '<center>Please choose a service</center>'
}]
});
var searchPanel = new Ext.Panel({
title: 'Search',
iconCls: 'search',
fullscreen: true,
items: [{
html: '<center>Search</center>'
}]
});
var feedtabpanel = new Ext.Carousel({
title: 'More',
iconCls: 'more',
fullscreen: true,
sortable : true,
xtype:'panel',
scroll:{direction:'vertical',threshold:7},
items: [
{
title: 'Contact',
html : '<center><h1>Contact Us</h1></center>',
},
{
title: 'Feedback',
html : '<center><h1>Let us know what you think<h1></center>',
},
{
title: 'Tell a friend',
html : '<center><h1>Tell your friends how much you love this app</h1></center>',
}
]
});
searchForms = new Ext.TabPanel({
fullscreen: true,
title: 'Search',
displayField: 'text',
store: searchForm,
iconCls: 'search',
items: [{
id: 'searchSubmit',
xtype: 'form',
standardSubmit : true,
scroll: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Keywords',
defaults: {
// labelAlign: 'right'
labelWidth: '35%'
},
items: [{
xtype: 'textfield',
name: 'keywords',
id: 'keywords',
placeHolder: 'EG: Music, TV',
autoCapitalize : true,
required: true,
useClearIcon: true
}]
}, {
xtype: 'fieldset',
title: 'Advanced Search',
items: [{
xtype: 'selectfield',
name: 'genre',
id: 'genre',
label: 'Genre',
options: [{
text: 'All',
value: ' '
text: 'Country',
value: '1'
text: 'Sci-Fi',
value: '2'
text: 'Western',
value: '3'
}]
}, {
xtype: 'selectfield',
name: 'media',
id: 'media',
label: 'Media',
options: [{
text: 'All',
value: ' '
text: 'Music',
value: '1'
text: 'TV',
value: '2'
text: 'Movie',
value: '3'
}]
}]
}, {
layout: 'vbox',
defaults: {xtype: 'button', flex: 1, style: 'margin: .5em;'},
items: [{
text: 'Search',
ui: 'confirm',
scope: this,
hasDisabled: false,
handler: function(){
searchForms.submit({
url: 'search.php'
});
}
}, {
text: 'Reset',
ui: 'decline',
handler: function(){
searchForms.reset();
}
}]
}]
}]
});
Ext.regModel('mobile', {
fields: [
{name: 'text', type: 'string'}
]
});
var searchForm = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'search.php',
reader: {
type: 'tree',
root: 'items'
}
}
});
var store = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'areas.php',
reader: {
type: 'tree',
root: 'items'
}
}
});
var nestedList = new Ext.NestedList({
fullscreen: true,
title: 'Location',
displayField: 'text',
store: store,
iconCls: 'locate',
});
nestedList.on('leafitemtap', function(subList, subIdx, el, e) {
var store = subList.getStore(),
record = store.getAt(subIdx),
recordNode = record.node,
title = nestedList.renderTitleText(recordNode),
card, preventHide, anim;
if (record) {
card = record.get('card');
anim = record.get('animation');
preventHide = record.get('preventHide');
}
if (card) {
tabPanel.setCard(card, anim || 'slide');
tabPanel.currentCard = card;
}
});
var services = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'subcats.php',
reader: {
type: 'tree',
root: 'items'
}
}
});
var servicesList = new Ext.NestedList({
fullscreen: true,
title: 'Services',
displayField: 'text',
store: services,
iconCls: 'team',
});
servicesList.on('leafitemtap', function(subList, subIdx, el, e) {
var store = subList.getStore(),
record = store.getAt(subIdx),
recordNode = record.node,
title = servicesList.renderTitleText(recordNode),
card, preventHide, anim;
if (record) {
card = record.get('card');
anim = record.get('animation');
preventHide = record.get('preventHide');
}
if (card) {
tabPanel.setCard(card, anim || 'slide');
tabPanel.currentCard = card;
}
});
Ext.setup({
icon: 'icon.png',
glossOnIcon: false,
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
onReady: function() {
tabPanel = new Ext.TabPanel({
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
fullscreen: true,
ui: 'dark',
animation: {
type: 'cardslide',
cover: true
},
items: [
homePanel,
nestedList,
servicesList,
searchForms,
feedtabpanel
]
});
}
})
Just update your store with the filter() function. First you have to add the correct filterParam to your store configuration. After this, you can call the filter() function in your search button handler. E.g.
searchForm.filter('keywordParam', searchfield.getValue());
After this, your store will get updated without the page refreshing. You could then use a DataView to show your search results.