Kendo UI custom grid popup editor window only opens once - javascript

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(); //

Related

Kendo Grid : Default value 1 in cell in inline edit mode, how to change it?

I have following config foo column in grid:
field:
actionName: {
editable: true,
nullable: true,
defaultValue: {"name" : "TEST123"},
type: "object"
},
Column:
{
field :"actionName",
title : $translate.instant('ACTIONNAME'),
width: "200px",
editor: GlobalHelperService.getActionNamesListForAutocomplete,
template: '#: data.actionName.name #',
filterable: { cell: { operator:"contains"
}
}
},
Which works almost fine, but if i clicked on cell item i always got following value (see. image below), instead of the text defined in template attribute.
How can i solve it please?
Many thanks for any advice.
It might not be the cleanest way, but you could use the edit event like I do in this blog post.
$("#grid").kendoGrid({
edit: onEdit
});
function onEdit(editEvent) {
// Ignore edits of existing rows.
if(!editEvent.model.isNew()) { return; }
editEvent.model.set("actionName", {name: "TEST123"});
}
Although as I note in that post, setting the default value with .set() might not work in this case, and you might need to edit the text in the edit box directly:
editEvent.container
.find("[name=actionName]")
.val("TEST123")
.trigger("change");

Browse button of filefield missing

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.

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.

How to remove checkall option in extjs checkboxmodel?

How to remove check all option is extjs 4 checkboxmodel?
Regards
When defining a grid (in 4.2.1), set this config option to:
selModel: Ext.create('Ext.selection.CheckboxModel', { showHeaderCheckbox: false }),
(The relevant part is showHeaderCheckbox :false)
I have managed to hide it using pure CSS:
Code:
.x-column-header-checkbox {display:none;}
When you're creating your checkboxmodel, try specifying injectCheckbox: false into its configuration. From the API:
Instructs the SelectionModel whether or not to inject the checkbox header automatically or not. (Note: By not placing the checkbox in manually, the grid view will need to be rendered 2x on initial render.) Supported values are a Number index, false and the strings 'first' and 'last'.
Inside grid panel afterrender event using jquery
listeners: {
afterrender: function (grid) {
$('.x-column-header-checkbox').css('display','none');
}
}
According to API, the type of "header" property is String. Said that, the correct value is ''. It has worked for me on ExtJS 3.4
this.queueSelModel = new Ext.grid.CheckboxSelectionModel({
singleSelect : true, // or false, how you like
header : ''
});
heder:false in config or injectCheckBoxHeader = false hide the entire column. CSS solution is class based so any other widget using the same selection model would also hide the entire check.
In ExtJS 4 a header config can be provided as below to display a blank or custom text in the header.
getHeaderConfig: function() {
var me = this;
showCheck = false;
return {
isCheckerHd: showCheck,
text : ' ',
width: me.headerWidth,
sortable: false,
draggable: false,
resizable: false,
hideable: false,
menuDisabled: true,
dataIndex: '',
cls: showCheck ? Ext.baseCSSPrefix + 'column-header-checkbox ' : '',
renderer: Ext.Function.bind(me.renderer, me),
//me.renderEmpty : renders a blank header over a check box column
editRenderer: me.editRenderer || me.renderEmpty,
locked: me.hasLockedHeader()
};
},
I encountered this issue in ExtJS 4.0.7 version.
First I removed checkbox layout:
.rn-grid-without-selectall .x-column-header-checkbox .x-column-header-text
{
display: none !important;
}
Then I used the following code in afterrender listener of the grid:
afterrender: function (grid) {
this.columns[0].isCheckerHd = false;
}
It is not a good solution but it can be used as a starting point.
Thanks for all the good hints here.
For Sencha 3.4, this is the extremely simple pure CSS I ended up using,
My_Panel_With_a_Grid_Without_Header_CheckBox = Ext.extend(Ext.Panel, {....
cls: 'innerpanel hiddeGridCheckBoxOnSingleSelect',
....}
in my CCS file:
.hiddeGridCheckBoxOnSingleSelect .x-grid3-hd-checker {
visibility:hidden
}
Define {Header: false} in checkboxselectionModel
this.queueSelModel = new Ext.grid.CheckboxSelectionModel({
singleSelect : false,
header : false
});

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