Browse button of filefield missing - javascript

I have a filefield in my extjs page. The upload functionality is working fine, alright.
The filefield is placed in a widget window. When the window is closed and reopened the filefield doesn't create properly. The browse button is missing in it. This happens only when I close the window without uploading anything at all.
The below is the code for the same:
var stockAuditUploadFile = Ext.widget('window', {
title: 'Upload the Stock Audit file',
closeAction: 'hide',
width: 500,
autoHeight: true,
layout: 'fit',
resizable: false,
modal: true,
items: [{
xtype: 'filefield',
id: 'filedata',
emptyText: 'Select a document to upload...',
fieldLabel: 'File',
waitMsg: 'Please wait...',
buttonText: 'Browse',
validator: function (v) {
if (!/\.xls$/.test(v)) {
return 'Only Excel files allowed';
}
return true;
}
}],
buttons: [{
text: 'Upload',
handler: function () {
//callUpload();
if (myuploadform.getForm().isValid()) {
//alert('in456side');
form_action = 1;
myuploadform.getForm().submit({
url: 'submission/stockupload.jsp',
success: function (result, action) {
}
});
}
Ext.Msg.alert('File Uploaded Successfully');
stockAuditUploadFile.destroy();
}
}]
});
stockAuditUploadFile.show();
When the widget window opens for the first time, everything works fine including the validation for excel file uploading but on close and reopen the browse button is missing.
Is there any mistake in my code?

I found the solution to the above issue.
The closeAction: 'hide' was the problem. On hide, things in Extjs go wild, haven't understood that yet but on changing the above to closeAction: 'destroy' the filefield works fine.
Though the hide was working in fiddle, it didn't work good for me in my project. So, I believe it is better to use the below even though the hide-closeAction may work good for others.
closeAction:'destroy' brings the browse button alright.

Related

Second File Upload fails in ExtJS 6, works in ExtJS 4

