Wie bringe ich das Optionsfeld (disabled) im oberen <select> an die erste Stelle des unteren <select>?
http://pastie.org/private/ua9cmxmywdt2rcgdq8cjq
Flask Macro - Selectbox rendern
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
ohne das du noch das Macro zeigst kommt hier wohl keiner weiter...
Gruß, noisefloor
ohne das du noch das Macro zeigst kommt hier wohl keiner weiter...
Gruß, noisefloor
Hallo Noisefloor
Die Definition vom Macro (_formhelpers.html) steht oben im paste. Meinst du den Aufruf?
Wäre dann einfach:
LG
Die Definition vom Macro (_formhelpers.html) steht oben im paste. Meinst du den Aufruf?
Wäre dann einfach:
Code: Alles auswählen
{{ render_selectfield(form.country) }}
Das <select> wird ja durch die Umwandlung von `field` in eine Zeichenkette erzeugt. Wenn Du da etwas anders haben willst, dann musst Du auch *dort* ansetzen. Also was ist `field` für ein Datentyp und wie kann man die Umwandlung da beeinflussen, falls man das überhaupt kann. Wenn man das nicht kann, dann musst Du das durch eine Funktion oder ein Makro ersetzen das `field` so in HTML umwandelt wie Du das gerne hättest.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
BlackJack es ja schon gesagt: das Makro ist im Prinzip zu "high level". Wenn du die Optionen des Select-Fields per Schleife im Makro erzeugst, dann ist auch das setzen der nicht-wählbaren Default-Option nicht das Problem.
Gruß, noisefloor
Nee - war ein Denkfehler meinerseits, sorry.Die Definition vom Macro (_formhelpers.html) steht oben im paste. Meinst du den Aufruf?
BlackJack es ja schon gesagt: das Makro ist im Prinzip zu "high level". Wenn du die Optionen des Select-Fields per Schleife im Makro erzeugst, dann ist auch das setzen der nicht-wählbaren Default-Option nicht das Problem.
Gruß, noisefloor
Ich verstehe da gerade nur Bahnhof. Das ich das obere Select idealerweise irgendwie beim Field als Argument übergeben müsste ist mir klar.
Das WTForm field ist:
Es stammt aus dem Paket:
wtforms.ext.sqlalchemy.fields
Das WTForm field ist:
Code: Alles auswählen
country = QuerySelectField('Country', query_factory=lambda: Country.query, get_label=lambda x: x.name)
wtforms.ext.sqlalchemy.fields
@meego: Da würde man dann wohl diesen Typ und das zugeordnete widget entsprechend ableiten und modifizieren müssen damit das dann entsprechend gerendert wird. Das `Field` müsste bei `iter_choices()` diese spezielle Option als erstes liefern und das Widget müsste in seiner `render_option()`-Methode dieses erste spezielle Feld mit dem `disabled`-HTML-Attribut rendern.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@meego: vom Prinzip her so (das ist kein echter Jinja2 Code):
Gruß, noisefloor
@meego: vom Prinzip her so (das ist kein echter Jinja2 Code):
Code: Alles auswählen
<select>
<option value="" disabled selected>Choose an option</option>
{% for field in fields %}
<option value="{{ field.value }}">{{ field.name }}</option>
{% endfor %}
</select>
@blackjack: Over my head.
@noisefloor: Folgendes funktioniert nicht:
Resultat:
Habe ich einen Fehler drin?
@noisefloor: Folgendes funktioniert nicht:
Code: Alles auswählen
{% macro render_selectfield(field) %}
<div class="input-field col s6">
<select>
<option value="" disabled selected>{{ _('Wähle deine Option') }}</option>
{% for f in field %}
<option value="{{ f.value }}">{{ f.name }}</option>
{% endfor %}
</select>
</div>
{% endmacro %}
Code: Alles auswählen
3 x <option value="">country</option>
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Ob `f.value` und `f.name` bei dir richtig ist weiß niemand außer dir, weil wir den restlichen Code nicht kennen. Das musst du halt ggf. noch anpassen, je nach dem, was in `field` so "drin" ist.
Gruß, noisefloor
Natürlich, sonst würde es ja funktionierenHabe ich einen Fehler drin?
Ob `f.value` und `f.name` bei dir richtig ist weiß niemand außer dir, weil wir den restlichen Code nicht kennen. Das musst du halt ggf. noch anpassen, je nach dem, was in `field` so "drin" ist.
Gruß, noisefloor
Hallo Noisy
Das WTForm?:
Oder das Modell?:
Da wäre das Attribut .name eigentlich vorhanden.
Das WTForm?:
Code: Alles auswählen
country = QuerySelectField('Country', query_factory=lambda: Country.query, get_label=lambda x: x.name)
Code: Alles auswählen
class Country(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
ich habe zwar früher auch mal WTForms und SQLAlchemy benutzt - aber nie so, mit dem dynamischen befüllen von WTForms Feldern aus SA (und, das muss ich dann an dieser Stelle doch mal sagen: jetzt weiß ich auch wieder, warum ich heute Django nehme ).
Letzte Idee von mir: auf der Konsole debuggen bzw. inspizieren. Also alles importieren, und mal in die Form-Klasse reinschauen bzw. schauen, was hinter den Attributen des Klasse so für Inhalt steckt.
Gruß, noisefloor
ich habe zwar früher auch mal WTForms und SQLAlchemy benutzt - aber nie so, mit dem dynamischen befüllen von WTForms Feldern aus SA (und, das muss ich dann an dieser Stelle doch mal sagen: jetzt weiß ich auch wieder, warum ich heute Django nehme ).
Letzte Idee von mir: auf der Konsole debuggen bzw. inspizieren. Also alles importieren, und mal in die Form-Klasse reinschauen bzw. schauen, was hinter den Attributen des Klasse so für Inhalt steckt.
Gruß, noisefloor
@meego: WTForms ist ja ganz schön verschachtelt. Als erstes brauchst Du ein neues Select-Widget, dann ein QuerySelectField, das auf dieses Widget verweist:
Code: Alles auswählen
from wtforms import widgets
class SelectWithChooseOption(widgets.Select):
def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id)
if self.multiple:
kwargs['multiple'] = True
html = ['<select %s>' % html_params(name=field.name, **kwargs)]
any_selected = False
for val, label, selected in field.iter_choices():
html.append(self.render_option(val, label, selected))
any_selected |= selected
html.insert(1, self.render_option('', 'Choose your option', selected=not any_selected, disabled=True)
html.append('</select>')
return HTMLString(''.join(html))
class QuerySelectFieldWithChooseOption(QuerySelectField):
widget = SelectWithChooseOption()
Huch, Sirius, das ist aber kompliziert. Und das ist tatsächlich die einfachste Art und Weise zum Ergebnis zu kommen?
@noisefloor: Django habe ich mir auch angesehen, das Tutorial war aber nicht gerade Newbiefreundlich und didaktisch eher verwirrend, immer vom Spezialfall zur normalen Anwendung. Jetzt würde ich vielleicht schon etwas mehr davon verstehen.
@noisefloor: Django habe ich mir auch angesehen, das Tutorial war aber nicht gerade Newbiefreundlich und didaktisch eher verwirrend, immer vom Spezialfall zur normalen Anwendung. Jetzt würde ich vielleicht schon etwas mehr davon verstehen.
@meego: Den ”einfacheren” Weg hatte ich ja schon angerissen, da muss man dann aber sowohl das `Field` als auch das passende `Widget` ableiten. Dafür muss man nicht den grossteil der `__call__()`-Methode vom originalen `Select` abschreiben.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Und kompliziert ist es für doch doch nicht wirklich - Code per C&P übernehmen und gut ist
Gruß, noisefloor
Auf anderem Wege habe ich das zumindest nicht geschafft. Und die Lösung von Sirius findet man so oder in sehr ähnlicher Form auch in diversen Threads bei SO.das ist aber kompliziert. Und das ist tatsächlich die einfachste Art und Weise zum Ergebnis zu kommen?
Und kompliziert ist es für doch doch nicht wirklich - Code per C&P übernehmen und gut ist
Gruß, noisefloor
@Blackjack, ich weiss nicht einmal, wozu die __call__ methode gut ist. Meinst du, mit einem Programmier-Profi zu sprechen?
@Noisefloor: C & P mache ich nur ungern, wenn ich den Code selber nicht verstehe. Was ist SO? Eine andere Alternative wäre einfach die normale Selectbox rendern, zumal das ganze JS-zeug etwas langsam ist.
@Noisefloor: C & P mache ich nur ungern, wenn ich den Code selber nicht verstehe. Was ist SO? Eine andere Alternative wäre einfach die normale Selectbox rendern, zumal das ganze JS-zeug etwas langsam ist.
@meego: Was die `__call__()`-Methode generell macht kann man in der Python-Dokumentation nachlesen und was sie bei WTForms semantisch macht, sollte man dort in der Dokumentation nachlesen können. Die wandelt das `Field` in HTML-Quelltext um. Wenn man also beeinflussen will *wie* das passiert, dann muss man sich die halt anschauen und zum Beispiel kopieren und den eigenen Wünschen anpassen. Alternativ kann man schauen was die so von sich und anderen Objekten verwendet und dort die entsprechenden Methoden überschreiben/verändern.
SO = StackOverflow.
SO = StackOverflow.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Bei WTForms z.B. leitest du dir auch eigne Klassen ab und zu wissen, was die Basisklasse macht. Und warum da die Attribute so definiert werden, wie es halt gemacht wird, ist den meisten wahrscheinlich auch nicht klar.
Die Alternative zur Lösung von Sirius wäre noch, dass du den "Choose an Option" Eintrag regulär einfügst und dann auf der Webseite per JavaScript deaktivierst. Wobei das eigene Widget IMHO deutlich eleganter ist.
Und nochmal kurz zu Django: in einer meiner Apps leite ich eine Form aus einem Model für die DB ab. Beim Rendern der Form im Template ist der 1. automatisch `-------`. Diese ist zwar auswählbar, allerdings validiert die Form nicht, wenn man diesen Eintrag wählt.
Ich habe früher ja auch Bottle + WTForms + SQLAlchemy eingesetzt. Was ich selber aber bei Django _wesentlich_ angenehmer finde ist, dass alles unter einer Haube ist und damit sehr gut integriert. Was nicht heißt, dass Django per se besser und alles andere keine Existenzberechtigung.
Gruß, noisefloor
Sagen wir mal so: die meisten von uns - und da schließe ich mich explizit mit ein - werden den Code der Module, die wir einsetzen, nicht verstehenC & P mache ich nur ungern, wenn ich den Code selber nicht verstehe.
Bei WTForms z.B. leitest du dir auch eigne Klassen ab und zu wissen, was die Basisklasse macht. Und warum da die Attribute so definiert werden, wie es halt gemacht wird, ist den meisten wahrscheinlich auch nicht klar.
Die Alternative zur Lösung von Sirius wäre noch, dass du den "Choose an Option" Eintrag regulär einfügst und dann auf der Webseite per JavaScript deaktivierst. Wobei das eigene Widget IMHO deutlich eleganter ist.
Und nochmal kurz zu Django: in einer meiner Apps leite ich eine Form aus einem Model für die DB ab. Beim Rendern der Form im Template ist der 1. automatisch `-------`. Diese ist zwar auswählbar, allerdings validiert die Form nicht, wenn man diesen Eintrag wählt.
Ich habe früher ja auch Bottle + WTForms + SQLAlchemy eingesetzt. Was ich selber aber bei Django _wesentlich_ angenehmer finde ist, dass alles unter einer Haube ist und damit sehr gut integriert. Was nicht heißt, dass Django per se besser und alles andere keine Existenzberechtigung.
Gruß, noisefloor
Gerade mal schnell ausprobiert. Sieht aus wie im Widgetsbeispiel in der Doku, was ist das Problem?:
@Blackjack: Danke, werde mir wtforms mal etwas genauer ansehen.
@Noisy: Ein '-------' finde ich aber jetzt aber etwas schräg (wenn man das nicht ändern kann). Ja, ich habe mir auch schon die Sinnfrage gestellt, weil man ja letztlich doch alle Erweiterungen benötigt (Migrationen, Admin, wtforms, alchemy, babel). Allerdings haben die selbst im Djangoforum gesagt, SQLalchemy würden sie lieber verwenden und irgendwie ist's bis jetzt einfach näher an der Pythonsyntax, also gerade als Newbie vielleicht besser zum lernen.
Code: Alles auswählen
Traceback (most recent call last):
File "/../forms.py", line 76
html.append('</select>')
@Noisy: Ein '-------' finde ich aber jetzt aber etwas schräg (wenn man das nicht ändern kann). Ja, ich habe mir auch schon die Sinnfrage gestellt, weil man ja letztlich doch alle Erweiterungen benötigt (Migrationen, Admin, wtforms, alchemy, babel). Allerdings haben die selbst im Djangoforum gesagt, SQLalchemy würden sie lieber verwenden und irgendwie ist's bis jetzt einfach näher an der Pythonsyntax, also gerade als Newbie vielleicht besser zum lernen.