PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/widgets/BootActiveForm.php

https://bitbucket.org/Crisu83/yii-bootstrap/
PHP | 432 lines | 212 code | 48 blank | 172 comment | 25 complexity | c040964d2bf702ce5b6da3ef791021e6 MD5 | raw file
Possible License(s): BSD-2-Clause, Apache-2.0, BSD-3-Clause, GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * BootActiveForm class file.
  4. * @author Christoffer Niska <ChristofferNiska@gmail.com>
  5. * @copyright Copyright &copy; Christoffer Niska 2011-
  6. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  7. */
  8. class BootActiveForm extends CActiveForm
  9. {
  10. /**
  11. * @var string the error message type. Valid types are 'inline' and 'block'.
  12. */
  13. public $errorMessageType = 'inline';
  14. /**
  15. * @var boolean whether this is a stacked form.
  16. */
  17. public $stacked = false;
  18. /**
  19. * Initializes the widget.
  20. * This renders the form open tag.
  21. */
  22. public function init()
  23. {
  24. $cssClass = $this->stacked ? 'form-stacked' : '';
  25. if (!isset($this->htmlOptions['class']))
  26. $this->htmlOptions['class'] = $cssClass;
  27. else
  28. $this->htmlOptions['class'] .= ' '.$cssClass;
  29. if ($this->errorMessageType === 'inline')
  30. $this->errorMessageCssClass = 'help-inline';
  31. else
  32. $this->errorMessageCssClass = 'help-block';
  33. parent::init();
  34. }
  35. /**
  36. * Creates an input row of a specific type.
  37. * @param string $type the input type
  38. * @param CModel $model the data model
  39. * @param string $attribute the attribute
  40. * @param array $data the data for list inputs
  41. * @param array $htmlOptions additional HTML attributes
  42. * @return string the generated row
  43. */
  44. public function inputRow($type, $model, $attribute, $data = null, $htmlOptions = array())
  45. {
  46. ob_start();
  47. Yii::app()->controller->widget('bootstrap.widgets.BootInput',array(
  48. 'type'=>$type,
  49. 'form'=>$this,
  50. 'model'=>$model,
  51. 'attribute'=>$attribute,
  52. 'data'=>$data,
  53. 'htmlOptions'=>$htmlOptions,
  54. ));
  55. return ob_get_clean();
  56. }
  57. /**
  58. * Renders a checkbox input row.
  59. * @param CModel $model the data model
  60. * @param string $attribute the attribute
  61. * @param array $htmlOptions additional HTML attributes
  62. * @return string the generated row
  63. */
  64. public function checkBoxRow($model, $attribute, $htmlOptions = array())
  65. {
  66. return $this->inputRow('checkbox', $model, $attribute, null, $htmlOptions);
  67. }
  68. /**
  69. * Renders a checkbox list input row.
  70. * @param CModel $model the data model
  71. * @param string $attribute the attribute
  72. * @param array $data the list data
  73. * @param array $htmlOptions additional HTML attributes
  74. * @return string the generated row
  75. */
  76. public function checkBoxListRow($model, $attribute, $data = array(), $htmlOptions = array())
  77. {
  78. return $this->inputRow('checkboxlist', $model, $attribute, $data, $htmlOptions);
  79. }
  80. /**
  81. * Renders a drop-down list input row.
  82. * @param CModel $model the data model
  83. * @param string $attribute the attribute
  84. * @param array $data the list data
  85. * @param array $htmlOptions additional HTML attributes
  86. * @return string the generated row
  87. */
  88. public function dropDownListRow($model, $attribute, $data = array(), $htmlOptions = array())
  89. {
  90. return $this->inputRow('dropdownlist', $model, $attribute, $data, $htmlOptions);
  91. }
  92. /**
  93. * Renders a file field input row.
  94. * @param CModel $model the data model
  95. * @param string $attribute the attribute
  96. * @param array $htmlOptions additional HTML attributes
  97. * @return string the generated row
  98. */
  99. public function fileFieldRow($model, $attribute, $htmlOptions = array())
  100. {
  101. return $this->inputRow('filefield', $model, $attribute, null, $htmlOptions);
  102. }
  103. /**
  104. * Renders a password field input row.
  105. * @param CModel $model the data model
  106. * @param string $attribute the attribute
  107. * @param array $htmlOptions additional HTML attributes
  108. * @return string the generated row
  109. */
  110. public function passwordFieldRow($model, $attribute, $htmlOptions = array())
  111. {
  112. return $this->inputRow('password', $model, $attribute, null, $htmlOptions);
  113. }
  114. /**
  115. * Renders a radio button input row.
  116. * @param CModel $model the data model
  117. * @param string $attribute the attribute
  118. * @param array $htmlOptions additional HTML attributes
  119. * @return string the generated row
  120. */
  121. public function radioButtonRow($model, $attribute, $htmlOptions = array())
  122. {
  123. return $this->inputRow('radiobutton', $model, $attribute, null, $htmlOptions);
  124. }
  125. /**
  126. * Renders a radio button list input row.
  127. * @param CModel $model the data model
  128. * @param string $attribute the attribute
  129. * @param array $data the list data
  130. * @param array $htmlOptions additional HTML attributes
  131. * @return string the generated row
  132. */
  133. public function radioButtonListRow($model, $attribute, $data = array(), $htmlOptions = array())
  134. {
  135. return $this->inputRow('radiobuttonlist', $model, $attribute, $data, $htmlOptions);
  136. }
  137. /**
  138. * Renders a text field input row.
  139. * @param CModel $model the data model
  140. * @param string $attribute the attribute
  141. * @param array $htmlOptions additional HTML attributes
  142. * @return string the generated row
  143. */
  144. public function textFieldRow($model, $attribute, $htmlOptions = array())
  145. {
  146. return $this->inputRow('textfield', $model, $attribute, null, $htmlOptions);
  147. }
  148. /**
  149. * Renders a text area input row.
  150. * @param CModel $model the data model
  151. * @param string $attribute the attribute
  152. * @param array $htmlOptions additional HTML attributes
  153. * @return string the generated row
  154. */
  155. public function textAreaRow($model, $attribute, $htmlOptions = array())
  156. {
  157. return $this->inputRow('textarea', $model, $attribute, null, $htmlOptions);
  158. }
  159. /**
  160. * Renders a captcha row.
  161. * @param CModel $model the data model
  162. * @param string $attribute the attribute
  163. * @param array $htmlOptions additional HTML attributes
  164. * @return string the generated row
  165. * @since 0.9.3
  166. */
  167. public function captchaRow($model, $attribute, $htmlOptions = array())
  168. {
  169. return $this->inputRow('captcha', $model, $attribute, null, $htmlOptions);
  170. }
  171. /**
  172. * Renders an uneditable text field row.
  173. * @param CModel $model the data model
  174. * @param string $attribute the attribute
  175. * @param array $htmlOptions additional HTML attributes
  176. * @return string the generated row
  177. * @since 0.9.5
  178. */
  179. public function uneditableRow($model, $attribute, $htmlOptions = array())
  180. {
  181. return $this->inputRow('uneditable', $model, $attribute, null, $htmlOptions);
  182. }
  183. /**
  184. * Renders a checkbox list for a model attribute.
  185. * This method is a wrapper of {@link CHtml::activeCheckBoxList}.
  186. * Please check {@link CHtml::activeCheckBoxList} for detailed information
  187. * about the parameters for this method.
  188. * @param CModel $model the data model
  189. * @param string $attribute the attribute
  190. * @param array $data value-label pairs used to generate the check box list.
  191. * @param array $htmlOptions additional HTML options.
  192. * @return string the generated check box list
  193. * @since 0.9.5
  194. */
  195. public function checkBoxList($model, $attribute, $data, $htmlOptions = array())
  196. {
  197. return $this->inputsList('checkbox', $model, $attribute, $data, $htmlOptions);
  198. }
  199. /**
  200. * Renders a radio button list for a model attribute.
  201. * This method is a wrapper of {@link CHtml::activeRadioButtonList}.
  202. * Please check {@link CHtml::activeRadioButtonList} for detailed information
  203. * about the parameters for this method.
  204. * @param CModel $model the data model
  205. * @param string $attribute the attribute
  206. * @param array $data value-label pairs used to generate the radio button list.
  207. * @param array $htmlOptions additional HTML options.
  208. * @return string the generated radio button list
  209. * @since 0.9.5
  210. */
  211. public function radioButtonList($model, $attribute, $data, $htmlOptions = array())
  212. {
  213. return $this->inputsList('radio', $model, $attribute, $data, $htmlOptions);
  214. }
  215. /**
  216. * Renders an input list.
  217. * @param string $type the input type. Valid types are 'checkbox' and 'radio'.
  218. * @param CModel $model the data model
  219. * @param string $attribute the attribute
  220. * @param array $data value-label pairs used to generate the radio button list.
  221. * @param array $htmlOptions additional HTML options.
  222. * @return string the generated input list.
  223. * @since 0.9.5
  224. */
  225. protected function inputsList($type, $model, $attribute, $data, $htmlOptions = array())
  226. {
  227. CHtml::resolveNameID($model, $attribute, $htmlOptions);
  228. $selection = CHtml::resolveValue($model, $attribute);
  229. if ($model->hasErrors($attribute))
  230. {
  231. if(isset($htmlOptions['class']))
  232. $htmlOptions['class'] .= ' '.CHtml::$errorCss;
  233. else
  234. $htmlOptions['class'] = CHtml::$errorCss;
  235. }
  236. $name = $htmlOptions['name'];
  237. unset($htmlOptions['name']);
  238. if (array_key_exists('uncheckValue', $htmlOptions))
  239. {
  240. $uncheck = $htmlOptions['uncheckValue'];
  241. unset($htmlOptions['uncheckValue']);
  242. }
  243. else
  244. $uncheck = '';
  245. $hiddenOptions = isset($htmlOptions['id']) ? array('id' => CHtml::ID_PREFIX.$htmlOptions['id']) : array('id' => false);
  246. $hidden = $uncheck !== null ? CHtml::hiddenField($name, $uncheck, $hiddenOptions) : '';
  247. unset($htmlOptions['template'], $htmlOptions['separator'], $htmlOptions['labelOptions']);
  248. $items = array();
  249. $baseID = CHtml::getIdByName($name);
  250. $id = 0;
  251. $method = $type === 'checkbox' ? 'checkBox' : 'radioButton';
  252. foreach($data as $value => $label)
  253. {
  254. $checked =! strcmp($value, $selection);
  255. $htmlOptions['value'] = $value;
  256. $htmlOptions['id'] = $baseID.'_'.$id++;
  257. $option = CHtml::$method($name, $checked, $htmlOptions);
  258. $items[] = '<label>'.$option.'<span>'.$label.'</span></label>';
  259. }
  260. return $hidden.'<ul class="inputs-list"><li>'.implode('</li><li>',$items).'</li></ul>';
  261. }
  262. /**
  263. * Displays a summary of validation errors for one or several models.
  264. * This method is very similar to {@link CHtml::errorSummary} except that it also works
  265. * when AJAX validation is performed.
  266. * @param mixed $models the models whose input errors are to be displayed. This can be either
  267. * a single model or an array of models.
  268. * @param string $header a piece of HTML code that appears in front of the errors
  269. * @param string $footer a piece of HTML code that appears at the end of the errors
  270. * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
  271. * @return string the error summary. Empty if no errors are found.
  272. * @see CHtml::errorSummary
  273. */
  274. public function errorSummary($models, $header = null, $footer = null, $htmlOptions = array())
  275. {
  276. if (!isset($htmlOptions['class']))
  277. $htmlOptions['class'] = 'alert-message block-message error'; // Bootstrap error class as default
  278. return parent::errorSummary($models, $header, $footer, $htmlOptions);
  279. }
  280. /**
  281. * Displays the first validation error for a model attribute.
  282. * @param CModel $model the data model
  283. * @param string $attribute the attribute name
  284. * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
  285. * @param boolean $enableAjaxValidation whether to enable AJAX validation for the specified attribute.
  286. * @param boolean $enableClientValidation whether to enable client-side validation for the specified attribute.
  287. * @return string the validation result (error display or success message).
  288. */
  289. public function error($model, $attribute, $htmlOptions = array(), $enableAjaxValidation = true, $enableClientValidation = true)
  290. {
  291. if (!$this->enableAjaxValidation)
  292. $enableAjaxValidation = false;
  293. if (!$this->enableClientValidation)
  294. $enableClientValidation = false;
  295. if (!isset($htmlOptions['class']))
  296. $htmlOptions['class'] = $this->errorMessageCssClass;
  297. if (!$enableAjaxValidation && !$enableClientValidation)
  298. return $this->errorSpan($model, $attribute, $htmlOptions);
  299. $id = CHtml::activeId($model,$attribute);
  300. $inputID = isset($htmlOptions['inputID']) ? $htmlOptions['inputID'] : $id;
  301. unset($htmlOptions['inputID']);
  302. if (!isset($htmlOptions['id']))
  303. $htmlOptions['id'] = $inputID.'_em_';
  304. $option = array(
  305. 'id'=>$id,
  306. 'inputID'=>$inputID,
  307. 'errorID'=>$htmlOptions['id'],
  308. 'model'=>get_class($model),
  309. 'name'=>CHtml::resolveName($model, $attribute),
  310. 'enableAjaxValidation'=>$enableAjaxValidation,
  311. 'inputContainer'=>'div.clearfix', // Bootstrap requires this
  312. );
  313. $optionNames = array(
  314. 'validationDelay',
  315. 'validateOnChange',
  316. 'validateOnType',
  317. 'hideErrorMessage',
  318. 'inputContainer',
  319. 'errorCssClass',
  320. 'successCssClass',
  321. 'validatingCssClass',
  322. 'beforeValidateAttribute',
  323. 'afterValidateAttribute',
  324. );
  325. foreach ($optionNames as $name)
  326. {
  327. if (isset($htmlOptions[$name]))
  328. {
  329. $option[$name] = $htmlOptions[$name];
  330. unset($htmlOptions[$name]);
  331. }
  332. }
  333. if ($model instanceof CActiveRecord && !$model->isNewRecord)
  334. $option['status'] = 1;
  335. if ($enableClientValidation)
  336. {
  337. $validators = isset($htmlOptions['clientValidation']) ? array($htmlOptions['clientValidation']) : array();
  338. foreach ($model->getValidators($attribute) as $validator)
  339. {
  340. if ($enableClientValidation && $validator->enableClientValidation)
  341. {
  342. if (($js = $validator->clientValidateAttribute($model,$attribute)) != '')
  343. $validators[] = $js;
  344. }
  345. }
  346. if ($validators !== array())
  347. $option['clientValidation']="js:function(value, messages, attribute) {\n".implode("\n",$validators)."\n}";
  348. }
  349. $html = $this->errorSpan($model, $attribute, $htmlOptions);
  350. if ($html === '')
  351. {
  352. if (isset($htmlOptions['style']))
  353. $htmlOptions['style'] = rtrim($htmlOptions['style'], ';').';display:none';
  354. else
  355. $htmlOptions['style'] = 'display:none';
  356. $html = CHtml::tag('span', $htmlOptions, '');
  357. }
  358. $this->attributes[$inputID] = $option;
  359. return $html;
  360. }
  361. /**
  362. * Displays the first validation error for a model attribute.
  363. * @param CModel $model the data model
  364. * @param string $attribute the attribute name
  365. * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
  366. * This parameter has been available since version 1.0.7.
  367. * @return string the error display. Empty if no errors are found.
  368. * @see CModel::getErrors
  369. * @see errorMessageCss
  370. */
  371. public static function errorSpan($model, $attribute, $htmlOptions = array())
  372. {
  373. CHtml::resolveName($model, $attribute);
  374. $error = $model->getError($attribute);
  375. if ($error !== null)
  376. {
  377. if (!isset($htmlOptions['class']))
  378. $htmlOptions['class'] = 'help-inline';
  379. return CHtml::tag('span', $htmlOptions, $error); // Bootstrap errors must be spans
  380. }
  381. else
  382. return '';
  383. }
  384. }