diff --git a/administrator/components/com_banners/tmpl/banner/edit.php b/administrator/components/com_banners/tmpl/banner/edit.php index de5f921a6bce8..59eeca131a9ed 100644 --- a/administrator/components/com_banners/tmpl/banner/edit.php +++ b/administrator/components/com_banners/tmpl/banner/edit.php @@ -15,7 +15,6 @@ use Joomla\CMS\Router\Route; HTMLHelper::_('behavior.formvalidator'); -HTMLHelper::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); HTMLHelper::_('script', 'com_banners/admin-banner-edit.min.js', array('version' => 'auto', 'relative' => true)); ?> diff --git a/administrator/components/com_categories/Field/CategoryeditField.php b/administrator/components/com_categories/Field/CategoryeditField.php index 9e808139eabe4..5c6f3ec5be899 100644 --- a/administrator/components/com_categories/Field/CategoryeditField.php +++ b/administrator/components/com_categories/Field/CategoryeditField.php @@ -11,20 +11,18 @@ defined('JPATH_BASE') or die; +use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Language\Text; use Joomla\CMS\Factory; -use Joomla\CMS\Form\FormHelper; +use Joomla\CMS\Form\Field\ListField; use Joomla\CMS\HTML\HTMLHelper; -use Joomla\CMS\Language\Text; -use Joomla\Utilities\ArrayHelper; - -FormHelper::loadFieldClass('list'); /** * Category Edit field.. * * @since 1.6 */ -class CategoryeditField extends \JFormFieldList +class CategoryeditField extends ListField { /** * To allow creation of new categories. @@ -42,6 +40,14 @@ class CategoryeditField extends \JFormFieldList */ public $type = 'CategoryEdit'; + /** + * Name of the layout being used to render the field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $layout = 'joomla.form.field.categoryedit'; + /** * Method to attach a JForm object to the field. * @@ -340,88 +346,15 @@ protected function getOptions() */ protected function getInput() { - $html = array(); - $class = array(); - $attr = ''; - - // Initialize some field attributes. - $class[] = !empty($this->class) ? $this->class : ''; - - if ($this->allowAdd) - { - $customGroupText = Text::_('JGLOBAL_CUSTOM_CATEGORY'); - - $class[] = 'chosen-custom-value'; - $attr .= ' data-custom_group_text="' . $customGroupText . '" ' - . 'data-no_results_text="' . Text::_('JGLOBAL_ADD_CUSTOM_CATEGORY') . '" ' - . 'data-placeholder="' . Text::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" '; - } - - if ($class) - { - $attr .= 'class="' . implode(' ', $class) . '"'; - } - - $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; - $attr .= $this->multiple ? ' multiple' : ''; - $attr .= $this->required ? ' required' : ''; - $attr .= $this->autofocus ? ' autofocus' : ''; - - // To avoid user's confusion, readonly="true" should imply disabled="true". - if ((string) $this->readonly == '1' - || (string) $this->readonly == 'true' - || (string) $this->disabled == '1' - || (string) $this->disabled == 'true') - { - $attr .= ' disabled="disabled"'; - } - - // Initialize JavaScript field attributes. - $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; - - // Get the field options. - $options = (array) $this->getOptions(); + $data = $this->getLayoutData(); - // Create a read-only list (no name) with hidden input(s) to store the value(s). - if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') - { - $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); + $data['options'] = $this->getOptions(); + $data['allowCustom'] = $this->allowAdd; - // E.g. form field type tag sends $this->value as array - if ($this->multiple && is_array($this->value)) - { - if (!count($this->value)) - { - $this->value[] = ''; - } - - foreach ($this->value as $value) - { - $html[] = ''; - } - } - else - { - $html[] = ''; - } - } - else - { - // Create a regular list. - if (count($options) === 0) - { - // All Categories have been deleted, so we need a new category (This will create on save if selected). - $options[0] = new \stdClass; - $options[0]->value = 'Uncategorised'; - $options[0]->text = 'Uncategorised'; - $options[0]->level = '1'; - $options[0]->published = '1'; - $options[0]->lft = '1'; - } - - $html[] = HTMLHelper::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); - } + $renderer = $this->getRenderer($this->layout); + $renderer->setComponent('com_categories'); + $renderer->setClient(1); - return implode($html); + return $renderer->render($data); } } diff --git a/administrator/components/com_categories/categories.xml b/administrator/components/com_categories/categories.xml index f6e4aafc1006d..d6d0e6b240875 100644 --- a/administrator/components/com_categories/categories.xml +++ b/administrator/components/com_categories/categories.xml @@ -19,6 +19,7 @@ forms Helper helpers + layouts Model Table tmpl diff --git a/administrator/components/com_categories/forms/category.xml b/administrator/components/com_categories/forms/category.xml index c01c3eca4d512..61a5053e5c3b6 100644 --- a/administrator/components/com_categories/forms/category.xml +++ b/administrator/components/com_categories/forms/category.xml @@ -28,7 +28,6 @@ diff --git a/administrator/components/com_categories/forms/filter_categories.xml b/administrator/components/com_categories/forms/filter_categories.xml index 107c036081792..f0a10cf2e5826 100644 --- a/administrator/components/com_categories/forms/filter_categories.xml +++ b/administrator/components/com_categories/forms/filter_categories.xml @@ -44,6 +44,7 @@ type="tag" label="JOPTION_SELECT_TAG" mode="nested" + custom="false" onchange="this.form.submit();" > diff --git a/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php b/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php new file mode 100644 index 0000000000000..2067a97059795 --- /dev/null +++ b/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php @@ -0,0 +1,130 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + * @var string $accept File types that are accepted. + */ + +$html = array(); +$classes = array(); +$attr = ''; +$attr2 = ''; + +// Initialize some field attributes. +$attr .= !empty($size) ? ' size="' . $size . '"' : ''; +$attr .= $multiple ? ' multiple' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; + +// To avoid user's confusion, readonly="true" should imply disabled="disabled". +if ($readonly || $disabled) +{ + $attr .= ' disabled="disabled"'; +} + +$attr2 .= !empty($class) ? ' class="' . $class . '"' : ''; +$attr2 .= ' search-placeholder="' . $this->escape(Text::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY')) . '" '; + +if ($allowCustom) +{ + $attr2 .= ' allow-custom'; +} + +if ($required) +{ + $attr .= ' required class="required"'; + $attr2 .= ' required'; +} + +// Create a read-only list (no name) with hidden input(s) to store the value(s). +if ($readonly) +{ + $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $value, $id); + + // E.g. form field type tag sends $this->value as array + if ($multiple && is_array($value)) + { + if (!count($value)) + { + $value[] = ''; + } + + foreach ($value as $val) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } +} +else +{ + // Create a regular list. + if (count($options) === 0) + { + // All Categories have been deleted, so we need a new category (This will create on save if selected). + $options[0] = new \stdClass; + $options[0]->value = 'Uncategorised'; + $options[0]->text = 'Uncategorised'; + $options[0]->level = '1'; + $options[0]->published = '1'; + $options[0]->lft = '1'; + } + + $html[] = HTMLHelper::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); +} + +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +Factory::getDocument()->getWebAssetManager()->enableAsset('choicesjs'); +HTMLHelper::_('webcomponent', 'system/webcomponents/joomla-field-fancy-select.min.js', ['version' => 'auto', 'relative' => true]); + +?> + +> diff --git a/administrator/components/com_categories/tmpl/category/edit.php b/administrator/components/com_categories/tmpl/category/edit.php index 03299c2db3a83..7bfcc035e7748 100644 --- a/administrator/components/com_categories/tmpl/category/edit.php +++ b/administrator/components/com_categories/tmpl/category/edit.php @@ -18,7 +18,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/components/com_config/tmpl/component/default.php b/administrator/components/com_config/tmpl/component/default.php index 4407c6a039c56..8cf04a3bdf69d 100644 --- a/administrator/components/com_config/tmpl/component/default.php +++ b/administrator/components/com_config/tmpl/component/default.php @@ -27,7 +27,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); HTMLHelper::_('behavior.tabstate'); -HTMLHelper::_('formbehavior.chosen', '.chosen-custom-value', null, array('disable_search_threshold' => 0)); // @TODO delete this when custom elements modal is merged HTMLHelper::_('script', 'com_config/admin-application-default.min.js', ['version' => 'auto', 'relative' => true]); diff --git a/administrator/components/com_contact/tmpl/contact/edit.php b/administrator/components/com_contact/tmpl/contact/edit.php index d30065779db35..03b1eb91cd5e4 100644 --- a/administrator/components/com_contact/tmpl/contact/edit.php +++ b/administrator/components/com_contact/tmpl/contact/edit.php @@ -18,7 +18,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/components/com_content/forms/article.xml b/administrator/components/com_content/forms/article.xml index 44ba59e7560c6..15824972b0986 100644 --- a/administrator/components/com_content/forms/article.xml +++ b/administrator/components/com_content/forms/article.xml @@ -1,56 +1,55 @@
- - - - - - - - - - - - - - - - - - - - - - JYES - @@ -239,13 +237,13 @@
- @@ -269,7 +267,7 @@ - JHIDE - - -
@@ -577,7 +575,7 @@ label="JGLOBAL_LINKED_TITLES_LABEL" /> - - -
- @@ -715,7 +713,7 @@ type="media" label="COM_CONTENT_FIELD_INTRO_LABEL" /> - + COM_CONTENT_LEFT - - - COM_CONTENT_NONE - - - - - - JGLOBAL_NOINDEX_NOFOLLOW - - -
- - diff --git a/administrator/components/com_content/forms/filter_articles.xml b/administrator/components/com_content/forms/filter_articles.xml index 4c8b2c48daf0a..63061f4246747 100644 --- a/administrator/components/com_content/forms/filter_articles.xml +++ b/administrator/components/com_content/forms/filter_articles.xml @@ -33,8 +33,9 @@ type="category" label="JOPTION_SELECT_CATEGORY" multiple="true" - class="multipleCategories" extension="com_content" + layout="joomla.form.field.list-fancy-select" + hint="JOPTION_SELECT_CATEGORY" onchange="this.form.submit();" published="0,1,2" /> @@ -44,7 +45,8 @@ type="accesslevel" label="JOPTION_SELECT_ACCESS" multiple="true" - class="multipleAccessLevels" + layout="joomla.form.field.accesslevel-fancy-select" + hint="JOPTION_SELECT_ACCESS" onchange="this.form.submit();" /> @@ -52,7 +54,8 @@ name="author_id" type="author" multiple="true" - class="multipleAuthors" + layout="joomla.form.field.list-fancy-select" + hint="JOPTION_SELECT_AUTHOR" onchange="this.form.submit();" > @@ -72,8 +75,9 @@ name="tag" type="tag" multiple="true" - class="multipleTags" + hint="JOPTION_SELECT_TAG" mode="nested" + custom="false" onchange="this.form.submit();" /> diff --git a/administrator/components/com_content/forms/filter_featured.xml b/administrator/components/com_content/forms/filter_featured.xml index d4d977acb827e..08d235e492591 100644 --- a/administrator/components/com_content/forms/filter_featured.xml +++ b/administrator/components/com_content/forms/filter_featured.xml @@ -35,8 +35,9 @@ type="category" label="JOPTION_SELECT_CATEGORY" multiple="true" - class="multipleCategories" extension="com_content" + layout="joomla.form.field.list-fancy-select" + hint="JOPTION_SELECT_CATEGORY" onchange="this.form.submit();" /> @@ -45,7 +46,8 @@ type="accesslevel" label="JOPTION_SELECT_ACCESS" multiple="true" - class="multipleAccessLevels" + layout="joomla.form.field.accesslevel-fancy-select" + hint="JOPTION_SELECT_ACCESS" onchange="this.form.submit();" /> @@ -54,7 +56,8 @@ type="author" label="JOPTION_SELECT_AUTHOR" multiple="true" - class="multipleAuthors" + layout="joomla.form.field.list-fancy-select" + hint="JOPTION_SELECT_AUTHOR" onchange="this.form.submit();" > @@ -75,8 +78,9 @@ type="tag" labl="JOPTION_SELECT_TAG" multiple="true" - class="multipleTags" mode="nested" + custom="false" + hint="JOPTION_SELECT_TAG" onchange="this.form.submit();" /> diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index 005d69a5093d2..c3941a608862f 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -19,7 +19,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); $this->configFieldsets = array('editorConfig'); $this->hiddenFieldsets = array('basic-limited'); diff --git a/administrator/components/com_content/tmpl/articles/default.php b/administrator/components/com_content/tmpl/articles/default.php index cfb175c95a810..e96f63f3fa3e4 100644 --- a/administrator/components/com_content/tmpl/articles/default.php +++ b/administrator/components/com_content/tmpl/articles/default.php @@ -23,10 +23,6 @@ use Joomla\Component\Content\Administrator\Helper\ContentHelper; HTMLHelper::_('behavior.multiselect'); -HTMLHelper::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_TAG'))); -HTMLHelper::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_CATEGORY'))); -HTMLHelper::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_ACCESS'))); -HTMLHelper::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_AUTHOR'))); $app = Factory::getApplication(); $user = Factory::getUser(); diff --git a/administrator/components/com_content/tmpl/articles/modal.php b/administrator/components/com_content/tmpl/articles/modal.php index 27178f86549ae..7e47fa7970b09 100644 --- a/administrator/components/com_content/tmpl/articles/modal.php +++ b/administrator/components/com_content/tmpl/articles/modal.php @@ -30,10 +30,6 @@ HTMLHelper::_('script', 'com_content/admin-articles-modal.min.js', array('version' => 'auto', 'relative' => true)); HTMLHelper::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); HTMLHelper::_('behavior.multiselect'); -HTMLHelper::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_TAG'))); -HTMLHelper::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_CATEGORY'))); -HTMLHelper::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_ACCESS'))); -HTMLHelper::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_AUTHOR'))); $function = $app->input->getCmd('function', 'jSelectArticle'); $editor = $app->input->getCmd('editor', ''); diff --git a/administrator/components/com_content/tmpl/featured/default.php b/administrator/components/com_content/tmpl/featured/default.php index efbfd6d8049ef..f357fc2222fb6 100644 --- a/administrator/components/com_content/tmpl/featured/default.php +++ b/administrator/components/com_content/tmpl/featured/default.php @@ -20,10 +20,6 @@ use Joomla\Component\Content\Administrator\Helper\ContentHelper; HTMLHelper::_('behavior.multiselect'); -HTMLHelper::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_ACCESS'))); -HTMLHelper::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_AUTHOR'))); -HTMLHelper::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_CATEGORY'))); -HTMLHelper::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_TAG'))); $user = Factory::getUser(); $userId = $user->get('id'); diff --git a/administrator/components/com_fields/Helper/FieldsHelper.php b/administrator/components/com_fields/Helper/FieldsHelper.php index 9c40d4e13ecf0..dbca7b70643f9 100644 --- a/administrator/components/com_fields/Helper/FieldsHelper.php +++ b/administrator/components/com_fields/Helper/FieldsHelper.php @@ -312,7 +312,10 @@ public static function prepareForm($context, Form $form, $data) // Choose the first category available $xml = new \DOMDocument; + libxml_use_internal_errors(true); $xml->loadHTML($formField->__get('input')); + libxml_clear_errors(); + libxml_use_internal_errors(false); $options = $xml->getElementsByTagName('option'); if (!$assignedCatids && $firstChoice = $options->item(0)) diff --git a/administrator/components/com_fields/forms/field.xml b/administrator/components/com_fields/forms/field.xml index ecf46ab464525..17906b556b1d9 100644 --- a/administrator/components/com_fields/forms/field.xml +++ b/administrator/components/com_fields/forms/field.xml @@ -31,7 +31,7 @@ 0 )); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/components/com_fields/tmpl/field/modal.php b/administrator/components/com_fields/tmpl/field/modal.php index 23970f554bf80..6ab9a96aab686 100644 --- a/administrator/components/com_fields/tmpl/field/modal.php +++ b/administrator/components/com_fields/tmpl/field/modal.php @@ -16,7 +16,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/components/com_fields/tmpl/fields/default_batch_body.php b/administrator/components/com_fields/tmpl/fields/default_batch_body.php index 6060fa285541e..b2be9c0cafde4 100644 --- a/administrator/components/com_fields/tmpl/fields/default_batch_body.php +++ b/administrator/components/com_fields/tmpl/fields/default_batch_body.php @@ -12,8 +12,6 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; -HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); - HTMLHelper::_('script', 'com_fields/admin-fields-default-batch.js', ['version' => 'auto', 'relative' => true]); $context = $this->escape($this->state->get('filter.context')); diff --git a/administrator/components/com_fields/tmpl/fields/modal.php b/administrator/components/com_fields/tmpl/fields/modal.php index 0aa6a68b17178..25fc4a5c18519 100644 --- a/administrator/components/com_fields/tmpl/fields/modal.php +++ b/administrator/components/com_fields/tmpl/fields/modal.php @@ -21,7 +21,6 @@ } HTMLHelper::_('behavior.core'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); HTMLHelper::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); HTMLHelper::_('script', 'com_fields/admin-fields-modal.js', array('version' => 'auto', 'relative' => true)); diff --git a/administrator/components/com_fields/tmpl/group/edit.php b/administrator/components/com_fields/tmpl/group/edit.php index 4b78214cb0904..f296629836839 100644 --- a/administrator/components/com_fields/tmpl/group/edit.php +++ b/administrator/components/com_fields/tmpl/group/edit.php @@ -17,7 +17,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); HTMLHelper::_('behavior.tabstate'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/components/com_fields/tmpl/groups/default.php b/administrator/components/com_fields/tmpl/groups/default.php index 43a42fc03a2e3..01588a65bdc99 100644 --- a/administrator/components/com_fields/tmpl/groups/default.php +++ b/administrator/components/com_fields/tmpl/groups/default.php @@ -18,7 +18,6 @@ use Joomla\Component\Fields\Administrator\Helper\FieldsHelper; HTMLHelper::_('behavior.multiselect'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); $app = Factory::getApplication(); $user = Factory::getUser(); diff --git a/administrator/components/com_fields/tmpl/groups/default_batch_body.php b/administrator/components/com_fields/tmpl/groups/default_batch_body.php index 55f3bec2c8dec..3d5d20ebed07c 100644 --- a/administrator/components/com_fields/tmpl/groups/default_batch_body.php +++ b/administrator/components/com_fields/tmpl/groups/default_batch_body.php @@ -11,7 +11,6 @@ use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Layout\LayoutHelper; -HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); ?>
diff --git a/administrator/components/com_modules/Field/ModulesPositionField.php b/administrator/components/com_modules/Field/ModulesPositionField.php index c31aaf39306c4..1207d748f1d62 100644 --- a/administrator/components/com_modules/Field/ModulesPositionField.php +++ b/administrator/components/com_modules/Field/ModulesPositionField.php @@ -12,17 +12,15 @@ defined('JPATH_BASE') or die; use Joomla\CMS\Factory; -use Joomla\CMS\Form\FormHelper; +use Joomla\CMS\Form\Field\ListField; use Joomla\Component\Modules\Administrator\Helper\ModulesHelper; -FormHelper::loadFieldClass('list'); - /** * Modules Position field. * * @since 3.4.2 */ -class ModulesPositionField extends \JFormFieldList +class ModulesPositionField extends ListField { /** * The form field type. diff --git a/administrator/components/com_modules/Field/ModulesPositioneditField.php b/administrator/components/com_modules/Field/ModulesPositioneditField.php new file mode 100644 index 0000000000000..7688cbe806e50 --- /dev/null +++ b/administrator/components/com_modules/Field/ModulesPositioneditField.php @@ -0,0 +1,64 @@ +getLayoutData(); + + $clientId = Factory::getApplication()->input->get('client_id', 0, 'int'); + $positions = HTMLHelper::_('modules.positions', $clientId, 1, $this->value); + + $data['client'] = $clientId; + $data['positions'] = $positions; + + $renderer = $this->getRenderer($this->layout); + $renderer->setComponent('com_modules'); + $renderer->setClient(1); + + return $renderer->render($data); + } +} diff --git a/administrator/components/com_modules/Helper/ModulesHelper.php b/administrator/components/com_modules/Helper/ModulesHelper.php index 4cc87de546d39..45b2788c45ce1 100644 --- a/administrator/components/com_modules/Helper/ModulesHelper.php +++ b/administrator/components/com_modules/Helper/ModulesHelper.php @@ -107,6 +107,10 @@ public static function getPositions($clientId, $editPositions = false) { $options[] = HTMLHelper::_('select.option', 'none', Text::_('COM_MODULES_NONE')); } + elseif (!$position) + { + $options[] = HTMLHelper::_('select.option', '', Text::_('COM_MODULES_NONE')); + } else { $options[] = HTMLHelper::_('select.option', $position, $position); diff --git a/administrator/components/com_modules/Service/HTML/Modules.php b/administrator/components/com_modules/Service/HTML/Modules.php index e9b003dbbcb58..3264eeb62e4ad 100644 --- a/administrator/components/com_modules/Service/HTML/Modules.php +++ b/administrator/components/com_modules/Service/HTML/Modules.php @@ -148,7 +148,7 @@ public function positions($clientId, $state = 1, $selectedPosition = '') $templateGroups = array(); // Add an empty value to be able to deselect a module position - $option = ModulesHelper::createOption(); + $option = ModulesHelper::createOption('', Text::_('COM_MODULES_NONE')); $templateGroups[''] = ModulesHelper::createOptionGroup('', array($option)); // Add positions from templates @@ -181,8 +181,7 @@ public function positions($clientId, $state = 1, $selectedPosition = '') // Add custom position to options $customGroupText = Text::_('COM_MODULES_CUSTOM_POSITION'); - - $editPositions = true; + $editPositions = true; $customPositions = ModulesHelper::getPositions($clientId, $editPositions); $templateGroups[$customGroupText] = ModulesHelper::createOptionGroup($customGroupText, $customPositions); diff --git a/administrator/components/com_modules/View/Modules/HtmlView.php b/administrator/components/com_modules/View/Modules/HtmlView.php index 4157b75d64944..23477545d91d8 100644 --- a/administrator/components/com_modules/View/Modules/HtmlView.php +++ b/administrator/components/com_modules/View/Modules/HtmlView.php @@ -184,7 +184,6 @@ protected function addToolbar() if ($user->authorise('core.create', 'com_modules') && $user->authorise('core.edit', 'com_modules') && $user->authorise('core.edit.state', 'com_modules')) { - HTMLHelper::_('bootstrap.renderModal', 'collapseModal'); $title = Text::_('JTOOLBAR_BATCH'); // Instantiate a new FileLayout instance and render the batch button diff --git a/administrator/components/com_modules/forms/module.xml b/administrator/components/com_modules/forms/module.xml index 7a80a3a3cc298..145de7d805e96 100644 --- a/administrator/components/com_modules/forms/module.xml +++ b/administrator/components/com_modules/forms/module.xml @@ -1,16 +1,16 @@ -
- + - - - - - - - - - - - - - section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + * @var string $accept File types that are accepted. + * @var array $positions Array of the positions + */ + +$attributes = array( + 'class="' . $class . '"', + ' allow-custom', + ' search-placeholder="' . $this->escape(Text::_('JGLOBAL_TYPE_OR_SELECT_SOME_OPTIONS')) . '" ', +); + +$selectAttr = array( + $disabled ? 'disabled' : '', + $readonly ? 'readonly' : '', + strlen($hint) ? 'placeholder="' . $this->escape($hint) . '"' : '', + $onchange ? ' onchange="' . $onchange . '"' : '', + $autofocus ? ' autofocus' : '', +); + +if ($required) +{ + $selectAttr[] = ' required class="required"'; + $attributes[] = ' required'; +} + +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +Factory::getDocument()->getWebAssetManager()->enableAsset('choicesjs'); +HTMLHelper::_('webcomponent', 'system/webcomponents/joomla-field-fancy-select.min.js', ['version' => 'auto', 'relative' => true]); + +?> +> $id, + 'list.select' => $value, + 'list.attr' => implode(' ', $selectAttr), + ) + ); +?> + diff --git a/administrator/components/com_modules/tmpl/module/edit.php b/administrator/components/com_modules/tmpl/module/edit.php index 237f388907f1b..f59d494ceb967 100644 --- a/administrator/components/com_modules/tmpl/module/edit.php +++ b/administrator/components/com_modules/tmpl/module/edit.php @@ -19,8 +19,6 @@ HTMLHelper::_('behavior.combobox'); HTMLHelper::_('behavior.keepalive'); HTMLHelper::_('behavior.tabstate'); -HTMLHelper::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_CATEGORY'))); -HTMLHelper::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_TAG'))); $hasContent = empty($this->item->module) || isset($this->item->xml->customContent); $hasContentFieldName = 'content'; @@ -49,6 +47,7 @@ $isModal = $input->get('layout') == 'modal' ? true : false; $layout = $isModal ? 'modal' : 'edit'; $tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; + ?> @@ -139,7 +138,7 @@ form->getLabel('position'); ?>
- loadTemplate('positions'); ?> + form->getInput('position'); ?>
diff --git a/administrator/components/com_modules/tmpl/module/edit_positions.php b/administrator/components/com_modules/tmpl/module/edit_positions.php deleted file mode 100644 index c1ddf7094a8a2..0000000000000 --- a/administrator/components/com_modules/tmpl/module/edit_positions.php +++ /dev/null @@ -1,32 +0,0 @@ -item->client_id; -$state = 1; -$selectedPosition = $this->item->position; -$positions = HTMLHelper::_('modules.positions', $clientId, $state, $selectedPosition); - -// Add custom position to options -$customGroupText = Text::_('COM_MODULES_CUSTOM_POSITION'); - -// Build field -$attr = array( - 'id' => 'jform_position', - 'list.select' => $this->item->position, - 'list.attr' => 'class="chosen-custom-value"', -); - -JHtml::_('formbehavior.chosen', '#jform_position'); - -echo HTMLHelper::_('select.groupedlist', $positions, 'jform[position]', $attr); diff --git a/administrator/components/com_modules/tmpl/modules/default_batch_body.php b/administrator/components/com_modules/tmpl/modules/default_batch_body.php index e305603b59b4b..2ccf347aefb5c 100644 --- a/administrator/components/com_modules/tmpl/modules/default_batch_body.php +++ b/administrator/components/com_modules/tmpl/modules/default_batch_body.php @@ -9,6 +9,7 @@ defined('_JEXEC') or die; +use Joomla\CMS\Factory; use Joomla\CMS\Helper\ModuleHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; @@ -23,19 +24,17 @@ $positions['']['items'][] = ModulesHelper::createOption('nochange', Text::_('COM_MODULES_BATCH_POSITION_NOCHANGE')); $positions['']['items'][] = ModulesHelper::createOption('noposition', Text::_('COM_MODULES_BATCH_POSITION_NOPOSITION')); -// Add custom position to options -$customGroupText = Text::_('COM_MODULES_CUSTOM_POSITION'); - // Build field $attr = array( - 'id' => 'batch-position-id', - 'list.attr' => 'class="chosen-custom-value" ' - . 'data-custom_group_text="' . $customGroupText . '" ' - . 'data-no_results_text="' . Text::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' - . 'data-placeholder="' . Text::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ' + 'id' => 'batch-position-id', ); -HTMLHelper::_('formbehavior.chosen', '.chosen-custom-value'); +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +Factory::getDocument()->getWebAssetManager()->enableAsset('choicesjs'); +HTMLHelper::_('webcomponent', 'system/webcomponents/joomla-field-fancy-select.min.js', ['version' => 'auto', 'relative' => true]); + ?>

