PageRenderTime 50ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/www/libs/nette-dev/Forms/Controls/SelectBox.php

https://github.com/bazo/Mokuji
PHP | 243 lines | 119 code | 52 blank | 72 comment | 17 complexity | fe3c9e2645b4a0355e1a64d5fe6c92f1 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. <?php
  2. /**
  3. * Nette Framework
  4. *
  5. * @copyright Copyright (c) 2004, 2010 David Grudl
  6. * @license http://nettephp.com/license Nette license
  7. * @link http://nettephp.com
  8. * @category Nette
  9. * @package Nette\Forms
  10. */
  11. /**
  12. * Select box control that allows single item selection.
  13. *
  14. * @copyright Copyright (c) 2004, 2010 David Grudl
  15. * @package Nette\Forms
  16. *
  17. * @property-read mixed $rawValue
  18. * @property array $items
  19. * @property-read mixed $selectedItem
  20. * @property-read bool $firstSkipped
  21. */
  22. class SelectBox extends FormControl
  23. {
  24. /** @var array */
  25. private $items = array();
  26. /** @var array */
  27. protected $allowed = array();
  28. /** @var bool */
  29. private $skipFirst = FALSE;
  30. /** @var bool */
  31. private $useKeys = TRUE;
  32. /**
  33. * @param string label
  34. * @param array items from which to choose
  35. * @param int number of rows that should be visible
  36. */
  37. public function __construct($label = NULL, array $items = NULL, $size = NULL)
  38. {
  39. parent::__construct($label);
  40. $this->control->setName('select');
  41. $this->control->size = $size > 1 ? (int) $size : NULL;
  42. $this->control->onfocus = 'this.onmousewheel=function(){return false}'; // prevents accidental change in IE
  43. $this->label->onclick = 'document.getElementById(this.htmlFor).focus();return false'; // prevents deselect in IE 5 - 6
  44. if ($items !== NULL) {
  45. $this->setItems($items);
  46. }
  47. }
  48. /**
  49. * Returns selected item key.
  50. * @return mixed
  51. */
  52. public function getValue()
  53. {
  54. $allowed = $this->allowed;
  55. if ($this->skipFirst) {
  56. $allowed = array_slice($allowed, 1, count($allowed), TRUE);
  57. }
  58. return is_scalar($this->value) && isset($allowed[$this->value]) ? $this->value : NULL;
  59. }
  60. /**
  61. * Returns selected item key (not checked).
  62. * @return mixed
  63. */
  64. public function getRawValue()
  65. {
  66. return is_scalar($this->value) ? $this->value : NULL;
  67. }
  68. /**
  69. * Ignores the first item in select box.
  70. * @param string
  71. * @return SelectBox provides a fluent interface
  72. */
  73. public function skipFirst($item = NULL)
  74. {
  75. if (is_bool($item)) {
  76. $this->skipFirst = $item;
  77. } else {
  78. $this->skipFirst = TRUE;
  79. if ($item !== NULL) {
  80. $this->items = array('' => $item) + $this->items;
  81. $this->allowed = array('' => '') + $this->allowed;
  82. }
  83. }
  84. return $this;
  85. }
  86. /**
  87. * Is first item in select box ignored?
  88. * @return bool
  89. */
  90. final public function isFirstSkipped()
  91. {
  92. return $this->skipFirst;
  93. }
  94. /**
  95. * Are the keys used?
  96. * @return bool
  97. */
  98. final public function areKeysUsed()
  99. {
  100. return $this->useKeys;
  101. }
  102. /**
  103. * Sets items from which to choose.
  104. * @param array
  105. * @return SelectBox provides a fluent interface
  106. */
  107. public function setItems(array $items, $useKeys = TRUE)
  108. {
  109. $this->items = $items;
  110. $this->allowed = array();
  111. $this->useKeys = (bool) $useKeys;
  112. foreach ($items as $key => $value) {
  113. if (!is_array($value)) {
  114. $value = array($key => $value);
  115. }
  116. foreach ($value as $key2 => $value2) {
  117. if (!$this->useKeys) {
  118. if (!is_scalar($value2)) {
  119. throw new InvalidArgumentException("All items must be scalars.");
  120. }
  121. $key2 = $value2;
  122. }
  123. if (isset($this->allowed[$key2])) {
  124. throw new InvalidArgumentException("Items contain duplication for key '$key2'.");
  125. }
  126. $this->allowed[$key2] = $value2;
  127. }
  128. }
  129. return $this;
  130. }
  131. /**
  132. * Returns items from which to choose.
  133. * @return array
  134. */
  135. final public function getItems()
  136. {
  137. return $this->items;
  138. }
  139. /**
  140. * Returns selected value.
  141. * @return string
  142. */
  143. public function getSelectedItem()
  144. {
  145. if (!$this->useKeys) {
  146. return $this->getValue();
  147. } else {
  148. $value = $this->getValue();
  149. return $value === NULL ? NULL : $this->allowed[$value];
  150. }
  151. }
  152. /**
  153. * Generates control's HTML element.
  154. * @return Html
  155. */
  156. public function getControl()
  157. {
  158. $control = parent::getControl();
  159. $selected = $this->getValue();
  160. $selected = is_array($selected) ? array_flip($selected) : array($selected => TRUE);
  161. $option = Html::el('option');
  162. foreach ($this->items as $key => $value) {
  163. if (!is_array($value)) {
  164. $value = array($key => $value);
  165. $dest = $control;
  166. } else {
  167. $dest = $control->create('optgroup')->label($key);
  168. }
  169. foreach ($value as $key2 => $value2) {
  170. if ($value2 instanceof Html) {
  171. $dest->add((string) $value2->selected(isset($selected[$key2])));
  172. } elseif ($this->useKeys) {
  173. $dest->add((string) $option->value($key2)->selected(isset($selected[$key2]))->setText($this->translate($value2)));
  174. } else {
  175. $dest->add((string) $option->selected(isset($selected[$value2]))->setText($this->translate($value2)));
  176. }
  177. }
  178. }
  179. return $control;
  180. }
  181. /**
  182. * Filled validator: has been any item selected?
  183. * @param IFormControl
  184. * @return bool
  185. */
  186. public static function validateFilled(IFormControl $control)
  187. {
  188. $value = $control->getValue();
  189. return is_array($value) ? count($value) > 0 : $value !== NULL;
  190. }
  191. }