Ajax/JavaScript Tabellenzeilen einfügen/löschen

PHPler

Grünschnabel
Huhu,

im moment komme ich einfach nicht weiter mit meinem Script, da ich nicht weiss, wo mein Denkfehler liegt.

Ich möchte eine Tabelle füllen und diese dann bei Klick auf die Grundeinträge leeren, bzw. neue Einträge reinschreiben.. das ganze mit dem Reinschreiben funktioniert soweit schon nur werden beim löschen zu viele Einträge entnommen. Das ist jetzt mein Problem.

Code:
<%-- 
    Document   : index.jsp
    Created on : 12.06.2009, 13:07:25
    Author     : Roth-D
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<html>
    <head>
        <title>JSP and Servlet using AJAX</title>
        <script type="text/javascript">

            function getXMLObject()  //XML OBJECT
            {
                var xmlHttp = false;
                try {
                    xmlHttp = new ActiveXObject("Msxml2.XMLHTTP")  // For Old Microsoft Browsers
                }
                catch (e) {
                    try {
                        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")  // For Microsoft IE 6.0+
                    }
                    catch (e2) {
                        xmlHttp = false   // No Browser accepts the XMLHTTP Object then false
                    }
                }
                if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
                    xmlHttp = new XMLHttpRequest();        //For Mozilla, Opera Browsers
                }
                return xmlHttp;  // Mandatory Statement returning the ajax object created
            }
            var xmlhttp = new getXMLObject();	//xmlhttp holds the ajax object

            function request(s) {
                if(xmlhttp) {
                    xmlhttp.open("GET","gettime?orgID="+s.title,true); //send to servlet
                    xmlhttp.onreadystatechange  = handleServerResponse;
                    xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                    xmlhttp.send(null);
                }
            }

            function handleServerResponse() {
                if (xmlhttp.readyState == 4) {// 4 = "loaded"
                    if(xmlhttp.status == 200) {// 200 = "OK"
                        var result = xmlhttp.responseText;

                        var theTable = (document.all) ? document.all.myTABLE : document.getElementById("history");
                        var theTableBody = theTable.tBodies[0];
                        var where = null;

                        for (var i = 0; i < theTableBody.rows.length; i++) {
                            var v1 = new String(theTableBody.rows[i].cells[1].title);
                            var v2 = new String(trim(result));
                            if(v1.toString() == v2.toString()) {
                                where = i+1;
                            }
                            v1 = new String(theTableBody.rows[i].cells[3].title);
                            while (v1.toString() == new String("del")) {
                                theTableBody.deleteRow(i);
                            }
                        }

                        for (var z = 0; z < 4; z++) {
                            var newCell;
                            var newRow = theTableBody.insertRow(where);
                            for (var i = 0; i < 7; i++) {
                                newCell = newRow.insertCell(i);
                                if (i > 2) {
                                    newCell.innerHTML = result;
                                    newCell.title = "del";
                                }
                            }
                        }
                    }
                    else {
                        alert("Error during AJAX call. Please try again");
                    }
                }
            }
            function trim (zeichenkette) {
                // Erst führende, dann Abschließende Whitespaces entfernen
                // und das Ergebnis dieser Operationen zurückliefern
                return zeichenkette.replace (/^\s+/, '').replace (/\s+$/, '');
            }
        </script>
        <body>
            <table id="history">
                <tr id="f1">
                    <th id="no"></th>
                    <th id="no"></th>
                    <th id="no"></th>
                    <th>Art</th>
                    <th>Beginn</th>
                    <th>Ende</th>
                    <th>Anzahl Tage</th>
                </tr>
                <tr>
                    <th id="no">Abteilung II</th>
                    <th id="no">-</th>
                    <th id="no">-</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                </tr>
                <tr>
                    <th id="no">-</th>
                    <th onClick="request(this);" id="no" title="12">Gruppe 1</th>
                    <th id="no">-</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                </tr>
                <tr>
                    <th id="no">-</th>
                    <th onClick="request(this);" id="no" title="13">Gruppe 2</th>
                    <th id="no">-</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                </tr>
                <tr>
                    <th id="no">-</th>
                    <th onClick="request(this);" id="no" title="14">Gruppe 3</th>
                    <th id="no">-</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                    <th>&nbsp;</th>
                </tr>
            </table>
        </body>
    </head>