@@ -74,7 +73,9 @@
+ +
diff --git a/administrator/components/com_newsfeeds/tmpl/newsfeed/edit.php b/administrator/components/com_newsfeeds/tmpl/newsfeed/edit.php index 88e9f25884d13..a8be9822cfa37 100644 --- a/administrator/components/com_newsfeeds/tmpl/newsfeed/edit.php +++ b/administrator/components/com_newsfeeds/tmpl/newsfeed/edit.php @@ -18,7 +18,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/components/com_workflow/tmpl/stage/edit.php b/administrator/components/com_workflow/tmpl/stage/edit.php index c2321caf0f636..f4e04d263c138 100644 --- a/administrator/components/com_workflow/tmpl/stage/edit.php +++ b/administrator/components/com_workflow/tmpl/stage/edit.php @@ -17,7 +17,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect', null, array('disable_search_threshold' => 0)); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/components/com_workflow/tmpl/transition/edit.php b/administrator/components/com_workflow/tmpl/transition/edit.php index ff79170b8d53b..81a0a64823596 100644 --- a/administrator/components/com_workflow/tmpl/transition/edit.php +++ b/administrator/components/com_workflow/tmpl/transition/edit.php @@ -16,7 +16,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect', null, array('disable_search_threshold' => 0 )); // In case of modal $isModal = $this->input->get('layout') == 'modal' ? true : false; diff --git a/administrator/components/com_workflow/tmpl/workflow/edit.php b/administrator/components/com_workflow/tmpl/workflow/edit.php index d2ba332f8f593..b9be3e3048d80 100644 --- a/administrator/components/com_workflow/tmpl/workflow/edit.php +++ b/administrator/components/com_workflow/tmpl/workflow/edit.php @@ -17,7 +17,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('formbehavior.chosen', '.advancedSelect', null, array('disable_search_threshold' => 0 )); $app = Factory::getApplication(); $input = $app->input; diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini index 1d2efed5c8e5a..cf780aa91a6bf 100644 --- a/administrator/language/en-GB/en-GB.ini +++ b/administrator/language/en-GB/en-GB.ini @@ -523,6 +523,7 @@ JGLOBAL_SEF_NOIDS_LABEL="Remove IDs from URLs" JGLOBAL_SELECT_ALLOW_DENY_GROUP="Change %s permission for %s group." JGLOBAL_SELECT_AN_OPTION="Select an option" JGLOBAL_SELECT_NO_RESULTS_MATCH="No results match" +JGLOBAL_SELECT_PRESS_TO_SELECT="Press to select" JGLOBAL_SELECT_SOME_OPTIONS="Select some options" JGLOBAL_SELECTION_ALL="Select All" JGLOBAL_SELECTION_INVERT="Toggle Selection" diff --git a/administrator/templates/atum/scss/template.scss b/administrator/templates/atum/scss/template.scss index e7ddc12fa3edf..544f3ee9e5403 100644 --- a/administrator/templates/atum/scss/template.scss +++ b/administrator/templates/atum/scss/template.scss @@ -47,6 +47,7 @@ @import "vendor/bootstrap/pagination"; @import "vendor/bootstrap/table"; @import "vendor/chosen"; +@import "vendor/choicesjs"; @import "vendor/dragula"; @import "vendor/minicolors"; @import "vendor/tinymce"; diff --git a/administrator/templates/atum/scss/vendor/_choicesjs.scss b/administrator/templates/atum/scss/vendor/_choicesjs.scss new file mode 100644 index 0000000000000..4a6138a566d26 --- /dev/null +++ b/administrator/templates/atum/scss/vendor/_choicesjs.scss @@ -0,0 +1,82 @@ +// choices.js + +// Fix position +.choices__list--dropdown { + z-index: 10; +} + +// Fix close button +.choices__button_joomla { + position: relative; + text-indent: -9999px; + cursor: pointer; + background: none; + border: 0; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + + &::before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: block; + text-align: center; + text-indent: 0; + content: "\00d7"; + } + + &:focus { + outline: none; + } +} + +.choices[data-type*="select-one"] { + .choices__button_joomla { + position: absolute; + top: 50%; + right: 0; + width: 20px; + height: 20px; + padding: 0; + margin-top: -10px; + margin-right: 25px; + border-radius: 10em; + opacity: .5; + &:hover, &:focus { opacity: 1; } + &:focus { box-shadow: 0 0 0 2px #00bcd4; } + } + + &[dir="rtl"] { + .choices__button_joomla { + right: auto; + left: 0; + margin-right: 0; + margin-left: 25px; + } + } +} + +.choices[data-type*="select-multiple"], +.choices[data-type*="text"] { + .choices__button_joomla { + position: relative; + display: inline-block; + width: 8px; + padding-left: 16px; + margin-top: 0; + margin-right: -4px; + margin-bottom: 0; + margin-left: 8px; + line-height: 1; + border-left: 1px solid #008fa1; + opacity: .75; + &:hover, &:focus { opacity: 1; } + &::before { + color: #fff; + } + } +} + diff --git a/build/build-modules-js/settings.json b/build/build-modules-js/settings.json index ab0c719c7581d..bd6d67ad46708 100644 --- a/build/build-modules-js/settings.json +++ b/build/build-modules-js/settings.json @@ -14,6 +14,7 @@ "field-simple-color", "field-send-test-mail", "field-subform", + "field-fancy-select", "editor-codemirror", "hidden-mail", "editor-none", @@ -55,6 +56,9 @@ "field-subform": { "css": "media/system/webcomponents/css", "js": "media/system/webcomponents/js" + }, + "field-fancy-select": { + "js": "media/system/webcomponents/js" } }, "vendors": { @@ -151,6 +155,26 @@ "dependencies": [], "licenseFilename": "LICENSE" }, + "choices.js": { + "name": "choicesjs", + "js": { + "assets/scripts/dist/choices.js": "js/choices.js", + "assets/scripts/dist/choices.min.js": "js/choices.min.js" + }, + "css": { + "assets/styles/css/choices.css": "css/choices.css", + "assets/styles/css/choices.min.css": "css/choices.min.css" + }, + "provideAssets": [ + { + "name": null, + "js": ["choices.min.js"], + "css": ["choices.min.css"] + } + ], + "dependencies": [], + "licenseFilename": "LICENSE" + }, "diff": { "name": "diff", "js": { diff --git a/build/media/webcomponents/js/field-fancy-select/field-fancy-select.js b/build/media/webcomponents/js/field-fancy-select/field-fancy-select.js new file mode 100644 index 0000000000000..e35a5ad3e33c5 --- /dev/null +++ b/build/media/webcomponents/js/field-fancy-select/field-fancy-select.js @@ -0,0 +1,180 @@ +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/** + * Fancy select field, which use Choices.js + * + * Example: + * + * + * + * + * Possible attributes: + * + * allow-custom Whether allow User to dynamically add a new value. + * new-item-prefix="" Prefix for a dynamically added value. + * + * remote-search Enable remote search. + * url="" Url for remote search. + * term-key="term" Variable key name for searched term, will be appended to Url. + * + * min-term-length="1" The minimum length a search value should be before choices are searched. + * placeholder="" The value of the inputs placeholder. + * search-placeholder="" The value of the search inputs placeholder. + */ +;(function(customElements){ + "use strict"; + + class JoomlaFieldFancySelect extends HTMLElement { + + // Properties getters/setters + get allowCustom() { return this.hasAttribute('allow-custom'); } + get remoteSearch() { return this.hasAttribute('remote-search'); } + get url() { return this.getAttribute('url'); } + get termKey() { return this.getAttribute('term-key') || 'term'; } + get minTermLength() { return parseInt(this.getAttribute('min-term-length')) || 1; } + get newItemPrefix() { return this.getAttribute('new-item-prefix') || ''; } + get placeholder() { return this.getAttribute('placeholder'); } + get searchPlaceholder() { return this.getAttribute('search-placeholder'); } + get value() { return this.choicesInstance.getValue(true); } + set value($val) { this.choicesInstance.setValueByChoice('' + $val); } + + connectedCallback() { + if (!window.Choices) { + throw new Error('JoomlaFieldFancySelect require Choices.js to work'); + } + + // Get a element to work'); + } + + // Init Choices + this.choicesInstance = new Choices(this.select, { + placeholderValue: this.placeholder, + searchPlaceholderValue: this.searchPlaceholder, + removeItemButton: true, + searchFloor: this.minTermLength, + searchResultLimit: 10, + shouldSort: false, + fuseOptions: { + threshold: 0.3 // Strict search + }, + noResultsText: Joomla.Text._('JGLOBAL_SELECT_NO_RESULTS_MATCH', 'No results found'), + noChoicesText: Joomla.Text._('JGLOBAL_SELECT_NO_RESULTS_MATCH', 'No results found'), + itemSelectText: Joomla.Text._('JGLOBAL_SELECT_PRESS_TO_SELECT', 'Press to select'), + + // Redefine some classes + classNames: { + button: 'choices__button_joomla' // It is need because an original styling use unavailable Icon.svg file + } + }); + + // Collect an existing values, to avoid duplications + this.choicesCache = {}; + + // Handle typing of custom term + if (this.allowCustom) { + this.addEventListener('keydown', (event) => { + if (event.keyCode !== 13 || event.target !== this.choicesInstance.input) return; + event.preventDefault(); + + if (this.choicesInstance.highlightPosition + || !event.target.value || this.choicesCache[event.target.value]) return; + + // Make sure nothing is highlighted + const highlighted = this.choicesInstance.dropdown.querySelector('.' + this.choicesInstance.config.classNames.highlightedState); + if (highlighted) return; + + this.choicesInstance.setChoices([{ + value: this.newItemPrefix + event.target.value, + label: event.target.value, + selected: true, + customProperties: { + value: event.target.value // Store real value, just in case + } + }], 'value', 'label', false); + + this.choicesCache[event.target.value] = event.target.value; + + event.target.value = null; + this.choicesInstance.hideDropdown(); + + return false; + }); + } + + // Handle remote search + if (this.remoteSearch && this.url) { + // Cache existing + this.choicesInstance.presetChoices.forEach((choiceItem) => { + this.choicesCache[choiceItem.value] = choiceItem.label; + }); + + const lookupDelay = 300; + let lookupTimeout = null; + this.activeXHR = null; + this.select.addEventListener('search', (event) => { + clearTimeout(lookupTimeout); + lookupTimeout = setTimeout(this.requestLookup.bind(this), lookupDelay); + }); + } + } + + disconnectedCallback() { + // Destroy Choices instance, to unbind an event listeners + if (this.choicesInstance) { + this.choicesInstance.destroy(); + this.choicesInstance = null; + } + if (this.activeXHR){ + this.activeXHR.abort(); + this.activeXHR = null; + } + } + + requestLookup() { + let url = this.url; + url += (url.indexOf('?') === -1 ? '?' : '&'); + url += encodeURIComponent(this.termKey) + '=' + encodeURIComponent(this.choicesInstance.input.value); + + // Stop previous request if any + if (this.activeXHR){ + this.activeXHR.abort(); + } + + this.activeXHR = Joomla.request({ + url: url, + onSuccess: (response, xhr) => { + this.activeXHR = null; + const items = response ? JSON.parse(response) : []; + if (!items.length) return; + + // Remove duplications + let item; + for(let i = items.length - 1; i >= 0; i--) { + item = items[i]; + if (this.choicesCache[item.value]) { + items.splice(i, 1); + } + } + + // Add new options to field, assume that each item is object, eg {value: "foo", text: "bar"} + if (items.length) { + this.choicesInstance.setChoices(items, 'value', 'text', false); + } + }, + onError: () => { + this.activeXHR = null; + } + }); + } + } + + customElements.define('joomla-field-fancy-select', JoomlaFieldFancySelect); + +})(customElements); diff --git a/build/media_src/system/js/searchtools.es6.js b/build/media_src/system/js/searchtools.es6.js index e93d24b38b726..d6ed8c80393f5 100644 --- a/build/media_src/system/js/searchtools.es6.js +++ b/build/media_src/system/js/searchtools.es6.js @@ -179,13 +179,28 @@ this.checkActiveStatus(this); - document.body.addEventListener('click', () => { + document.body.addEventListener('click', (event) => { if (document.body.classList.contains('filters-shown')) { + + // Ignore click inside the filter container + if (event.composedPath && typeof event.composedPath === 'function') { + // Browser that support composedPath() + if (event.composedPath().indexOf(this.filterContainer) !== -1) { + return; + } + } else { + let node = event.target; + while (node !== document.body) { + if (node === this.filterContainer) { + return; + } + node = node.parentNode; + } + } + this.hideFilters(); } }); - - this.filterContainer.addEventListener('click', (e) => { e.stopPropagation(); }, true); } checkFilter(element) { diff --git a/components/com_config/forms/modules.xml b/components/com_config/forms/modules.xml index 76ea9a6c6669d..2b9f48a1d6988 100644 --- a/components/com_config/forms/modules.xml +++ b/components/com_config/forms/modules.xml @@ -1,8 +1,8 @@
- - - - - - - - - diff --git a/components/com_config/tmpl/modules/default.php b/components/com_config/tmpl/modules/default.php index f7e216d9ad7dd..c2e1489236ff4 100644 --- a/components/com_config/tmpl/modules/default.php +++ b/components/com_config/tmpl/modules/default.php @@ -92,7 +92,7 @@ form->getLabel('position'); ?>
- loadTemplate('positions'); ?> + form->getInput('position'); ?>
diff --git a/components/com_config/tmpl/modules/default_positions.php b/components/com_config/tmpl/modules/default_positions.php deleted file mode 100644 index c331344b9633e..0000000000000 --- a/components/com_config/tmpl/modules/default_positions.php +++ /dev/null @@ -1,30 +0,0 @@ - 0)); - -// Add custom position to options -$customGroupText = Text::_('COM_MODULES_CUSTOM_POSITION'); - -// Build field -$attr = array( - 'id' => 'jform_position', - 'list.select' => $this->item['position'], - 'list.attr' => 'class="chosen-custom-value custom-select" ' - . 'data-custom_group_text="' . $customGroupText . '" ' - . 'data-no_results_text="' . Text::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' - . 'data-placeholder="' . Text::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ' -); - -echo HTMLHelper::_('select.groupedlist', $this->positions, 'jform[position]', $attr); diff --git a/components/com_content/tmpl/form/edit.php b/components/com_content/tmpl/form/edit.php index 1e9e3e46bb2a2..c54e69e1240a7 100644 --- a/components/com_content/tmpl/form/edit.php +++ b/components/com_content/tmpl/form/edit.php @@ -18,7 +18,6 @@ HTMLHelper::_('behavior.tabstate'); HTMLHelper::_('behavior.keepalive'); HTMLHelper::_('behavior.formvalidator'); -HTMLHelper::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0)); HTMLHelper::_('script', 'com_content/form-edit.js', ['version' => 'auto', 'relative' => true]); diff --git a/language/en-GB/en-GB.ini b/language/en-GB/en-GB.ini index 5cd911f6aa48b..e2c8dbd31d079 100644 --- a/language/en-GB/en-GB.ini +++ b/language/en-GB/en-GB.ini @@ -276,6 +276,7 @@ JGLOBAL_SECRETKEY="Secret Key" JGLOBAL_SECRETKEY_HELP="If you have enabled two factor authentication in your user account please enter your secret key. If you do not know what this means, you can leave this field blank." JGLOBAL_SELECT_AN_OPTION="Select an option" JGLOBAL_SELECT_NO_RESULTS_MATCH="No results match" +JGLOBAL_SELECT_PRESS_TO_SELECT="Press to select" JGLOBAL_SELECT_SOME_OPTIONS="Select some options" JGLOBAL_START_PUBLISH_AFTER_FINISH="Item start publishing date must be before finish publishing date" JGLOBAL_SUBCATEGORIES="Subcategories" diff --git a/layouts/joomla/form/field/accesslevel-fancy-select.php b/layouts/joomla/form/field/accesslevel-fancy-select.php new file mode 100644 index 0000000000000..554856737d827 --- /dev/null +++ b/layouts/joomla/form/field/accesslevel-fancy-select.php @@ -0,0 +1,79 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + */ + +$attr = ''; + +// Initialize some field attributes. +$attr .= $disabled ? ' disabled' : ''; +$attr .= !empty($size) ? ' size="' . $size . '"' : ''; +$attr .= $multiple ? ' multiple' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; + +$attr2 = ''; +$attr2 .= !empty($class) ? ' class="' . $class . '"' : ''; +$attr2 .= ' placeholder="' . $this->escape($hint ?: Text::_('JGLOBAL_TYPE_OR_SELECT_SOME_OPTIONS')) . '" '; + +if ($required) +{ + $attr .= ' required class="required"'; + $attr2 .= ' required'; +} + +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +Factory::getDocument()->getWebAssetManager()->enableAsset('choicesjs'); +HTMLHelper::_('webcomponent', 'system/webcomponents/joomla-field-fancy-select.min.js', ['version' => 'auto', 'relative' => true]); + +?> + +> diff --git a/layouts/joomla/form/field/accesslevel.php b/layouts/joomla/form/field/accesslevel.php new file mode 100644 index 0000000000000..cdf2eda51cf1a --- /dev/null +++ b/layouts/joomla/form/field/accesslevel.php @@ -0,0 +1,59 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + */ + +$attr = ''; + +// Initialize some field attributes. +$attr .= !empty($class) ? ' class="custom-select ' . $class . '"' : ' class="custom-select"'; +$attr .= $disabled ? ' disabled' : ''; +$attr .= !empty($size) ? ' size="' . $size . '"' : ''; +$attr .= $multiple ? ' multiple' : ''; +$attr .= $required ? ' required' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; + +echo HTMLHelper::_('access.level', $name, $value, $attr, $options, $id); diff --git a/layouts/joomla/form/field/list-fancy-select.php b/layouts/joomla/form/field/list-fancy-select.php new file mode 100644 index 0000000000000..794c951f1bc63 --- /dev/null +++ b/layouts/joomla/form/field/list-fancy-select.php @@ -0,0 +1,112 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + */ + +$html = array(); +$attr = ''; + +// Initialize the field attributes. +$attr .= !empty($size) ? ' size="' . $size . '"' : ''; +$attr .= $multiple ? ' multiple' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; + +// To avoid user's confusion, readonly="readonly" should imply disabled="disabled". +if ($readonly || $disabled) +{ + $attr .= ' disabled="disabled"'; +} + +$attr2 = ''; +$attr2 .= !empty($class) ? ' class="' . $class . '"' : ''; +$attr2 .= ' placeholder="' . $this->escape($hint ?: Text::_('JGLOBAL_TYPE_OR_SELECT_SOME_OPTIONS')) . '" '; + +if ($required) +{ + $attr .= ' required class="required"'; + $attr2 .= ' required'; +} + +// Create a read-only list (no name) with hidden input(s) to store the value(s). +if ($readonly) +{ + $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $value, $id); + + // E.g. form field type tag sends $this->value as array + if ($multiple && is_array($value)) + { + if (!count($value)) + { + $value[] = ''; + } + + foreach ($value as $val) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } +} +else +// Create a regular list. +{ + $html[] = HTMLHelper::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); +} + +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +Factory::getDocument()->getWebAssetManager()->enableAsset('choicesjs'); +HTMLHelper::_('webcomponent', 'system/webcomponents/joomla-field-fancy-select.min.js', ['version' => 'auto', 'relative' => true]); + +?> + +> diff --git a/layouts/joomla/form/field/list.php b/layouts/joomla/form/field/list.php new file mode 100644 index 0000000000000..a23785d3f065d --- /dev/null +++ b/layouts/joomla/form/field/list.php @@ -0,0 +1,94 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + */ + +$html = array(); +$attr = ''; + +// Initialize the field attributes. +$attr .= !empty($class) ? ' class="custom-select ' . $class . '"' : ' class="custom-select"'; +$attr .= !empty($size) ? ' size="' . $size . '"' : ''; +$attr .= $multiple ? ' multiple' : ''; +$attr .= $required ? ' required' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; + +// To avoid user's confusion, readonly="readonly" should imply disabled="disabled". +if ($readonly || $disabled) +{ + $attr .= ' disabled="disabled"'; +} + +// Create a read-only list (no name) with hidden input(s) to store the value(s). +if ($readonly) +{ + $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $value, $id); + + // E.g. form field type tag sends $this->value as array + if ($multiple && is_array($value)) + { + if (!count($value)) + { + $value[] = ''; + } + + foreach ($value as $val) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } +} +else +// Create a regular list. +{ + $html[] = HTMLHelper::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); +} + +echo implode($html); diff --git a/layouts/joomla/form/field/tag.php b/layouts/joomla/form/field/tag.php new file mode 100644 index 0000000000000..1f26b4b9e0ab2 --- /dev/null +++ b/layouts/joomla/form/field/tag.php @@ -0,0 +1,129 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + * @var boolean $allowCustom Flag, to allow add custom values + * @var boolean $remoteSearch Flag, to enable remote search + * @var integer $minTermLength Minimum length of the term to start searching + */ + +$html = array(); +$attr = ''; + +// Initialize some field attributes. +$attr .= $multiple ? ' multiple' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; + +// To avoid user's confusion, readonly="readonly" should imply disabled="disabled". +if ($readonly || $disabled) +{ + $attr .= ' disabled="disabled"'; +} + +$attr2 = ''; +$attr2 .= !empty($class) ? ' class="' . $class . '"' : ''; +$attr2 .= ' placeholder="' . $this->escape($hint ?: Text::_('JGLOBAL_TYPE_OR_SELECT_SOME_OPTIONS')) . '" '; + +if ($allowCustom) +{ + $attr2 .= $allowCustom ? ' allow-custom' : ''; + $attr2 .= $allowCustom ? ' new-item-prefix="#new#"' : ''; +} + +if ($remoteSearch) +{ + $attr2 .= ' remote-search'; + $attr2 .= ' url="' . Uri::root(true) . '/index.php?option=com_tags&task=tags.searchAjax"'; + $attr2 .= ' term-key="like"'; + $attr2 .= ' min-term-length="' . $minTermLength .'"'; +} + +if ($required) +{ + $attr .= ' required class="required"'; + $attr2 .= ' required'; +} + +// Create a read-only list (no name) with hidden input(s) to store the value(s). +if ($readonly) +{ + $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $value, $id); + + // E.g. form field type tag sends $this->value as array + if ($multiple && is_array($value)) + { + if (!count($value)) + { + $value[] = ''; + } + + foreach ($value as $val) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } +} +else +// Create a regular list. +{ + $html[] = HTMLHelper::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); +} + +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +Factory::getDocument()->getWebAssetManager()->enableAsset('choicesjs'); +HTMLHelper::_('webcomponent', 'system/webcomponents/joomla-field-fancy-select.min.js', ['version' => 'auto', 'relative' => true]); + +?> + +> diff --git a/libraries/cms/html/formbehavior.php b/libraries/cms/html/formbehavior.php index 31be8b6be885e..9de64ef8e527b 100644 --- a/libraries/cms/html/formbehavior.php +++ b/libraries/cms/html/formbehavior.php @@ -17,7 +17,9 @@ /** * Utility class for form related behaviors * - * @since 3.0 + * @since 3.0 + * + * @deprecated 5.0 Without replacement */ abstract class JHtmlFormbehavior { diff --git a/libraries/cms/html/tag.php b/libraries/cms/html/tag.php index 9559664f55c5e..8d8df40a929b0 100644 --- a/libraries/cms/html/tag.php +++ b/libraries/cms/html/tag.php @@ -165,6 +165,8 @@ public static function tags($config = array('filter.published' => array(0, 1))) * @return void * * @since 3.1 + * + * @deprecated 5.0 Without replacement */ public static function ajaxfield($selector = '#jform_tags', $allowCustom = true) { diff --git a/libraries/src/Form/Field/AccesslevelField.php b/libraries/src/Form/Field/AccesslevelField.php index 8c4b8e853ce66..d505a22d93966 100644 --- a/libraries/src/Form/Field/AccesslevelField.php +++ b/libraries/src/Form/Field/AccesslevelField.php @@ -10,11 +10,6 @@ defined('JPATH_PLATFORM') or die; -use Joomla\CMS\Form\FormHelper; -use Joomla\CMS\HTML\HTMLHelper; - -FormHelper::loadFieldClass('list'); - /** * Form Field class for the Joomla Platform. * Provides a list of access levels. Access levels control what users in specific @@ -23,7 +18,7 @@ * @see JAccess * @since 1.7.0 */ -class AccesslevelField extends \JFormFieldList +class AccesslevelField extends ListField { /** * The form field type. @@ -34,30 +29,10 @@ class AccesslevelField extends \JFormFieldList protected $type = 'Accesslevel'; /** - * Method to get the field input markup. + * Name of the layout being used to render the field * - * @return string The field input markup. - * - * @since 1.7.0 + * @var string + * @since __DEPLOY_VERSION__ */ - protected function getInput() - { - $attr = ''; - - // Initialize some field attributes. - $attr .= !empty($this->class) ? ' class="custom-select ' . $this->class . '"' : ' class="custom-select"'; - $attr .= $this->disabled ? ' disabled' : ''; - $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; - $attr .= $this->multiple ? ' multiple' : ''; - $attr .= $this->required ? ' required' : ''; - $attr .= $this->autofocus ? ' autofocus' : ''; - - // Initialize JavaScript field attributes. - $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; - - // Get the field options. - $options = $this->getOptions(); - - return HTMLHelper::_('access.level', $this->name, $this->value, $attr, $options, $this->id); - } + protected $layout = 'joomla.form.field.accesslevel'; } diff --git a/libraries/src/Form/Field/ListField.php b/libraries/src/Form/Field/ListField.php index 6d0e198221b89..c08b7c3d285c1 100644 --- a/libraries/src/Form/Field/ListField.php +++ b/libraries/src/Form/Field/ListField.php @@ -14,7 +14,6 @@ use Joomla\CMS\Factory; use Joomla\CMS\Form\FormField; use Joomla\CMS\Helper\ModuleHelper; -use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Associations; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Language\Text; @@ -37,6 +36,14 @@ class ListField extends FormField */ protected $type = 'List'; + /** + * Name of the layout being used to render the field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $layout = 'joomla.form.field.list'; + /** * Method to get the field input markup for a generic list. * Use the multiple attribute to enable multiselect. @@ -47,61 +54,11 @@ class ListField extends FormField */ protected function getInput() { - $html = array(); - $attr = ''; - - // Initialize some field attributes. - $attr .= !empty($this->class) ? ' class="custom-select ' . $this->class . '"' : ' class="custom-select"'; - $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; - $attr .= $this->multiple ? ' multiple' : ''; - $attr .= $this->required ? ' required' : ''; - $attr .= $this->autofocus ? ' autofocus' : ''; - - // To avoid user's confusion, readonly="true" should imply disabled="true". - if ((string) $this->readonly == '1' - || (string) $this->readonly == 'true' - || (string) $this->disabled == '1' - || (string) $this->disabled == 'true') - { - $attr .= ' disabled="disabled"'; - } - - // Initialize JavaScript field attributes. - $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; - - // Get the field options. - $options = (array) $this->getOptions(); + $data = $this->getLayoutData(); - // Create a read-only list (no name) with hidden input(s) to store the value(s). - if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') - { - $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); - - // E.g. form field type tag sends $this->value as array - if ($this->multiple && is_array($this->value)) - { - if (!count($this->value)) - { - $this->value[] = ''; - } - - foreach ($this->value as $value) - { - $html[] = ''; - } - } - else - { - $html[] = ''; - } - } - else - // Create a regular list. - { - $html[] = HTMLHelper::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); - } + $data['options'] = (array) $this->getOptions(); - return implode($html); + return $this->getRenderer($this->layout)->render($data); } /** diff --git a/libraries/src/Form/Field/TagField.php b/libraries/src/Form/Field/TagField.php index 0fd4d0d1500bc..e7b2496f240a1 100644 --- a/libraries/src/Form/Field/TagField.php +++ b/libraries/src/Form/Field/TagField.php @@ -12,20 +12,16 @@ use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; -use Joomla\CMS\Form\FormHelper; use Joomla\CMS\Helper\TagsHelper; -use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Multilanguage; use Joomla\Utilities\ArrayHelper; -FormHelper::loadFieldClass('list'); - /** * List of Tags field. * * @since 3.1 */ -class TagField extends \JFormFieldList +class TagField extends ListField { /** * A flexible tag list that respects access controls @@ -51,6 +47,14 @@ class TagField extends \JFormFieldList */ protected $comParams = null; + /** + * Name of the layout being used to render the field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $layout = 'joomla.form.field.tag'; + /** * Constructor * @@ -73,16 +77,7 @@ public function __construct() */ protected function getInput() { - // AJAX mode requires ajax-chosen - if (!$this->isNested()) - { - // Get the field id - $id = $this->element['id'] ?? null; - $cssId = '#' . $this->getId($id, $this->element['name']); - - // Load the ajax-chosen customised field - HTMLHelper::_('tag.ajaxfield', $cssId, $this->allowCustom()); - } + $data = $this->getLayoutData(); if (!is_array($this->value) && !empty($this->value)) { @@ -103,9 +98,17 @@ protected function getInput() { $this->value = explode(',', $this->value); } + + $data['value'] = $this->value; } - return parent::getInput(); + $data['remoteSearch'] = $this->isRemoteSearch(); + $data['options'] = $this->getOptions(); + $data['isNested'] = $this->isNested(); + $data['allowCustom'] = $this->allowCustom(); + $data['minTermLength'] = (int) $this->comParams->get('min_term_length', 3); + + return $this->getRenderer($this->layout)->render($data); } /** @@ -121,6 +124,12 @@ protected function getOptions() $app = Factory::getApplication(); $tag = $app->getLanguage()->getTag(); + // Return only basic options, everything else will be searched via AJAX + if ($this->isRemoteSearch() && !$this->value) + { + return parent::getOptions(); + } + $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('DISTINCT a.id AS value, a.path, a.title AS text, a.level, a.published, a.lft') @@ -154,6 +163,12 @@ protected function getOptions() $query->where($db->quoteName('a.lft') . ' > 0'); + // Preload only active values, everything else will be searched via AJAX + if ($this->isRemoteSearch() && $this->value) + { + $query->where('a.id IN (' . implode(',', $this->value) . ')'); + } + // Filter on the published state if (is_numeric($published)) { @@ -261,11 +276,28 @@ public function isNested() */ public function allowCustom() { - if (isset($this->element['custom']) && (string) $this->element['custom'] === 'deny') + if ($this->element['custom'] && in_array((string) $this->element['custom'], array('0', 'false', 'deny'))) { return false; } - return true; + return Factory::getUser()->authorise('core.create', 'com_tags'); + } + + /** + * Check whether need to enable AJAX search + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function isRemoteSearch() + { + if ($this->element['remote-search']) + { + return !in_array((string) $this->element['remote-search'], array('0', 'false', '')); + } + + return $this->comParams->get('tag_field_ajax_mode', 1) == 1; } } diff --git a/modules/mod_languages/tmpl/default.php b/modules/mod_languages/tmpl/default.php index 5b4fbb038ea4e..269244c56acf4 100644 --- a/modules/mod_languages/tmpl/default.php +++ b/modules/mod_languages/tmpl/default.php @@ -15,10 +15,6 @@ HTMLHelper::_('stylesheet', 'mod_languages/template.css', array('version' => 'auto', 'relative' => true)); -if ($params->get('dropdown', 1) && !$params->get('dropdownimage', 0)) -{ - HTMLHelper::_('formbehavior.chosen'); -} ?>
diff --git a/package.json b/package.json index 489017513a79c..9ffb39e9ad66e 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "chosen-js": "1.6.2", "codemirror": "5.35.0", "cropperjs": "1.2.2", + "choices.js": "^3.0.4", "css-vars-ponyfill": "^1.9.0", "diff": "3.4.0", "dragula": "3.7.2", diff --git a/templates/cassiopeia/scss/template.scss b/templates/cassiopeia/scss/template.scss index 4141eb5a7e9ba..ab4f3635955f2 100644 --- a/templates/cassiopeia/scss/template.scss +++ b/templates/cassiopeia/scss/template.scss @@ -51,6 +51,7 @@ @import "vendor/bootstrap/pagination"; @import "vendor/bootstrap/table"; @import "vendor/chosen"; +@import "vendor/choicesjs"; @import "vendor/dragula"; @import "vendor/minicolors"; @import "vendor/tinymce"; diff --git a/templates/cassiopeia/scss/vendor/_choicesjs.scss b/templates/cassiopeia/scss/vendor/_choicesjs.scss new file mode 100644 index 0000000000000..4a6138a566d26 --- /dev/null +++ b/templates/cassiopeia/scss/vendor/_choicesjs.scss @@ -0,0 +1,82 @@ +// choices.js + +// Fix position +.choices__list--dropdown { + z-index: 10; +} + +// Fix close button +.choices__button_joomla { + position: relative; + text-indent: -9999px; + cursor: pointer; + background: none; + border: 0; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + + &::before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: block; + text-align: center; + text-indent: 0; + content: "\00d7"; + } + + &:focus { + outline: none; + } +} + +.choices[data-type*="select-one"] { + .choices__button_joomla { + position: absolute; + top: 50%; + right: 0; + width: 20px; + height: 20px; + padding: 0; + margin-top: -10px; + margin-right: 25px; + border-radius: 10em; + opacity: .5; + &:hover, &:focus { opacity: 1; } + &:focus { box-shadow: 0 0 0 2px #00bcd4; } + } + + &[dir="rtl"] { + .choices__button_joomla { + right: auto; + left: 0; + margin-right: 0; + margin-left: 25px; + } + } +} + +.choices[data-type*="select-multiple"], +.choices[data-type*="text"] { + .choices__button_joomla { + position: relative; + display: inline-block; + width: 8px; + padding-left: 16px; + margin-top: 0; + margin-right: -4px; + margin-bottom: 0; + margin-left: 8px; + line-height: 1; + border-left: 1px solid #008fa1; + opacity: .75; + &:hover, &:focus { opacity: 1; } + &::before { + color: #fff; + } + } +} +