- Added support for textarea and HTMLarea fields + i18n additional labels

(editor Save/Cancel,  YUI Datatable Loading/Error messages, and also column sort tooltips (new in YUI 29.0).
- Added CSS files for the existing two DataTable Templates.  Each file should be added to the corresponding
  template as a CSS Attachment.
- Avoid terminating the editor on Enter.
- Arrange for TAB to save and move editor for next cell also for HTMLarea editor.
- Define classes "wg-dt-textarea" and "wg-dt-htmlarea" + styling for the corresponding cells.
- Commented out handleTableKeyEvent() (reason in the code).
- Implemented a simple workaround to restore the "editor" field (not preserved due to an unknown reason).
This commit is contained in:
Amir Plivatsky 2011-07-12 23:34:27 +03:00
parent 1fd29bf2a1
commit 5aa0835649
5 changed files with 293 additions and 38 deletions

View file

@ -74,6 +74,18 @@ our $I18N = {
context => q{Format for a column with a date},
},
"format textarea" => {
message => q{Textarea},
lastUpdated => 0,
context => q{Format for a textarea column},
},
"format htmlarea" => {
message => q{HTMLarea},
lastUpdated => 0,
context => q{Format for an HTMLarea column},
},
"add column" => {
message => q{Add Column},
lastUpdated => 0,
@ -152,6 +164,23 @@ our $I18N = {
context => q{The name of a newly added value to a column},
},
"data error" => {
message => q{Data error.},
lastUpdated => 0,
context => q{Message to display when DataTable has data error},
},
"sort ascending" => {
message => q{Click to sort ascending},
lastUpdated => 0,
context => q{Message to display in tooltip to sort Column in ascending order},
},
"sort descending" => {
message => q{Click to sort descending},
lastUpdated => 0,
context => q{Message to display in tooltip to sort Column in descending order},
},
};
1;

View file

@ -0,0 +1,60 @@
/**
* wg-datatable-html.css
* CSS rules for DataTable assets
*
* Add as attachment to Default DetaTable template (HTML)
*/
/* start content at top of cells */
.dataTable table>tbody>tr>td {
vertical-align: 0;
}
.dataTable>table>tbody>tr>td>p:first-child { /* for htmlarea, but really applies to the starting p of any cell */
margin-top: 0;
}
/* padding in all data cells */
.dataTable table>tbody>tr>td {
padding-left: 10px;
padding-right: 10px;
}
/* examples of further styles */
/* limited textarea/htmlarea cells, show vertical scrollbar if needed */
/*
.dataTable table>tbody>tr>td {
height: 70px;
width: 200px;
overflow-y: auto;
}
*/
/* styling a particular DataTable in the page, by assetId */
/*
#dataTablesrvp2vk8QJqY5E0imSRQag.dataTable table>tbody>tr>td {
color:red;
height:auto;
width:150px;
overflow-y: visible
}
*/
/* minimum row height */
/*
.dataTable table>tbody>tr>td {
min-height:70px;
height:auto !important;
height:70px;
}
*/
/* styling a particular column (e.g column 2), by assetId */
/*
#dataTablesvE67R6JQfmEI__T9pIAkQ.dataTable table>tbody>tr>td:first-child+td {
color:blue;
}
*/

View file

@ -0,0 +1,59 @@
/**
* wg-datatable-yui.css
* CSS rules for DataTable assets
*
* Add as attachment to Default DetaTable template (YUI)
*/
/* start content at top of cells */
.yui-dt-editable {
vertical-align: 0;
}
.wg-dt-htmlarea>p:first-child {
margin-top: 0;
}
/* padding in all data cells */
td.yui-dt-editable .yui-dt-liner {
padding-left: 10px;
padding-right: 10px;
}
/* examples of further styles */
/* limited textarea/htmlarea cells, show vertical scrollbar if needed */
/*
.wg-dt-textarea, .wg-dt-htmlarea {
height: 70px;
width: 200px;
overflow-y: auto;
}
*/
/* styling a particular DataTable in the page */
/*
#dataTablesrvp2vk8QJqY5E0imSRQag .wg-dt-textarea, #dataTablesrvp2vk8QJqY5E0imSRQag .wg-dt-htmlarea {
color:red;
height:auto;
width:150px;
overflow:visible;
}
*/
/* minimum row height */
/*
td.yui-dt-editable .yui-dt-liner {
min-height:70px;
height:auto !important;
height:70px;
}
*/
/* styling a particular column */
/*
#dataTablesrvp2vk8QJqY5E0imSRQag .yui-dt-col-col1 .yui-dt-liner {
color:blue;
}
*/

View file

@ -7,3 +7,15 @@
.yui-dt-editable .yui-dt-liner {
min-height: 10px;
}
/* displaying the initial blank line in HTMLarea is not useful */
.wg-dt-htmlarea>p:first-child {
margin-top: 0;
}
/* size of Textarea/HTMLarea cell */
.wg-dt-textarea, .wg-dt-htmlarea {
height: 50px;
width: 150px;
overflow-y: auto;
}

View file

@ -1,4 +1,3 @@
/*global WebGUI*/
// Initialize namespace
if (typeof WebGUI == "undefined") {
@ -8,7 +7,6 @@ if (typeof WebGUI.Form == "undefined") {
WebGUI.Form = {};
}
/**
* This object contains scripts for the DataTable form control
*/
@ -39,6 +37,21 @@ WebGUI.Form.DataTable
this.options = options;
this.schemaDialog = undefined;
/************************************************************************
* editorByFormat ( event, data )
* Return the DataTable editor type that matches the given format
*/
this.editorByFormat
= function ( format ) {
switch( format ) {
case "text":
case "number":
case "link":
return "textbox";
}
return format;
};
/************************************************************************
* addRow ( event, data )
* Add a row to the bottom of the table
@ -105,16 +118,21 @@ WebGUI.Form.DataTable
/************************************************************************
* handleEditorKeyEvent ( obj )
* Handle a keypress when the Cell Editor is open
* Enter will close the editor and move down
* Not implemented: Enter will close the editor and move down
* Tab will close the editor and move right.
* Use the handleTableKeyEvent() to handle the moving
* Open a new cell editor on the newly focused cell
*/
this.handleEditorKeyEvent
= function ( obj ) {
// 9 = tab, 13 = enter
var e = obj.event;
if ( e.keyCode == 9 || e.keyCode == 13 ) {
// Avoid terminating the editor on enter
if ( e.keyCode == 13) {
return false;
}
if ( e.keyCode == 9) {
var cell = this.dataTable.getCellEditor().getTdEl();
var nextCell = this.dataTable.getNextTdEl( cell );
this.dataTable.saveCellEditor();
@ -128,8 +146,6 @@ WebGUI.Form.DataTable
// No next cell, make a new row and open the editor for that one
this.dataTable.addRow( {} );
}
// BUG: If pressing Enter, editor gets hidden right away due to YUI default event
// putting e.preventDefault() and return false here makes no difference
}
};
@ -159,7 +175,10 @@ WebGUI.Form.DataTable
* handleTableKeyEvent ( obj )
* Handle a keypress inside the DataTable
* Space will open the cell editor
* Note: it doesn't currently work: getSelectedTdEls() always returns [] when selectionMode is "standard"
* Commented out for now.
*/
/*
this.handleTableKeyEvent
= function ( obj ) {
// 9 = tab, 13 = enter, 32 = space
@ -171,6 +190,7 @@ WebGUI.Form.DataTable
}
}
};
*/
/************************************************************************
* hideSchemaDialog ( )
@ -211,7 +231,13 @@ WebGUI.Form.DataTable
}
var dataTableOptions = {
dateOptions : { format : this.options.dateFormat }
dateOptions : {
format : this.options.dateFormat,
MSG_LOADING : this.i18n.get( "WebGUI", "Loading..." ),
MSG_ERROR : this.i18n.get( "Form_DataTable", "data error" ),
MSG_SORTASC : this.i18n.get( "Form_DataTable", "sort ascending" ),
MSG_SORTDESC : this.i18n.get( "Form_DataTable", "sort descending" )
}
};
if ( this.options.showEdit ) {
@ -222,6 +248,40 @@ WebGUI.Form.DataTable
dataTableOptions.initialRequest = "";
}
for ( var i = 0; i < this.columns.length; i++ ) {
this.columns[ i ].editor = this.editorByFormat( this.columns[ i ].formatter );
}
var widget = YAHOO.widget,
DT = widget.DataTable;
// Dynamically add HTMLarea field type
// HTMLAreaCellEditor is like TextareaCellEditor, but with an additional property "htmlarea" which is true
var HTMLAreaCellEditor = function(a) {
widget.TextareaCellEditor.superclass.constructor.call(this, a);
};
YAHOO.lang.extend( HTMLAreaCellEditor, widget.TextareaCellEditor, {
htmlarea : true
} );
// Extend the static arrays of editors and formatters
DT.Editors[ "htmlarea" ] = HTMLAreaCellEditor;
// Define classes "wg-dt-textarea" and "wg-dt-htmlarea" that can be overided by a stylesheet
// (e.g. in the extraHeadTags of the asset).
var formatter = function ( type ) {
var fmt = function( el, oRecord, oColumn, oData ) {
var value = YAHOO.lang.isValue(oData) ? oData : "";
el.innerHTML = "<div class='wg-dt-" + type + "'>" + value + "</div>";
};
return fmt;
};
DT.Formatter[ "textarea" ] = formatter( "textarea" );
DT.Formatter[ "htmlarea" ] = formatter( "htmlarea" );
// XXX need to do it with YUI API
widget.BaseCellEditor.prototype.LABEL_SAVE = this.i18n.get( "Form_DataTable", "save" );
widget.BaseCellEditor.prototype.LABEL_CANCEL = this.i18n.get( "Form_DataTable", "cancel" );
this.dataTable = new YAHOO.widget.DataTable(
this.containerId,
this.columns,
@ -230,12 +290,52 @@ WebGUI.Form.DataTable
);
if ( this.options.showEdit ) {
var tinymceEdit = "tinymce-edit";
var saveThis = this;
this.dataTable.doBeforeShowCellEditor = function( oCellEditor ) {
if ( !oCellEditor.htmlarea ) {
return true;
}
oCellEditor.getInputValue = function() {
return tinyMCE.activeEditor.getContent();
};
oCellEditor.textarea.setAttribute( 'id', tinymceEdit );
tinyMCE.execCommand( 'mceAddControl', false, tinymceEdit );
setTimeout(function(){ tinyMCE.execCommand( 'mceFocus',false, tinymceEdit ); }, 0);
// watch hitting tab, which should save the current cell and open an editor on the next
tinyMCE.activeEditor.onKeyDown.add(
function( eh, t ) {
return function(ed, e) { // ed unused
eh.call( t, { event: e } );
};
}( saveThis.handleEditorKeyEvent, saveThis )
);
return true;
};
// Remove TinyMCE on save or cancel
var mceRemoveControl = function ( oArgs ) {
var oCellEditor = oArgs.editor;
if ( oCellEditor.htmlarea ) {
tinyMCE.execCommand( 'mceRemoveControl', false, tinymceEdit );
oCellEditor.textarea.removeAttribute( 'id' );
}
};
this.dataTable.subscribe( "editorSaveEvent", mceRemoveControl );
this.dataTable.subscribe( "editorCancelEvent", mceRemoveControl );
// Add the class so our editors get the right skin
YAHOO.util.Dom.addClass( document.body, "yui-skin-sam" );
this.dataTable.subscribe( "cellDblclickEvent", this.dataTable.onEventShowCellEditor );
this.dataTable.subscribe( "rowClickEvent", this.dataTable.onEventSelectRow );
this.dataTable.subscribe( "tableKeyEvent", this.handleTableKeyEvent, this, true );
/* this.handleTableKeyEvent() is commented out, see there for the reason */
/* this.dataTable.subscribe( "tableKeyEvent", this.handleTableKeyEvent, this, true ); */
this.dataTable.subscribe( "editorKeydownEvent", this.handleEditorKeyEvent, this, true );
this.dataTable.subscribe( "editorShowEvent", this.handleEditorShowEvent, this, true );
this.dataTable.subscribe( "rowAddEvent", this.handleRowAdd, this, true );
@ -288,7 +388,6 @@ WebGUI.Form.DataTable
scope : this
}
} );
// This data table will be submitted async
if ( this.options.ajaxSaveUrl ) {
var save = new YAHOO.widget.Button( {
@ -340,6 +439,8 @@ WebGUI.Form.DataTable
"format link",
"format number",
"format date",
"format textarea",
"format htmlarea",
"add column",
"cancel",
"ok",
@ -349,7 +450,13 @@ WebGUI.Form.DataTable
"help select row",
"help add row",
"help default sort",
"help reorder column"
"help reorder column",
"data error",
"sort ascending",
"sort descending"
],
'WebGUI' : [
"Loading..."
]
},
onpreload : {
@ -372,7 +479,7 @@ WebGUI.Form.DataTable
var helpDialog = new YAHOO.widget.Panel( "helpWindow", {
modal : false,
draggable : true,
zIndex : 1000
zIndex : 10000
} );
helpDialog.setHeader( "DataTable Help" );
helpDialog.setBody(
@ -411,28 +518,16 @@ WebGUI.Form.DataTable
};
var buttonLabel = this.i18n.get( "Form_DataTable", "delete column" );
var availableFormats = [
{
"value" : "text",
"label" : this.i18n.get( "Form_DataTable", "format text" )
},
{
"value" : "number",
"label" : this.i18n.get( "Form_DataTable", "format number" )
},
{
"value" : "email",
"label" : this.i18n.get( "Form_DataTable", "format email" )
},
{
"value" : "link",
"label" : this.i18n.get( "Form_DataTable", "format link" )
},
{
"value" : "date",
"label" : this.i18n.get( "Form_DataTable", "format date" )
}
];
var availableFormats = [];
var formatType = [ "text", "number", "email", "link", "date", "textarea", "htmlarea" ];
for ( var fti = 0; fti < formatType.length; fti++) {
availableFormats.push(
{
"value" : formatType[fti],
"label" : this.i18n.get( "Form_DataTable", "format " + formatType[fti] )
}
);
}
// function for creating new database columns to the table schema
var createTableColumn = function(i,cols) {
@ -602,7 +697,7 @@ WebGUI.Form.DataTable
this.updateSchema
= function () {
var data = this.schemaDialog.getData();
// First delete columns
var deleteCols = YAHOO.lang.JSON.parse( data[ "deleteCols" ] );
for ( var x = 0; x < deleteCols.length; x++ ) {
@ -630,7 +725,7 @@ WebGUI.Form.DataTable
var rows = this.dataTable.getRecordSet().getRecords();
for ( var r = 0; r < rows.length; r++ ) {
rows[ r ].setData( newKey, rows[ r ].getData( oldKey ) );
rows[ r ].setData( oldKey, undefined );
rows[ r ].setData( oldKey, undefined );
}
}
@ -640,7 +735,7 @@ WebGUI.Form.DataTable
formatter : format,
resizeable : ( col ? col.resizeable : 1 ),
sortable : ( col ? col.sortable : 1 ),
editor : ( format == "date" ? "date" : "textbox")
editor : this.editorByFormat( format )
};
if ( format == "date" ) {
newCol["dateOptions"] = { format : this.options.dateFormat };
@ -671,9 +766,9 @@ WebGUI.Form.DataTable
}
}
}
i++;
}
this.dataTable.render();
this.schemaDialog.cancel();
};