Moved Form/Field widgets into package humhub\modules\ui\form\widgets

This commit is contained in:
Lucas Bartholemy 2018-05-03 17:36:44 +02:00
parent 83771a8abe
commit 98e9b0e759
30 changed files with 1284 additions and 946 deletions

View File

@ -45,3 +45,4 @@ HumHub Change Log - v1.3-dev Branch
- Chg: Reduced email length to 150 chars to support utf8mb4 charset
- Enh: Added UI core module to group UI components
- Enh: Added new IconPicker form field
- Chg: Moved form widgets from `humhub\widgets` to `humhub\modules\ui\form\widgets` (added compatibility layer)

View File

@ -23,6 +23,12 @@ The existing `humhub\components\queue\ActiveJob` is declared as deprecated and w
Added new user status (User::SOFT_DELETED). You can find more information here: [Users](modules-users.md)
### Widgets
Moved all form and field related widgets from `humhub\widgets` to `humhub\modules\ui\form\widgets` namespace.
There is a compatibility layer for the 1.3 release.
Migrate from 1.1 to 1.2
-----------------------
@ -128,4 +134,4 @@ No breaking changes.
- Now handle ContentContainerController layouts, new option showSidebar
- New ContentAddonController Class
- New Wiki Parser / Editor Widget
- New Wiki Parser / Editor Widget

View File

@ -0,0 +1,111 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*
*/
namespace humhub\modules\content\widgets;
use Yii;
use humhub\libs\Html;
use humhub\modules\content\models\ContentTag;
use humhub\modules\ui\form\widgets\JsInputWidget;
class ContentTagDropDown extends JsInputWidget
{
/**
* @var string tagClass
*/
public $tagClass;
public $query;
public $contentContainer;
public $includeGlobal = false;
public $type = true;
public $prompt = false;
public $promptValue = 0;
public $items;
private $itemOptions = [];
public function int()
{
if (!$this->tagClass) {
$this->tagClass = ContentTag::class;
// Reset default behavior inf no specific tagClass is given
if ($this->type === true) {
$this->type = null;
}
}
if (!$this->none && !$this->noneLabel) {
$this->noneLabel = Yii::t('ContentModule.widgets_ContentTagDropDown', 'None');
}
}
public function run()
{
$items = $this->getItems();
if (empty($items)) {
return;
}
$options = $this->getOptions();
unset($options['id']);
if ($this->form && $this->hasModel()) {
return $this->form->field($this->model, $this->attribute)->dropDownList($items, $options);
} elseif ($this->hasModel()) {
return Html::activeDropDownList($this->model, $this->attribute, $items, $options);
} else {
return Html::dropDownList($this->name, $this->value, $items, $options);
}
}
public function getAttributes()
{
$result = [
'class' => 'form-control',
'options' => $this->itemOptions
];
if ($this->prompt) {
$result['prompt'] = $this->prompt;
}
return $result;
}
public function getItems()
{
if ($this->items) {
return $this->items;
}
if (!$this->query) {
if ($this->contentContainer) {
$this->query = call_user_func($this->tagClass .'::findByContainer', $this->contentContainer, $this->includeGlobal);
} elseif (!empty($this->type)) {
$type = ($this->type === true) ? $this->tagClass : $this->type;
$this->query = call_user_func($this->tagClass .'::findByType', [$type]);
} else {
$this->query = call_user_func($this->tagClass .'::find');
}
}
$tags = $this->items = $this->query->all();
$result = [];
foreach ($tags as $tag) {
$result[$tag->id] = $tag->name;
$this->itemOptions[$tag->id] = [
'data-type-color' => $tag->color
];
}
return $result;
}
}

View File

