Button, wird 2mal dargestellt

Django, Flask, Bottle, WSGI, CGI…
Antworten
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

Hallo,

ich habe folgendes Problem:
ich will einen Datenbankzugriff machen und diese auf meinem Browser darstellen, was auch sehr gut funktioniert. Nun würde ich aber gerne noch einen Button hinzufügen, der dann eine spezielle Funktion ausführt.
Leider erscheint nach dem 2ten Refresh ein 2ter Button, der dann auch nicht mehr weggeht. ich habe den Button, schon an allen möglichen Stellen verschoben, leider immer der selbe Effekt, kann mir jemand sagen was ich falsch mache?

Hier mein Code dazu:

Code: Alles auswählen

  <html>
    <body>
      {% for article in latest_articles_list %}
      <div id="myContent">{{ article.title }}</div>	
      {%endfor%}
    </body>
  </html>
{% endblock %}

<form
    <input type="submit" value="Button" />
</form>
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Susanne,

wie sollen wir aus dem, was Du uns zeigst, raten was schief läuft?
Das html das Du mitgeschickt hast ist fehlerhaft:
1. {% endblock %} ohne {%block%}
2. <from hat kein schließendes >
3. <from ... ist außerhalb des body-Tags.
erdmulch
User
Beiträge: 230
Registriert: Samstag 17. Juli 2010, 19:50

OK, ich dachte, es ist dann vielleicht übersichtlicher
aber ich kann auch gerne den ganzen Code veröffentlichen

Code: Alles auswählen

{% block content %}