</html>

Mein Problem ist jetzt, wenn ich Gruppe 1 öffne, sie danach wieder öffne, werden nicht nur die untereinträge gelöscht, was eigentlich passieren sollte, sondern auch Gruppe 2 und Gruppe 3.. diese sollten jedoch bestehen bleiben. Ich finde einfach meinen Denkfehler nicht.

Das Hauptproblem liegt dann wohl also in diesen Zeilen hier:
Code:
v1 = new String(theTableBody.rows[i].cells[3].title);
                            while (v1.toString() == new String("del")) {
                                theTableBody.deleteRow(i);
                            }

vielleicht weiss ja jemand weiter, ich komme einfach nicht drauf.

Falls jemand zum testen noch die gettime.java brauch um das ganze mit dem Servlet zu testen:
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/**
 *
 * @author Roth-D
 */
public class gettime extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            /* TODO output your page here
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet gettime</title>");  
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet gettime at " + request.getContextPath () + "</h1>");
            out.println("</body>");
            out.println("</html>");
             */

            out.println(request.getParameter("orgID"));

            //out.println(request.getParameter("orgID"));
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}

Ich danke schonmal für jegliche vorschläge.
 
Hi,

du musst innerhalb der while-Schleife die Variable neu setzen, um sie in der Bedingung prüfen zu können. Ansonsten ist diese immer wahr und es werden alle nachfolgenden Zeile gelöscht.
Code:
v1 = new String(theTableBody.rows[i].cells[3].title);
while (v1.toString() == new String("del")) {
  theTableBody.deleteRow(i);
  v1 = new String(theTableBody.rows[i].cells[3].title);
}

Ciao
Quaese
 
Danke das hat schonmal geholfen, aber jetzt tritt ein Phänomen auf, das ich wiederum nicht verstehe. Muss ich "where" auch neu setzen?

Denn wenn ich auf "Gruppe 1" klicke und dann auf "Gruppe 2", erscheint der Inhalt von "Gruppe 2" erstmal an der falschen Stelle:

13 13 13 13
13 13 13 13
13 13 13 13
13 13 13 13
Art Beginn Ende Anzahl Tage
Abteilung II - -
- Gruppe 1 -
- Gruppe 2 -
- Gruppe 3 -

Klicke ich dann nochmal auf "Gruppe 2" wird es mir erst an der richtigen Stelle ausgegeben:

Art Beginn Ende Anzahl Tage
Abteilung II - -
- Gruppe 1 -
- Gruppe 2 -
13 13 13 13
13 13 13 13
13 13 13 13
13 13 13 13
- Gruppe 3 -

EDIT: Hab es gelöst, hab einfach die while-Schleife in eine eigene for-Schleife gesetzt!

Vielen Dank für die Hilfe!

EDIT2: Nochmal kurz eine Frage, wenn ich "Gruppe 2" öffne und dann "Gruppe 1" öffne, geht das ohne das ich zwei mal auf "Gruppe 1" klicke, öffne ich z.B. dann nochmal "Gruppe 2" muss ich mit dem ersten klick auf "Gruppe 2", "Gruppe 1" schliessen und dann nochmal klicken, um "Gruppe 2" letztendlich zu öffnen. In meinem Quellcode ist die Reihenfolge der Schleifen ja eigentlich so, dass erst gelöscht wird und dann gefüllt. Warum muss ich trotzdem zwei mal klicken?
 
Zuletzt bearbeitet:
Hi,

eventuell hilft dir eine etwas andere Vorgehensweise.

