1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
<?php
namespace MediaWiki\Widget;
use OOUI\CheckboxInputWidget;
use OOUI\FieldLayout;
use OOUI\HtmlSnippet;
use OOUI\Tag;
use OOUI\Widget;
/**
* Check matrix widget. Displays a matrix of checkboxes for given options
*
* @copyright 2018 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license MIT
*/
class CheckMatrixWidget extends Widget {
/** @var string|null */
protected $name;
/** @var string|null */
protected $id;
/** @var array */
protected $columns;
/** @var array */
protected $rows;
/** @var array */
protected $tooltips;
/** @var array */
protected $tooltipsHtml;
/** @var array */
protected $values;
/** @var array */
protected $forcedOn;
/** @var array */
protected $forcedOff;
/**
* Operates similarly to MultiSelectWidget, but instead of using an array of
* options, uses an array of rows and an array of columns to dynamically
* construct a matrix of options. The tags used to identify a particular cell
* are of the form "columnName-rowName"
*
* @param array $config Configuration array with the following options:
* - columns
* - Required associative array mapping column labels (as HTML) to their tags.
* - rows
* - Required associative array mapping row labels (as HTML) to their tags.
* - force-options-on
* - Array of column-row tags to be displayed as enabled but unavailable to change.
* - force-options-off
* - Array of column-row tags to be displayed as disabled but unavailable to change.
* - tooltips
* - Optional associative array mapping row labels to tooltips (as text, will be escaped).
* - tooltips-html
* - Optional associative array mapping row labels to tooltips (as HTML). Takes precedence
* over text tooltips.
*/
public function __construct( array $config = [] ) {
// Configuration initialization
parent::__construct( $config );
$this->name = $config['name'] ?? null;
$this->id = $config['id'] ?? null;
// Properties
$this->rows = $config['rows'] ?? [];
$this->columns = $config['columns'] ?? [];
$this->tooltips = $config['tooltips'] ?? [];
$this->tooltipsHtml = $config['tooltips-html'] ?? [];
$this->values = $config['values'] ?? [];
$this->forcedOn = $config['forcedOn'] ?? [];
$this->forcedOff = $config['forcedOff'] ?? [];
// Build the table
$table = new Tag( 'table' );
$table->addClasses( [ 'mw-htmlform-matrix mw-widget-checkMatrixWidget-matrix' ] );
$thead = new Tag( 'thead' );
$table->appendContent( $thead );
$tr = new Tag( 'tr' );
// Build the header
$tr->appendContent( $this->getCellTag( "\u{00A0}" ) );
foreach ( $this->columns as $columnLabel => $columnTag ) {
$tr->appendContent(
$this->getCellTag( new HtmlSnippet( $columnLabel ), 'th' )
);
}
$thead->appendContent( $tr );
// Build the options matrix
$tbody = new Tag( 'tbody' );
$table->appendContent( $tbody );
foreach ( $this->rows as $rowLabel => $rowTag ) {
$tbody->appendContent(
$this->getTableRow( $rowLabel, $rowTag )
);
}
// Initialization
$this->addClasses( [ 'mw-widget-checkMatrixWidget' ] );
$this->appendContent( $table );
}
/**
* Get a formatted table row for the option, with
* a checkbox widget.
*
* @param string $label Row label (as HTML)
* @param string $tag Row tag name
*
* @return Tag The resulting table row
*/
private function getTableRow( $label, $tag ) {
$row = new Tag( 'tr' );
$tooltip = $this->getTooltip( $label );
$labelFieldConfig = $tooltip ? [ 'help' => $tooltip ] : [];
// Build label cell
$labelField = new FieldLayout(
new Widget(), // Empty widget, since we don't have the checkboxes here
[
'label' => new HtmlSnippet( $label ),
'align' => 'inline',
] + $labelFieldConfig
);
$row->appendContent( $this->getCellTag( $labelField ) );
// Build checkbox column cells
foreach ( $this->columns as $columnTag ) {
$thisTag = "$columnTag-$tag";
// Construct a checkbox
$checkbox = new CheckboxInputWidget( [
'value' => $thisTag,
'name' => $this->name ? "{$this->name}[]" : null,
'id' => $this->id ? "{$this->id}-$thisTag" : null,
'selected' => $this->isTagChecked( $thisTag ),
'disabled' => $this->isTagDisabled( $thisTag ),
] );
$row->appendContent( $this->getCellTag( $checkbox ) );
}
return $row;
}
/**
* Get an individual cell tag with requested content
*
* @param mixed $content Content for the <td> cell
* @param string $tagElement
* @return Tag Resulting cell
*/
private function getCellTag( $content, $tagElement = 'td' ) {
$cell = new Tag( $tagElement );
$cell->appendContent( $content );
return $cell;
}
/**
* Check whether the given tag's checkbox should
* be checked
*
* @param string $tagName
* @return bool Tag should be checked
*/
private function isTagChecked( $tagName ) {
// If the tag is in the value list
return in_array( $tagName, (array)$this->values, true ) ||
// Or if the tag is forced on
in_array( $tagName, (array)$this->forcedOn, true );
}
/**
* Check whether the given tag's checkbox should
* be disabled
*
* @param string $tagName
* @return bool Tag should be disabled
*/
private function isTagDisabled( $tagName ) {
return (
// If the entire widget is disabled
$this->isDisabled() ||
// If the tag is 'forced on' or 'forced off'
in_array( $tagName, (array)$this->forcedOn, true ) ||
in_array( $tagName, (array)$this->forcedOff, true )
);
}
/**
* Get the tooltip help associated with this row
*
* @param string $label Label name
*
* @return string Tooltip. Null if none is available.
*/
private function getTooltip( $label ) {
if ( isset( $this->tooltipsHtml[ $label ] ) ) {
return new HtmlSnippet( $this->tooltipsHtml[ $label ] );
} else {
return $this->tooltips[ $label ] ?? null;
}
}
protected function getJavaScriptClassName() {
return 'mw.widgets.CheckMatrixWidget';
}
public function getConfig( &$config ) {
$config += [
'name' => $this->name,
'id' => $this->id,
'rows' => $this->rows,
'columns' => $this->columns,
'tooltips' => $this->tooltips,
'tooltipsHtml' => $this->tooltipsHtml,
'forcedOff' => $this->forcedOff,
'forcedOn' => $this->forcedOn,
'values' => $this->values,
];
return parent::getConfig( $config );
}
}
|