[TASK] Rebuild language selection list in lang module
authorKai Vogel <kai.vogel@speedprogs.de>
Sun, 2 Sep 2012 17:42:45 +0000 (19:42 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 11 Sep 2012 14:58:04 +0000 (16:58 +0200)
This patch replaces the language selection field in language module.

Change-Id: I52fd08df4bfd4687c65588cd3e479d08b48d68df
Resolves: #40430
Related: #39963
Releases: 6.0
Reviewed-on: http://review.typo3.org/14293
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/lang/Classes/Controller/LanguageController.php
typo3/sysext/lang/Classes/Domain/Model/LanguageSelectionForm.php
typo3/sysext/lang/Classes/ViewHelpers/Be/ContainerViewHelper.php [new file with mode: 0644]
typo3/sysext/lang/Classes/ViewHelpers/Be/FormEngineBasedCheckboxGroupViewHelper.php [new file with mode: 0644]
typo3/sysext/lang/Resources/Private/Layouts/Default.html
typo3/sysext/lang/Resources/Private/Partials/LanguageSelectionList.html
typo3/sysext/lang/Resources/Private/Partials/TranslationUpdateList.html
typo3/sysext/lang/Resources/Public/JavaScript/LangModule.js [new file with mode: 0644]
typo3/sysext/lang/Resources/Public/StyleSheet/LangModule.css [new file with mode: 0644]
typo3/sysext/lang/ext_tables.php

index d2a8522..a95ec39 100644 (file)
@@ -95,54 +95,39 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
        /**
         * Index action
         *
+        * @param \TYPO3\CMS\Lang\Domain\Model\LanguageSelectionForm $languageSelectionForm
+        * @param mixed $extensions Extensions to show in form
         * @return void
+        * @dontvalidate $languageSelectionForm
+        * @dontvalidate $extensions
         */
-       public function indexAction() {
-               $languages = $this->languageRepository->findAll();
-               $selectedLanguages = $this->languageRepository->findSelected();
-               $extensions = $this->extensionRepository->findAll();
-
-               if ($this->request->hasArgument('updateResult')) {
-                       $extensions = $this->mergeUpdateResult($extensions, $this->request->getArgument('updateResult'));
+       public function indexAction(\TYPO3\CMS\Lang\Domain\Model\LanguageSelectionForm $languageSelectionForm = NULL, $extensions = NULL) {
+               if ($languageSelectionForm === NULL) {
+                       $languageSelectionForm = $this->objectManager->create('TYPO3\\CMS\\Lang\\Domain\\Model\\LanguageSelectionForm');
+                       $languageSelectionForm->setLanguages($this->languageRepository->findAll());
+                       $languageSelectionForm->setSelectedLanguages($this->languageRepository->findSelected());
                }
 
-               $this->view->assign('languages', $languages);
-               $this->view->assign('selectedLanguages', $selectedLanguages);
-               $this->view->assign('extensions', $extensions);
-       }
-
-       /**
-        * Merge update results after translation update into extension models for rendering
-        *
-        * @param array $extensions
-        * @param array $updateResult
-        * @return array
-        */
-       protected function mergeUpdateResult(array $extensions, array $updateResult) {
-               foreach ($updateResult as $key => $messages) {
-                       $extensions[$key]->setUpdateResult($messages);
+               if (empty($extensions)) {
+                       $extensions = $this->extensionRepository->findAll();
                }
 
-               return $extensions;
+               $this->view->assign('languageSelectionForm', $languageSelectionForm);
+               $this->view->assign('extensions', $extensions);
        }
 
        /**
-        * Save selected locale(s)
+        * Update the language selection form
         *
-        * @param \TYPO3\CMS\Lang\Domain\Model\LanguageSelectionForm $form
+        * @param \TYPO3\CMS\Lang\Domain\Model\LanguageSelectionForm $languageSelectionForm
         * @return void
+        * @dontvalidate $languageSelectionForm
         */
-       public function saveSelectedLocaleAction(\TYPO3\CMS\Lang\Domain\Model\LanguageSelectionForm $form) {
-               $selectedLanguages = array();
-               foreach ($form->getLocale() as $locale => $value) {
-                       if ($value) {
-                               $selectedLanguages[] = $locale;
-                       }
+       public function updateLanguageSelectionAction(\TYPO3\CMS\Lang\Domain\Model\LanguageSelectionForm $languageSelectionForm) {
+               if ($languageSelectionForm !== NULL) {
+                       $this->languageRepository->updateSelectedLanguages($languageSelectionForm->getSelectedLanguages());
                }
-
-               $this->languageRepository->updateSelectedLanguages($selectedLanguages);
-
-               $this->forward('index');
+               $this->redirect('index');
        }
 
        /**
@@ -150,7 +135,7 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
         *
         * @return void
         */
-       protected function initializeUpdateTranslationAction() {
+       public function initializeUpdateTranslationAction() {
                $this->icons = array(
                        'ok' => \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-status-checked'),
                        'unavailable' => \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-info'),
@@ -159,19 +144,22 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
        }
 
        /**
-        * Update translation(s)
+        * Update translations
         *
-        * @param \TYPO3\CMS\Lang\Domain\Model\UpdateTranslationForm $form
         * @return void
         */
-       public function updateTranslationAction(\TYPO3\CMS\Lang\Domain\Model\UpdateTranslationForm $form) {
-               $result = array();
+       public function updateTranslationAction() {
+               $selectedLanguages = $this->languageRepository->findSelected();
+               $extensions = $this->extensionRepository->findAll();
+
+               if (empty($selectedLanguages)) {
+                       $this->forward('index');
+               }
 
                try {
-                       if (count($form->getSelectedLanguages())) {
-                               foreach ($form->getExtensions() as $extension) {
-                                       $result[$extension] = $this->checkTranslationForExtension($form->getSelectedLanguages(), $extension);
-                               }
+                       foreach ($extensions as $key => $extension) {
+                               $updateResult = $this->checkTranslationForExtension($selectedLanguages, $key);
+                               $extensions[$key]->setUpdateResult($updateResult);
                        }
                } catch (\Exception $exception) {
                        $flashMessage = $this->objectManager->create(
@@ -183,7 +171,7 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
                        \TYPO3\CMS\Core\Messaging\FlashMessageQueue::addMessage($flashMessage);
                }
 
-               $this->forward('index', NULL, NULL, array('updateResult' => $result));
+               $this->forward('index', NULL, NULL, array('extensions' => $extensions));
        }
 
        /**
@@ -193,7 +181,7 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
         * @param string $extensionKey
         * @return array
         */
-       public function checkTranslationForExtension($languages, $extensionKey) {
+       protected function checkTranslationForExtension($languages, $extensionKey) {
                $result = array();
 
                /** @var $terConnection \TYPO3\CMS\Lang\Utility\Connection\Ter */
@@ -201,24 +189,26 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
                $mirrorUrl = $this->repositoryHelper->getMirrors()->getMirrorUrl();
 
                $fetch = $terConnection->fetchTranslationStatus($extensionKey, $mirrorUrl);
-               foreach ($languages as $lang) {
-                       if (!isset($fetch[$lang])) {
+               foreach ($languages as $language) {
+                       $locale = $language->getLocale();
+
+                       if (!isset($fetch[$locale])) {
                                        // No translation available
-                               $result[$lang] = array(
+                               $result[$locale] = array(
                                        'icon' => $this->icons['unavailable'],
                                        'message' => 'translation_n_a'
                                );
                        } else {
-                               $zip = PATH_site . 'typo3temp' . DIRECTORY_SEPARATOR . $extensionKey . '-l10n-' . $lang . '.zip';
+                               $zip = PATH_site . 'typo3temp' . DIRECTORY_SEPARATOR . $extensionKey . '-l10n-' . $locale . '.zip';
                                $md5OfTranslationFile = '';
                                if (is_file($zip)) {
                                        $md5OfTranslationFile = md5_file($zip);
                                }
 
-                               if ($md5OfTranslationFile !== $fetch[$lang]['md5']) {
-                                       $update = $terConnection->updateTranslation($extensionKey, $lang, $mirrorUrl);
+                               if ($md5OfTranslationFile !== $fetch[$locale]['md5']) {
+                                       $update = $terConnection->updateTranslation($extensionKey, $locale, $mirrorUrl);
 
-                                       $result[$lang] = $update ?
+                                       $result[$locale] = $update ?
                                                array(
                                                        'icon' => $this->icons['ok'],
                                                        'message' => 'translation_msg_updated'
@@ -229,7 +219,7 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
                                                );
                                } else {
                                                // Translation is up to date
-                                       $result[$lang] = array(
+                                       $result[$locale] = array(
                                                'icon' => $this->icons['ok'],
                                                'message' => 'translation_status_uptodate'
                                        );
@@ -239,6 +229,6 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
 
                return $result;
        }
-}
 
+}
 ?>
\ No newline at end of file
index 2c35afe..9bed97d 100644 (file)
@@ -35,26 +35,50 @@ class LanguageSelectionForm extends \TYPO3\CMS\Extbase\DomainObject\AbstractEnti
        /**
         * @var array
         */
-       protected $locale = array();
+       protected $languages = array();
 
        /**
-        * Setter for the choosen locale
+        * @var array
+        */
+       protected $selectedLanguages = array();
+
+       /**
+        * Setter for the languages
         *
-        * @param array $locale all locale that were selected in the form
+        * @param array $locale Selected languages
         * @return void
         */
-       public function setLocale(array $locale) {
-               $this->locale = $locale;
+       public function setLanguages(array $languages) {
+               $this->languages = $languages;
        }
 
        /**
-        * Getter for the choosen locale
+        * Getter for the languages
         *
         * @return array
         */
-       public function getLocale() {
-               return $this->locale;
+       public function getLanguages() {
+               return $this->languages;
+       }
+
+       /**
+        * Setter for the selected languages
+        *
+        * @param array $locale Selected languages
+        * @return void
+        */
+       public function setSelectedLanguages(array $selectedLanguages) {
+               $this->selectedLanguages = $selectedLanguages;
        }
-}
 
+       /**
+        * Getter for the selected languages
+        *
+        * @return array
+        */
+       public function getSelectedLanguages() {
+               return $this->selectedLanguages;
+       }
+
+}
 ?>
\ No newline at end of file
diff --git a/typo3/sysext/lang/Classes/ViewHelpers/Be/ContainerViewHelper.php b/typo3/sysext/lang/Classes/ViewHelpers/Be/ContainerViewHelper.php
new file mode 100644 (file)
index 0000000..61a5305
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+namespace TYPO3\CMS\Lang\ViewHelpers\Be;
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Kai Vogel <kai.vogel@speedprogs.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * View helper which allows you to create extbase based modules in the style of TYPO3 default modules.
+ * Note: This feature is experimental!
+ *
+ * = Examples =
+ *
+ * <code title="Simple">
+ * <f:be.container>your module content</f:be.container>
+ * </code>
+ * <output>
+ * "your module content" wrapped with propper head & body tags.
+ * Default backend CSS styles and JavaScript will be included
+ * </output>
+ *
+ * <code title="All options">
+ * <f:be.container pageTitle="foo" enableJumpToUrl="false" enableClickMenu="false" loadPrototype="false" loadScriptaculous="false" loadJQuery="false" scriptaculousModule="someModule,someOtherModule" loadExtJs="true" loadExtJsTheme="false" extJsAdapter="jQuery" enableExtJsDebug="true" addCssFile="{f:uri.resource(path:'styles/backend.css')}" addJsFile="{f:uri.resource(path:'scripts/main.js')}">your module content</f:be.container>
+ * </code>
+ * <output>
+ * "your module content" wrapped with propper head & body tags.
+ * Custom CSS file EXT:your_extension/Resources/Public/styles/backend.css and JavaScript file EXT:your_extension/Resources/Public/scripts/main.js will be loaded
+ * </output>
+ */
+class ContainerViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper {
+
+       /**
+        * Render start page with template.php and pageTitle
+        *
+        * @param string  $pageTitle title tag of the module. Not required by default, as BE modules are shown in a frame
+        * @param boolean $enableJumpToUrl If TRUE, includes "jumpTpUrl" javascript function required by ActionMenu. Defaults to TRUE
+        * @param boolean $enableClickMenu If TRUE, loads clickmenu.js required by BE context menus. Defaults to TRUE
+        * @param boolean $loadPrototype specifies whether to load prototype library. Defaults to TRUE
+        * @param boolean $loadScriptaculous specifies whether to load scriptaculous libraries. Defaults to FALSE
+        * @param string  $scriptaculousModule additionales modules for scriptaculous
+        * @param boolean $loadExtJs specifies whether to load ExtJS library. Defaults to FALSE
+        * @param boolean $loadExtJsTheme whether to load ExtJS "grey" theme. Defaults to FALSE
+        * @param string  $extJsAdapter load alternative adapter (ext-base is default adapter)
+        * @param boolean $enableExtJsDebug if TRUE, debug version of ExtJS is loaded. Use this for development only
+        * @param boolean $loadJQuery whether to load jQuery library. Defaults to FALSE
+        * @param string $addCssFile Custom CSS file to be loaded
+        * @param string $addJsFile Custom JavaScript file to be loaded
+        * @return string
+        * @see template
+        * @see t3lib_PageRenderer
+        */
+       public function render($pageTitle = '', $enableJumpToUrl = TRUE, $enableClickMenu = TRUE, $loadPrototype = TRUE, $loadScriptaculous = FALSE, $scriptaculousModule = '', $loadExtJs = FALSE, $loadExtJsTheme = TRUE, $extJsAdapter = '', $enableExtJsDebug = FALSE, $loadJQuery = FALSE, $addCssFile = NULL, $addJsFile = NULL) {
+               $doc = $this->getDocInstance();
+               $pageRenderer = $doc->getPageRenderer();
+               if ($enableJumpToUrl) {
+                       $doc->JScode .= ('
+                               <script language="javascript" type="text/javascript">
+                                       script_ended = 0;
+                                       function jumpToUrl(URL) {
+                                               document.location = URL;
+                                       }
+                                       ' . $doc->redirectUrls()) . '
+                               </script>
+                       ';
+               }
+               if ($enableClickMenu) {
+                       $doc->loadJavascriptLib('js/clickmenu.js');
+               }
+               if ($loadPrototype) {
+                       $pageRenderer->loadPrototype();
+               }
+               if ($loadScriptaculous) {
+                       $pageRenderer->loadScriptaculous($scriptaculousModule);
+               }
+               if ($loadExtJs) {
+                       $pageRenderer->loadExtJS(true, $loadExtJsTheme, $extJsAdapter);
+                       if ($enableExtJsDebug) {
+                               $pageRenderer->enableExtJsDebug();
+                       }
+               }
+               if ($loadJQuery) {
+                       $pageRenderer->loadJquery();
+               }
+               if ($addCssFile !== NULL) {
+                       $pageRenderer->addCssFile($addCssFile);
+               }
+               if ($addJsFile !== NULL) {
+                       $pageRenderer->addJsFile($addJsFile);
+               }
+               $output = $this->renderChildren();
+               $output = $doc->startPage($pageTitle) . $output;
+               $output .= $doc->endPage();
+               return $output;
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/lang/Classes/ViewHelpers/Be/FormEngineBasedCheckboxGroupViewHelper.php b/typo3/sysext/lang/Classes/ViewHelpers/Be/FormEngineBasedCheckboxGroupViewHelper.php
new file mode 100644 (file)
index 0000000..f987d86
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+namespace TYPO3\CMS\Lang\ViewHelpers\Be;
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Kai Vogel <kai.vogel@speedprogs.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Checkbox group view helper
+ *
+ *
+ * Usage:
+ *
+ * {namespace myext=ENET\MyExt\ViewHelpers}
+ * <myext:be.formEngineBasedCheckboxGroup name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" value="{paymentOptions}" />
+ *
+ * or:
+ *
+ * <myext:be.formEngineBasedCheckboxGroup name="paymentOptions" options="{options}" optionValueField="id" optionLabelField="firstName" />
+ *
+ *
+ * @author Kai Vogel <kai.vogel@speedprogs.de>
+ * @package lang
+ * @subpackage ViewHelpers
+ */
+class FormEngineBasedCheckboxGroupViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\SelectViewHelper {
+
+       /**
+        * @var string
+        */
+       protected $tagName = 'div';
+
+       /**
+        * @var TYPO3\CMS\Extbase\Object\ObjectManager
+        */
+       protected $objectManager;
+
+       /**
+        * Injects the object manager
+        *
+        * @param TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
+        * @return void
+        */
+       public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManager $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+
+       /**
+        * Arguments initialization
+        *
+        * @return void
+        */
+       public function initializeArguments() {
+               parent::initializeArguments();
+               $this->registerArgument('optionIcon', 'string', 'If specified, will show the given icon in front of each option label.');
+       }
+
+       /**
+        * Render the field
+        *
+        * @return string Rendered field
+        */
+       public function render() {
+               if ($items === NULL) {
+                       $items = $this->renderChildren();
+               }
+
+               $formName = $this->viewHelperVariableContainer->get('TYPO3\\CMS\\Fluid\\ViewHelpers\\FormViewHelper', 'formObjectName');
+               $fieldName = $this->getName();
+               $content = $this->renderCheckboxGroupField($formName, $fieldName);
+               $this->tag->setContent($content);
+
+               return $this->tag->render();
+       }
+
+
+       /**
+        * Returns the HTML content for a checkbox group field
+        *
+        * @param string $formName Name of the form
+        * @param string $fieldName Name of the field
+        * @return string HTML content
+        */
+       protected function renderCheckboxGroupField($formName, $fieldName) {
+               if (empty($this->arguments['options'])) {
+                       return '';
+               }
+
+               $options = $this->getOptions();
+               if (empty($options)) {
+                       $options = array('' => '');
+               }
+
+               $icon = (!empty($this->arguments['optionIcon']) ? $this->arguments['optionIcon'] : '');
+               $items = array();
+               $checkedItems = array();
+
+               foreach($options as $value => $label) {
+                       $items[] = array($label, $value, $icon);
+                       if ($this->isChecked($value)) {
+                               $checkedItems[] = $value;
+                       }
+                               // Register the field name for each option for the token generation
+                       $this->registerFieldNameForFormTokenGeneration($fieldName . '[]');
+               }
+
+               $setup = array(
+                       'itemFormElValue' => implode(',', $checkedItems),
+                       'itemFormElName'  => $this->getName(),
+                       'fieldChangeFunc' => array(),
+               );
+
+                       // Render field with default form engine
+               $formEngine = $this->objectManager->create('TYPO3\CMS\Backend\Form\FormEngine');
+               $formEngine->formName = $formName;
+               $content = $formEngine->getSingleField_typeSelect_checkbox('', '', array(), $setup, array(), $items, '%s');
+               unset($formEngine);
+
+               return $content;
+       }
+
+       /**
+        * Check if an option is checked
+        *
+        * @param string $value Value to check
+        * @return boolean TRUE if the value is checked
+        */
+       protected function isChecked($value) {
+               $selectedValue = $this->getSelectedValue();
+               return (is_array($selectedValue) && in_array($value, $selectedValue));
+       }
+
+}
+?>
\ No newline at end of file
index 7ec8d1a..e5c4555 100644 (file)
@@ -1,4 +1,10 @@
-<f:be.container loadExtJs="1">
+{namespace lang=TYPO3\CMS\Lang\ViewHelpers}
+
+<lang:be.container
+       loadJQuery="1"
+       addCssFile="{f:uri.resource(path:'StyleSheet/LangModule.css')}"
+       addJsFile="{f:uri.resource(path:'JavaScript/LangModule.js')}"
+>
        <div class="typo3-fullDoc">
 
                <div id="typo3-docheader">
@@ -25,4 +31,4 @@
                </div>
 
        </div>
-</f:be.container>
\ No newline at end of file
+</lang:be.container>
\ No newline at end of file
index e572e44..5076026 100644 (file)
@@ -1,82 +1,12 @@
-<div id="ext-comp-1098" class=" x-panel x-panel-noborder x-box-item" style="width: 250px; left: 0px; top: 0px;">
-       <div class="x-panel-bwrap" id="ext-gen43">
-               <div class="x-panel-body x-panel-body-noheader x-panel-body-noborder" id="ext-gen44" style="width: 250px; height: 415px;">
-
-                       <div id="em-languagegrid" class="x-panel x-grid-panel" style="width: 250px;">
-                               <div class="x-panel-bwrap" id="ext-gen49">
-                                       <div class="x-panel-body x-panel-body-noheader" id="ext-gen50" style="width: 250px; height: 415px;">
-                                               <div class="x-grid3" hidefocus="true" id="ext-gen52" style="width: 250px; height: 415px;">
-                                                       <div class="x-grid3-viewport" id="ext-gen53">
-                                                               <div class="x-grid3-header" id="ext-gen54">
-                                                                       <div class="x-grid3-header-inner" id="ext-gen56" style="width: 250px;">
-                                                                               <div class="x-grid3-header-offset" style="width: 249px;">
-                                                                                       <table border="0" cellspacing="0" cellpadding="0" style="width: 232px;">
-                                                                                               <thead>
-                                                                                               <tr class="x-grid3-hd-row">
-                                                                                                       <td class="x-grid3-hd x-grid3-cell x-grid3-td-checker x-grid3-cell-first"
-                                                                                                               style="width: 20px;">
-                                                                                                               <div class="x-grid3-hd-inner x-grid3-hd-checker" unselectable="on" style="">
-                                                                                                                       <a class="x-grid3-hd-btn" href="#"></a><img alt="" class="x-grid3-sort-icon" src="clear.gif">
-                                                                                                               </div>
-                                                                                                       </td>
-                                                                                                       <td class="x-grid3-hd x-grid3-cell x-grid3-td-lang-label sort-asc"
-                                                                                                               style="width: 106px;">
-                                                                                                               <div class="x-grid3-hd-inner x-grid3-hd-lang-label" unselectable="on" style="">
-                                                                                                                       <a class="x-grid3-hd-btn" href="#"></a>Language<img alt="" class="x-grid3-sort-icon" src="clear.gif">
-                                                                                                               </div>
-                                                                                                       </td>
-                                                                                                       <td class="x-grid3-hd x-grid3-cell x-grid3-td-lang-key x-grid3-cell-last"
-                                                                                                               style="width: 106px;">
-                                                                                                               <div class="x-grid3-hd-inner x-grid3-hd-lang-key" unselectable="on" style="">
-                                                                                                                       <a class="x-grid3-hd-btn" href="#"></a>Short<img alt="" class="x-grid3-sort-icon" src="clear.gif">
-                                                                                                               </div>
-                                                                                                       </td>
-                                                                                               </tr>
-                                                                                               </thead>
-                                                                                       </table>
-                                                                               </div>
-                                                                       </div>
-                                                                       <div class="x-clear"></div>
-                                                               </div>
-                                                               <div class="x-grid3-scroller" id="ext-gen55" style="overflow-x: hidden; width: 250px; height: 390px;">
-                                                                       <div class="x-grid3-body" style="width: 232px; " id="ext-gen57">
-
-                                                                               <f:form action="saveSelectedLocale" name="form" object="{form}">
-                                                                                       <f:form.submit value="{f:translate(key:'button_save')}"/>
-                                                                                       <f:for each="{languages}" as="language" iteration="iteration">
-                                                                                               <div class="x-grid3-row x-grid3-row-first" style="width: 232px;">
-                                                                                                       <table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="width:232px;">
-                                                                                                               <tbody>
-                                                                                                               <tr>
-                                                                                                                       <td class="x-grid3-col x-grid3-cell x-grid3-td-checker x-grid3-cell-first " style="width: 20px;" tabindex="0">
-                                                                                                                               <f:form.checkbox name="form[locale][{language.locale}]" value="1" checked="{language.selected}"/>
-                                                                                                                       </td>
-                                                                                                                       <td class="x-grid3-col x-grid3-cell x-grid3-td-lang-label" style="width: 106px;" tabindex="0">
-                                                                                                                               <div class="x-grid3-cell-inner x-grid3-col-lang-label" unselectable="on">
-                                                                                                                                       <span class="">&nbsp;</span>{language.language}
-                                                                                                                               </div>
-                                                                                                                       </td>
-                                                                                                                       <td class="x-grid3-col x-grid3-cell x-grid3-td-lang-key x-grid3-cell-last" style="width: 106px;" tabindex="0">
-                                                                                                                               <div class="x-grid3-cell-inner x-grid3-col-lang-key" unselectable="on">{language.locale}
-                                                                                                                               </div>
-                                                                                                                       </td>
-                                                                                                               </tr>
-                                                                                                               </tbody>
-                                                                                                       </table>
-                                                                                               </div>
-                                                                                       </f:for>
-                                                                               </f:form>
-
-                                                                       </div>
-                                                                       <a href="#" class="x-grid3-focus" tabindex="-1" id="ext-gen58" style="left: 0px; top: 0px;"></a></div>
-                                                       </div>
-                                                       <div class="x-grid3-resize-marker" id="ext-gen59">&nbsp;</div>
-                                                       <div class="x-grid3-resize-proxy" id="ext-gen60">&nbsp;</div>
-                                               </div>
-                                       </div>
-                               </div>
-                       </div>
-
-               </div>
-       </div>
-</div>
\ No newline at end of file
+{namespace lang=TYPO3\CMS\Lang\ViewHelpers}
+
+<f:form action="updateLanguageSelection" name="languageSelectionForm" object="{languageSelectionForm}">
+       <lang:be.formEngineBasedCheckboxGroup
+               property="selectedLanguages"
+               options="{languageSelectionForm.languages}"
+               optionValueField="locale"
+               optionLabelField="language"
+               optionIcon="empty-empty"
+               class="languageSelection"
+       />
+</f:form>
\ No newline at end of file
index c6bca5e..59adcdf 100644 (file)
@@ -2,18 +2,7 @@
        <div class="x-panel-bwrap" id="ext-gen46">
                <div class="x-panel-body x-panel-body-noheader x-panel-body-noborder" id="ext-gen47" style="width: 1049px; height: 415px;">
 
-                       <f:form action="updateTranslation" name="form" object="{form}">
-                               <fieldset style="display: none;">
-                                       <f:for each="{selectedLanguages}" as="language">
-                                               <f:form.hidden name="form[selectedLanguages][]" value="{language.locale}"/>
-                                       </f:for>
-                               </fieldset>
-
-                               <fieldset style="display: none;">
-                                       <f:for each="{extensions}" as="extension">
-                                               <f:form.hidden name="form[extensions][]" value="{extension.key}"/>
-                                       </f:for>
-                               </fieldset>
+                       <f:form action="updateTranslation" name="form">
 
                                <fieldset id="ext-comp-1100" class=" x-fieldset x-form-label-left" style="width: 1029px;">
                                        <div class="x-fieldset-bwrap" id="ext-gen62">
@@ -74,7 +63,7 @@
                                                                                                                                                </div>
                                                                                                                                        </td>
 
-                                                                                                                                       <f:render partial="TranslationHeaders" arguments="{languages: languages}"/>
+                                                                                                                                       <f:render partial="TranslationHeaders" arguments="{languages: languageSelectionForm.languages}"/>
                                                                                                                                </tr>
                                                                                                                                </thead>
                                                                                                                        </table>
@@ -87,7 +76,7 @@
                                                                                                         style="width: 1029px; height: 337px;">
                                                                                                        <div class="x-grid3-body" style="width: 370px;" id="ext-gen79">
 
-                                                                                                               <f:render partial="ExtensionRow" arguments="{languages: languages, selectedLanguages: selectedLanguages, extensions: extensions}"/>
+                                                                                                               <f:render partial="ExtensionRow" arguments="{languages: languageSelectionForm.languages, selectedLanguages: languageSelectionForm.selectedLanguages, extensions: extensions}"/>
 
                                                                                                        </div>
                                                                                                        <a href="#" class="x-grid3-focus" tabindex="-1" id="ext-gen80" style="left: 0px; top: 0px;"></a></div>
diff --git a/typo3/sysext/lang/Resources/Public/JavaScript/LangModule.js b/typo3/sysext/lang/Resources/Public/JavaScript/LangModule.js
new file mode 100644 (file)
index 0000000..dabbbaf
--- /dev/null
@@ -0,0 +1,11 @@
+TYPO3.jQuery(document).ready(function($) {
+
+       /**
+        * Add click event handler to submit language selection form when choosing
+        * a new or remove an existing language
+        */
+       $('.languageSelection .c-checkbox, .languageSelection .c-labelCell').on('click', function(event) {
+               $('form[name="languageSelectionForm"]').submit();
+       });
+
+});
\ No newline at end of file
diff --git a/typo3/sysext/lang/Resources/Public/StyleSheet/LangModule.css b/typo3/sysext/lang/Resources/Public/StyleSheet/LangModule.css
new file mode 100644 (file)
index 0000000..0ee63cf
--- /dev/null
@@ -0,0 +1,91 @@
+/**
+ * Style definitions for the language selection field
+ */
+div.languageSelection table.typo3-TCEforms-select-checkbox {
+       margin-bottom: 10px;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tbody {
+       display: block;
+       height: 390px;
+       overflow-y: scroll;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr td {
+       vertical-align: middle;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr.c-header td,
+div.languageSelection table.typo3-TCEforms-select-checkbox tr td.c-checkbox,
+div.languageSelection table.typo3-TCEforms-select-checkbox tr td.c-labelCell {
+       padding: 1px 3px;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr td.c-labelCell {
+       width: 180px;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr td.c-labelCell img,
+div.languageSelection table.typo3-TCEforms-select-checkbox tr td.c-labelCell span {
+       margin-right: 5px;
+       max-width: 16px;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox td.c-descr {
+       width: 0px;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox td.c-descr img {
+       float: right;
+}
+
+div.languageSelection table.typo3-TCEforms-select-singlebox {
+       margin-bottom: 10px;
+       margin-top: 4px;
+}
+
+div.languageSelection span.t3-icon-edit-undo {
+       display: none;
+}
+
+div.languageSelection tr.c-header-checkbox-controls input.checkbox {
+       display: none;
+}
+
+div.languageSelection tr.c-header-checkbox-controls td {
+       padding: 0;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox {
+       background-color: #ffffff;
+       border: 1px solid #aaa;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr.c-header td {
+       background-color: #fff;
+       font-weight: bold;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr:nth-child(2n) {
+       background-color: #f7f7f7;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr.c-selectedItem {
+       background-color: #d8ecd0;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr.c-invalidItem {
+       color: #dddddd;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr:hover {
+       background-color: #dedede;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr.c-selectedItem:hover {
+       background-color: #abd99a;
+}
+
+div.languageSelection table.typo3-TCEforms-select-checkbox tr.c-invalidItem:hover {
+       background-color: transparent;
+}
\ No newline at end of file
index 86960b9..be32f47 100644 (file)
@@ -12,7 +12,7 @@ if (TYPO3_MODE == 'BE' && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) {
                'after:extensionmanager', // Position
                array(
                                // An array holding the controller-action-combinations that are accessible
-                       'Language' => 'index, saveSelectedLocale, updateTranslation'
+                       'Language' => 'index, updateLanguageSelection, updateTranslation'
                ),
                array(
                        'access' => 'admin',
@@ -22,4 +22,4 @@ if (TYPO3_MODE == 'BE' && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) {
        );
 }
 
-?>
\ No newline at end of file
+?>