extjs store.load after form.submit - extjs

I'm trying to reload an Extjs-store, after user has download a PDF.
The process is the following:
User double clicks a cell in GridPanel
Form is created, submitted, and a procedure in the backend creates an PDF and makes some changes on data of GridPanel store
PDF will be downloaded by user
But how to reload the store with the new data in it?
There is no afterRender on form-submit.
I think this should be an easy problem, but I do not have any ideas how to solve it.

This is a snipped I found in my code base (inside a controller):
var form = button.up().up().down('form').getForm();
form.submit({ success : this.onFileUpload, failure: this.onFileUpload, scope: this});
...
onFileUpload: function (form, action){
var data = action.result.data;
...
if (action.result.success){
...
//**your store reload could be here!**
...
} else {
...
}
}
My form response is not responding with a file (just some standard html return), but I guess it should work.

here is a bit of my code:
function makeprintForm(array, setStatusX, grid) {
var filename = 'asd.pdf';
var url_pdf = 'someURL?FileName=' + filename;
var printForm = Ext.create('Ext.form.Panel', ({
url: currentContextPath + encodeURIComponent('http://' + host + ':' + port + url_pdf),
hidden: true,
id: 'printForm',
name: 'printForm',
method: 'post',
standardSubmit: true,
target: '_blank',
items: [{
xtype: 'textfield',
fieldLabel: 'print_id',
name: 'print_id',
value: array
},
{
xtype: 'textfield',
fieldLabel: 'username',
name: 'username',
value: username
},
{
xtype: 'textfield',
fieldLabel: 'language_field',
name: 'language',
value: language
}
]
}));
Ext.getCmp('printForm').getForm().submit({ success : this.reload_grid_after_submit(), scope: document.getElementById(nameSpace + 'formIS')});
}
function reload_grid_after_submit(){
console.log('reload_grid_after_submit');
Ext.getCmp('grid').getStore().proxy.setExtraParam('status', 'NEW');
Ext.getCmp('grid').getStore().load();
}

You can use a form in an alert box. I used a window here. Then onsubmit of the form you can use findRecord to find a record from the store and edit it. For better explanation please find the fiddle here. P.S sorry for the delay I was on a vacation. Please mark it as an answer if it's correct so it helps other people in the future. Or please comment if there is something which needs to be changed. Thanks
Ext.getCmp('myGrid').addListener('rowdblclick', function (a, b, c, d) {
win = new Ext.Window({
width: 300,
height: 150,
draggable: false,
border: false,
modal: true,
resizable: false,
items: [{
xtype: 'textfield',
fieldLabel: 'What is your new name',
id: 'newNameField'
}, {
xtype: 'button',
name: 'sampleButton',
text: 'Change My Name!',
style: 'margin:15px',
width: 150,
handler: function () {
name = Ext.getCmp('myGrid').getStore().getAt(d).data['name'];
console.log(name);
var newName = Ext.getCmp("newNameField").value;
console.log("replacing " + name + " with " + newName + " in the store");
var entry = userStore.findRecord('name', name);
entry.set('name', newName);
win.hide();
}
}]
})
win.show();
})

Related

ExtJS 6 - How to upload a file without using form?