Very low-level file upload:
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'form',
items: [{
xtype: 'filefield',
fieldLabel: 'Select file',
listeners: {
change: {
fn: me.onFilefieldChange,
scope: me
}
}
}]
},{
...
onFilefieldChange: function(filefield, value, eOpts) {
var form = filefield.up('form').getForm();
form.submit({
url: APIURI+'FileUpload',
headers: {'Accept':'application/json','Content-Type':'application/json'},
waitMsg: 'Uploading',
success: function(fp, o) {
var filedata = Ext.decode(o.response.responseText).data;
var rec = Ext.create("MyApp.model.FileModel",filedata);
Ext.getStore("FileStore").add(rec);
},
failure: function(fp, o) {
Ext.alert("ERROR", "File save failed"));
}
});
The first file upload works like a charm; the file is packed into the multipart/mime and submitted correctly.
The second file upload from the very same file upload field fails, because the file is not packed into the mime.
If I close the window and open it again, the file field is working again - for a single upload, that is.
The difference in DOM of the file input field tells us why the browser behaves like this. The following three attributes are magically missing from the <input type="file" field after the first file upload:
data-ref=​"fileInputEl"
name=​"filefield-1333-button"
data-componentid=​"filefield-1333-button"
Now, this does not happen if I use the file upload field in the sencha docs. It doesn't happen with my code in ExtJS 4.2.2. But it does happen with ExtJS 6.0.1.
You wouldn't know why, would you?
It is a bug in Sencha ExtJS 6 Framework. Everything works as expected if you provide a name property to the file upload field.
xtype: 'filefield',
fieldLabel: 'Select file',
name: 'RequiredSenchaBugWorkaround',
...
Adding a name doesn't always work. It still has issues in Ext 6.2. In addition to that you should do
FileInputField1.reset();
This makes sure that the field is reset and lets you upload the same file again.

Kendo UI custom grid popup editor window only opens once

I would like to use a custom window as popup editor of a Kendo UI Grid. Its content will be complex with search fields and a grid to display search results. To do that, I don't want to use the Kendo template mechanism but a real popup window.
While doing tests with custom editor I faced an issue. Even with a very basic and simple scenario (just the create command), I'm only able to open the editor once. The second time I get an error, the editor doesn't show up anymore and the grid becomes empty.
Here is my HTML code :
<div id="main-content">
<div id="custom-window">
</div>
<table id="my-table-grid">
</table>
</div>
The JavaScript part :
function openCustomWindow(e) {
e.preventDefault();
myWindow.center().open();
}
function editorWindowClosed(e) {
myGrid.cancelRow();
}
var myWindow = $("#custom-window").kendoWindow({
modal: true,
resizable: false,
title: "Test",
visible: false,
close: editorWindowClosed
}).data("kendoWindow");
var dummyDataSource = new kendo.data.DataSource(
{
schema : {
model : {
id: "id",
fields: {
postion: { type: "number"},
name: { type: "string"},
}
}
}
});
dummyDataSource.add({postion: 1, name: "gswin"});
var myGrid = $("#my-table-grid").kendoGrid({
dataSource: dummyDataSource,
toolbar: [ {
name: "create",
text: "Create"
} ],
editable: {
mode: "popup",
window: {
animation: false,
open: openCustomWindow,
}
},
columns: [
{
field: "postion",
title: "Postion"
},
{
field: "name",
title: "Name"
}
]
}).data("kendoGrid");
The error message in the JavaScript console :
Uncaught TypeError: Cannot read property 'uid' of
undefinedut.ui.DataBoundWidget.extend.cancelRow #
kendo.all.min.js:29ut.ui.DataBoundWidget.extend.addRow #
kendo.all.min.js:29(anonymous function) #
kendo.all.min.js:29jQuery.event.dispatch #
jquery-2.1.3.js:4430jQuery.event.add.elemData.handle #
jquery-2.1.3.js:4116
And finally a jsfiddle link to show what I'm doing. (The popup is empty because I just want to fix the open / close mechanism before going any further)
I don't understand why I get this error, I expected to be able to open / close the popup as many time as I wanted. The default editor popup is working fine.
One of my colleague found the solution (thanks to him).
Actually this piece of code
editable: {
mode: "popup",
window: {
animation: false,
open: openCustomWindow,
}
}
is designed to configure the default popup...
The right way to use a custom popup is the following :
editable :true,
edit: openCustomWindow,
With this approach it's also better to use
function editorWindowClosed(e) {
myGrid.cancelChanges();
}
Instead of
function editorWindowClosed(e) {
myGrid.cancelRow();
}
Working jsfiddle link
Actually the approach in my previous answer solved my issue but is causing another issue. The grid becomes editable but in the default mode (which is "inline").
Doing this
editable: "popup",
edit: openCustomWindow
has fixed this other issue but is now displaying 2 popups.
I finally succeeded to hide the default popup and only show my custom popup but it ended with the orginal issue described in initial question...
Considering all those informations I arrived to the conclusion that working with a custom popup window is definitely not an option. I'll start working with teamplates instead.
Another solution would have been to use a template to override the toolbar with a custom "Add" button and use a custom command for edition. But at this point I consider that too "tricky".
To prevent Kendo UI custom grid popup editor window, define the editable property:
editable:
{
mode: "popup",
window: {
animation: false,
open: updateRowEventHandler
}
} // skip edit property
Then paste preventDefault() at the beginning of the handler:
function updateRowEventHandler(e) {
e.preventDefault(); //

Smart file component(html5smartfile) not working

I have been working on developing a custom extjs console to enable author drop an asset using html5smartfile component. But somehow, the html5smartfile component is not working the way it should. The Area where an author can drop an asset is not displaying. The same is working fine if I am creating a CQ5 dialog. But in my case where i have created a window it's not working.
I have declared my smartfile component like this:
var assetLinkDropField = {
xtype: 'html5smartfile',
fieldLabel: 'Asset Link',
ddAccept: 'video/.*',
ddGroups: 'media',
fileReferenceParameter: './linkUrl',
name: './linkUrl',
allowUpload: false,
allowFileNameEditing: false,
allowFileReference: true,
transferFileName: false
};
But this is rendering like this:
After a lot of work, I found out that the CQ5 dialog updates the view for the component but in case of my window, I have to update it myself. Thus, with a slight manipulation, i just succeeded in displaying the drag area by tweaking the declaration like this:
var assetLinkDropField = {
xtype: 'html5smartfile',
fieldLabel: 'Asset Link',
ddAccept: 'video/.*',
ddGroups: 'media',
fileReferenceParameter: './linkUrl',
name: './linkUrl',
allowUpload: false,
allowFileNameEditing: false,
allowFileReference: true,
transferFileName: false,
listeners: {
afterlayout: function () {
this.updateView();
}
}
}
So now the panel looks like:
But still the Drag and Drop is not working. My Window declaration is like this:
win = new CQ.Ext.Window({
height : 750,
width : 700,
layout : 'anchor',
// animateTarget : btn.el,
closeAction : 'close', // Prevent destruction on Close
id : 'manageLinkWindow',
title : '<b>Multi Link Widget Dialog</b>',
frame : true,
draggable : false,
modal : false, //Mask entire page
constrain : true,
buttonAlign : 'center',
items : [assetLinkDropField]
});
}
I think you should not use
ddAccept: 'video/.*',
This allows only videos from the content finder to be dragged and dropped. It should be "image/".
Verify your other extjs properties / configs for html5smartfile if the above doesn't resolves your problem.

Re-rendering .ascx page with extjs

I need to dynamically add a column to a page that has already been loaded. The column is represented by an object that is created AFTER the .ascx page is loaded (via user interaction). On the JavaScript side of things, I have a Panel with a TabPanel:
var reportPanel = new Ext.Panel({
layout: 'fit',
items: [
new Ext.TabPanel({
id: 'reportTabs',
renderTo: 'reportTabContainer',
activeTab: 0,
autoHeight: true,
minHeight: 600,
plain: true,
stateful: true,
deferredRender: false,//allows both reports to run at once
defaults:
{
autoHeight: true
},
items: tabsConfig
})
]
});
};
an item in tabsConfig looks like this:
{{ id: 'totalOperation', title: 'Total Operation', autoLoad: {{url: '" +Url.Action("Detail","OverallReport") +"', params: 'null', scripts: true, timeout: '9000000', method: 'POST'}}
My problem is that once the column object has been created, I need to re-render the ascx page (aka the extJSpanel) after a specific AJAX call. I have tried panel.removeAll(true) as well as panel.doLayout(false,true), and that does not remove any of the elements in the panel, or refresh the page.
In short--I need to destroy an .ascx page before an AJAX call to the controller, and let the return of the AJAX call re-populate the ascx control (using return PartialView(...) ).
Any suggestions would be greatly appreciated.
Answered my question-this little snippet of code solved it:
var contentPanel = Ext.getCmp('totalOperation');
contentPanel.autoLoad = {
url: 'URL path of controller method'
};
contentPanel.doAutoLoad();

Ext.MessageBox under TabPanel

I got problem like this:
There is TabPanel with two tab. First is FormPanel, second is GridPanel.
And I've added listener to beforetabchange. When values in FormPanel are changed there should appear Ext.MessageBox.cofirm with question: 'Do you want save your changes?'.
And it's appear but under TabPanel.
It doesn't work with any type of message box.
This is little bit weird because, when I click on submit button in this form, there is wait message box and after changes are saved there is information box.
Any ideas?
edited
I've removed all config sets from tabPanel and formPanel which is first tab, so everything is default. Message box looks like that (right now):
Ext.MessageBox.confirm('Title','message',Ext.emptyFn);
I think the problem is that the message box is binded somehow to gridPanel which is under the tabPanel.
I've added plugin to tabPanel and on beforetabchange event I show this confirm message.
Funny thing is that I do exactly the same code in plugin which is added to submit button in formPanel and there everything works perfect.
edited
new Ext.TabPanel({
activeTab: 0,
id: 'tabPanel_id',
items: [
new Ext.form.FormPanel({
cls: 'xf-windowForm',
bodyCssClass: '',
autoHeight: false,
autoScroll: true,
border: false,
layout: 'form',
buttonAlign: 'center',
monitorValid: true,
labelAlign: 'right',
labelPad: 10,
defaults: {
msgTarget: 'under',
anchor: '100%'
},
id: 'formPanel_id',
title: translate('tab_title-general'),
items: [
new Ext.form.TextField({
fieldLabel: 'label',
name: 'name',
id: 'id'
})
],
buttons: [
new Ext.Button({
text: 'save',
type: 'submit',
formBind: true,
plugins: {
init: function (component) {
component.on({
click: function() {
Ext.MessageBox.confirm('title', 'messsage', Ext.emptyFn);
}
});
}
}
})
]
}),
new Ext.Panel()
],
plugins: {
init: function(component) {
component.on({
beforetabchange: function() {
Ext.MessageBox.confirm('title', 'messsage', Ext.emptyFn);
}
});
}
}
});
There is also gridPanel under this tabPanel.
And this message box in buttons plugin works fine (tab panel becomes grey and message box appears on top), but the second one, in tabpanels plugin, add another mask on grid and shows under the panel and above the grid.
edited
Ext.onReady(function(){
new Ext.Window({
initHidden: false,
width: 700,
title: 'WindowTitle',
items: [
new Ext.TabPanel({
items: [
new Ext.Panel({title: 'Title1'}),
new Ext.Panel({title: 'Title2'})
],
plugins: {
init: function(component) {
component.on({
beforetabchange: function(t,c,n) {
Ext.MessageBox.confirm('MessageBoxTitle', 'Confirm message.', Ext.emptyFn, component);
}
});
}
}
})
]
});
});
That's complete code where problem occurs.
Message box in window show event is displayed ok, but in tabPanel it's under the window.
I'm working on FF 4.0.1, but problem occurs also in IE 8 and Chrome 12.
I'm using Ext JS 3.3.1.
solution
z-index of windows must be decreased (ie. to 7000, default is 9000).
To do that I'm using Ext.WindowGroup.
windows = new Ext.WindowGroup();
windows.zseed = 7000;
//and in config properties in window:
manager:windows
Thank's everyone for help.
"I think the problem is that the message box is binded somehow to gridPanel which is under the tabPanel."
MessageBox isn't bound to an existing panel, its a singleton and is basically a shortcut to creating a window rendered to the body, as per source code:
http://dev.sencha.com/deploy/ext-3.3.1/docs/source/MessageBox.html#cls-Ext.MessageBox
Kevin is on to something with the z-index being a likely culprit, as I've fixed issues in the past with the Ext.Notifications ux having a lower z-index than the main content.
Try running your messagebox call from the console and see if it appears. That will help determine if your wait messagebox is closing out the confirm messagebox (note the mention of it being a singleton above) or something odd where you're not seeing some other javascript error thats causing your code to not be run. Then, if you don't see the messagebox when run from the console, try the isVisible() api call to see if it thinks its being displayed (which will likely narrow it down to a css issue).
Ext MessageBox doesn't block your code until the user does something the way an alert() does. As a result, it's going to pop up the message box, and then proceed to render the new tab that the user just clicked on. Perhaps when the new tab renders, the Ext window manager is putting that window on top, since it rendered most recently?
You could try using setTimeout to display the message box after a short delay. That will give the new tab a chance to be on top, and then the message box renders, hopefully on top of everything, since it was the most recent.
setTimeout will work, there was same issue like
page- button -
on click - window with grid -
click on grid item->there should be a message box on top,
but it was under the window,
then i tried
click on grid item-
setTimeOut(function(){ Ext.MessageBox.alert('MessageBoxTitle', 'Confirm message.')}, 200);
I have used following method. It is working for me.
beforetabchange: function(tabpanel, newTab, oldTab){
if (!tabpanel.allowAction){
Ext.Msg.confirm('Confirm', 'Your Message',function(btn) {
if (btn == 'yes') {
/* logic*/
tabpanel.allowAction = true;
this.setActiveTab(newTab.id);
}else{ /* logic */}
});
return false;
}
delete tabpanel.allowAction;
}
Ext.create('Ext.window.MessageBox', {
alwaysOnTop: true,
closeAction: 'destroy'
}).show({
title: 'Title',
buttons: Ext.Msg.OK,
message: 'Message'
});
This should make the MessageBox appear on top.
Look at the fourth example in this page.
http://docs.sencha.com/extjs/5.1.0/api/Ext.window.MessageBox.html

Categories

Resources