vypnutí překladu u options v selectBoxu
- Michal III
- Člen | 83
Řeším úplně stejný problém, ale koukám, že ačkoli jsem našel založené téma dřív, než jsem ho založil sám, odpověď jsem se stejně nedozvěděl.
Opravdu nevíte někdo?
- Michal III
- Člen | 83
Nedokázal jsem přijít na způsob vhodně podědit, protože jsem nedokázal zavolat metodu předka svého předka, takže než abych dělal paralelní třídu, prostě jsem modifikoval SelectBox.
Nicméně se mi zdá, že by tato funkcionalita měla být implementována už v základu, protože jsou situace, kdy chceme přeložit jen label a prompt, ale nikoliv hodnoty v options (např. pokud jsou jako hodnoty v SelectBoxu jména).
- Michal III
- Člen | 83
Modifikoval jsem SelectBox.php následujícím způsobem:
<?php
/**
* This file is part of the Nette Framework (https://nette.org)
*
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*
* For the full copyright and license information, please view
* the file license.txt that was distributed with this source code.
* @package Nette\Forms\Controls
*/
/**
* Select box control that allows single item selection.
*
* @author David Grudl
*
* @property-read mixed $rawValue
* @property bool $prompt
* @property array $items
* @property-read string $selectedItem
* @package Nette\Forms\Controls
*/
class SelectBox extends FormControl
{
/** @var array */
private $items = array();
/** @var array */
protected $allowed = array();
/** @var mixed */
private $prompt = FALSE;
/** @var bool */
private $useKeys = TRUE;
/** @var bool */
private $translateValues = false;
/**
* Sets Translate Values option
* @param array
* @return SelectBox provides a fluent interface
*/
public function setTranslateValues($opt = true)
{
$this->translateValues = $opt;
return $this;
}
/**
* Are values in options translated?
* @return bool
*/
public function areValuesTranslated()
{
return $this->translateValues;
}
/**
* @param string label
* @param array items from which to choose
* @param int number of rows that should be visible
*/
public function __construct($label = NULL, array $items = NULL, $size = NULL)
{
parent::__construct($label);
$this->control->setName('select');
$this->control->size = $size > 1 ? (int) $size : NULL;
if ($items !== NULL) {
$this->setItems($items);
}
}
/**
* Returns selected item key.
* @return mixed
*/
public function getValue()
{
$allowed = $this->allowed;
if ($this->prompt) {
$allowed = array_slice($allowed, 1, count($allowed), TRUE);
}
return is_scalar($this->value) && isset($allowed[$this->value]) ? $this->value : NULL;
}
/**
* Returns selected item key (not checked).
* @return mixed
*/
public function getRawValue()
{
return is_scalar($this->value) ? $this->value : NULL;
}
/**
* Has been any item selected?
* @return bool
*/
public function isFilled()
{
$value = $this->getValue();
return is_array($value) ? count($value) > 0 : $value !== NULL;
}
/**
* Ignores the first item in select box.
* @param string
* @return SelectBox provides a fluent interface
*/
public function setPrompt($prompt)
{
$this->prompt = $prompt;
if ($prompt !== NULL && !is_bool($prompt)) {
$this->items = array('' => $prompt) + $this->items;
$this->allowed = array('' => '') + $this->allowed;
}
return $this;
}
/** @deprecated */
function skipFirst($v = NULL)
{
trigger_error(__METHOD__ . '() is deprecated; use setPrompt() instead.', E_USER_WARNING);
return $this->setPrompt($v);
}
/**
* Is first item in select box ignored?
* @return bool
*/
final public function getPrompt()
{
return $this->prompt;
}
/**
* Are the keys used?
* @return bool
*/
final public function areKeysUsed()
{
return $this->useKeys;
}
/**
* Sets items from which to choose.
* @param array
* @return SelectBox provides a fluent interface
*/
public function setItems(array $items, $useKeys = TRUE)
{
$this->items = $items;
if ($this->prompt) {
$this->items = array('' => is_bool($this->prompt) ? $this->items[''] : $this->prompt) + $this->items;
}
$this->allowed = $this->prompt ? array('' => '') : array();
$this->useKeys = (bool) $useKeys;
foreach ($items as $key => $value) {
if (!is_array($value)) {
$value = array($key => $value);
}
foreach ($value as $key2 => $value2) {
if (!$this->useKeys) {
if (!is_scalar($value2)) {
throw new InvalidArgumentException("All items must be scalar.");
}
$key2 = $value2;
}
if (isset($this->allowed[$key2])) {
throw new InvalidArgumentException("Items contain duplication for key '$key2'.");
}
$this->allowed[$key2] = $value2;
}
}
return $this;
}
/**
* Returns items from which to choose.
* @return array
*/
final public function getItems()
{
return $this->items;
}
/**
* Returns selected value.
* @return string
*/
public function getSelectedItem()
{
if (!$this->useKeys) {
return $this->getValue();
} else {
$value = $this->getValue();
return $value === NULL ? NULL : $this->allowed[$value];
}
}
/**
* Generates control's HTML element.
* @return Html
*/
public function getControl()
{
$control = parent::getControl();
if ($this->prompt) {
reset($this->items);
$control->data('nette-empty-value', $this->useKeys ? key($this->items) : current($this->items));
}
$selected = $this->getValue();
$selected = is_array($selected) ? array_flip($selected) : array($selected => TRUE);
$option = Html::el('option');
//******
if($this->prompt && array_key_exists('', $this->items)) $this->items[''] = $this->translate($this->items['']);
foreach ($this->items as $key => $value) {
if (!is_array($value)) {
$value = array($key => $value);
$dest = $control;
} else {
$dest = $control->create('optgroup')->label($this->translate($key));
}
foreach ($value as $key2 => $value2) {
if ($value2 instanceof Html) {
$dest->add((string) $value2->selected(isset($selected[$key2])));
} else {
$key2 = $this->useKeys ? $key2 : $value2;
//$value2 = $this->translate((string) $value2);
$value2 = $this->translateValues ? $this->translate((string) $value2) : (string) $value2;
$dest->add((string) $option->value($key2)
->selected(isset($selected[$key2]))
->setText($value2));
}
}
}
return $control;
}
}
?>
Přidal jsem tedy proměnnou $translateValues, defaultně je vypnuto, pro změnu stavu se používá metoda setTranslateValues($opt = true).
- pawouk
- Člen | 172
Určitě bych se vyhnul modifikování kodu třetích stran, to je vždy špatná volba. Je potřeba bud podědit, což jde skoro vždy. Je občas narazim na nějakou vyjímku třeba u metody final. A nabo méně vhodné je třídu zkopírovat a přejmenovat Namespace například na XNette. Určitě ale nikdy needitovat Nette (tedy ani žádnou jinou knihovnu).
- Michal III
- Člen | 83
Také mě to štve, ale bohužel, jak již jsem říkal, u té třídy SelectBox, kterou bych měl dědit, bych potřeboval přepsat jednu metodu, která nejprve zavolá metodu svého předka a bohužel nelze zavolat parent::parent::metoda();
- jtousek
- Člen | 951
@pawouk: Dovolil bych si nesouhlasit. :-) Od té doby co je spousta projektů takhle na GitHubu je v podobných případech naopak vhodné knihovnu upravit přímo a poslat pull request.
Má zkušenost je taková, že se nebojím zasahovat do kódu Nette (nebo jiných knihoven) když to potřebuji – časem se většina změn stejně objeví přímo v oficiálním Nette nebo přijdu na jiný způsob. Právě teď sice používám svou upravenou verzi, ale Nette 2.1 všechny ty úpravy bude mít také.
- Panda
- Člen | 569
Teď jsem to taky potřeboval a zkusil jsem najít, jestli to v současném
Nette nejde už nějak zařídit… A pořád je to stejné.
SelectBox
u jde předat v poli hodnot místo stringu Html element
<option>
. Stačí pole sestavit takto (pozor,
value
musíme option
u specifikovat sami!):
$newItems = array();
foreach ($items as $key => $value) {
$newItems[$key] = \Nette\Utils\Html::el('option')->value($key)->setText($value);
}
Pole $newItems
je pak možné použít jako pole hodnot a texty
v objektech Html
nejsou překládány.
Editoval Panda (20. 8. 2012 17:35)
- SvvimX
- Člen | 65
přišel jsem na to uplně náhodou, nebo se do Nette tato možnost přidala?
Stačí prostě:
$this ->addSelect( "year", __ ( "Year" ), $years )
->setDefaultValue( date("Y") )
->setPrompt( __ ( "== Year ==" ) )
->setTranslator( NULL )
;
nastavit setTranslator( NULL ) ale pak je potřeba ručně přeložit název a prompt.