Nachdem sowieso eine Referenz auf die Tabellenzelle übergeben wird, kannst du dich anhand dieser so durch den Dokumentenbaum hangeln, dass nur die Zeilen in deren unmittelbarer Abhängikeit bearbeitet werden.

Klartext:
  • der callback-Funktion (onreadystate) wird die Referenz auf die Zelle übergeben
  • die zugehörige Zeile wird ermittelt (parentNode)
  • der Tabellenkörper wird ermittelt
  • der Zeilenindex wird ermittelt
  • von diesem Index aus werden die nachfolgenden Zeilen auf das Schlüsselwort "del" im Titel untersucht und eventuell entfernt
  • die neuen Zeilen mitsamt der Inhalte werden eingefügt

Beispiel:
Code:
function getXMLObject()  //XML OBJECT
{
  var xmlHttp = false;
  try {
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP")  // For Old Microsoft Browsers
  }
  catch (e) {
      try {
          xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")  // For Microsoft IE 6.0+
      }
      catch (e2) {
          xmlHttp = false   // No Browser accepts the XMLHTTP Object then false
      }
  }
  if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
      xmlHttp = new XMLHttpRequest();        //For Mozilla, Opera Browsers
  }
  return xmlHttp;  // Mandatory Statement returning the ajax object created
}
var xmlhttp = new getXMLObject(); //xmlhttp holds the ajax object

function request(s) {
  if(xmlhttp) {
      xmlhttp.open("GET","gettime?orgID="+s.title,true); //send to servlet
      xmlhttp.onreadystatechange = function(){
        handleServerResponse(s);
      }
      xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      xmlhttp.send(null);
  }
}

function handleServerResponse(objCell){
  if(xmlhttp.readyState == 4){
    if(xmlhttp.status == 200){
      var result = xmlhttp.responseText;  // Antwort
      var intIndex = -1;                  // Zeilenindex
      var objRow = objCell.parentNode;    // Zugehörige Zeile zur übergebenen Zelle
      var objTBody = objRow.parentNode;   // Tabellenkörper

      // Kollektion aller Tabellenzellen
      var arrRows = objRow.parentNode.getElementsByTagName("tr");

      // Kollektion durchlaufen und Zeilenindex ermitteln
      for(var i=0; i<arrRows.length; i++){
      	if(arrRows[i] == objRow){
          intIndex = i;
          break;
        }
      }

      // Falls es sich um keine gültige Zeile handelt
      if(intIndex == -1) return;

      // Falls der "Löschindex" existiert
      if(intIndex+1 < arrRows.length){
        // del-Zeilen entfernen
        v1 = objTBody.rows[intIndex+1].cells[3].title;
        while (v1 == "del") {
          objTBody.deleteRow(intIndex+1);
          v1 = (intIndex+1 < arrRows.length)? objTBody.rows[intIndex+1].cells[3].title : null;
        }
      }

      for(var z = 0; z < 4; z++){
        var newRow = objTBody.insertRow(intIndex+1);
        for (var i = 0; i < 7; i++) {
          var newCell = newRow.insertCell(i);
          if (i > 2) {
            newCell.innerHTML = result + " - " + new Date().getTime();
            newCell.title = "del";
          }
        }
      }

    }
  }
}

Vielleicht hilft dir das weiter.

Ciao
Quaese
 
...
Vielleicht hilft dir das weiter.

Hi, danke nochmal für deine Mühe.

So hab ich noch gar nicht gedacht. Aber ich glaube du hast da was missverstanden, oder ich hab mich nicht deutlich ausgedrückt, gedacht war, dass wenn ich auf "Gruppe 1" klicke, "Gruppe 2" geleert wird.

Aber ich denke ich komme ab hier wieder selbst zurecht. Wenn nicht, setze ich den Thread wieder auf "unerledigt" und hoffe auf Hilfe ;)

Vielen Dank nocheinmal!
 

Neue Beiträge

Zurück