Klimov Paul
10 years ago
6 changed files with 287 additions and 68 deletions
@ -0,0 +1,101 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\bootstrap; |
||||||
|
|
||||||
|
use Yii; |
||||||
|
use yii\helpers\Json; |
||||||
|
|
||||||
|
/** |
||||||
|
* BootstrapWidgetTrait is the trait, which provides basic for all bootstrap widgets features. |
||||||
|
* |
||||||
|
* Note: class, which uses this trait must declare public field named `options` with the array default value: |
||||||
|
* |
||||||
|
* ```php |
||||||
|
* class MyWidget extends \yii\base\Widget |
||||||
|
* { |
||||||
|
* use BootstrapWidgetTrait; |
||||||
|
* |
||||||
|
* public $options = []; |
||||||
|
* } |
||||||
|
* ``` |
||||||
|
* |
||||||
|
* This field is not present in the trait in order to avoid possible PHP Fatal error on definition conflict. |
||||||
|
* |
||||||
|
* @author Antonio Ramirez <amigo.cobos@gmail.com> |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0.5 |
||||||
|
*/ |
||||||
|
trait BootstrapWidgetTrait |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var array the options for the underlying Bootstrap JS plugin. |
||||||
|
* Please refer to the corresponding Bootstrap plugin Web page for possible options. |
||||||
|
* For example, [this page](http://getbootstrap.com/javascript/#modals) shows |
||||||
|
* how to use the "Modal" plugin and the supported options (e.g. "remote"). |
||||||
|
*/ |
||||||
|
public $clientOptions = []; |
||||||
|
/** |
||||||
|
* @var array the event handlers for the underlying Bootstrap JS plugin. |
||||||
|
* Please refer to the corresponding Bootstrap plugin Web page for possible events. |
||||||
|
* For example, [this page](http://getbootstrap.com/javascript/#modals) shows |
||||||
|
* how to use the "Modal" plugin and the supported events (e.g. "shown"). |
||||||
|
*/ |
||||||
|
public $clientEvents = []; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Initializes the widget. |
||||||
|
* This method will register the bootstrap asset bundle. If you override this method, |
||||||
|
* make sure you call the parent implementation first. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if (!isset($this->options['id'])) { |
||||||
|
$this->options['id'] = $this->getId(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Registers a specific Bootstrap plugin and the related events |
||||||
|
* @param string $name the name of the Bootstrap plugin |
||||||
|
*/ |
||||||
|
protected function registerPlugin($name) |
||||||
|
{ |
||||||
|
$view = $this->getView(); |
||||||
|
|
||||||
|
BootstrapPluginAsset::register($view); |
||||||
|
|
||||||
|
$id = $this->options['id']; |
||||||
|
|
||||||
|
if ($this->clientOptions !== false) { |
||||||
|
$options = empty($this->clientOptions) ? '' : Json::htmlEncode($this->clientOptions); |
||||||
|
$js = "jQuery('#$id').$name($options);"; |
||||||
|
$view->registerJs($js); |
||||||
|
} |
||||||
|
|
||||||
|
$this->registerClientEvents(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Registers JS event handlers that are listed in [[clientEvents]]. |
||||||
|
* @since 2.0.2 |
||||||
|
*/ |
||||||
|
protected function registerClientEvents() |
||||||
|
{ |
||||||
|
if (!empty($this->clientEvents)) { |
||||||
|
$id = $this->options['id']; |
||||||
|
$js = []; |
||||||
|
foreach ($this->clientEvents as $event => $handler) { |
||||||
|
$js[] = "jQuery('#$id').on('$event', $handler);"; |
||||||
|
} |
||||||
|
$this->getView()->registerJs(implode("\n", $js)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\bootstrap; |
||||||
|
|
||||||
|
/** |
||||||
|
* InputWidget is an adjusted for bootstrap needs version of [[\yii\widgets\InputWidget]]. |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0.5 |
||||||
|
*/ |
||||||
|
class InputWidget extends \yii\widgets\InputWidget |
||||||
|
{ |
||||||
|
use BootstrapWidgetTrait; |
||||||
|
} |
@ -0,0 +1,107 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\bootstrap; |
||||||
|
|
||||||
|
use yii\base\InvalidConfigException; |
||||||
|
|
||||||
|
/** |
||||||
|
* ToggleButtonGroup allows rendering form inputs Checkbox/Radio toggle button groups. |
||||||
|
* |
||||||
|
* You can use this widget in an [[yii\bootstrap\ActiveForm|ActiveForm]] using the [[yii\widgets\ActiveField::widget()|widget()]] |
||||||
|
* method, for example like this: |
||||||
|
* |
||||||
|
* ```php |
||||||
|
* <?= $form->field($model, 'item_id')->widget(\yii\bootstrap\ToggleButtonGroup::classname(), [ |
||||||
|
* // configure additional widget properties here |
||||||
|
* ]) ?> |
||||||
|
* ``` |
||||||
|
* |
||||||
|
* @see http://getbootstrap.com/javascript/#buttons-checkbox-radio |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0.5 |
||||||
|
*/ |
||||||
|
class ToggleButtonGroup extends InputWidget |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string input type, can be: |
||||||
|
* - 'checkbox' |
||||||
|
* - 'radio' |
||||||
|
*/ |
||||||
|
public $type; |
||||||
|
/** |
||||||
|
* @var array the data item used to generate the checkboxes. |
||||||
|
* The array values are the labels, while the array keys are the corresponding checkbox or radio values. |
||||||
|
*/ |
||||||
|
public $items = []; |
||||||
|
/** |
||||||
|
* @var array, the HTML attributes for the label (button) tag. |
||||||
|
* @see Html::checkbox() |
||||||
|
* @see Html::radio() |
||||||
|
*/ |
||||||
|
public $labelOptions = []; |
||||||
|
/** |
||||||
|
* @var boolean whether the items labels should be HTML-encoded. |
||||||
|
*/ |
||||||
|
public $encodeLabels = true; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
$this->registerPlugin('button'); |
||||||
|
Html::addCssClass($this->options, 'btn-group'); |
||||||
|
$this->options['data-toggle'] = 'buttons'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function run() |
||||||
|
{ |
||||||
|
if (!isset($this->options['item'])) { |
||||||
|
$this->options['item'] = [$this, 'renderItem']; |
||||||
|
} |
||||||
|
switch ($this->type) { |
||||||
|
case 'checkbox' : |
||||||
|
return Html::activeCheckboxList($this->model, $this->attribute, $this->items, $this->options); |
||||||
|
case 'radio': |
||||||
|
return Html::activeRadioList($this->model, $this->attribute, $this->items, $this->options); |
||||||
|
default: |
||||||
|
throw new InvalidConfigException("Unsupported type '{$this->type}'"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Default callback for checkbox/radio list item rendering. |
||||||
|
* @param integer $index item index. |
||||||
|
* @param string $label item label. |
||||||
|
* @param string $name input name. |
||||||
|
* @param boolean $checked whether value is checked or not. |
||||||
|
* @param string $value input value. |
||||||
|
* @return string generated HTML. |
||||||
|
* @see Html::checkbox() |
||||||
|
* @see Html::radio() |
||||||
|
*/ |
||||||
|
public function renderItem($index, $label, $name, $checked, $value) |
||||||
|
{ |
||||||
|
$labelOptions = $this->labelOptions; |
||||||
|
Html::addCssClass($labelOptions, 'btn'); |
||||||
|
if ($checked) { |
||||||
|
Html::addCssClass($labelOptions, 'active'); |
||||||
|
} |
||||||
|
$type = $this->type; |
||||||
|
if ($this->encodeLabels) { |
||||||
|
$label = Html::encode($label); |
||||||
|
} |
||||||
|
return Html::$type($name, $checked, ['label' => $label, 'labelOptions' => $labelOptions, 'value' => $value]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\bootstrap; |
||||||
|
|
||||||
|
use yii\base\Model; |
||||||
|
use yii\bootstrap\ToggleButtonGroup; |
||||||
|
|
||||||
|
/** |
||||||
|
* @group bootstrap |
||||||
|
*/ |
||||||
|
class ToggleButtonGroupTest extends TestCase |
||||||
|
{ |
||||||
|
public function testCheckbox() |
||||||
|
{ |
||||||
|
ToggleButtonGroup::$counter = 0; |
||||||
|
$html = ToggleButtonGroup::widget([ |
||||||
|
'type' => 'checkbox', |
||||||
|
'model' => new ToggleButtonGroupTestModel(), |
||||||
|
'attribute' => 'value', |
||||||
|
'items' => [ |
||||||
|
'1' => 'item 1', |
||||||
|
'2' => 'item 2', |
||||||
|
], |
||||||
|
]); |
||||||
|
|
||||||
|
$expectedHtml = <<<HTML |
||||||
|
<input type="hidden" name="ToggleButtonGroupTestModel[value]" value=""><div id="togglebuttongrouptestmodel-value" class="btn-group" data-toggle="buttons"><label class="btn"><input type="checkbox" name="ToggleButtonGroupTestModel[value][]" value="1"> item 1</label> |
||||||
|
<label class="btn"><input type="checkbox" name="ToggleButtonGroupTestModel[value][]" value="2"> item 2</label></div> |
||||||
|
HTML; |
||||||
|
$this->assertEqualsWithoutLE($expectedHtml, $html); |
||||||
|
} |
||||||
|
|
||||||
|
public function testRadio() |
||||||
|
{ |
||||||
|
ToggleButtonGroup::$counter = 0; |
||||||
|
$html = ToggleButtonGroup::widget([ |
||||||
|
'type' => 'radio', |
||||||
|
'model' => new ToggleButtonGroupTestModel(), |
||||||
|
'attribute' => 'value', |
||||||
|
'items' => [ |
||||||
|
'1' => 'item 1', |
||||||
|
'2' => 'item 2', |
||||||
|
], |
||||||
|
]); |
||||||
|
|
||||||
|
$expectedHtml = <<<HTML |
||||||
|
<input type="hidden" name="ToggleButtonGroupTestModel[value]" value=""><div id="togglebuttongrouptestmodel-value" class="btn-group" data-toggle="buttons"><label class="btn"><input type="radio" name="ToggleButtonGroupTestModel[value]" value="1"> item 1</label> |
||||||
|
<label class="btn"><input type="radio" name="ToggleButtonGroupTestModel[value]" value="2"> item 2</label></div> |
||||||
|
HTML; |
||||||
|
$this->assertEqualsWithoutLE($expectedHtml, $html); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ToggleButtonGroupTestModel extends Model |
||||||
|
{ |
||||||
|
public $value; |
||||||
|
} |
Loading…
Reference in new issue