[wtforms][bottle] checkbox Übergabe.

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Hallo Leute.

Ich arbeite gerade mit wtforms und bottle.

In einem Formular gibt es eine Checkbox, die wenn sie nicht 'gechecked' ist, auch nicht an das Script im POST übermittelt wird.

Wie bekomme ich es hin, das die Checkbox trotzdem übermittelt wird, auch wenn der Haken nicht gesetzt ist?

Stehe gerade mächtig auf dem Schlauch.

Ich lasse mir aus dem übersendeten Formular eine Liste generieren. Leider fehlt dort dann die Checkbox. Um sie dort hinein zu bekommen dachte ich schon, es selber zu machen, das ist aber wie ich denke keine saubere Lösung.

Wenn ich mit wtforms, das Formular Objekt mit dem POST erstelle, habe ich die Checkbox mit drin, kann aber sonst nichts weiter mit anfangen, da ja dort der gesamte HTML code steht und ich keine Lust habe, diesen auseinander zu "parsen", das ist ja dann bestimmt auch nicht Sinn und Zweck der Sache.

Ich hoffe Ihr könnt mir dabei Helfen.

Gruß, deadshox
Zuletzt geändert von lynadge am Freitag 4. Februar 2011, 10:13, insgesamt 2-mal geändert.
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Wenn du unbedingt einen Rückgabewert brauchst, ist eine Checkbox wohl nicht das Richtige. Du könntest ja auch zwei RadioButtons machen mit Ja/Nein Werten. Dann bekommst du auf jeden Fall eine Rückmeldung ...
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

grundsätzlich finde ich das Verhalten "komisch". Normales HTML liefert für Checkboxen immer einen Wert...

Lt. Doku ist eine Checkbox ein "BooleanField". Heißt, dass nicht zurück geliefert wird kann eigentlich nicht sein. Es sollte wohl eher so sein, dass un-gecheckt "False" zurück geliefert wird.

Gruß, noisefloor
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Das tut es auch

Code: Alles auswählen

tracker.enabled = form.enabled.data
ist bei mir ein BooleanField

Code: Alles auswählen

enabled = BooleanField(u'Enabled?')
und gibt bei der Ausgabe im View

Code: Alles auswählen

<li>Enabled: {{ tracker.enabled }}</li>
dann auch fein
Enabled: False
oder
Enabled: True
aus, wie erwartet.

Frank
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Radio Buttons möchte ich nicht. Es muss damit Funktionieren! ;)

@noisefloor, ja, ich habe auch erwartet das wenigstens ein 'False' zurück geliefert wird. Wie kann ich das genau abfragen?

Eine vage Vermutung wäre noch, das es vielleicht an bottle liegt. Denn wenn ich über 'bottle.request.POST' oder 'bottle.request.forms' iteriere steht nirgends die Checkbox mit drin, außer sie ist halt "ge-checked".

@frabron, ich blicke bei deinem Code nicht durch, in wtforms und bottle gibt es kein 'enabled'. Könntest du es bitte ein wenig genauer beschreiben?
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Ok, Kommando zurück.

Wenn ich über das Initialisierte Form Objekt iteriere und z.b. die ID abfrage, reicht mir das schon.

Ich wusste vorher nur nicht wie ich auf Dinge wie name, value, id, flags, ... zugreifen soll.

Danke für eure Antworten!
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Klar, das da oben ist ein Beispiel aus einer Anwendung von mir. Ich habe ein Formular

Code: Alles auswählen

class EditTracker(TokenForm):
    enabled = BooleanField(u'Enabled?')
    valid_until = DateField(u'Valid Until', validators=[validators.required()])
    events = SelectMultipleField(u'Associate events to tracker')
wo enabled halt ein BooleanField ist.

In meinem View:

Code: Alles auswählen