<script type="text/javascript">
var xmlHttpObject = false;
if (typeof XMLHttpRequest != 'undefined') 
{
    xmlHttpObject = new XMLHttpRequest();
}
if (!xmlHttpObject) 
{
    try 
    {
        xmlHttpObject = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e) 
    {
        try 
        {
            xmlHttpObject = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(e) 
        {
            xmlHttpObject = null;
        }
    }
}
function loadContent() 
{
    xmlHttpObject.open('get', "{% url /home/susanne/tmp/djangoprojs/Wetterstation/Wetterstation/articles.views.index %}", true);
    xmlHttpObject.onreadystatechange = handleContent;
    xmlHttpObject.send();
    return false;
}


function handleContent()
{      
    if (xmlHttpObject.readyState == 4)
    {   
        document.getElementById('myContent').innerHTML = xmlHttpObject.responseText; 	
    }
}
setInterval("loadContent();", 1000);
</script>
  <html>
    <body>
      <form>
        <input type="submit" value="Button" /> 
      </form>
      {% for article in latest_articles_list %}
      <div id="myContent">{{ article.title }}</div>	
      {%endfor%}
    </body>
  </html>
{% endblock %}
BlackJack

Ui, Susanne heisst jetzt erdmulch? Oder ist's umgekehrt? ;-)

Jetzt vergleich mal das was im Template steht mit dem was der Browser letztendlich darstellt. Wenn Du/Ihr euch das HTML-DOM mit dem entsprechenden Browserfunktionen anschaut, dann seht ihr ja wo der zweite Button im DOM platziert wird. Ich rate einfach mal ganz frei, dass das innerhalb des <div> mit der ID `myContent` ist. Sollte dem so sein, dann überlegt doch mal ganz scharf wie der da wohl hinkommen mag.

Edit: Da wird wieder kaputtes HTML erzeugt. Das `id`-Attribut muss innerhalb des Dokuments *eindeutig* sein, dass heisst jede ID darf nur einmal vorkommen. Das ist bei dem Template nicht mehr der Fall wenn es mehr als einen `article` gibt. Und die muss es ja potentiell geben, sonst macht die Schleife keinen Sinn.
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

hallo nochmals,

ja wir machen es zusammen in einem Schulprojekt.

Da es sich um eine Endlos-Schleife handelt, wird immer der aktuelle Wert über mein "MyCondent" in dem HTML-Tag eingesetzt und angezeigt.
Ok, wenn jetzt der zweite Schleifendurchgang ist das erste HTMl-Tag immer noch da und das zweite wird schon gesetzt.

komischerweise wird der Wert der ausgelesen hat nicht zweimal dargestellt sondern nur einmal. Aber alles was nach der Schleife kommt wird 2mal dargestellt und das ist das, was ich nicht verstehe.
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo ihr zwei,

dann gebt mal schnell Eurer url statt /home/susanne/tmp/djangoprojs/Wetterstation/Wetterstation/articles.views.index den Namen 'articles.view.index' dann müsst ihr den beim Kopieren nicht jedesmal
ändern.

Durch setInterval("loadContent();", 1000); wird ja jede Sekunde das Element mit der ID 'myContent'
mit neuem Inhalt gefüllt.
Die Frage ist ja nun, was wird da reingeschrieben?
Könnte es sein, dass articles.view.index eine Seite liefert, die auch einen Button enthält?
Dann wären's nämlich zwei.
BlackJack

@Susanne: Deine Beschreibung verwirrt mich etwas. Im *Template* ist keine Endlosschleife sonst würde die Seite nie an den Browser ausgeliefert werden. Wenn alle `article` aus `latest_articles_list` generiert wurden, dann ist gibt es mehr als ein <div> mit der selben ID — das darf nicht sein.

Die Endlosschleife ist im JavaScript-Code und ersetzt in ”den” Tag mit der ID `myContent` das HTML mit dem was die AJAX-Anfrage liefert. Welches da genau ersetzt wird dürfte vom Browser abhängen, denn eigentlich darf es ja nur eines geben.
Susanne
User
Beiträge: 35
Registriert: Dienstag 8. Januar 2013, 19:49

sorry, wenn ich jetzt nochmals dazwischen komme, aber ich will es verstehen

"Durch setInterval("loadContent();", 1000); wird ja jede Sekunde das Element mit der ID 'myContent'
mit neuem Inhalt gefüllt.
Die Frage ist ja nun, was wird da reingeschrieben?
Könnte es sein, dass articles.view.index eine Seite liefert, die auch einen Button enthält?
Dann wären's nämlich zwei."

den ersten Teil der antwort verstehe ich. Ich fülle, jede Sekunde das Element "myContent" mit Inhalt, ja soweit stimme ich zu.
der zweite Teil verstehe ich nicht ganz und genau da liegt mein Problem. meine articles.view.index macht nur einen Datenbank zugriff. Dank Ajax wird diese View Sekündlich aufgerufen, sodass auch der Datenbankzugriff sekündlich erfolgt und die View aktualisiert wird. siehe Code.
Nach meiner Logik, dürfte nun jetzt nur der Inhalt von latest_articles_list aktualisiert werden.

Code: Alles auswählen

def index(request):
    "Create a list of the 5 latest articles"
    latest_articles_list = Article.objects.all().order_by('-pub_date')[:1]
    return render(request,'articles.html', {'latest_articles_list': latest_articles_list,})
Mein Button ist ja außerhalb von der Schleife. Oder wird mein Button 2 mal aufgerufen, weil ich sekündlich eine anfrage an meine View mache? aber dann müsste die Anzahl der Button ständig um 1 erweitert werden.
Und da ist im mom mein Problem. Wie würde es denn richtig aussehen? muss ich meinen Button irgendwie entkoppeln? ja, ich weiß mit einer ID, aber wie? da sich der Inhalt von "myContent" ständig ändert?
BlackJack

@Susanne: *Du* musst doch wissen was in dem View geliefert wird. Da wird ein Template mit Daten gefüllt und zum Browser gesendet, wo es dann per JavaScript in das Element mit der ID `myContent` eingefügt wird. Das HTML was da im Template steht wird komplett an der Stelle eingefügt. Wenn da ein Button dabei ist, dann wird der ebenfalls eingefügt. Du darfst da wirklich nur das HTML schicken was an dieser Stelle eingefügt werden soll und nicht etwa eine komplette HTML-Seite — was ich jetzt einfach mal vermute das ist was Du da machst.

Ebenso vermute ich mal, dass Du eigentlich ein Tag um diese Artikelschleife herum legen willst, welches die ID hat um dann später die ganzen Artikel-<div>s durch neue, aktuellere Daten zu ersetzen.
Antworten