Ext JS provides fileuploadfield which is bundled with a button to browse local files. I just need to upload a file using as soon as it is selected from local instead of using a submit button in order to trigger the post process. Could not find an event which is fired after the file is selected.
p.s. Actually, the version I use is Ext JS 6 but I think the solutions based on previous versions do the work as well.
Form is not required. You can use AJAX and FormData.
var file = s.fileInputEl.dom.files[0],
data = new FormData();
data.append('file', file);
Ext.Ajax.request({
url: '/upload/files',
rawData: data,
headers: {'Content-Type':null}, //to use content type of FormData
success: function(response){ }
});
Online demo here
You will need to use a form if you want to submit the file. Even if you want the button to be in a toolbar, you can enclose it in a form and it will still look like a normal toolbar button (you will need to specify the proper ui config for this).
Example:
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
items: [{
xtype: 'form',
padding: '10 0 0',
url: 'submit/image',
items: {
xtype: 'filefield',
buttonOnly: true,
width: 100,
buttonConfig: {
text: 'Add logo',
width: '100%',
ui: 'default-toolbar-small'
},
listeners: {
change: function (filefield) {
filefield.up('form').submit();
}
}
}
}, {
text: 'Remove logo'
}, '-', {
text: 'Discard changes'
}]
}]
Working fiddle example: https://fiddle.sencha.com/#view/editor&fiddle/1pdk
While I agree with scebotari's answer that in your case embedding a form in the toolbar is probably the easiest solution, for the sake of answering the original question:
If you really cannot or do not want to use a form and you're not limited regarding browser support, have a look at the FileReader.
The idea is to read the file contents on the client side (JavaScript) and then send the data using a regular AJAX request.
Your code could look like that:
function (fileField) {
var file = fileField.fileInputEl.dom.files[0],
reader;
if (file === undefined || !(file instanceof File)) {
return;
}
reader = new FileReader();
reader.onloadend = function (event) {
var binaryString = '',
bytes = new Uint8Array(event.target.result),
length = bytes.byteLength,
i,
base64String;
// convert to binary string
for (i = 0; i < length; i++) {
binaryString += String.fromCharCode(bytes[i]);
}
// convert to base64
base64String = btoa(binaryString);
Ext.Ajax.request({
url: 'save-file.php',
method: 'POST',
params: {
data: base64String
}
});
};
reader.readAsArrayBuffer(file);
}
You are looking for the event change on the fileuploadfield.
The code could look like this:
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
title: 'Upload Panel',
items: [{
xtype: 'filefield',
name: 'photo',
fieldLabel: 'Photo',
labelWidth: 50,
msgTarget: 'side',
allowBlank: false,
anchor: '100%',
buttonText: 'Select Photo...',
listeners: {
change: function (me, value, eOpts) {
console.log('trigger upload of file:', value);
}
}
}],
});
Fiddle https://fiddle.sencha.com/#view/editor&fiddle/1pd2

Saving data entered in extJS textbox

I have made textboxes in ExtJS through which I will be taking input for an ID and a name. I want to use these values(ID and name) in some other classes. So, I want to save these values somewhere(preferably in a string) so that they can be used later.
Please can someone advise me on how to do that.
function textBoxTab() {
var simple = new Ext.FormPanel({
labelWidth: 75,
frame: true,
title: 'TAB_DIM',
bodyStyle: 'padding:5px 5px 0',
width: 350,
defaults: {
width: 230
},
defaultType: 'textfield',
items: [{
xtype: 'textfield',
name: 'Module_id',
fieldLabel: 'Module_id',
allowBlank: false // requires a non-empty value
}, {
xtype: 'textfield',
name: 'Module_desc',
fieldLabel: 'Module_desc',
allowBlank: false // requires a non-empty value
}],
buttons: [{
text: 'Cancel',
handler: function() {
this.up('form').getForm().reset();
}
}, {
text: 'Submit',
handler: function() {
var form = this.up('form').getForm();
form.submit({
clientValidation: true,
url: 'save.txt',
success: function() {
Ext.Msg.alert('saved');
},
failure: function(form, action) {}
});
if (form.isValid()) {
//Ext.Msg.alert('Submitted Values', form.getValues(true));
this.up('form').getForm().submit();
}
}
}]
});
simple.render(document.body);
}
I have tried this "url:'save.txt" thing but it is not working.
Please help, thanks in advance.
The best way is to store them in a model, and have a controller manage your views and models.
There is several guide on how to architect your ExtJS application using MVC (model-view-controller) :
http://docs.sencha.com/extjs/4.2.1/#!/guide/application_architecture
http://docs.sencha.com/extjs/4.2.1/#!/guide/mvc_pt1
http://docs.sencha.com/extjs/4.2.1/#!/guide/mvc_pt2
http://docs.sencha.com/extjs/4.2.1/#!/guide/mvc_pt3
(The previous links are for ExtJS v4)

Display issue with RowEditor and checkcolumn on ExtJS GridPanel