@tracker.route('/details/<imei>', methods=['POST','GET'])
def details(imei=None):
    # ...    
    form = forms.EditTracker(formdata=request.form, events=selected)

    # ....
    
    if request.method == 'POST' and form.validate():
        tracker.valid_until = form.valid_until.data
        # hier wird der BooleanField Wert dem Tracker -  Objekt zugeordnet
        tracker.enabled = form.enabled.data
        database.db_session.add(tracker)
        database.db_session.commit()
        return redirect(url_for('details', imei=tracker.imei))
        
    return render_template('tracker/details.html', tracker=tracker, form=form)
Und die Ausgabe im Template:

Code: Alles auswählen

    <h2>Details for Tracker {{  tracker.imei }}</h2>
    <ul>
        <li>Imei: {{ tracker.imei }}</li>
        <li>Setup date: {{ tracker.setup_date }}</li>
        <li>Valid until: {{ tracker.valid_until }}</li>
        <li>Enabled: {{ tracker.enabled }}</li>
    </ul>
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Super. Jetzt hat erst verstanden. :) Danke dir!
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Ok, scheint doch noch nicht gelöst zu sein.

Wenn ich das Formular via JavaScript erweitere, sendet bottle die neue Checkbox
nicht mit, wenn sie nicht "ge-checked" ist.

Dem entsprechend kann sie nicht in das Formular Objekt eingetragen werden und
existiert nicht mehr.

Ich erweitere ja das Formular Objekt mit den mitgelieferten POST Daten und ist
die Checkbox nicht drin, kann das Objekt ja nicht erweitert werden. Außer ich
mache ein extra HiddenField welches den 'False' Wert hat der Checkbox hat.

Kann das Problem einer Nachvollziehen?
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Nö, so kann man das nicht nachvollziehen. In deiner Beschreibung sind zu viele unbekannte. Mal ganz abgesehen davon, dass Bottle keine Formulare versendet. Das Versenden von Formulardaten an den Server (da wo dein Bottle läuft) ist immer noch Sache des Browsers.

Wenn du das Formular mit JS erweiterst: Ist die Checkbox richtig platziert und formell richtig? Mal im Firebug gecheckt, was du da versendest?
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Ok, dann hab ich mich halt falsch ausgedrückt. Entschuldige.

Also bottle nimmt das Formular vom Browser an und legt es in 'bottle.request.forms' und 'bottle.request.POST' ab. Dort sind aber keine Checkboxen enthalten, wenn sie leer sind.

Das ist wohl ein Problem bei HTML, denn in PHP werden leere Checkboxen auch nicht übertragen.

Die erste Checkbox, ist, wenn sie leer ist, auch nicht in 'bottle.request.POST' enthalten. Erst wenn ich das Formular mit der wtforms Klasse erstelle, ist die Checkbox drin und auf 'False' gesetzt, da ich sie ja in der Klasse definiert habe.

Die 2te Checkbox ist aber nicht definiert, da sie ja erst durch JavaScript erstellt wird, als Kopie der ersten mit anderer ID und anderem Namen. Diese füge ich dann nach dem Absenden des Formulars in die Klasse mit setattr() ein. Leider geht das nicht, wenn keine Checkbox in 'bottle.request.POST' enthalten ist.

In der Anwendung ist es möglich beliebig viele Checkboxen zu erstellen. Deshalb muss es auch alles variable bleiben.

Verständlicher?
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Jo, wie gesagt, validiere doch mal im Firebug, was du an den Server zurücksendest und ob die Checkboxen per Javascript auch an der richtigen Stelle im DOM eingehängt werden.
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Wie kann ich das machen?

Die Checkbox sollten an der richtigen stelle sein, innerhalb des <form>.

#Edit
Habe es jetzt erst einmal mit einem selectField gelöst. Das ging schneller, die Checkbox hat mir einfach zu viel Zeit geraubt. Die Lösung Interessiert mich trotzdem und ich würde sie dann auch gerne wieder einbauen.
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Du entwickelst Webanwendungen und kennst Firebug nicht? :shock:
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Heh, nein, so nicht. Ich kenne Firebug, habe ihn aber bis jetzt nur für CSS kram gebraucht. JavaScript habe ich lange schon nicht mehr benutzt. Ich glaub da gabs den noch nich. :D
Antworten