Bottle -- wie eine url "senden"ohne die Seite zu aktivieren

Django, Flask, Bottle, WSGI, CGI…
Antworten
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

Für mein PY Projekt brauchst mal wieder einen Nachtreter :shock:

Mein Problem liegt im Zusammenspiel der notwendigen Module/Programme, wobei mir die Übergabe vom User-Interface zu Python Schwierigkeiten macht.

Das Projekt arbeitet mit bottle, bootstrap und jQuery.

Mein 'main' PY Programm startet einen Thread mit einem Listener:

Code: Alles auswählen

def jobs_serve(jobs_event, name):
    address = server, int(port)
    listener = Listener(address, authkey=authKey())
    control = True
    while control:
        ....
Dieser Listener und von 'main' geladener Client (module 'web.py' mit Bottle code) sind das Duo, das die Verbindung zum User-Interface herstellt.
Das UserInterface wird mit "http://server:port" aufgerufen.

Bis hier klappt alles prima .. solange ich auf der aufgerufenen Seite bleibe bzw. Seitenwechsel erwünscht sind.

Im wesentlichen benutze ich hierfür Aufrufe wie

Code: Alles auswählen

<a role="menuitem" onclick="openJob()">  'Job' Docu </a>
mit entsprechendem Javascript. Oder

Code: Alles auswählen

<li role="presentation" class="active"><a href="/prefs">Call Prefs</a></li>
Dabei wird eine neue WEB-Seite aufgebaut.
Allerdings gibt es (min.) eine Funktion (die auf einem 'button' liegt) und die ein derartiges Commando absetzen soll aber mit der ich eigentlich die WEB-Seite nicht verlassen möchte!

Die erforderliche Funktion entspricht

Code: Alles auswählen

http://server:port/control?details
.
Wenn ich dies von der WEB-Seite aus mache mit Code auf dem button:

Code: Alles auswählen

 <a role="menuitem" href="/control?details" >go 'Job'</a>
wird 'web.py' aufgerufen mit

Code: Alles auswählen

@route('/control')
def myControl():
   ....
Dabei wir unmittelbar eine neue Web-Seite mit der entsprechenden URL angezeigt.

Bitte jetzt nicht: ist doch klar! ... ja ist mir schon klar, aber wie kann ich es erreichen, dass die aufrufene Seite erhalten bleibt?

Ich hatte schon an <form> gedacht, aber das passt nicht so recht in der WEB-Seiten Struktur.
Gibt's eine andere Lösung?

Note: Sicher nicht einfach nach zu vollziehen, da etwas komplex. Falls nötig kann ich den bisherigen Code zur Verfügung stellen.

Danke schon mal!

Guenter
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

OK, sieht aus als wäre dies eine Lösung:

Code: Alles auswählen

<a role="menuitem" href="/control?details" target="control" >go 'Job'</a>
D.h. hier wird eine neue Seite mit dem target="control" und mit dem 'reply' code geöffnet bzw. weitere Aufrufe schreiben das 'reply' in die bereits existente "target" WEB-Seite. Und die aufrufende Seite bleibt bestehen.

Gibt's eine andere Möglichkeit?
BlackJack

@gNeandr: AJAX wäre sonst vielleicht eine Lösung. jQuery bietet da ja ein paar Funktionen für. Das Ergebnis des Aufrufs kannst Du dann dynamisch per JavaScript in die bereits angezeigte Webseite einbauen.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

@BlackJack
Danke! Kannst du evtl. auf Beispiele verweisen? Auf den jQ Seiten sind -- soweit ich es gesehen habe --- keine verwertbaren aufgeführt :(
BlackJack

@gNeandr: Da sind doch Beispiele in der Dokumentation. Du willst im einfachtsten Fall einen HTTP-GET oder -POST absetzen und dafür hat jQuery die Funktionen `get()` oder `post()`.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

@BlackJack
OK, das mit ajax/get() funktioniert ...

Aus

Code: Alles auswählen

 <a role="menuitem" href="/control?details" >go 'Job'</a>
wird

Code: Alles auswählen

<a role="menuitem" onclick="controlIt()"  >go 'Job'</a>
Die folgende Funktion holt die "control" Sequenz und fügt sie in das get() ein. Der zurückgegebene "Status" wird auf der aufrufenden WEB-Seite angezeigt ... und wichtig: die WEB-SEite wird nicht mehr mit dem URL-Aufruf gewechselt.

Code: Alles auswählen

function controlIt() {
   var sControl =  $('#currentJob')[0].textContent
   $.get("/control?" + sControl,
     function(data,status){
       $('#controlStatus').html(status)
   });
}
BlackJack

@gNeandr: Die Definition von `sContent` erscheint mir etwas, naja umständlich weiss ich jetzt nicht, aber statt sich mit dem Indexzugriff vom jQuery-Objekt das HTML-DOM-Objekt geben zu lassen um dann dort `textContent` abzufragen hätte ich direkt auf dem jQuery-Objekt die `text()`-Methode verwendet.

Edit: Und das Fragezeichen in der URL würde ich weglassen und den Parameter als zusätzliches Argument (`data`) übergeben.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

@BlackJack
Nix für ungut .. schon klar, dass die `text()`-Methode einfacher ist.
Aber mit sControl kann ich besser debuggen, dh. sehen ob der zu sendende String OK ist.

Alles hat seinen Preis.

Bei der Gelegenheit dir nochmals Dank für deine Hilfe und Geduld ... und 1000 gute Wünsche für's 2015 ... darf man doch auch Mitte Januar noch sagen.

Keep going!

Guenter
BlackJack

@gNeandr: Gegen `sControl` selbst hatte ich ja gar nichts gesagt, aber jetzt wo Du's erwähnst: Ist überflüssig das an einen Namen zu binden. Wieso ist das besser zu debuggen? Das sieht man doch über den Browser welche URL da angefordert wird.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

@BlackJack
Du hattest geschrieben: "Die Definition von `sContent` " und das ist eigentlich nicht in meinem Posting .. soweit ich es sehe :|
Insofern hatte ich gelesen `sControl` ...

Wie gesagt mir ist es immer lieber einen weiter zu übergebenden Parameter in meinen Programm/meiner Funktion im Debug Mode sehen und ggf. ändern zu können. Hat mir schon 'n Menge Zeit erspart. Und für die Produktionsversion tut's heutzutage eigentlich auch nicht mehr weh (Laufzeit) etwas ausführlicher zu sein..
BlackJack

@gNeandr: Argh, ich meinte natürlich beide male `sControl` und es ging mir auch nicht um Laufzeit sondern einfach dass das eine überflüssige Definition ist. Wenn man da unbedingt zur Laufzeit etwas ändern möchte bevor `jQuery.get()` aufgerufen wird kann man das ja auch im DOM machen, also den Textinhalt vom Element mit der ID `currentJob`. Ich hätte es jedenfalls so geschrieben:

Code: Alles auswählen

var controlIt = function () {
   $.get('/control', $('#currentJob').text(), function(data, status) {
       $('#controlStatus').html(status)
   });
};
Antworten