@ -0,0 +1,38 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
/**
* A HumHub enhanced version of [[\yii\bootstrap\ActiveField]].
*
* @since 1.2
* @author Luke
*/
class ActiveField extends \yii\bootstrap\ActiveField
{
/**
* @inheritdoc
*/
public function widget($class, $config = [])
{
/* @var $class \yii\base\Widget */
$config['model'] = $this->model;
$config['attribute'] = $this->attribute;
$config['view'] = $this->form->getView();
if (isset($config['options']) && isset(class_parents($class)['humhub\widgets\InputWidget'])) {
$this->adjustLabelFor($config['options']);
}
return parent::widget($class, $config);
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
/**
* ActiveForm
*
* @since 1.1
* @author Luke
*/
class ActiveForm extends \yii\bootstrap\ActiveForm
{
/**
* @inheritdoc
*/
public $enableClientValidation = false;
/**
* @inheritdoc
*/
public $fieldClass = 'humhub\modules\ui\form\widgets\ActiveField';
}

View File

@ -0,0 +1,406 @@
<?php
namespace humhub\modules\ui\form\widgets;
use Yii;
use yii\helpers\Html;
use yii\helpers\Url;
use humhub\modules\ui\form\widgets\JsInputWidget;
/**
* Abstract class for picker form fields.
*
* Subclasses should at least overwrite the following fields:
*
* - $defaultRoute for defining a default search query route
* - $itemClass defines the type of item e.g. User/Space/...
* - $itemKey defines the key attribute used as option values e.g. id/guid
*
* And the following methods:
*
* - getItemText for retrieving the option text for an item
* - getItemImage for retrieving the option image (if required)
*
*
* The json result of a picker search query should return an array of items with the following key/values:
*
* - id: option value (itemKey) (required)
* - text: option text (required)
* - image: option image (optional)
* - priority: used to sort results (optional)
* - disabled: can be used to disable certain items (optional)
* - disabbledText: text describing the reason why the item is disabled (optional)
*
* @package humhub.modules_core.user.widgets
* @since 1.2
* @author buddha
*/
abstract class BasePicker extends JsInputWidget
{
/**
* Defines the javascript picker implementation.
*
* @var string
*/
public $jsWidget = 'ui.picker.Picker';
/**
* Disabled items
*/
public $disabledItems;
/**
* Default route used for search queries.
* This can be overwritten by defining the $url.
*
* @var string
*/
public $defaultRoute;
/**
* Search url used to overwrite the $defaultRoute for a picker isntance.
*
* @var string
*/
public $url;
/**
* Maximum amount of selection items.
*
* @var integer
*/
public $maxSelection = 50;
/**
* Minimum character input before triggering search query.
*
* @var integer
*/
public $minInput = 3;
/**
* Minimum character input before triggering search query.
*
* @var integer
*/
public $maxInput = 20;
/**
* Array of item instances. If this array is set the picker will ignore the
* actual model attribute and instead use this array as selection.
*
* It this array is not set, the picker will try to load the items by means of the
* model attribute
*
* @see BasePicker::loadItems
* @var array
*/
public $selection;
/**
* @var array Array of item instances used as long the minInput is not exceed.
*/
public $defaultResults = [];
/**
* The item class used to load items by means of the model attribute value.
*
* @var string
*/
public $itemClass;
/**
* The item key used as option value and loading items by attribute value.
* e.g. id or guid
*
* @var string
*/
public $itemKey;
/**
* If the ActiveForm is set, it will be used to create the picker field,
* otherwise it's created by Html::activeDropDownList
*
* @var \yii\widgets\ActiveForm
*/
public $form;
/**
* @deprecated since 1.2.2 use $name instead
*/
public $formName;
/**
* Model instance.
*
* @var \yii\db\ActiveRecord
*/
public $model;
/**
* Model attribute which holds the picker value. The referenced model attribute has to be an
* array.
*
* @var string
*/
public $attribute;
/**
* Can be used to overwrite the default placeholder.
* @var string
*/
public $placeholder;
/**
* Can be used to overwrite the default add more placeholder.
* @var string
*/
public $placeholderMore;
/**
* If set to true the picker will be focused automatically.
*
* @var boolean
*/
public $focus = false;
/**
* @inheritdoc
* @var boolean
*/
public $init = true;
/**
* Used to retrieve the option text of a given $item.
*
* @param \yii\db\ActiveRecord $item selected item
* @return string item option text
*/
protected abstract function getItemText($item);
/**
* Used to retrieve the option image url of a given $item.
*
* @param \yii\db\ActiveRecord $item selected item
* @return string image url or null if no selection image required.
*/
protected abstract function getItemImage($item);
/**
* @inhertidoc
*/
public function run()
{
\humhub\assets\Select2BootstrapAsset::register($this->view);
//Only for compatibility
if (empty($this->name)) {
$this->name = $this->formName;
}
if ($this->selection != null && !is_array($this->selection)) {
$this->selection = [$this->selection];
}
// Prepare current selection and selection options
$selection = [];
$selectedOptions = $this->getSelectedOptions();
foreach ($selectedOptions as $id => $option) {
$selection[$id] = $option['data-text'];
}
$options = $this->getOptions();
$options['options'] = $selectedOptions;
if ($this->form != null) {
return $this->form->field($this->model, $this->attribute)->dropDownList($selection, $options);
} else if ($this->model != null) {
return Html::activeDropDownList($this->model, $this->attribute, $selection, $options);
} else {
$name = (!$this->name) ? 'pickerField' : $this->name;
return Html::dropDownList($name, $this->value, $selection, $options);
}
}
/**
* Prepares the selected options either by using the $selection array or by loading the items
* by means of the model attribute value.
*
* The resulting array has the following format:
*
* [itemKey] => [
* 'data-text' => itemText
* 'data-image' => itemImage
* 'selected' => selected
* ]
*
* Subclasses should overwrite the getItemText and getItemImage function for this purpose.
*
* @return array
*/
protected function getSelectedOptions()
{
if (!$this->selection && $this->model != null) {
$attribute = $this->attribute;
if (strrpos($attribute, '[') !== false) {
$this->selection = $this->loadItems(Html::getAttributeValue($this->model, $attribute));
} else {
$this->selection = $this->loadItems($this->model->$attribute);
}
}
if (!$this->selection) {
$this->selection = [];
}
$result = [];
foreach ($this->selection as $item) {
if (!$item) {
continue;
}
$result[$this->getItemKey($item)] = $this->buildItemOption($item);
}
return $result;
}
/**
* Responsible for building the option data for an item.
*
* @param type $item
* @param type $selected
* @return string
*/
protected function buildItemOption($item, $selected = true)
{
$result = [
'data-id' => $this->getItemKey($item),
'data-text' => $this->getItemText($item),
'data-image' => $this->getItemImage($item),
];
if ($selected) {
$result['selected'] = 'selected';
}
return $result;
}
/**
* Returns the item key which is used as option value. By default we use
* the $itemKey attribibute of $item.
*
* e.g. $itemKey = 'id'
*
* @param type $item
* @return type
*/
protected function getItemKey($item)
{
$itemKey = $this->itemKey;
return $item->$itemKey;
}
/**
* Loads all items of the given $selection array.
* The $selection array contains all selected itemKeys.
*
* @param array $selection array of itemKeys
* @return type array of items of type $itemClass or empty array for an empty selection
*/
public function loadItems($selection = null)
{
if (empty($selection)) {
return [];
}
// For older version (prior 1.2) - try to convert comma separated list to array
if (!is_array($selection)) {
$selection = explode(',', $selection);
}
$itemClass = $this->itemClass;
return $itemClass::find()->where([$this->itemKey => $selection])->all();
}
/*
* @inheritdoc
*/
protected function getAttributes()
{
return [
'multiple' => 'multiple',
'size' => '1',
'class' => 'form-control',
'style' => 'width:100%',
'title' => $this->placeholder
];
}
/**
* Returns an array of data attributes for this picker isntance.
* Following data attributes can be configured by default:
*
* - data-placeholder: Placeholder text if no value is set.
* - data-placeholder-more: Placeholder text displayed if at least one item is set.
* - data-maximum-selected: Info message displayed if $maxSelection is exceed.
* - data-no-result: Empty result message.
* - data-format-ajax-error: Ajax error message.
* - data-load-more: Load more items text.
* - data-input-too-short: Info message displayed if $minInput characters is not exceed.
* - data-input-too-long: Info message displayed if $maxInput characters is exceed.
*
* @return array
*/
protected function getData()
{
$allowMultiple = $this->maxSelection !== 1;
$placeholder = ($this->placeholder != null) ? $this->placeholder : Yii::t('UserModule.widgets_BasePickerField', 'Select {n,plural,=1{item} other{items}}', ['n' => ($allowMultiple) ? 2 : 1]);
$placeholderMore = ($this->placeholderMore != null) ? $this->placeholderMore : Yii::t('UserModule.widgets_BasePickerField', 'Add more...');
$result = [
'picker-url' => $this->getUrl(),
'picker-focus' => ($this->focus) ? 'true' : null,
'disabled-items' => (!$this->disabledItems) ? null : $this->disabledItems,
'maximum-selection-length' => $this->maxSelection,
'maximum-input-length' => $this->maxInput,
'minimum-input-length' => $this->minInput,
'placeholder' => $placeholder,
'placeholder-more' => $placeholderMore,
'no-result' => Yii::t('UserModule.widgets_BasePickerField', 'Your search returned no matches.'),
'format-ajax-error' => Yii::t('UserModule.widgets_BasePickerField', 'An unexpected error occurred while loading the result.'),
'load-more' => Yii::t('UserModule.widgets_BasePickerField', 'Load more'),
'input-too-short' => Yii::t('UserModule.widgets_BasePickerField', 'Please enter at least {n} character', ['n' => $this->minInput]),
'input-too-long' => Yii::t('UserModule.widgets_BasePickerField', 'You reached the maximum number of allowed charachters ({n}).', ['n' => $this->maxInput]),
'default-results' => $this->getDefaultResultData()
];
if ($this->maxSelection) {
$result['maximum-selected'] = Yii::t('UserModule.widgets_BasePickerField', 'This field only allows a maximum of {n,plural,=1{# item} other{# items}}.', ['n' => $this->maxSelection]);
}
return $result;
}
protected function getDefaultResultData()
{
$result = [];
foreach ($this->defaultResults as $item) {
$result[] = $this->buildItemOption($item);
}
return $result;
}
/**
* Returns the url for this picker instance. If no $url is set we use the $defaultRoute for creating the url.
*
* @return strings
*/
protected function getUrl()
{
return ($this->url) ? $this->url : Url::to([$this->defaultRoute]);
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
use humhub\modules\ui\form\widgets\JsInputWidget;
/**
* Adds a color picker form field for the given model.
*
* @since 1.3
* @author buddha
*/
class ColorPicker extends JsInputWidget
{
/**
* @deprecated since v1.2.2 use $attribute instead
*/
public $field;
/**
* @var string the container id used to append the actual color picker js widget.
*/
public $container;
/**
* @inheritdoc
*/
public $attribute = 'color';
/**
* @inheritdoc
*/
public function init()
{
if (!empty($this->field)) {
$this->attribute = $this->field;
}
}
/**
* @inheritdoc
*/
public function run()
{
return $this->render('@ui/form/widgets/views/colorPickerField', [
'model' => $this->model,
'field' => $this->attribute,
'container' => $this->container,
'inputId' => $this->getId(true)
]);
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
use Yii;
use yii\jui\DatePicker as BaseDatePicker;
use humhub\libs\Html;
/**
* DatePicker form field widget
*
* @since 1.3.0
* @inheritdoc
* @package humhub\modules\ui\form\widgets
*/
class DatePicker extends BaseDatePicker
{
/**
* @inheritdoc
*/
public function init()
{
if ($this->dateFormat === null) {
$this->dateFormat = Yii::$app->formatter->dateInputFormat;
}
Html::addCssClass($this->options, 'form-control');
parent::init();
}
}

View File

@ -0,0 +1,59 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
use Yii;
use humhub\libs\Html;
use yii\helpers\Json;
use humhub\assets\JqueryTimeEntryAsset;
use humhub\modules\ui\form\widgets\JsInputWidget;
/**
* DurationPicker renders an UI form widget to select time durations.
*
* @since 1.3
* @author Luke
*/
class DurationPicker extends JsInputWidget
{
/**
* @inheritdoc
*/
public function run()
{
$view = $this->getView();
$id = $this->options['id'];
$options = [
'show24Hours' => true,
'unlimitedHours' => true,
'defaultTime' => '01:00',
'timeSteps' => [1, 15],
'spinnerImage' => ''
];
JqueryTimeEntryAsset::register($view);
$view->registerJs("$('#{$id}').timeEntry(" . Json::htmlEncode($options) . ");");
Html::addCssClass($this->options, 'form-control');
if ($this->model !== null) {
return Html::activeTextInput($this->model, $this->attribute, $this->getOptions());
} else {
return Html::input($this->name, $this->value, $this->getOptions());
}
}
public static function getDuration(\DateTime $start, \DateTime $end)
{
$duration = $start->diff($end);
return $duration->h . ':' . $duration->m;
}
}

View File

@ -24,7 +24,6 @@ use yii\web\JsExpression;
* ```
*
* @since 1.3
* @package humhub\widgets
*/
class IconPicker extends Select2
{

View File

@ -0,0 +1,113 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
use humhub\widgets\JsWidget;
use yii\base\InvalidConfigException;
use yii\base\Model;
use yii\helpers\Html;
use yii\widgets\InputWidget;
/**
* InputWidget is the base class for widgets that collect user inputs.
*
* An input widget can be associated with a data model and an attribute,
* or a name and a value. If the former, the name and the value will
* be generated automatically.
*
* Classes extending from this widget can be used in an [[\yii\widgets\ActiveForm|ActiveForm]]
* using the [[\yii\widgets\ActiveField::widget()|widget()]] method, for example like this:
*
* ```php
* <?= $form->field($model, 'from_date')->widget('WidgetClassName', [
* // configure additional widget properties here
* ]) ?>
* ```
*
* For more details and usage information on InputWidget, see the [guide article on forms](guide:input-forms).
*
* @see InputWidget
* @author Luke
* @since 1.3
*/
abstract class JsInputWidget extends JsWidget
{
/**
* If the ActiveForm is set, it should be used to create input field.
* This may differ between implementations.
*
* @var \yii\widgets\ActiveForm
*/
public $form;
/**
* @var Model the data model that this widget is associated with.
*/
public $model;
/**
* @var string the model attribute that this widget is associated with.
*/
public $attribute;
/**
* @var string the input name. This must be set if [[model]] and [[attribute]] are not set.
*/
public $name;
/**
* @var string the input value.
*/
public $value;
/**
* @var array the HTML attributes for the input tag.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*
* @throws InvalidConfigException
*/
public function init()
{
if ($this->name === null && !$this->hasModel()) {
throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified.");
}
if (!$this->id && !isset($this->options['id'])) {
$this->id = $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId(true);
}
parent::init();
}
/**
* @return string the field value either by extracting from model or if no model is given `$this->value`
* @since 1.3
*/
protected function getValue()
{
if ($this->hasModel()) {
return Html::getAttributeValue($this->model, $this->attribute);
}
return $this->value;
}
/**
* @return bool whether this widget is associated with a data model.
*/
protected function hasModel()
{
return $this->model instanceof Model && $this->attribute !== null;
}
}

View File

@ -0,0 +1,150 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*
*/
namespace humhub\modules\ui\form\widgets;
use humhub\assets\BootstrapMarkdownAsset;
use humhub\libs\Html;
use humhub\modules\file\widgets\UploadButton;
use yii\helpers\Url;
/**
* Simple Markdown Editor form fields.
*
* @package humhub\widgets
* @since 1.2.2
*/
class Markdown extends JsInputWidget
{
/**
* @inheritdoc
*/
public $jsWidget = 'ui.markdown.MarkdownField';
/**
* @var int defines the HTML rows attribute of the textarea
*/
public $rows = 3;
/**
* @var string markdown preview url
*/
public $previewUrl;
/**
* HMarkdown parser class used for preview
*
* @var string
*/
public $parserClass = "HMarkdown";
/**
* @var bool show label
*/
public $label = false;
/**
* @var string defines the name of the hidden input name for uploaded files if not set the UploadButton default is used
* @see UploadButton
*/
public $filesInputName;
/**
* Can defined in addition to $fileAttribute to change the form model of the file from $model to $fileModel.
* Note: this is only affects the formName for the file upload.
* @var string
*/
public $fileModel;
/**
* Can be set if $model is defined, to create a loadable fileInput name which is respected in Model::load()
* Note: this is only affects the formName for the file upload.
* @var string
*/
public $fileAttribute;
/**
* @var boolean if set to true the markdown field will be disabled
*/
public $disabled = false;
/**
* @var boolean if set to true the markdown field will set to readonly
*/
public $readonly = false;
/**
* @var string
*/
public $placeholder;
/**
* @inheritdoc
*/
public $fadeIn = 'fast';
/**
* @inheritdoc
*/
public $init = true;
public function init()
{
if (empty($this->previewUrl)) {
$this->previewUrl = Url::toRoute(['/markdown/preview', 'parser' => $this->parserClass]);
}
}
public function run()
{
BootstrapMarkdownAsset::register($this->view);
$this->view->registerCssFile('@web-static/css/bootstrap-markdown-override.css');
if ($this->placeholder === null && $this->hasModel()) {
$this->placeholder = $this->model->getAttributeLabel($this->attribute);
}
if ($this->form != null) {
$textArea = $this->form->field($this->model, $this->attribute)->textarea($this->getOptions())->label($this->label);
} else if ($this->model != null) {
$textArea = Html::activeTextarea($this->model, $this->attribute, $this->getOptions());
} else {
$textArea = Html::textarea($this->name, $this->value, $this->getOptions());
}
return $textArea;
}
public function getAttributes()
{
return [
'rows' => $this->rows,
'disabled' => $this->disabled,
'readonly' => $this->readonly,
'placeholder' => $this->placeholder,
'class' => 'form-control'
];
}
public function getData()
{
if (empty($this->fileModel)) {
$this->fileModel = $this->model;
}
if ($this->model && $this->fileAttribute) {
$this->filesInputName = $this->fileModel->formName() . '[' . $this->fileAttribute . '][]';
}
return [
'preview-url' => $this->previewUrl,
'files-input-name' => !empty($this->filesInputName) ? $this->filesInputName : null
];
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*
*/
namespace humhub\modules\ui\form\widgets;
use humhub\components\Widget;
use humhub\widgets\LayoutAddons;
/**
* Class MarkdownModals provides modals which are added used by the Markdown widget.
* The widget is automatically added to the layout addons.
*
* @see LayoutAddons
* @since 1.3
*/
class MarkdownModals extends Widget
{
public function run()
{
return $this->render('markdownModals');
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
/**
* Multiselect
*
* @since 1.3
* @author Luke
*/
class MultiSelect extends BasePicker
{
/**
* @inerhitdoc
*/
public $minInput = 0;
/**
* Possible values
* @var type
*/
public $items = [];
/**
* @inheritdoc
*/
protected function getItemText($item)
{
return array_values($item)[0];
}
/**
* @inheritdoc
*/
protected function getItemImage($item)
{
return null;
}
protected function getItemKey($item)
{
return key($item);
}
protected function getSelectedOptions()
{
if (empty($this->selection)) {
$attribute = $this->attribute;
$this->selection = ($this->model) ? $this->model->$attribute : [];
}
if (empty($this->selection)) {
$this->selection = [];
}
$result = [];
foreach ($this->items as $key => $value) {
if (!$value || !$key) {
continue;
}
$result[$key] = $this->buildItemOption([$key => $value], in_array($key, $this->selection));
}
return $result;
}
protected function getData()
{
$result = parent::getData();
unset($result['picker-url']);
return $result;
}
protected function getUrl()
{
return null;
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\form\widgets;
use Yii;
/**
* TimePicker form field widget
*
* @inheritdoc
* @package humhub\modules\ui\form\widgets
*/
class TimePicker extends \kartik\time\TimePicker
{
/**
* @inheritdoc
*/
public function init()
{
parent::init();
if (!isset($this->pluginOptions['showMeridian'])) {
$this->pluginOptions['showMeridian'] = Yii::$app->formatter->isShowMeridiem();
}
if (!isset($this->pluginOptions['defaultTime'])) {
$this->pluginOptions['defaultTime'] = ($this->pluginOptions['showMeridian']) ? '10:00 AM' : '10:00';
}
}
}

View File

@ -0,0 +1,55 @@
<?php
use humhub\modules\file\widgets\UploadButton;
use humhub\widgets\Button;
use humhub\widgets\ModalButton;
use humhub\widgets\ModalDialog;
?>
<div class="modal modal-top" id="markdown-modal-file-upload" tabindex="-1" role="dialog" aria-labelledby="addImageModalLabel" style="z-index:99999" aria-hidden="true">
<?php ModalDialog::begin(['header' => Yii::t('widgets_views_markdownEditor', 'Add image/file')])?>
<div class="modal-body">
<div class="uploadForm">
<?= UploadButton::widget([
'id' => 'markdown-file-upload',
'label' => true,
'tooltip' => false,
'progress' => '#markdown-modal-upload-progress',
'cssButtonClass' => 'btn-default btn-sm',
'dropZone' => '#markdown-modal-file-upload',
'hideInStream' => true
]) ?>
</div>
<br>
<div id="markdown-modal-upload-progress" style="display:none"></div>
</div>
<div class="modal-footer">
<?= ModalButton::cancel(Yii::t('base', 'Close')) ?>
</div>
<?php ModalDialog::end() ?>
</div>
<div class="modal modal-top" id="markdown-modal-add-link" tabindex="-1" role="dialog" style="z-index:99999" aria-labelledby="addLinkModalLabel" aria-hidden="true">
<?php ModalDialog::begin(['header' => Yii::t('widgets_views_markdownEditor', 'Add link')])?>
<div class="modal-body">
<div class="form-group">
<label for="addLinkTitle"><?= Yii::t('widgets_views_markdownEditor', 'Title'); ?></label>
<input type="text" class="form-control linkTitle"
placeholder="<?= Yii::t('widgets_views_markdownEditor', 'Title of your link'); ?>">
</div>
<div class="form-group">
<label for="addLinkTarget"><?= Yii::t('widgets_views_markdownEditor', 'Target'); ?></label>
<input type="text" class="form-control linkTarget"
placeholder="<?= Yii::t('widgets_views_markdownEditor', 'Enter a url (e.g. http://example.com)'); ?>">
</div>
</div>
<div class="modal-footer">
<?= ModalButton::cancel(Yii::t('base', 'Close')) ?>
<?= Button::primary(Yii::t('widgets_views_markdownEditor', 'Add link'))->cssClass('addLinkButton')->loader(false) ?>
</div>
<?php ModalDialog::end() ?>
</div>

View File

@ -11,27 +11,11 @@ namespace humhub\widgets;
/**
* A HumHub enhanced version of [[\yii\bootstrap\ActiveField]].
*
* @see \humhub\modules\ui\form\widgets\ActiveField
* @since 1.2
* @deprecated since 1.3
* @author Luke
*/
class ActiveField extends \yii\bootstrap\ActiveField
class ActiveField extends \humhub\modules\ui\form\widgets\ActiveField
{
/**
* @inheritdoc
*/
public function widget($class, $config = [])
{
/* @var $class \yii\base\Widget */
$config['model'] = $this->model;
$config['attribute'] = $this->attribute;
$config['view'] = $this->form->getView();
if (isset($config['options']) && isset(class_parents($class)['humhub\widgets\InputWidget'])) {
$this->adjustLabelFor($config['options']);
}
return parent::widget($class, $config);
}
}

View File

@ -11,20 +11,11 @@ namespace humhub\widgets;
/**
* ActiveForm
*
* @see \humhub\modules\ui\form\widgets\ActiveForm
* @deprecated since 1.3
* @since 1.1
* @author Luke
*/
class ActiveForm extends \yii\bootstrap\ActiveForm
class ActiveForm extends \humhub\modules\ui\form\widgets\ActiveForm
{
/**
* @inheritdoc
*/
public $enableClientValidation = false;
/**
* @inheritdoc
*/
public $fieldClass = 'humhub\widgets\ActiveField';
}

View File

@ -2,404 +2,12 @@
namespace humhub\widgets;
use Yii;
use yii\helpers\Html;
use \yii\helpers\Url;
/**
* Abstract class for picker form fields.
*
* Subclasses should at least overwrite the following fields:
*
* - $defaultRoute for defining a default search query route
* - $itemClass defines the type of item e.g. User/Space/...
* - $itemKey defines the key attribute used as option values e.g. id/guid
*
* And the following methods:
*
* - getItemText for retrieving the option text for an item
* - getItemImage for retrieving the option image (if required)
*
*
* The json result of a picker search query should return an array of items with the following key/values:
*
* - id: option value (itemKey) (required)
* - text: option text (required)
* - image: option image (optional)
* - priority: used to sort results (optional)
* - disabled: can be used to disable certain items (optional)
* - disabbledText: text describing the reason why the item is disabled (optional)
*
* @package humhub.modules_core.user.widgets
* @deprecated since 1.3
* @since 1.2
* @author buddha
*/
abstract class BasePickerField extends InputWidget
abstract class BasePickerField extends \humhub\modules\ui\form\widgets\BasePicker
{
/**
* Defines the javascript picker implementation.
*
* @var string
*/
public $jsWidget = 'ui.picker.Picker';
/**
* Disabled items
*/
public $disabledItems;
/**
* Default route used for search queries.
* This can be overwritten by defining the $url.
*
* @var string
*/
public $defaultRoute;
/**
* Search url used to overwrite the $defaultRoute for a picker isntance.
*
* @var string
*/
public $url;
/**
* Maximum amount of selection items.
*
* @var integer
*/
public $maxSelection = 50;
/**
* Minimum character input before triggering search query.
*
* @var integer
*/
public $minInput = 3;
/**
* Minimum character input before triggering search query.
*
* @var integer
*/
public $maxInput = 20;
/**
* Array of item instances. If this array is set the picker will ignore the
* actual model attribute and instead use this array as selection.
*
* It this array is not set, the picker will try to load the items by means of the
* model attribute
*
* @see BasePickerField::loadItems
* @var array
*/
public $selection;
/**
* @var array Array of item instances used as long the minInput is not exceed.
*/
public $defaultResults = [];
/**
* The item class used to load items by means of the model attribute value.
*
* @var string
*/
public $itemClass;
/**
* The item key used as option value and loading items by attribute value.
* e.g. id or guid
*
* @var string
*/
public $itemKey;
/**
* If the ActiveForm is set, it will be used to create the picker field,
* otherwise it's created by Html::activeDropDownList
*
* @var \yii\widgets\ActiveForm
*/
public $form;
/**
* @deprecated since 1.2.2 use $name instead
*/
public $formName;
/**
* Model instance.
*
* @var \yii\db\ActiveRecord
*/
public $model;
/**
* Model attribute which holds the picker value. The referenced model attribute has to be an
* array.
*
* @var string
*/
public $attribute;
/**
* Can be used to overwrite the default placeholder.
* @var string
*/
public $placeholder;
/**
* Can be used to overwrite the default add more placeholder.
* @var string
*/
public $placeholderMore;
/**
* If set to true the picker will be focused automatically.
*
* @var boolean
*/
public $focus = false;
/**
* @inheritdoc
* @var boolean
*/
public $init = true;
/**
* Used to retrieve the option text of a given $item.
*
* @param \yii\db\ActiveRecord $item selected item
* @return string item option text
*/
protected abstract function getItemText($item);
/**
* Used to retrieve the option image url of a given $item.
*
* @param \yii\db\ActiveRecord $item selected item
* @return string image url or null if no selection image required.
*/
protected abstract function getItemImage($item);
/**
* @inhertidoc
*/
public function run()
{
\humhub\assets\Select2BootstrapAsset::register($this->view);
//Only for compatibility
if(empty($this->name)) {
$this->name = $this->formName;
}
if ($this->selection != null && !is_array($this->selection)) {
$this->selection = [$this->selection];
}
// Prepare current selection and selection options
$selection = [];
$selectedOptions = $this->getSelectedOptions();
foreach ($selectedOptions as $id => $option) {
$selection[$id] = $option['data-text'];
}
$options = $this->getOptions();
$options['options'] = $selectedOptions;
if ($this->form != null) {
return $this->form->field($this->model, $this->attribute)->dropDownList($selection, $options);
} else if ($this->model != null) {
return Html::activeDropDownList($this->model, $this->attribute, $selection, $options);
} else {
$name = (!$this->name) ? 'pickerField' : $this->name;
return Html::dropDownList($name, $this->value, $selection, $options);
}
}
/**
* Prepares the selected options either by using the $selection array or by loading the items
* by means of the model attribute value.
*
* The resulting array has the following format:
*
* [itemKey] => [
* 'data-text' => itemText
* 'data-image' => itemImage
* 'selected' => selected
* ]
*
* Subclasses should overwrite the getItemText and getItemImage function for this purpose.
*
* @return array
*/
protected function getSelectedOptions()
{
if (!$this->selection && $this->model != null) {
$attribute = $this->attribute;
if(strrpos($attribute, '[') !== false) {
$this->selection = $this->loadItems(Html::getAttributeValue($this->model, $attribute));
} else {
$this->selection = $this->loadItems($this->model->$attribute);
}
}
if (!$this->selection) {
$this->selection = [];
}
$result = [];
foreach ($this->selection as $item) {
if (!$item) {
continue;
}
$result[$this->getItemKey($item)] = $this->buildItemOption($item);
}
return $result;
}
/**
* Responsible for building the option data for an item.
*
* @param type $item
* @param type $selected
* @return string
*/
protected function buildItemOption($item, $selected = true)
{
$result = [
'data-id' => $this->getItemKey($item),
'data-text' => $this->getItemText($item),
'data-image' => $this->getItemImage($item),
];
if ($selected) {
$result['selected'] = 'selected';
}
return $result;
}
/**
* Returns the item key which is used as option value. By default we use
* the $itemKey attribibute of $item.
*
* e.g. $itemKey = 'id'
*
* @param type $item
* @return type
*/
protected function getItemKey($item)
{
$itemKey = $this->itemKey;
return $item->$itemKey;
}
/**
* Loads all items of the given $selection array.
* The $selection array contains all selected itemKeys.
*
* @param array $selection array of itemKeys
* @return type array of items of type $itemClass or empty array for an empty selection
*/
public function loadItems($selection = null)
{
if (empty($selection)) {
return [];
}
// For older version (prior 1.2) - try to convert comma separated list to array
if (!is_array($selection)) {
$selection = explode(',', $selection);
}
$itemClass = $this->itemClass;
return $itemClass::find()->where([$this->itemKey => $selection])->all();
}
/*
* @inheritdoc
*/
protected function getAttributes()
{
return [
'multiple' => 'multiple',
'size' => '1',
'class' => 'form-control',
'style' => 'width:100%',
'title' => $this->placeholder
];
}
/**
* Returns an array of data attributes for this picker isntance.
* Following data attributes can be configured by default:
*
* - data-placeholder: Placeholder text if no value is set.
* - data-placeholder-more: Placeholder text displayed if at least one item is set.
* - data-maximum-selected: Info message displayed if $maxSelection is exceed.
* - data-no-result: Empty result message.
* - data-format-ajax-error: Ajax error message.
* - data-load-more: Load more items text.
* - data-input-too-short: Info message displayed if $minInput characters is not exceed.
* - data-input-too-long: Info message displayed if $maxInput characters is exceed.
*
* @return array
*/
protected function getData()
{
$allowMultiple = $this->maxSelection !== 1;
$placeholder = ($this->placeholder != null) ? $this->placeholder : Yii::t('UserModule.widgets_BasePickerField', 'Select {n,plural,=1{item} other{items}}', ['n' => ($allowMultiple) ? 2 : 1]);
$placeholderMore = ($this->placeholderMore != null) ? $this->placeholderMore : Yii::t('UserModule.widgets_BasePickerField', 'Add more...');
$result = [
'picker-url' => $this->getUrl(),
'picker-focus' => ($this->focus) ? 'true' : null,
'disabled-items' => (!$this->disabledItems) ? null : $this->disabledItems,
'maximum-selection-length' => $this->maxSelection,
'maximum-input-length' => $this->maxInput,
'minimum-input-length' => $this->minInput,
'placeholder' => $placeholder,
'placeholder-more' => $placeholderMore,
'no-result' => Yii::t('UserModule.widgets_BasePickerField', 'Your search returned no matches.'),
'format-ajax-error' => Yii::t('UserModule.widgets_BasePickerField', 'An unexpected error occurred while loading the result.'),
'load-more' => Yii::t('UserModule.widgets_BasePickerField', 'Load more'),
'input-too-short' => Yii::t('UserModule.widgets_BasePickerField', 'Please enter at least {n} character', ['n' => $this->minInput]),
'input-too-long' => Yii::t('UserModule.widgets_BasePickerField', 'You reached the maximum number of allowed charachters ({n}).', ['n' => $this->maxInput]),
'default-results' => $this->getDefaultResultData()
];
if ($this->maxSelection) {
$result['maximum-selected'] = Yii::t('UserModule.widgets_BasePickerField', 'This field only allows a maximum of {n,plural,=1{# item} other{# items}}.', ['n' => $this->maxSelection]);
}
return $result;
}
protected function getDefaultResultData()
{
$result = [];
foreach ($this->defaultResults as $item) {
$result[] = $this->buildItemOption($item);
}
return $result;
}
/**
* Returns the url for this picker instance. If no $url is set we use the $defaultRoute for creating the url.
*
* @return strings
*/
protected function getUrl()
{
return ($this->url) ? $this->url : Url::to([$this->defaultRoute]);
}
}

View File

@ -8,45 +8,17 @@
namespace humhub\widgets;
use humhub\modules\ui\form\widgets\ColorPicker;
/**
* Adds a color picker form field for the given model.
*
* @see ColorPicker
* @deprecated since 1.3
* @author buddha
*/
class ColorPickerField extends InputWidget
class ColorPickerField extends ColorPicker
{
/**
* @deprecated since v1.2.2 use $attribute instead
*/
public $field;
/**
* The container id used to append the actual color picker js widget.
* @var string
*/
public $container;
/**
* @inheritdoc
*/
public $attribute = 'color';
public function init()
{
if(!empty($this->field)) {
$this->attribute = $this->field;
}
}
public function run()
{
return $this->render('colorPickerField', [
'model' => $this->model,
'field' => $this->attribute,
'container' => $this->container,
'inputId' => $this->getId(true)
]);
}
}

View File

@ -8,102 +8,14 @@
namespace humhub\widgets;
use humhub\libs\Html;
use humhub\modules\content\models\ContentTag;
class ContentTagDropDown extends InputWidget
/**
* Class ContentTagDropDown
*
* @see \humhub\modules\content\widgets\ContentTagDropDown
* @deprecated since 1.3
* @package humhub\widgets
*/
class ContentTagDropDown extends \humhub\modules\content\widgets\ContentTagDropDown
{
/**
* @var string tagClass
*/
public $tagClass;
public $query;
public $contentContainer;
public $includeGlobal = false;
public $type = true;
public $prompt = false;
public $promptValue = 0;
public $items;
private $itemOptions = [];
public function int()
{
if (!$this->tagClass) {
$this->tagClass = ContentTag::class;
// Reset default behavior inf no specific tagClass is given
if ($this->type === true) {
$this->type = null;
}
}
if (!$this->none && !$this->noneLabel) {
$this->noneLabel = Yii::t('ContentModule.widgets_ContentTagDropDown', 'None');
}
}
public function run()
{
$items = $this->getItems();
if (empty($items)) {
return;
}
$options = $this->getOptions();
unset($options['id']);
if ($this->form && $this->hasModel()) {
return $this->form->field($this->model, $this->attribute)->dropDownList($items, $options);
} elseif ($this->hasModel()) {
return Html::activeDropDownList($this->model, $this->attribute, $items, $options);
} else {
return Html::dropDownList($this->name, $this->value, $items, $options);
}
}
public function getAttributes()
{
$result = [
'class' => 'form-control',
'options' => $this->itemOptions
];
if ($this->prompt) {
$result['prompt'] = $this->prompt;
}
return $result;
}
public function getItems()
{
if ($this->items) {
return $this->items;
}
if (!$this->query) {
if ($this->contentContainer) {
$this->query = call_user_func($this->tagClass .'::findByContainer', $this->contentContainer, $this->includeGlobal);
} elseif (!empty($this->type)) {
$type = ($this->type === true) ? $this->tagClass : $this->type;
$this->query = call_user_func($this->tagClass .'::findByType', [$type]);
} else {
$this->query = call_user_func($this->tagClass .'::find');
}
}
$tags = $this->items = $this->query->all();
$result = [];
foreach ($tags as $tag) {
$result[$tag->id] = $tag->name;
$this->itemOptions[$tag->id] = [
'data-type-color' => $tag->color
];
}
return $result;
}
}

View File

@ -8,31 +8,15 @@
namespace humhub\widgets;
use Yii;
use yii\jui\DatePicker as BaseDatePicker;
use humhub\libs\Html;
/**
* DatePicker
*
* @since 1.2.3
* @author Luke
* @see \humhub\modules\ui\form\widgets\DatePicker
* @deprecated since 1.3
* @package humhub\widgets
*/
class DatePicker extends BaseDatePicker
class DatePicker extends \humhub\modules\ui\form\widgets\DatePicker
{
/**
* @inheritdoc
*/
public function init()
{
if ($this->dateFormat === null) {
$this->dateFormat = Yii::$app->formatter->dateInputFormat;
}
Html::addCssClass($this->options, 'form-control');
parent::init();
}
}

View File

@ -8,52 +8,13 @@
namespace humhub\widgets;
use Yii;
use humhub\libs\Html;
use yii\helpers\Json;
use humhub\assets\JqueryTimeEntryAsset;
use humhub\widgets\InputWidget;
/**
* DurationPicker renders an UI form widget to select time durations.
*
* @since 1.2.3
* @see \humhub\modules\ui\form\widgets\DurationPicker
* @deprecated since 1.3
* @author Luke
*/
class DurationPicker extends InputWidget
class DurationPicker extends \humhub\modules\ui\form\widgets\DurationPicker
{
/**
* @inheritdoc
*/
public function run()
{
$view = $this->getView();
$id = $this->options['id'];
$options = [
'show24Hours' => true,
'unlimitedHours' => true,
'defaultTime' => '01:00',
'timeSteps' => [1, 15],
'spinnerImage' => ''
];
JqueryTimeEntryAsset::register($view);
$view->registerJs("$('#{$id}').timeEntry(" . Json::htmlEncode($options) . ");");
Html::addCssClass($this->options, 'form-control');
if ($this->model !== null) {
return Html::activeTextInput($this->model, $this->attribute, $this->getOptions());
} else {
return Html::input($this->name, $this->value, $this->getOptions());
}
}
public static function getDuration(\DateTime $start, \DateTime $end)
{
$duration = $start->diff($end);
return $duration->h . ':' . $duration->m;
}
}

View File

@ -8,102 +8,14 @@
namespace humhub\widgets;
use humhub\widgets\JsWidget;
use yii\base\Model;
use yii\base\InvalidConfigException;
use yii\helpers\Html;
use humhub\modules\ui\form\widgets\JsInputWidget;
/**
* InputWidget is the base class for widgets that collect user inputs.
*
* An input widget can be associated with a data model and an attribute,
* or a name and a value. If the former, the name and the value will
* be generated automatically.
*
* Classes extending from this widget can be used in an [[\yii\widgets\ActiveForm|ActiveForm]]
* using the [[\yii\widgets\ActiveField::widget()|widget()]] method, for example like this:
*
* ```php
* <?= $form->field($model, 'from_date')->widget('WidgetClassName', [
* // configure additional widget properties here
* ]) ?>
* ```
*
* For more details and usage information on InputWidget, see the [guide article on forms](guide:input-forms).
*
* @see JsInputWidget
* @deprecated since 1.3
* @author Luke
* @since 2.0
*/
class InputWidget extends JsWidget
class InputWidget extends JsInputWidget
{
/**
* If the ActiveForm is set, it should be used to create input field.
* This may differ between implementations.
*
* @var \yii\widgets\ActiveForm
*/
public $form;
/**
* @var Model the data model that this widget is associated with.
*/
public $model;
/**
* @var string the model attribute that this widget is associated with.
*/
public $attribute;
/**
* @var string the input name. This must be set if [[model]] and [[attribute]] are not set.
*/
public $name;
/**
* @var string the input value.
*/
public $value;
/**
* @var array the HTML attributes for the input tag.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
if ($this->name === null && !$this->hasModel()) {
throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified.");
}
if (!$this->id && !isset($this->options['id'])) {
$this->id = $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId(true);
}
parent::init();
}
/**
* @return string the field value either by extracting from model or if no model is given `$this->value`
* @since 1.3
*/
protected function getValue()
{
if($this->hasModel()) {
return Html::getAttributeValue($this->model, $this->attribute);
}
return $this->value;
}
/**
* @return bool whether this widget is associated with a data model.
*/
protected function hasModel()
{
return $this->model instanceof Model && $this->attribute !== null;
}
}

View File

@ -8,6 +8,7 @@
namespace humhub\widgets;
use humhub\modules\ui\form\widgets\MarkdownModals;
use Yii;
/**
@ -36,7 +37,7 @@ class LayoutAddons extends BaseStack
$this->addWidget(LoaderWidget::class, ['show' => false, 'id' => "humhub-ui-loader-default"]);
$this->addWidget(StatusBar::class);
$this->addWidget(BlueimpGallery::class);
$this->addWidget(MarkdownFieldModals::class);
$this->addWidget(MarkdownModals::class);
if (Yii::$app->params['enablePjax']) {
$this->addWidget(Pjax::class);

View File

@ -6,150 +6,18 @@
*
*/
/**
* Created by PhpStorm.
* User: buddha
* Date: 18.07.2017
* Time: 14:27
*/
namespace humhub\widgets;
use humhub\assets\BootstrapMarkdownAsset;
use humhub\libs\Html;
use humhub\modules\file\widgets\UploadButton;
use yii\helpers\Url;
use humhub\modules\ui\form\widgets\Markdown;
/**
* Simple Markdown Editor form fields.
*
* @see Markdown
* @deprecated since 1.3
* @package humhub\widgets
* @since 1.2.2
*/
class MarkdownField extends InputWidget
class MarkdownField extends Markdown
{
/**
* @inheritdoc
*/
public $jsWidget = 'ui.markdown.MarkdownField';
/**
* @var int defines the HTML rows attribute of the textarea
*/
public $rows = 3;
/**
* @var string markdown preview url
*/
public $previewUrl;
/**
* HMarkdown parser class used for preview
*
* @var string
*/
public $parserClass = "HMarkdown";
/**
* @var bool show label
*/
public $label = false;
/**
* @var string defines the name of the hidden input name for uploaded files if not set the UploadButton default is used
* @see UploadButton
*/
public $filesInputName;
/**
* Can defined in addition to $fileAttribute to change the form model of the file from $model to $fileModel.
* Note: this is only affects the formName for the file upload.
* @var string
*/
public $fileModel;
/**
* Can be set if $model is defined, to create a loadable fileInput name which is respected in Model::load()
* Note: this is only affects the formName for the file upload.
* @var string
*/
public $fileAttribute;
/**
* @var boolean if set to true the markdown field will be disabled
*/
public $disabled = false;
/**
* @var boolean if set to true the markdown field will set to readonly
*/
public $readonly = false;
/**
* @var string
*/
public $placeholder;
/**
* @inheritdoc
*/
public $fadeIn = 'fast';
/**
* @inheritdoc
*/
public $init = true;
public function init()
{
if (empty($this->previewUrl)) {
$this->previewUrl = Url::toRoute(['/markdown/preview', 'parser' => $this->parserClass]);
}
}
public function run()
{
BootstrapMarkdownAsset::register($this->view);
$this->view->registerCssFile('@web-static/css/bootstrap-markdown-override.css');
if($this->placeholder === null && $this->hasModel()) {
$this->placeholder = $this->model->getAttributeLabel($this->attribute);
}
if ($this->form != null) {
$textArea = $this->form->field($this->model, $this->attribute)->textarea($this->getOptions())->label($this->label);
} else if ($this->model != null) {
$textArea = Html::activeTextarea($this->model, $this->attribute, $this->getOptions());
} else {
$textArea = Html::textarea($this->name, $this->value, $this->getOptions());
}
return $textArea;
}
public function getAttributes()
{
return [
'rows' => $this->rows,
'disabled' => $this->disabled,
'readonly' => $this->readonly,
'placeholder' => $this->placeholder,
'class' => 'form-control'
];
}
public function getData()
{
if(empty($this->fileModel)) {
$this->fileModel = $this->model;
}
if($this->model && $this->fileAttribute) {
$this->filesInputName = $this->fileModel->formName().'['.$this->fileAttribute.'][]';
}
return [
'preview-url' => $this->previewUrl,
'files-input-name' => !empty($this->filesInputName) ? $this->filesInputName : null
];
}
}
}

View File

@ -1,4 +1,5 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
@ -6,22 +7,18 @@
*
*/
/**
* Created by PhpStorm.
* User: buddha
* Date: 18.07.2017
* Time: 15:11
*/
namespace humhub\widgets;
use humhub\modules\ui\form\widgets\MarkdownModals;
use humhub\components\Widget;
class MarkdownFieldModals extends Widget
/**
* Class MarkdownFieldModals
*
* @see MarkdownModals
* @deprecated since 1.3
* @package humhub\widgets
*/
class MarkdownFieldModals extends MarkdownModals
{
public function run() {
return $this->render('markdownFieldModals');
}
}
}

View File

@ -2,78 +2,14 @@
namespace humhub\widgets;
use humhub\modules\ui\form\widgets\MultiSelect;
/**
* @package humhub.modules_core.user.widgets
* @see MultiSelect
* @deprecated since 1.3
* @since 1.2
* @author buddha
*/
class MultiSelectField extends BasePickerField
class MultiSelectField extends MultiSelect
{
/**
* @inerhitdoc
*/
public $minInput = 0;
/**
* Possible values
* @var type
*/
public $items = [];
/**
* @inheritdoc
*/
protected function getItemText($item)
{
return array_values($item)[0];
}
/**
* @inheritdoc
*/
protected function getItemImage($item)
{
return null;
}
protected function getItemKey($item)
{
return key($item);
}
protected function getSelectedOptions()
{
if(empty($this->selection)) {
$attribute = $this->attribute;
$this->selection = ($this->model) ? $this->model->$attribute : [];
}
if(empty($this->selection)) {
$this->selection = [];
}
$result = [];
foreach ($this->items as $key => $value) {
if (!$value || !$key) {
continue;
}
$result[$key] = $this->buildItemOption([$key => $value], in_array($key, $this->selection));
}
return $result;
}
protected function getData()
{
$result = parent::getData();
unset($result['picker-url']);
return $result;
}
protected function getUrl()
{
return null;
}
}

View File

@ -7,22 +7,16 @@
namespace humhub\widgets;
use kartik\base\TranslationTrait;
use kartik\base\WidgetTrait;
use Yii;
class TimePicker extends \kartik\time\TimePicker
/**
* Class TimePicker
*
* @see \humhub\modules\ui\form\widgets\TimePicker
* @deprecated since 1.3
* @package humhub\widgets
*/
class TimePicker extends \humhub\modules\ui\form\widgets\TimePicker
{
public function init()
{
parent::init();
if (!isset($this->pluginOptions['showMeridian'])) {
$this->pluginOptions['showMeridian'] = Yii::$app->formatter->isShowMeridiem();
}
if (!isset($this->pluginOptions['defaultTime'])) {
$this->pluginOptions['defaultTime'] = ($this->pluginOptions['showMeridian']) ? '10:00 AM' : '10:00';
}
}
}