Index: t3lib/js/extjs/ux/Ext.app.SearchField.js
===================================================================
--- t3lib/js/extjs/ux/Ext.app.SearchField.js (revision 0)
+++ t3lib/js/extjs/ux/Ext.app.SearchField.js (revision 0)
@@ -0,0 +1,53 @@
+/*
+ * Ext JS Library 2.2.1
+ * Copyright(c) 2006-2009, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
+ initComponent : function() {
+ Ext.app.SearchField.superclass.initComponent.call(this);
+ this.on('specialkey', function(f, e) {
+ if (e.getKey() == e.ENTER) {
+ this.onTrigger2Click();
+ }
+ }, this);
+ },
+
+ validationEvent: false,
+ validateOnBlur: false,
+ trigger1Class: 'x-form-clear-trigger',
+ trigger2Class: 'x-form-search-trigger',
+ hideTrigger1: true,
+ width: 180,
+ hasSearch : false,
+ paramName : 'filterTxt',
+
+ onTrigger1Click : function() {
+ if (this.hasSearch) {
+ this.el.dom.value = '';
+ var o = {start: 0};
+ this.store.baseParams = this.store.baseParams || {};
+ this.store.baseParams[this.paramName] = '';
+ this.store.reload({params:o});
+ this.triggers[0].hide();
+ this.hasSearch = false;
+ }
+ },
+
+ onTrigger2Click : function() {
+ var v = this.getRawValue();
+ if (v.length < 1) {
+ this.onTrigger1Click();
+ return;
+ }
+ var o = {start: 0};
+ this.store.baseParams = this.store.baseParams || {};
+ this.store.baseParams[this.paramName] = v;
+ this.store.reload({params:o});
+ this.hasSearch = true;
+ this.triggers[0].show();
+ }
+});
Index: t3lib/js/extjs/ux/Ext.grid.RowExpander.js
===================================================================
--- t3lib/js/extjs/ux/Ext.grid.RowExpander.js (revision 0)
+++ t3lib/js/extjs/ux/Ext.grid.RowExpander.js (revision 0)
@@ -0,0 +1,159 @@
+/*
+ * Ext JS Library 2.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ *
+ * MODIFIED: SGB [12.12.07]
+ * Added support for a new config option, remoteDataMethod,
+ * including getter and setter functions, and minor mods
+ * to the beforeExpand and expandRow functions
+ */
+
+Ext.grid.RowExpander = function(config) {
+ Ext.apply(this, config);
+ Ext.grid.RowExpander.superclass.constructor.call(this);
+
+ if (this.tpl) {
+ if (typeof this.tpl == 'string') {
+ this.tpl = new Ext.Template(this.tpl);
+ }
+ this.tpl.compile();
+ }
+
+ this.state = {};
+ this.bodyContent = {};
+
+ this.addEvents({
+ beforeexpand : true,
+ expand: true,
+ beforecollapse: true,
+ collapse: true
+ });
+};
+
+Ext.extend(Ext.grid.RowExpander, Ext.util.Observable, {
+ header: "",
+ width: 20,
+ sortable: false,
+ fixed:true,
+ dataIndex: '',
+ id: 'expander',
+ lazyRender : true,
+ enableCaching: true,
+
+ getRowClass : function(record, rowIndex, p, ds) {
+ p.cols = p.cols-1;
+ var content = this.bodyContent[record.id];
+ if (!content && !this.lazyRender) {
+ content = this.getBodyContent(record, rowIndex);
+ }
+ if (content) {
+ p.body = content;
+ }
+ return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
+ },
+
+ init : function(grid) {
+ this.grid = grid;
+
+ var view = grid.getView();
+ view.getRowClass = this.getRowClass.createDelegate(this);
+
+ view.enableRowBody = true;
+
+ grid.on('render', function() {
+ view.mainBody.on('mousedown', this.onMouseDown, this);
+ }, this);
+ },
+
+ getBodyContent : function(record, index) {
+ if (!this.enableCaching) {
+ return this.tpl.apply(record.data);
+ }
+ var content = this.bodyContent[record.id];
+ if (!content) {
+ content = this.tpl.apply(record.data);
+ this.bodyContent[record.id] = content;
+ }
+ return content;
+ },
+ // Setter and Getter methods for the remoteDataMethod property
+ setRemoteDataMethod : function (fn) {
+ this.remoteDataMethod = fn;
+ },
+
+ getRemoteDataMethod : function (record, index) {
+ if (!this.remoteDataMethod) {
+ return;
+ }
+ return this.remoteDataMethod.call(this,record,index);
+ },
+
+ onMouseDown : function(e, t) {
+ if (t.className == 'x-grid3-row-expander') {
+ e.stopEvent();
+ var row = e.getTarget('.x-grid3-row');
+ this.toggleRow(row);
+ }
+ },
+
+ renderer : function(v, p, record) {
+ p.cellAttr = 'rowspan="2"';
+ return '
';
+ },
+
+ beforeExpand : function(record, body, rowIndex) {
+ if (this.fireEvent('beforexpand', this, record, body, rowIndex) !== false) {
+ // If remoteDataMethod is defined then we'll need a div, with a unique ID,
+ // to place the content
+ if (this.remoteDataMethod) {
+ this.tpl = new Ext.Template("<\div>");
+ }
+ if (this.tpl && this.lazyRender) {
+ body.innerHTML = this.getBodyContent(record, rowIndex);
+ }
+
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ toggleRow : function(row) {
+ if (typeof row == 'number') {
+ row = this.grid.view.getRow(row);
+ }
+ this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
+ },
+
+ expandRow : function(row) {
+ if (typeof row == 'number') {
+ row = this.grid.view.getRow(row);
+ }
+ var record = this.grid.store.getAt(row.rowIndex);
+ var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
+ if (this.beforeExpand(record, body, row.rowIndex)) {
+ this.state[record.id] = true;
+ Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
+ if (this.fireEvent('expand', this, record, body, row.rowIndex) !== false) {
+ // If the expand event is successful then get the remoteDataMethod
+ this.getRemoteDataMethod(record,row.rowIndex);
+ }
+ }
+ },
+
+ collapseRow : function(row) {
+ if (typeof row == 'number') {
+ row = this.grid.view.getRow(row);
+ }
+ var record = this.grid.store.getAt(row.rowIndex);
+ var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
+ if (this.fireEvent('beforcollapse', this, record, body, row.rowIndex) !== false) {
+ this.state[record.id] = false;
+ Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
+ this.fireEvent('collapse', this, record, body, row.rowIndex);
+ }
+ }
+});
Index: t3lib/js/extjs/ux/Ext.ux.FitToParent.js
===================================================================
--- t3lib/js/extjs/ux/Ext.ux.FitToParent.js (revision 0)
+++ t3lib/js/extjs/ux/Ext.ux.FitToParent.js (revision 0)
@@ -0,0 +1,33 @@
+/* plugin for resize of grid in single container */
+Ext.namespace('Ext.ux.plugins');
+
+Ext.ux.plugins.FitToParent = Ext.extend(Object, {
+ constructor : function(parent) {
+ this.parent = parent;
+ },
+ init : function(c) {
+ c.on('render', function(c) {
+ c.fitToElement = Ext.get(this.parent
+ || c.getPositionEl().dom.parentNode);
+ if (!c.doLayout) {
+ this.fitSizeToParent();
+ Ext.EventManager.onWindowResize(this.fitSizeToParent, this);
+ }
+ }, this, {
+ single : true
+ });
+ if (c.doLayout) {
+ c.monitorResize = true;
+ c.doLayout = c.doLayout.createInterceptor(this.fitSizeToParent);
+ }
+ },
+ fitSizeToParent : function() {
+ // Uses the dimension of the current viewport, but removes the document header
+ // and an addtional margin of 40 pixels (e.g. Safari needs this addition)
+
+ this.fitToElement.setHeight(document.viewport.getHeight() - this.fitToElement.getTop() - 40);
+ var pos = this.getPosition(true), size = this.fitToElement.getViewSize();
+ this.setSize(size.width - pos[0], size.height - pos[1]);
+
+ }
+});
Index: typo3/sysext/recycler/mod1/index.php
===================================================================
--- typo3/sysext/recycler/mod1/index.php (revision 8566)
+++ typo3/sysext/recycler/mod1/index.php (working copy)
@@ -47,6 +47,11 @@
protected $recordsPageLimit = 50;
/**
+ * @var t3lib_pageRenderer
+ */
+ protected $pageRenderer;
+
+ /**
* Initializes the Module
*
* @return void
@@ -57,6 +62,8 @@
$this->doc->setModuleTemplate(t3lib_extMgm::extPath('recycler') . 'mod1/mod_template.html');
$this->doc->backPath = $GLOBALS['BACK_PATH'];
+ $this->pageRenderer = $this->doc->getPageRenderer();
+
$this->relativePath = t3lib_extMgm::extRelPath('recycler');
$this->pageRecord = t3lib_BEfunc::readPageAccess($this->id, $this->perms_clause);
$this->isAccessibleForCurrentUser = (
@@ -135,44 +142,34 @@
*/
protected function loadHeaderData() {
// Load CSS Stylesheets:
- $this->loadStylesheet($this->relativePath . 'res/css/customExtJs.css');
+ $this->pageRenderer->addCssFile($this->relativePath . 'res/css/customExtJs.css');
+
// Load Ext JS:
- $this->doc->getPageRenderer()->loadExtJS();
+ $this->pageRenderer->loadExtJS();
+ $this->pageRenderer->enableExtJSQuickTips();
+
// Integrate dynamic JavaScript such as configuration or lables:
- $this->doc->JScode.= t3lib_div::wrapJS('
- Ext.namespace("Recycler");
- Recycler.statics = ' . json_encode($this->getJavaScriptConfiguration()) . ';
- Recycler.lang = ' . json_encode($this->getJavaScriptLabels()) . ';'
+ $this->pageRenderer->addInlineSettingArray(
+ 'Recycler',
+ $this->getJavaScriptConfiguration()
);
+ $this->pageRenderer->addInlineLanguageLabelArray(
+ $this->getJavaScriptLabels()
+ );
+
+
// Load Recycler JavaScript:
- $this->loadJavaScript($this->relativePath . 'res/js/ext_expander.js');
- $this->loadJavaScript($this->relativePath . 'res/js/search_field.js');
- $this->loadJavaScript($this->relativePath . 'res/js/t3_recycler.js');
- }
- /**
- * Loads a stylesheet by adding it to the HTML head section.
- *
- * @param string $fileName: Name of the file to be loaded
- * @return void
- */
- protected function loadStylesheet($fileName) {
- $fileName = t3lib_div::resolveBackPath($this->doc->backPath . $fileName);
- $this->doc->JScode .= TAB . '
' . LF;
+ // Load Plugins
+ $uxPath = $this->doc->backpath . '../t3lib/js/extjs/ux/';
+ $this->pageRenderer->addJsFile($uxPath . 'Ext.grid.RowExpander.js', NULL, TRUE);
+ $this->pageRenderer->addJsFile($uxPath . 'Ext.app.SearchField.js', NULL, TRUE);
+ $this->pageRenderer->addJsFile($uxPath . 'Ext.ux.FitToParent.js', NULL, TRUE);
+ // Load main script
+ $this->pageRenderer->addJsFile($this->relativePath . 'res/js/t3_recycler.js');
}
/**
- * Loads a JavaScript file.
- *
- * @param string $fileName: Name of the file to be loaded
- * @return void
- */
- protected function loadJavaScript($fileName) {
- $fileName = t3lib_div::resolveBackPath($this->doc->backPath . $fileName);
- $this->doc->JScode .= TAB . '' . LF;
- }
-
- /**
* Gets the JavaScript configuration for the Ext JS interface.
*
* @return array The JavaScript configuration
Index: typo3/sysext/recycler/res/css/customExtJs.css
===================================================================
--- typo3/sysext/recycler/res/css/customExtJs.css (revision 8566)
+++ typo3/sysext/recycler/res/css/customExtJs.css (working copy)
@@ -1,161 +1,32 @@
-body#ext-recycler-mod1-index-php {
- margin-left: 0;
+.delete {
+ background-image: url('../icons/delete.gif') !important;
}
-
-#recyclerContent {
- margin: 10px 0 0 0;
+.undelete {
+ background-image: url('../icons/arrow_rotate_anticlockwise.png') !important;
}
-
-.x-panel .x-grid-panel {
- padding: 0;
- margin: 0;
- background-image: none;
- background: none;
- border: none;
+.backup {
+ background-image: url('../icons/database_save.png') !important;
}
-
-body .x-panel {
- margin-bottom:20px;
+.filter_refresh {
+ background-image: url('../icons/filter_refresh.png') !important;
}
-
-.x-toolbar-left, .x-toolbar-right, .x-panel-mc, x-panel-tbar, .x-toolbar .x-small-editor .x-toolbar-layout-ct, x-toolbar-ct,
-.x-panel-nofooter .x-panel-bc, .x-panel-nofooter .x-window-bc,
-.x-toolbar,
-.x-small-editor,
-.x-toolbar-layout-ct,
-.x-panel-mr, .x-panel-ml, .x-panel-tr, .x-panel-tl, .x-panel-br, .x-panel-bl, .x-panel-ml, .x-panel-mr, .x-panel-tm, .x-panel-tc {
- background-image: none;
- background: none;
- padding: 0;
- margin: 0;
- border: none;
+.filter_clear {
+ background-image: url('../icons/filter_clear.png') !important;
}
-.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar {
- padding: 2px;
- margin: 0;
- border: 0;
+#recyclerContent {
+ margin-top: 10px;
}
-.x-panel-mr, .x-panel-ml {
- padding: 0;
- margin: 0;
+.recycler-messagebox {
+ padding: 10px;
+ font-size: 12px;
}
-.x-toolbar {
- padding: 0;
- margin: 0;
+ul.recycler-table-list {
+ list-style: disc;
+ margin: 5px 0 5px 15px;
}
-
-.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar,
-.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar {
- background-color: #585858;
-}
-
-.x-toolbar-ct .x-toolbar-left {
- width: 400px;
-}
-
-.x-toolbar-ct .x-toolbar-right, .x-toolbar-cell {
-}
-
-.x-toolbar-ct .xtb-text {
- color: #fff;
-}
-
-.icon-grid { background-image:url('../icons/recycler2.gif') !important; }
-
-#button-grid .x-panel-body {
- border:1px solid #99bbe8;
- border-top:0 none;
-}
-
-.loadingClass { top:200px !important; }
-
-.ext-el-mask-msg { width:200px; }
-
-.ext-el-mask-msg div {
- height:30px;
- background-image: url('../icons/loading.gif');
- background-position: 155px 3px;
- background-repeat: no-repeat;
-}
-
-.x-toolbar button {
- color: #fff;
-}
-
-.delete { background-image: url('../icons/delete.gif') !important; }
-.undelete { background-image: url('../icons/arrow_rotate_anticlockwise.png') !important; }
-.backup { background-image: url('../icons/database_save.png') !important; }
-.filter_refresh { background-image: url('../icons/filter_refresh.png') !important; }
-.filter_clear { background-image: url('../icons/filter_clear.png') !important; }
-
-.deletedPath { color: #ff0000; font-weight: bold; }
-
-.x-toolbar table { width: 100%; }
-
-#recordPaging table { width: auto; }
-#recordPaging .x-tbar-page-number { text-align: center; }
-
-.x-window-body { padding: 5px; }
-.x-window-body label { display: block; margin: 5px 0; }
-.x-window-body .x-form-cb-label { margin-left: 5px; }
-
-/* Single rows and elements */
-.x-grid3-body .x-grid3-td-expander {
- background-image: none;
-}
-
-.x-grid3-row {
- background-image:none;
-}
-
-.x-grid3-row-selected {
- background-color:#fff !important;
- background-image:none;
-}
-
-/* Flyout Menus */
-.x-menu-sep {
- display: none;
-}
-
-.x-menu {
- background-image: none;
-}
-
-.x-menu-item-active a.x-menu-item {
- border: 1px solid #adb5c1;
- background-color: #adb5c1;
- color: #fff;
-}
-
-.x-menu-list {
- padding:0;
-}
-
-/* Flyout Menu Shadows */
-.x-shadow .xstl, .x-shadow .xstc, .x-shadow .xstr, .x-shadow .xsbl,
-.x-shadow .xsbc, .x-shadow .xsbr, .x-shadow .xstl, .x-shadow .xstr, .x-shadow .xsml, .x-shadow .xsmr {
- background-image: none;
-}
-
-.x-grid3-body .x-grid3-td-checker {
- background-image: none;
- background-color: none;
-}
-
-.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,
-.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,
-.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander {
- background-image: none;
- background-color: none;
-}
-
-.x-grid3-row-body,
-.x-grid3-row-body-tr,
-.x-grid3-row-body-td,
-.x-grid3-body-cell {
- background-color: none;
+ul.recycler-table-list li {
+ margin-left: 10px;
}
\ No newline at end of file
Index: typo3/sysext/recycler/res/js/t3_recycler.js
===================================================================
--- typo3/sysext/recycler/res/js/t3_recycler.js (revision 8566)
+++ typo3/sysext/recycler/res/js/t3_recycler.js (working copy)
@@ -27,262 +27,328 @@
*
* @author Julian Kleinhans
* @author Erik Frister
+ * @author Steffen Kamper
* @package TYPO3
* @subpackage tx_recycler
* @version $Id$
*/
-Event.observe(window, 'load', function() {
- //Quicktips initialisieren
- Ext.QuickTips.init();
- // @todo: description
- // Ext.form.Field.prototype.msgTarget = 'side';
+Ext.ns('Recycler');
- // disable loadindicator
- Ext.UpdateManager.defaults.showLoadIndicator = false;
-
- // fire recycler grid
- new Recycler.grid.init();
+/****************************************************
+ * row expander
+ ****************************************************/
+Recycler.Expander = new Ext.grid.RowExpander({
+ tpl : new Ext.Template(
+ ' ' +
+ '' + TYPO3.lang.table + ': {table}
' +
+ '' + TYPO3.lang.crdate + ': {crdate}
' +
+ '' + TYPO3.lang.tstamp + ': {tstamp}
' +
+ '' + TYPO3.lang.owner + ': {owner} (UID: {owner_uid})
' +
+ '' + TYPO3.lang.path + ': {path}
' +
+ ' '
+ )
});
-Recycler.grid = {
- /**
- * Initializes the grid
- *
- * @return void
- **/
- init: function() {
- /****************************************************
- * row expander
- ****************************************************/
- var expander = new Ext.grid.RowExpander({
- tpl : new Ext.Template(
- ' ' +
- '' + Recycler.lang.table + ': {table}
' +
- '' + Recycler.lang.crdate + ': {crdate}
' +
- '' + Recycler.lang.tstamp + ': {tstamp}
' +
- '' + Recycler.lang.owner + ': {owner} (UID: {owner_uid})
' +
- '' + Recycler.lang.path + ': {path}
' +
- ' '
- )
- });
+/****************************************************
+ * Main store
+ ****************************************************/
+Recycler.MainStore = new Ext.data.Store({
+ storeId: 'deletedRecordsStore',
+ reader: new Ext.data.JsonReader({
+ totalProperty: 'total',
+ root: 'rows'
+ }, [
+ {name: 'uid', type: 'int'},
+ {name: 'pid', type: 'int'},
+ {name: 'record', mapping: 'title'},
+ {name: 'crdate'},
+ {name: 'tstamp'},
+ {name: 'owner'},
+ {name: 'owner_uid'},
+ {name: 'tableTitle'},
+ {name: 'table'},
+ {name: 'path'}
+ ]),
+ sortInfo: {
+ field: 'record',
+ direction: "ASC"
+ },
+ groupField: 'table',
+ url: TYPO3.settings.Recycler.ajaxController + '&cmd=getDeletedRecords',
+ baseParams: {
+ depth: TYPO3.settings.Recycler.depthSelection,
+ startUid: TYPO3.settings.Recycler.startUid,
+ pagingSizeDefault: TYPO3.settings.Recycler.pagingSize,
+ table: TYPO3.settings.Recycler.tableSelection
+ }
+
+});
- /****************************************************
- * pluggable renderer
- ****************************************************/
+/****************************************************
+ * Simple table store
+ ****************************************************/
+Recycler.TableStore = new Ext.data.Store({
+ url: TYPO3.settings.Recycler.ajaxController + '&startUid=' + TYPO3.settings.Recycler.startUid + '&cmd=getTables' + '&depth=' + TYPO3.settings.Recycler.depthSelection,
+ reader: new Ext.data.ArrayReader({}, [
+ {name: 'table', type: 'string'},
+ {name: 'records', type: 'int'},
+ {name: 'valueField', type: 'string'},
+ {name: 'tableTitle', type: 'string'}
+ ]),
+ listeners: {
+ 'load': {
+ fn: function(store, records) {
+ Ext.getCmp('tableSelector').setValue(TYPO3.settings.Recycler.tableSelection);
+ },
+ single: true
+ }
+ }
+})
- var renderTopic = function (value, p, record) {
- return String.format('{0}', value, record.data.table, record.data.uid, record.data.pid);
- };
-
- /****************************************************
- * row checkbox
- ****************************************************/
-
- var sm = new Ext.grid.CheckboxSelectionModel({
- singleSelect: false
+/****************************************************
+ * Confirmation Window
+ ****************************************************/
+Recycler.ConfirmWindow = Ext.extend(Ext.Window, {
+
+ width: 300,
+ height: 200,
+
+ title: '',
+ confirmText: '',
+ confirmQuestion: '',
+ records: [],
+ hideRecursive: false,
+ showRecursiveCheckbox: false,
+ arePagesAffected: false,
+ command: '',
+ template: new Ext.XTemplate(
+ '',
+ '',
+ '{[values]} ',
+ ' ',
+ ' '
+ ),
+ initComponent:function() {
+ Ext.apply(this, {
+ xtype: 'form',
+ bodyCssClass: 'recycler-messagebox',
+ modal: true,
+
+ items: [
+ {
+ xtype: 'label',
+ text: this.confirmText
+ }, {
+ xtype: 'displayfield',
+ tpl: this.template,
+ data: this.tables
+ }, {
+ xtype: 'label',
+ text: this.confirmQuestion
+ }, {
+ xtype: 'checkbox',
+ boxLabel: TYPO3.lang.boxLabel_undelete_recursive,
+ name: 'recursiveCheckbox',
+ disabled: !this.showRecursiveCheckbox,
+ itemId: 'recursiveCheck',
+ hidden: this.hideRecursive // hide the checkbox when frm is used to permanently delete
+ }
+ ],
+ buttons: [
+ {
+ text: TYPO3.lang.yes,
+ scope: this,
+ handler: function(button, event) {
+ var tcemainData = [];
+
+ for (var i=0; i < this.records.length; i++) {
+ tcemainData[i] = [this.records[i].data.table, this.records[i].data.uid];
+ }
+ Ext.Ajax.request({
+ url: TYPO3.settings.Recycler.ajaxController + '&cmd=' + this.command,
+ params: {
+ 'data': Ext.encode(tcemainData),
+ 'recursive': this.getComponent('recursiveCheck').getValue()
+ },
+ callback: function(options, success, response) {
+ if (response.responseText === "1") {
+ // reload the records and the table selector
+ Recycler.MainStore.reload();
+ Recycler.TableStore.reload();
+ if (this.arePagesAffected) {
+ Recycler.Utility.updatePageTree();
+ }
+ } else {
+ Ext.MessageBox.show({
+ title: 'ERROR',
+ msg: response.responseText,
+ buttons: Ext.MessageBox.OK,
+ icon: Ext.MessageBox.ERROR
+ });
+ }
+ }
+ });
+
+ this.close();
+ }
+ },{
+ text: TYPO3.lang.no,
+ scope: this,
+ handler: function(button, event) {
+ this.close();
+ }
+ }
+ ]
});
+ Recycler.ConfirmWindow.superclass.initComponent.apply(this, arguments);
+ }
+});
- /****************************************************
- * filter grid
- ****************************************************/
+/****************************************************
+ * Utility functions
+ ****************************************************/
+Recycler.Utility = {
+ updatePageTree: function() {
+ if (top && top.content && top.content.nav_frame && top.content.nav_frame.Tree) {
+ top.content.nav_frame.Tree.refresh();
+ }
+ },
+
+ // not used?
+ filterGrid: function(grid, component) {
+ var filterText = component.getValue();
- var filterGrid = function(grid, cmp) {
- var filterText = cmp.getValue();
-
- gridDs.setBaseParam('filterTxt', filterText);
- // load the datastore
- gridDs.load({
- params: {
- start: 0
- }
- });
- };
-
- /****************************************************
- * grid datastore
- ****************************************************/
- var gridDs = new Ext.data.Store({
- storeId: 'deletedRecordsStore',
- reader: new Ext.data.JsonReader({
- totalProperty: 'total',
- root: 'rows'
- }, [
- {name: 'uid', type: 'int'},
- {name: 'pid', type: 'int'},
- {name: 'record', mapping: 'title'},
- {name: 'crdate'},
- {name: 'tstamp'},
- {name: 'owner'},
- {name: 'owner_uid'},
- {name: 'tableTitle'},
- {name: 'table'},
- {name: 'path'}
- ]),
- sortInfo: {
- field: 'record',
- direction: "ASC"
- },
- groupField: 'table',
- url: Recycler.statics.ajaxController + '&cmd=getDeletedRecords'
+ Recycler.MainStore.setBaseParam('filterTxt', filterText);
+ // load the datastore
+ Recycler.MainStore.load({
+ params: {
+ start: 0
+ }
});
-
- gridDs.baseParams = {
- depth: Recycler.statics.depthSelection,
- startUid: Recycler.statics.startUid,
- pagingSizeDefault: Recycler.statics.pagingSize,
- table: Recycler.statics.tableSelection
- };
-
-
+ },
+
+ /****************************************************
+ * permanent deleting function
+ ****************************************************/
- /****************************************************
- * permanent deleting function
- ****************************************************/
+ function_delete: function(button, event) {
+ Recycler.Utility.rowAction(
+ 'doDelete',
+ TYPO3.lang.cmd_doDelete_confirmText,
+ TYPO3.lang.title_delete,
+ TYPO3.lang.text_delete
+ );
+ },
- var function_delete = function(ob) {
- rowAction(ob, Recycler.lang.cmd_doDelete_confirmText, 'doDelete', Recycler.lang.title_delete, Recycler.lang.text_delete);
- };
+ /****************************************************
+ * Undeleting function
+ ****************************************************/
- /****************************************************
- * Undeleting function
- ****************************************************/
+ function_undelete: function(button, event) {
+ Recycler.Utility.rowAction(
+ 'doUndelete',
+ TYPO3.lang.sure,
+ TYPO3.lang.title_undelete,
+ TYPO3.lang.text_undelete
+ );
+ },
- var function_undelete = function(ob) {
- rowAction(ob, Recycler.lang.sure, 'doUndelete', Recycler.lang.title_undelete, Recycler.lang.text_undelete);
- };
+ /****************************************************
+ * Row action function ( deleted or undeleted )
+ ****************************************************/
- /****************************************************
- * Row action function ( deleted or undeleted )
- ****************************************************/
+ rowAction: function(command, confirmQuestion, confirmTitle, confirmText) {
+ // get the 'undeleted records' grid object
+ var records = Recycler.Grid.getSelectionModel().getSelections();
- var rowAction = function(ob, confirmQuestion, cmd, confirmTitle, confirmText) {
- // get the 'undeleted records' grid object
- var recArray = gridContainer.getSelectionModel().getSelections();
+ if (records.length > 0) {
- if (recArray.length > 0) {
-
- // check if a page is checked
- var recursiveCheckbox = false;
- var arePagesAffected = false;
- var tables = [];
- var hideRecursive = ('doDelete' == cmd);
-
- for (iterator=0; iterator < recArray.length; iterator++) {
- if (tables.indexOf(recArray[iterator].data.table) < 0) {
- tables.push(recArray[iterator].data.table);
- }
- if (cmd == 'doUndelete' && recArray[iterator].data.table == 'pages' ) {
- recursiveCheckbox = true;
- arePagesAffected = true;
- }
+ // check if a page is checked
+ var recursiveCheckbox = false;
+ var arePagesAffected = false;
+ var tables = [];
+ var hideRecursive = ('doDelete' == command);
+
+ for (iterator=0; iterator < records.length; iterator++) {
+ if (tables.indexOf(records[iterator].data.table) < 0) {
+ tables.push(records[iterator].data.table);
}
+ if (command == 'doUndelete' && records[iterator].data.table == 'pages' ) {
+ recursiveCheckbox = true;
+ arePagesAffected = true;
+ }
+ }
- var frmConfirm = new Ext.Window({
- xtype: 'form',
- width: 300,
- height: 200,
- modal: true,
- title: confirmTitle,
- items: [
- {
- xtype: 'label',
- text: confirmText + tables.join(', ')
- },{
- xtype: 'label',
- text: confirmQuestion
- },{
- xtype: 'checkbox',
- boxLabel: Recycler.lang.boxLabel_undelete_recursive,
- name: 'recursiveCheckbox',
- disabled: !recursiveCheckbox,
- id: 'recursiveCheckbox',
- hidden: hideRecursive // hide the checkbox when frm is used to permanently delete
- }
- ],
- buttons: [
- {
- text: Recycler.lang.yes,
- handler: function(cmp, e) {
- var tcemainData = [];
+ var frmConfirm = new Recycler.ConfirmWindow({
+ title: confirmTitle,
+ records: records,
+ tables: tables,
+ confirmText: confirmText,
+ confirmQuestion: confirmQuestion,
+ hideRecursive: hideRecursive,
+ recursiveCheckbox: recursiveCheckbox,
+ arePagesAffected: arePagesAffected,
+ command: command
+ }).show();
- for (iterator=0; iterator < recArray.length; iterator++) {
- tcemainData[iterator] = [recArray[iterator].data.table, recArray[iterator].data.uid];
- }
+ } else {
+ // no row selected
+ Ext.MessageBox.show({
+ title: TYPO3.lang.error_NoSelectedRows_title,
+ msg: TYPO3.lang.error_NoSelectedRows_msg,
+ buttons: Ext.MessageBox.OK,
+ minWidth: 300,
+ minHeight: 200,
+ icon: Ext.MessageBox.ERROR
+ });
+ }
+ },
+
+ /****************************************************
+ * pluggable renderer
+ ****************************************************/
- Ext.Ajax.request({
- url: Recycler.statics.ajaxController + '&cmd=' + cmd,
- callback: function(options, success, response) {
- if (response.responseText === "1") {
- // reload the records and the table selector
- gridDs.reload();
- Ext.getCmp('tableSelector').store.reload();
- if (arePagesAffected) {
- Recycler.utility.updatePageTree();
- }
- }else{
- alert('ERROR: '+response.responseText);
- }
- },
- params: {'data': Ext.encode(tcemainData), 'recursive':frmConfirm.getComponent('recursiveCheckbox').getValue() }
- });
+ renderTopic: function (value, p, record) {
+ return String.format('{0}', value, record.data.table, record.data.uid, record.data.pid);
+ }
+};
- frmConfirm.destroy();
- }
- },{
- text: Recycler.lang.no,
- handler: function(cmp, e) {
- frmConfirm.destroy();
- }
- }
- ]
- });
- frmConfirm.show();
- } else {
- // no row selected
- Ext.MessageBox.show({
- title: Recycler.lang.error_NoSelectedRows_title,
- msg: Recycler.lang.error_NoSelectedRows_msg,
- buttons: Ext.MessageBox.OK,
- minWidth: 300,
- minHeight: 200,
- icon: Ext.MessageBox.INFO
- });
- }
- };
-
- /****************************************************
- * grid container
- ****************************************************/
- var gridContainer = new Ext.grid.GridPanel ({
- layout: 'fit',
- renderTo: Recycler.statics.renderTo,
- width: '98%',
- frame: true,
- border: true,
- defaults: {autoScroll: false},
- plain: true,
+/****************************************************
+ * grid container
+ ****************************************************/
+Recycler.GridContainer = Ext.extend(Ext.grid.GridPanel, {
+ layout: 'fit',
+ renderTo: TYPO3.settings.Recycler.renderTo,
+ width: '98%',
+ frame: true,
+ border: false,
+ defaults: {autoScroll: false},
+ plain: true,
+
+ initComponent : function() {
+ Ext.apply(this, {
id: 'delRecordId',
loadMask: true,
stripeRows: true,
collapsible: false,
animCollapse: false,
- store: gridDs,
+ store: Recycler.MainStore,
cm: new Ext.grid.ColumnModel([
- sm,
- expander,
+ new Ext.grid.CheckboxSelectionModel({singleSelect: false}),
+ Recycler.Expander,
{header: "UID", width: 10, sortable: true, dataIndex: 'uid'},
{header: "PID", width: 10, sortable: true, dataIndex: 'pid'},
- {id: 'record', header: Recycler.lang.records, width: 60, sortable: true, dataIndex: 'record', renderer: renderTopic},
- {id: 'table', header: Recycler.lang.table, width: 20, sortable: true, dataIndex: 'tableTitle'}
+ {id: 'record', header: TYPO3.lang.records, width: 60, sortable: true, dataIndex: 'record', renderer: Recycler.Utility.renderTopic},
+ {id: 'table', header: TYPO3.lang.table, width: 20, sortable: true, dataIndex: 'tableTitle'}
]),
viewConfig: {
forceFit: true
},
- sm: sm,
- plugins: [expander, new Ext.ux.plugins.FitToParent()],
+ sm: Recycler.SelectionModel,
+ plugins: [Recycler.Expander, new Ext.ux.plugins.FitToParent()],
bbar: [
{
@@ -291,11 +357,11 @@
****************************************************/
id: 'recordPaging',
xtype: 'paging',
- store: gridDs,
- pageSize: Recycler.statics.pagingSize,
+ store: Recycler.MainStore,
+ pageSize: TYPO3.settings.Recycler.pagingSize,
displayInfo: true,
- displayMsg: Recycler.lang.pagingMessage,
- emptyMsg: Recycler.lang.pagingEmpty
+ displayMsg: TYPO3.lang.pagingMessage,
+ emptyMsg: TYPO3.lang.pagingEmpty
}, '-', {
/****************************************************
* Delete button
@@ -303,11 +369,11 @@
xtype: 'button',
width: 80,
id: 'deleteButton',
- text: Recycler.lang.deleteButton_text,
- tooltip: Recycler.lang.deleteButton_tooltip,
+ text: TYPO3.lang.deleteButton_text,
+ tooltip: TYPO3.lang.deleteButton_tooltip,
iconCls: 'delete',
- disabled: Recycler.statics.deleteDisable,
- handler: function_delete
+ disabled: TYPO3.settings.Recycler.deleteDisable,
+ handler: Recycler.Utility.function_delete
}, {
/****************************************************
* Undelete button
@@ -315,28 +381,28 @@
xtype: 'button',
width: 80,
id: 'undeleteButton',
- text: Recycler.lang.undeleteButton_text,
- tooltip: Recycler.lang.undeleteButton_tooltip,
+ text: TYPO3.lang.undeleteButton_text,
+ tooltip: TYPO3.lang.undeleteButton_tooltip,
iconCls: 'undelete',
- handler: function_undelete
+ handler: Recycler.Utility.function_undelete
}
],
tbar: [
- Recycler.lang.search, ' ',
+ TYPO3.lang.search, ' ',
new Ext.app.SearchField({
- store: gridDs,
+ store: Recycler.MainStore,
width: 200
}),
'-', {
xtype: 'tbtext',
- text: Recycler.lang.depth + ':'
+ text: TYPO3.lang.depth + ':'
},{
/****************************************************
* Depth menu
****************************************************/
-
+
xtype: 'combo',
width: 150,
lazyRender: true,
@@ -344,36 +410,36 @@
displayField: 'label',
id: 'depthSelector',
mode: 'local',
- emptyText: Recycler.lang.depth,
+ emptyText: TYPO3.lang.depth,
selectOnFocus: true,
triggerAction: 'all',
editable: false,
forceSelection: true,
- hidden: Recycler.lang.showDepthMenu,
+ hidden: TYPO3.lang.showDepthMenu,
store: new Ext.data.SimpleStore({
autoLoad: true,
fields: ['depth','label'],
data : [
- ['0', Recycler.lang.depth_0],
- ['1', Recycler.lang.depth_1],
- ['2', Recycler.lang.depth_2],
- ['3', Recycler.lang.depth_3],
- ['4', Recycler.lang.depth_4],
- ['999', Recycler.lang.depth_infi]
+ ['0', TYPO3.lang.depth_0],
+ ['1', TYPO3.lang.depth_1],
+ ['2', TYPO3.lang.depth_2],
+ ['3', TYPO3.lang.depth_3],
+ ['4', TYPO3.lang.depth_4],
+ ['999', TYPO3.lang.depth_infi]
]
}),
- value: Recycler.statics.depthSelection,
+ value: TYPO3.settings.Recycler.depthSelection,
listeners: {
'select': {
fn: function(cmp, rec, index) {
var depth = rec.get('depth');
- gridDs.setBaseParam('depth', depth);
- gridDs.load({
+ Recycler.MainStore.setBaseParam('depth', depth);
+ Recycler.MainStore.load({
params: {
start: 0
}
});
-
+
Ext.getCmp('tableSelector').store.load({
params: {
depth: depth
@@ -384,7 +450,7 @@
}
},'-',{
xtype: 'tbtext',
- text: Recycler.lang.tableMenu_label
+ text: TYPO3.lang.tableMenu_label
},{
/****************************************************
@@ -396,45 +462,29 @@
valueField: 'valueField',
displayField: 'tableTitle',
id: 'tableSelector',
+ width: 220,
mode: 'local',
- emptyText: Recycler.lang.tableMenu_emptyText,
+ emptyText: TYPO3.lang.tableMenu_emptyText,
selectOnFocus: true,
triggerAction: 'all',
editable: false,
forceSelection: true,
- store: new Ext.data.Store({
- autoLoad: true,
- url: Recycler.statics.ajaxController + '&startUid=' + Recycler.statics.startUid + '&cmd=getTables' + '&depth=' + Recycler.statics.depthSelection,
- reader: new Ext.data.ArrayReader({}, [
- {name: 'table', type: 'string'},
- {name: 'records', type: 'int'},
- {name: 'valueField', type: 'string'},
- {name: 'tableTitle', type: 'string'}
- ]),
- listeners: {
- 'load': {
- fn: function(store, records) {
- Ext.getCmp('tableSelector').setValue(Recycler.statics.tableSelection);
- },
- single: true
- }
- }
- }),
- valueNotFoundText: String.format(Recycler.lang.noValueFound, Recycler.statics.tableSelection),
+ store: Recycler.TableStore,
+ valueNotFoundText: String.format(TYPO3.lang.noValueFound, TYPO3.settings.Recycler.tableSelection),
tpl: '{tableTitle} ({records})
{tableTitle} ({records})
',
listeners: {
'select': {
- fn: function(cmp, rec, index) {
- var table = rec.get('valueField');
+ fn: function(component, record, index) {
+ var table = record.get('valueField');
// do not reload if the table selected has no deleted records - hide all records
- if (rec.get('records') <= 0) {
- gridDs.filter('uid', '-1'); // never true
+ if (record.get('records') <= 0) {
+ Recycler.MainStore.filter('uid', '-1'); // never true
return false;
}
- gridDs.setBaseParam('table', table);
- gridDs.load({
+ Recycler.MainStore.setBaseParam('table', table);
+ Recycler.MainStore.load({
params: {
start: 0
}
@@ -444,50 +494,27 @@
}
}
]
-
});
- gridDs.load();
+ Recycler.GridContainer.superclass.initComponent.apply(this, arguments);
+ Recycler.TableStore.load();
}
-};
+});
-
-Recycler.utility = {
- updatePageTree: function() {
- if (top && top.content && top.content.nav_frame && top.content.nav_frame.Tree) {
- top.content.nav_frame.Tree.refresh();
- }
+Recycler.App = {
+ /**
+ * Initializes the recycler
+ *
+ * @return void
+ **/
+ init: function() {
+ Recycler.Grid = new Recycler.GridContainer();
+ Recycler.MainStore.load();
}
};
-/* plugin for resize of grid in single container */
-Ext.namespace('Ext.ux.plugins');
-Ext.ux.plugins.FitToParent = Ext.extend(Object, {
- constructor : function(parent) {
- this.parent = parent;
- },
- init : function(c) {
- c.on('render', function(c) {
- c.fitToElement = Ext.get(this.parent
- || c.getPositionEl().dom.parentNode);
- if (!c.doLayout) {
- this.fitSizeToParent();
- Ext.EventManager.onWindowResize(this.fitSizeToParent, this);
- }
- }, this, {
- single : true
- });
- if (c.doLayout) {
- c.monitorResize = true;
- c.doLayout = c.doLayout.createInterceptor(this.fitSizeToParent);
- }
- },
- fitSizeToParent : function() {
- // Uses the dimension of the current viewport, but removes the document header
- // and an addtional margin of 40 pixels (e.g. Safari needs this addition)
-
- this.fitToElement.setHeight(document.viewport.getHeight() - this.fitToElement.getTop() - 40);
- var pos = this.getPosition(true), size = this.fitToElement.getViewSize();
- this.setSize(size.width - pos[0], size.height - pos[1]);
-
- }
+Ext.onReady(function(){
+ // disable loadindicator
+ Ext.UpdateManager.defaults.showLoadIndicator = false;
+ // fire recycler grid
+ Recycler.App.init();
});