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