Add `ContentLanguageFormField`
authorMatthias Schmidt <gravatronics@live.com>
Tue, 16 Apr 2019 16:54:45 +0000 (18:54 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Tue, 16 Apr 2019 16:54:45 +0000 (18:54 +0200)
See #2509

com.woltlab.wcf/templates/__contentLanguageFormField.tpl [new file with mode: 0644]
syncTemplates.json
wcfsetup/install/files/acp/templates/__contentLanguageFormField.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/header.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Language/Chooser.js
wcfsetup/install/files/lib/system/form/builder/field/language/ContentLanguageFormField.class.php [new file with mode: 0644]

diff --git a/com.woltlab.wcf/templates/__contentLanguageFormField.tpl b/com.woltlab.wcf/templates/__contentLanguageFormField.tpl
new file mode 100644 (file)
index 0000000..f26a83a
--- /dev/null
@@ -0,0 +1,36 @@
+{include file='__formFieldHeader'}
+
+<noscript>
+       <select name="{@$field->getPrefixedId()}" id="{@$field->getPrefixedId()}"{if $field->isImmutable()} disabled{/if}>
+               {if !$field->isRequired()}
+                       <option>{lang}wcf.global.language.noSelection{/lang}</option>
+               {/if}
+               {foreach from=$field->getContentLanguages() item=contentLanguage}
+                       <option value="{@$contentLanguage->languageID}">{$contentLanguage}</option>
+               {/foreach}
+       </select>
+</noscript>
+
+<script data-relocate="true">
+       require(['WoltLabSuite/Core/Language/Chooser', 'Dom/Traverse', 'Dom/Util'], function(LanguageChooser, DomTraverse, DomUtil) {
+               var languages = {
+                       {implode from=$field->getContentLanguages() item=contentLanguage}
+                               '{@$contentLanguage->languageID}': {
+                                       iconPath: '{@$contentLanguage->getIconPath()|encodeJS}',
+                                       languageName: '{@$contentLanguage|encodeJS}'
+                               }
+                       {/implode}
+               };
+               
+               LanguageChooser.init(
+                       DomUtil.identify(DomTraverse.childByTag(elById('{@$field->getPrefixedId()}Container'), 'DD')),
+                       '{@$field->getPrefixedId()}',
+                       {if $field->getValue()}{@$field->getValue()}{else}0{/if},
+                       languages,
+                       undefined,
+                       {if !$field->isRequired()}true{else}false{/if}
+               )
+       });
+</script>
+
+{include file='__formFieldFooter'}
index f1eb2bcb319a1e3499267dcc5faa488291484087..a8f71962cdd7485e87015a8407af18110d31fbf6 100644 (file)
@@ -6,6 +6,7 @@
   "templates": [
     "__aclFormField",
     "__booleanFormField",
+    "__contentLanguageFormField",
     "__dateFormField",
     "__devtoolsLanguageChooser",
     "__form",
diff --git a/wcfsetup/install/files/acp/templates/__contentLanguageFormField.tpl b/wcfsetup/install/files/acp/templates/__contentLanguageFormField.tpl
new file mode 100644 (file)
index 0000000..f26a83a
--- /dev/null
@@ -0,0 +1,36 @@
+{include file='__formFieldHeader'}
+
+<noscript>
+       <select name="{@$field->getPrefixedId()}" id="{@$field->getPrefixedId()}"{if $field->isImmutable()} disabled{/if}>
+               {if !$field->isRequired()}
+                       <option>{lang}wcf.global.language.noSelection{/lang}</option>
+               {/if}
+               {foreach from=$field->getContentLanguages() item=contentLanguage}
+                       <option value="{@$contentLanguage->languageID}">{$contentLanguage}</option>
+               {/foreach}
+       </select>
+</noscript>
+
+<script data-relocate="true">
+       require(['WoltLabSuite/Core/Language/Chooser', 'Dom/Traverse', 'Dom/Util'], function(LanguageChooser, DomTraverse, DomUtil) {
+               var languages = {
+                       {implode from=$field->getContentLanguages() item=contentLanguage}
+                               '{@$contentLanguage->languageID}': {
+                                       iconPath: '{@$contentLanguage->getIconPath()|encodeJS}',
+                                       languageName: '{@$contentLanguage|encodeJS}'
+                               }
+                       {/implode}
+               };
+               
+               LanguageChooser.init(
+                       DomUtil.identify(DomTraverse.childByTag(elById('{@$field->getPrefixedId()}Container'), 'DD')),
+                       '{@$field->getPrefixedId()}',
+                       {if $field->getValue()}{@$field->getValue()}{else}0{/if},
+                       languages,
+                       undefined,
+                       {if !$field->isRequired()}true{else}false{/if}
+               )
+       });
+</script>
+
+{include file='__formFieldFooter'}
index 3d6110024512fd4e517f466ef1c6fc945e5dd628..89432be481b499d497489f3f5b97412d9db3534f 100644 (file)
                                'wcf.global.form.error.lessThan': '{lang __literal=true}wcf.global.form.error.lessThan{/lang}',
                                'wcf.global.form.error.multilingual': '{lang}wcf.global.form.error.multilingual{/lang}',
                                'wcf.global.form.input.maxItems': '{lang}wcf.global.form.input.maxItems{/lang}',
+                               'wcf.global.language.noSelection': '{lang}wcf.global.language.noSelection{/lang}',
                                'wcf.global.loading': '{lang}wcf.global.loading{/lang}',
                                'wcf.global.noSelection': '{lang}wcf.global.noSelection{/lang}',
                                'wcf.global.select': '{lang}wcf.global.select{/lang}',
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage.js
new file mode 100644 (file)
index 0000000..5778849
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Data handler for a content language form builder field in an Ajax form.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2019 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage
+ * @since      5.2
+ */
+define(['Core', 'WoltLabSuite/Core/Language/Chooser', '../Value'], function(Core, LanguageChooser, FormBuilderFieldValue) {
+       "use strict";
+       
+       /**
+        * @constructor
+        */
+       function FormBuilderFieldContentLanguage(fieldId) {
+               this.init(fieldId);
+       };
+       Core.inherit(FormBuilderFieldContentLanguage, FormBuilderFieldValue, {
+               /**
+                * @see WoltLabSuite/Core/Form/Builder/Field/Field#destroy
+                */
+               destroy: function() {
+                       LanguageChooser.removeChooser(this._fieldId);
+               }
+       });
+       
+       return FormBuilderFieldContentLanguage;
+});
index eca57aae4bdbec4dda775a988f64e2d80c7a860a..a012d2528892d01ac5f03b66ab266b0b7a856825 100644 (file)
@@ -79,7 +79,10 @@ define(['Dictionary', 'Language', 'Dom/Traverse', 'Dom/Util', 'ObjectMap', 'Ui/S
                        if (element.parentNode.nodeName === 'DD') {
                                container = elCreate('div');
                                container.className = 'dropdown';
-                               element.parentNode.insertBefore(container, element);
+                               
+                               // language chooser is the first child so that descriptions and error messages
+                               // are always shown below the language chooser
+                               DomUtil.prepend(container, element.parentNode);
                        }
                        else {
                                container = element.parentNode;
diff --git a/wcfsetup/install/files/lib/system/form/builder/field/language/ContentLanguageFormField.class.php b/wcfsetup/install/files/lib/system/form/builder/field/language/ContentLanguageFormField.class.php
new file mode 100644 (file)
index 0000000..dd8e0f7
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+namespace wcf\system\form\builder\field\language;
+use wcf\system\form\builder\field\AbstractFormField;
+use wcf\system\form\builder\field\IImmutableFormField;
+use wcf\system\form\builder\field\TDefaultIdFormField;
+use wcf\system\form\builder\field\TImmutableFormField;
+use wcf\system\form\builder\field\validation\FormFieldValidationError;
+use wcf\system\language\LanguageFactory;
+
+/**
+ * Implementation of a form field for to select the language of a certain content.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2019 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Form\Builder\Field\Language
+ * @since      5.2
+ */
+class ContentLanguageFormField extends AbstractFormField implements IImmutableFormField {
+       use TDefaultIdFormField;
+       use TImmutableFormField;
+       
+       /**
+        * @inheritDoc
+        */
+       protected $javaScriptDataHandlerModule = 'WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage';
+       
+       /**
+        * @inheritDoc
+        */
+       protected $templateName = '__contentLanguageFormField';
+       
+       /**
+        * Creates a new instance of `ContentLanguageFormField`.
+        */
+       public function __construct() {
+               $this->label('wcf.user.language');
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getContentLanguages() {
+               return LanguageFactory::getInstance()->getContentLanguages();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function isAvailable() {
+               return LanguageFactory::getInstance()->multilingualismEnabled()
+                       && !empty(LanguageFactory::getInstance()->getContentLanguageIDs())
+                       && parent::isAvailable();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readValue() {
+               if ($this->getDocument()->hasRequestData($this->getPrefixedId())) {
+                       $this->value = intval($this->getDocument()->getRequestData($this->getPrefixedId()));
+                       
+                       if (!$this->isRequired() && !$this->value) {
+                               $this->value = null;
+                       }
+               }
+               
+               return $this;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validate() {
+               if ($this->isRequired() && LanguageFactory::getInstance()->getLanguage($this->getValue()) === null) {
+                       $this->addValidationError(new FormFieldValidationError(
+                               'invalidValue',
+                               'wcf.global.form.error.noValidSelection'
+                       ));
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected static function getDefaultId() {
+               return 'languageID';
+       }
+}