I'm using an ExtJS (v3.4.0) GridPanel with the RowEditor extension to allow users to add lines of text to a grid. I have also used the checkcolumn extension so users can check certain lines of text for later processing. So far, it looks like this:
However, when editing a row, the problem at hand becomes apparent:
The value underlying the checkcolumn is being displayed in text form along with the actual checkbox. I figured since users can check the checkboxes without editing the row, I would make this column uneditable to fix my issue. However, after modifying my code the true/false value is still being displayed in edit mode, the text value is just not editable anymore.
My code so far:
Ext.QuickTips.init();
var FreeText = Ext.data.Record.create([{
name: 'text',
type: 'string'
}, {
name: 'active',
type: 'bool'
}]);
var store = new Ext.data.GroupingStore({
reader: new Ext.data.JsonReader({fields: FreeText}),
sortInfo: {field: 'text', direction: 'ASC'}
});
var editor = new Ext.ux.grid.RowEditor({
saveText: 'Update'
});
var freeTextPanel = new Ext.grid.GridPanel({
store: store,
width: 600,
region:'center',
margins: '0 5 5 5',
autoExpandColumn: 'text',
plugins: [editor],
view: new Ext.grid.GroupingView({
markDirty: false
}),
tbar: [{
iconCls: 'icon-add',
text: 'Add',
handler: function(){
var e = new FreeText({
text: "",
active: true
});
editor.stopEditing();
store.insert(0, e);
freeTextPanel.getView().refresh();
freeTextPanel.getSelectionModel().selectRow(0);
editor.startEditing(0);
}
},{
ref: '../removeBtn',
iconCls: 'icon-delete',
text: 'Delete',
disabled: true,
handler: function(){
editor.stopEditing();
var s = freeTextPanel.getSelectionModel().getSelections();
for(var i = 0, r; r = s[i]; i++){
store.remove(r);
}
}
}, {
xtype: 'tbseparator'
}, {
iconCls: 'icon-excel-import',
//text: 'Import from CSV',
tooltip: 'Import CSV',
handler: function() {
alert( "Excel import here!" );
}
}],
columns: [
{
xtype: 'checkcolumn',
header: 'Active',
dataIndex: 'active',
align: 'center',
width: 50
}, {
id: 'text',
header: 'Free Text',
dataIndex: 'text',
width: 220,
sortable: true,
editor: {
xtype: 'textfield',
allowBlank: false
}
}],
isCellEditable: function(col, row) {
var record = store.getAt(row);
if (record.get('active')) {
return false;
}
return Ext.grid.ColumnModel.prototype.isCellEditable.call(this, col, row);
}
});
var layout = new Ext.Panel({
title: 'Free text entry',
layout: 'border',
layoutConfig: {
columns: 1
},
width:600,
height: 600,
items: [freeTextPanel]
});
layout.render(Ext.getBody());
freeTextPanel.getSelectionModel().on('selectionchange', function(sm){
freeTextPanel.removeBtn.setDisabled(sm.getCount() < 1);
});
Is there an easy way to simply get rid of the true/false text when editing a row?
Just in case, below are my RowEditor.js and CheckColumn.js files:
RowEditor.js
http://trac.geoext.org/browser/ext/3.4.0/examples/ux/RowEditor.js?rev=2740
CheckColumn.js
http://trac.geoext.org/browser/ext/3.4.0/examples/ux/CheckColumn.js?rev=2740
Turns out the solution to my problem was rather simple.
In the startEditing method of the RowEditor.js file I added the following code. I checked implicitly on the name of my item instead of for the checkbox type, in case I still need this functionality for other checkboxes later on:
for(var i = 0, len = cm.getColumnCount(); i < len; i++){
val = this.preEditValue(record, cm.getDataIndex(i));
if( cm.getDataIndex(i) == 'active' ) {
val = "";
}
f = fields[i];
f.setValue(val);
this.values[f.id] = Ext.isEmpty(val) ? '' : val;
}

Remove fake path in extjs

