Form API - options css class zuweisen
Eingetragen von netzkoop (1820)
am 04.09.2008 - 16:18 Uhr in
am 04.09.2008 - 16:18 Uhr in
Ich möchte folgendes erreichen:
<select>
<option class="format1">Text</option>
<option class="format2">Text</option>
<option class="format3">Text</option>
</select>
Wie bekomme ich das in meine Form Options?
function myform_form() {
...
$options['wähl mich'] = t('Text');
...
'#options' => $options,
...
return $form;
}
merci
- Anmelden oder Registrieren um Kommentare zu schreiben
option mit class
am 05.09.2008 - 08:47 Uhr
Moin!
So wie ich das sehe, funktioniert das (leider) nicht so einfach. Du kannst nur dem
<select>
eine Klasse zuweisen, da#options
einfach nur ein Array mit Textwerten sein kann.Es gab die Anforderung schon mal, die scheint allerdingens bisher nicht in irgendeine Version eingeflossen zu sein.
Eine Möglichkeit, die Du mal ausprobieren könntest, wäre theme_select(). Wenn Du die überschreibst (und Dir eine eigene form_select_options() schreibst), könntest Du das so machen:
<?php
$options = array(
'wähl mich' => array('#value' => t('Text 1'), '#attributes' => array('class' => 'format1')),
'mich auch' => array('#value' => t('Text 2'), '#attributes' => array('class' => 'format2')),
);
?>
hth,
Stefan
PS: Das wäre dann sogar einen Patch für die form.inc wert.
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
form_select_options
am 05.09.2008 - 08:56 Uhr
Hm, hab gerade zuviel Zei :-}
Kann funktionieren, muss jedoch nicht:
<?php
function form_select_options($element, $choices = NULL) {
if (!isset($choices)) {
$choices = $element['#options'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
$value_is_array = is_array($element['#value']);
$options = '';
foreach ($choices as $key => $choice) {
if (isset($choice['#options']) && is_array($choice['#options'])) {
$options .= '<optgroup label="' . $key . '">';
$options .= form_select_options($element, $choice);
$options .= '</optgroup>';
}
elseif (is_object($choice)) {
$options .= form_select_options($element, $choice->option);
}
else {
$key = (string)$key;
if ($value_valid && (!$value_is_array && (string)$element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
$attributes = (isset($choice['#attributes']) ? drupal_attributes($choice['#attributes']) : '');
$options .= '<option value="' . check_plain($key) . '"' . $selected . $attributes '>' . check_plain($choice['#value']) . '</option>';
}
}
return $options;
}
?>
So in der Art könnte das aussehen.
Stefan
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
Hallo Stefan, vielen Dank!
am 05.09.2008 - 09:30 Uhr
Hallo Stefan,
vielen Dank! Damit werde ich gleich mal weiter probieren.
Und dann berichten :-)
-----------
Luca Curella
Kooperative Netze - Berlin
patch
am 05.09.2008 - 09:32 Uhr
Wenn Du das hinbekommen hast, könntest Du das ja gleich mal als patch auf d.o für drupal 7 posten. Das interessiert bestimmt noch mehr Leute.
Stefan
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
patch #2
am 05.09.2008 - 09:38 Uhr
http://drupal.org/node/284917
Da wurde das gleiche mit dem Attribut "disabled" gefordert und auch schon als patch umgesetzt. Vielleicht kannst Du Dich da ja mit einklinken...
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
@stBorchert, das hier kann
am 08.12.2008 - 10:54 Uhr
@stBorchert,
das hier kann wie beschrieben gewollt nicht funktionieren:
<?php
$options = array(
'wähl mich' => array('#value' => t('Text 1'), '#attributes' => array('class' => 'format1')),
'mich auch' => array('#value' => t('Text 2'), '#attributes' => array('class' => 'format2')),
);
?>
Denn dadurch entsteht ein Optgroup-Selectlist.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Da geht noch was.
optgroup
am 08.12.2008 - 13:15 Uhr
Das ist aber lange her :-).
Mal schauen...
Die optgroup wird doch nur unter folgender Bedingung gebildet:
<?php
if (isset($choice['#options']) && is_array($choice['#options']))
?>
Da dies nicht gegeben ist, wird in den
else
Zweig gesprungen und dort dieoption
Elemente mit Attributen aufgebaut.Oder nicht?
Ich glaube, ich muss das wirklich mal an einer echten Seite testen...Ok, habs nun getestet: mit der modifizierten Version von
form_select_options()
(siehe oben) funktioniert es. Damit kann manoption
Elementen auch eigene Klassen und sonstige Attribute zuweisen.Stefan
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
@Stephan, bei der modifiz. Variante von form_select_options() ..
am 08.12.2008 - 14:15 Uhr
@Stephan,
bei der obigen modifizierten Variante von form_select_options(), wie baust Du $element und $choices auf? Ich meine was steckt in $element und $choices damit die Optionen beispielsweise eigene Klassen erhalten?
Edit:
Bei Deinem Test hast Du die oben gepostete modifizierte Variante von form_select_options() verwendet? Ganz sicher?
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Da geht noch was.
select
am 08.12.2008 - 15:06 Uhr
<?php
$options = array(
array('#value' => 1, '#title' => t('Best patch ever'), '#attributes' => array('class' => 'choice-best')),
array('#value' => 2, '#title' => t('Good patch')),
array('#value' => 3, '#title' => t('Have seen better')),
array('#value' => 4, '#title' => t('Are you sure about this one')),
array('#value' => 5, '#title' => t('Bah, go away'), '#attributes' => array('class' => 'choice-worst')),
);
$form['test']['vote'] = array(
'#type' => 'select',
'#title' => t('Vote'),
'#description' => t('Select your rating for this patch. "1" is best while "5" is worst.'),
'#options' => $options,
'#size' => 1,
'#value' => 2
);
?>
Allerdingens sieht die Funktion jetzt etwas anders aus:
<?php
function form_select_options($element, $choices = NULL) {
if (!isset($choices)) {
$choices = $element['#options'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
$value_is_array = is_array($element['#value']);
$options = '';
foreach ($choices as $key => $choice) {
if (!is_array($choice)) {
$choice = array('#value' => $choice);
}
if (isset($choice['#options']) && is_array($choice['#options'])) {
$options .= '<optgroup label="'. $key .'">';
$options .= form_select_options($element, $choice);
$options .= '</optgroup>';
}
elseif (is_object($choice)) {
$options .= form_select_options($element, $choice->option);
}
else {
$key = (string)$key;
if ($value_valid && (!$value_is_array && (string)$element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
$attributes = (isset($choice['#attributes']) ? drupal_attributes($choice['#attributes']) : '');
$options .= '<option value="'. check_plain($key) .'"'. $selected . $attributes .'>'. check_plain($choice['#value']) .'</option>';
}
}
return $options;
}
?>
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
@Stefan, ich danke Dir. Aber ...
am 08.12.2008 - 15:52 Uhr
@Stefan, ich danke Dir.
Es ist aber wohl noch eine kleine Aenderung angebracht.
Ich mache das so:
<?php
function get_start_tree($mid, $group_menu) {
// Note: The function expects a pid
$rows = menu_groups_get_menu_items($group_menu->mid);
$tree = array();
foreach ($rows as $item) {
$tree[$item->path] = array('#title' => $item->title, '#attributes' => array('class' => 'menu-' . $item->mid));
}
return build_dropdown($tree, $group_menu->title, 'tree-block', 'learn-dropdown', FALSE, array('class' => 'tree-block-' . $mid));
}
function build_dropdown($options, $title = FALSE, $id = 'vc-learn', $name = 'dropdown', $value = FALSE, $attributes = array()) {
$element = array(
'#title' => $title,
'#attributes' => $attributes,
'#id' => $id,
'#name' => $name,
'#size' => 1,
'#options' => $options,
'#value' => $value,
'#multiple' => FALSE,
'#parents' => array(0),
);
return theme('select', $element);
}
?>
Damit der Titel richtig verwendet wird (und nicht '#value') hier meine kleine Aenderung gegenueber Deiner in form_select_options():
<?php
$options .= '<option value="'. check_plain($key) .'"'. $selected . $attributes .'>'. check_plain($choice['#title']) .'</option>';
?>
Also $choice['#value'] zu $choice['#title'] geaendert.
PS
Deine Loesung mit der veraenderten form_select_options() hat mich bei meiner aktuellen Aufgabe schnell weiter gebracht. :-)
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Da geht noch was.
option
am 08.12.2008 - 16:13 Uhr
@Stefan, ich danke Dir.
Aber gerne doch.
Deine Loesung mit der veraenderten form_select_options() hat mich bei meiner aktuellen Aufgabe schnell weiter gebracht. :-)
Super. Wieder eine gute Tat :-)
Kleine Anmerkung zu '#title' vs. '#value': warum baust Du die Optionen nicht gleich mit '#value' auf (ja, ich weiss. Es ist der Titel von $item. Jedoch verwendest Du ihn als Wert der Option)? Wenn dieser Patch endlich mal richtig passt, wird das wahrscheinlich in d7 Core einfliessen und dann entspricht das dem API.
'#value' wird ja immer als Wert genommen und '#title' als Titel (wie der Name schon sagt :-)).
Solange das als "Hack" eingebaut ist, ist das eigentlich vollkommen Wurst, wenn es jedoch mal im Core ist, müsstest Du es wieder umbauen. Und so würdest Du quasi jetzt schon ein Feature von Drupal verwenden, das es erst in einiger Zeit gibt. :-)
Ist nur so ein Gedanke, ich will Dir da auf keinen Fall etwas vorschreiben.
Stefan
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
'#title' oder '#value' - Gedanken
am 08.12.2008 - 18:12 Uhr
warum baust Du die Optionen nicht gleich mit '#value'
Das mache ich ja.
$tree[$item->path]
Der Array-Key ist der Value - der Value fuer das Option-Tag ist damit also bereits gesetzt und verwendet. Wenn ich nun Deinem Vorschlag folge verbiegt sich meine Logik gewaltig. Verwende ich Deine Version dann wird der '#value' zum Titel und '#title' zum Value.
Mein '#title' entstammt der Menue-Tabelle. Abgesehen davon, genau genommen ist '#value' der Wert fuer das Option-Tag-Attribut value.
So gesehen kann also ein Wert von '#value' nicht das Option-Feld als Solches bezeichnen da er eines der moeglichen Attribute des Option-Tag ist. Der Value ist eigentlich der wichtigste Parameter des Option-Tag wenn man diesen Wert willkuerlich angeben moechte.
Wenn man den Faden weiterspinnt kann aber auch '#title' nicht das Option-Feld als Solches bezeichnen da auch '#title' eines der moeglichen Attribute des Option-Tag ist.
Laut W3C ist '#title' als Element-Bezeichner nur fuer das Select-Tag moeglich. Daraus ergibt sich das man sich streiten koennte ob '#title' oder '#value' als Element-Bezeichner des Option-Tag verwendet werden. Irgendwie gibt es hierbei fuer mich Unklarheiten die Zweideutigkeiten entstehen lassen.
Wenn man andere Form-Tags betrachtet die eine Eingabe eines Wertes ermoeglichen so ist '#value' ein Attribut dieser Form-Tags. Warum soll da das Option-Tag eine Ausnahme machen - man kann zwar keinen Wert eingeben aber einen auswaehlen.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Da geht noch was.
option
am 08.12.2008 - 23:28 Uhr
Hm, man merkt: keine einfache Thematik :-)
Hast Recht, der angezeigte "Wert" eines
option
Elementes wäre in diesem Fall eher'#label'
statt'#value'
. Ich hab mir das API nochmal durchgeschaut in der Hoffnung ein Attribut für Label zu finden. Das gibt es leider nicht.Vielleicht sollte man statt
$key
'#return_value'
verwenden? Also:<?php
$options = array(
array('#value' => 'angezeigter Wert', '#return_value' => 100, '#attributes' => array()),
...
);
?>
Macht eigentlich auch Sinn, oder? Schliesslich sagt die API-Doku "#return_value: Value element should return when selected".
Ich werde den Patch mal anpassen und schauen, was dazu gesagt wird.
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
Warum eigentlich nur fuer Drupal 7?
am 09.12.2008 - 12:04 Uhr
Macht eigentlich auch Sinn, oder? Schliesslich sagt die API-Doku "#return_value: Value element should return when selected".
Das hoert sich sehr gut an.
Dieser Logik kann ich mich anschliessen. So sollte man den Patch einbringen.
Apropos Patch
Warum eigentlich nur fuer Drupal 7? Die Funktion existiert so auch in Drupal 5 und 6. Fuer diese beiden Versionen macht der Patch ebenso Sinn.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Da geht noch was.
backport
am 09.12.2008 - 12:40 Uhr
Stichwort: "Codefreeze"
Für Drupal 5 und 6 ist die Kernentwicklung bereits abgeschlossen. Ich weiss jetzt nicht, ob eine dann doch so grundlegende Änderung an der FormsAPI überhaupt mit Mini-Releases (5.13 bzw. 6.7) durchgeführt werden würde. Aber fragen kann ich ja mal...
Btw.: ich werde den Patch noch erweitern, so dass
theme_option()
eingeführt wird. Das ist dann noch generischer/sauberer.Tipp: Beachte die Verhaltensregeln des DrupalCenter.
Das HTML-Disaster von value.
am 09.12.2008 - 13:52 Uhr
Das mit der theme_option() erscheint mir sinnvoll.
Aber noch was anderes.
Das HTML-Disaster von value
Ein value ist nach allgemeinem Verständnis ein Wert den man in einem Formelement eintragen kann und der sich ändern kann. In diesem Zusammenhang gibt es auch default_value. Einen Wert der bereits eingetragen ist.
Gut verständlich weil logisch ist dies bei Formelementen wie einem Textfeld oder einer Textarea. Bei einem Textfeld oder einer Textarea kommt Niemand auf den Gedanken als Bezeichnung für diese Formelemente value zu verwenden. Es geht auch gar nicht. Denn es gibt dafür label.
Nun betrachte man das Formelement submit.
Beim Formelement "input type submit" wird die Bezeichnung des Formelementes, es ist ein Button, mit value festgelegt. Erstaunlich unter logischem Aspekt und dem eigentlichen Sinn von value.
Sinn eines Button ist es NICHT, seinen Wert zu ändern. Ein Button stellt eine Funktion für das Formular bereit und mit dieser Funktionalität ändert er sich nicht. Das wird auch Niemand erwarten. Ein Button kennt kein default_value. Wäre eigentlich irgendwie logisch, oder?
Allein schon das input von "input type submit" ist nicht logisch. Weil wie gesagt an einem Button selbst macht man keine Eingabe. Bestenfalls löst man mit ihm eine Eingabe aus.
Bei diesem Formelement, dem Button, wird das Disaster der Verwendung von value bei Formelementen sichtbar.
Warum wird die Bezeichnung eines Button nicht mit label geregelt? Das wäre logische Konsequenz wenn man Textfeld und Textarea betrachtet. Das Disaster betrifft aber nicht nur das Formelement "input type submit". Unklarheiten gibt es auch bei option, "input type radio" und "input type checkbox".
Eigentlich fehlt ein Foremelement-Parameter für option, "input type radio" und "input type checkbox".
Die Verwendung von value bei Formelementen entstammt der (historischen) Entwicklung der HTML Formelemente. Diese Entwicklung hat ihren Anfang bei statischem HTML ohne Perl und PHP und ist nicht mit der Zeit gegangen. Bei der dynamischen Generierung von Formelementen, beispielsweise mittels PHP, sollten auch die Bezeichner von option Tags, "input type radio" und "input type checkbox" eindeutig definierbar sein hinsichtlich der HTML-Logik der einzelnen Formelemente/Tags. In diesem Zusammenhang ist man nicht mit der Zeit gegangen.
Aktuell besteht für mich ein W3C Durcheinander bei der Verwendung von value und es bedarf aus meiner Sicht einer Überarbeitung und Anpassung der HTML-Syntax der Formelemente - zumindest was die Verwendung von value betrifft.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Da geht noch was.
options
am 21.12.2008 - 13:44 Uhr
Moin!
Das "Problem" an der ganzen Geschichte ist, dass sich durch die notwendigen Veränderungen an den option-Elementen auch eine Menge im drupal-Kern geändert hat. Soll heissen: es wird wahrscheinlich keine einfache Lösung für d5 oder d6 geben.
Die Änderungen sind leider einfach zu tiefgreifend.
Also: ja, man muss auf Drupal 7 warten.
Stefan
Tipp: Beachte die Verhaltensregeln des DrupalCenter.
jQuery
am 21.12.2008 - 23:15 Uhr
Moin!
Das kannst Du auch mit ein wenig jQuery-Maggi hinbekommen.
$(function() {
$('option').each(function() {
$(this).addClass('opt_' + $(this).value()); // prefix for numeric values
});
});
hth,
Stefan
Tipp: Beachte die Verhaltensregeln des DrupalCenter.