I am new to the extjs.Please help me to remove fakepath issue in filefield.I do not want to get the exact path .Removing "fakepath" string is ok for me. Code runs perfectly but path displays as C:\fakepath....
I created a seperate window inorder to upload a file. In my case Application should have a seperate window as a result of selecting a option from the menu.
Here is crateWindow function of my code :
createWindow: function() {
var desktop = teamApp.getDesktop();
var win = desktop.getWindow(this.windowId + '_win');
if(!win) {
win = desktop.createWindow({
id: this.windowId + '_win',
title: 'Upload a Audio',
iconCls: 'icon-upload-picture',
height:150,
width: 500,
layout: 'fit',
renderTo: Ext.getBody(),
items:
{
xtype: 'panel',
frame:true,
bodyPadding: '10',
items: [{
xtype: 'filefield',
id: 'form-file',
labelWidth: 100,
//emptyText: 'Select an audio file',
fieldLabel: 'Audio File',
name: 'file-path',
fieldWidth: 250,
allowBlank: false,
anchor: '100%',
buttonText: 'Browse'
}],
buttons: [{
text: 'Save',
handler: function(){
var form = this.up('form').getForm();
if(form.isValid()){
form.submit({
//url: 'file-upload.php',
waitMsg: 'Uploading your Audio file...',
success: function(fp, o) {
msg('Success', 'Processed file "' + o.result.file + '" on the server');
}
});
}
}
}]
}
})
}
win.show();
return win;
}
As far as I understand you cannot, as per documentation at http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.form.field.File
Because there is no secure cross-browser way to programmatically set the value of a file input, the standard Field setValue method is not implemented. The getValue method will return a value that is browser-dependent; some have just the file name, some have a full path, some use a fake path.
Update
What you can do is set fieldWidth to zero and add another textfield before the filefield. You can set the value of this textfield as the name of file selected by user by listening to change of file field and parsing the value from last index of \ till last.

load data from grid row into (pop up) form for editing

I read in Ext JS in Action ( by J. Garcia) that if we have an instance of Ext.data.Record, we can use the form's loadRecord method to set the form's values. However, he does not give a working example of this (in the example that he uses data is loaded into a form through a file called data.php). I have searched many forums and found the following entry helpful as it gave me an idea on how to solve my problem by using form's loadRecord method:
load data from grid to form
Now the code for my store and grid is as follows:
var userstore = Ext.create('Ext.data.Store', {
storeId: 'viewUsersStore',
model: 'Configs',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/user/getuserviewdata.castle',
reader: {
type: 'json',
root: 'users'
},
listeners: {
exception: function (proxy, response, operation, eOpts) {
Ext.MessageBox.alert("Error", "Session has timed-out. Please re-login and try again.");
}
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
id: 'viewUsersGrid',
title: 'List of all users',
store: Ext.data.StoreManager.lookup('viewUsersStore'),
columns: [
{ header: 'Username', dataIndex: 'username' },
{ header: 'Full Name', dataIndex: 'fullName' },
{ header: 'Company', dataIndex: 'companyName' },
{ header: 'Latest Time Login', dataIndex: 'lastLogin' },
{ header: 'Current Status', dataIndex: 'status' },
{ header: 'Edit',
menuDisabled: true,
sortable: false,
xtype: 'actioncolumn',
width: 50,
items: [{
icon: '../../../Content/ext/img/icons/fam/user_edit.png',
tooltip: 'Edit user',
handler: function (grid, rowIndex, colIndex) {
var rec = userstore.getAt(rowIndex);
alert("Edit " + rec.get('username')+ "?");
EditUser(rec.get('id'));
}
}]
},
]
});
function EditUser(id) {
//I think I need to have this code here - I don't think it's complete/correct though
var formpanel = Ext.getCmp('CreateUserForm');
formpanel.getForm().loadRecord(rec);
}
'CreateUserForm' is the ID of a form that already exists and which should appear when user clicks on Edit icon. That pop-up form should then automatically be populated with the correct data from the grid row.
However my code is not working. I get an error at the line 'formpanel.getForm().loadRecord(rec)' - it says 'Microsoft JScript runtime error: 'undefined' is null or not an object'.
Any tips on how to solve this?
Rec is undefined in your EditUser function. You give an ID as parameter to your EditUser, you need to give the record to it as a parameter instead.
//The call
EditUser(rec);
function EditUser(rec) {
var formpanel = Ext.getCmp('CreateUserForm');
formpanel.getForm().loadRecord(rec);
}

Resources