• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Frage Text aus Tabelle in Zwischenablage

Sclero2004

Mitglied
Ganz dummer Fehler von mir: Mit einfachen und doppelten Hochkommas durcheinander geraten. Und das Semikolon ist fehl am Platz:
Code:
fetch('handleFileAction?name="+ fileName + '&action=dir';)
muss, wenn Du die Parameter mit Komma trennen willst, so aussehen:
Code:
fetch('handleFileAction?'+ fileName + ',' + xText)
Bei einfachen Hochkommas muss man die Variablen mit "+" verketten.
Bei Backticks kann man die Syntax mit $ verwenden.
 

colaholiker

Mitglied
Hm, ich bekomme 2 Fehler, diesmal aber erst wenn der dir-Button gedrückt wird:

-Quellübergreifende (Cross-Origin) Anfrage blockiert: Die Gleiche-Quelle-Regel verbietet das Lesen der (...)
-Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

bei
fetch('handleFileAction?'+ fileName + ',' + xText)
kann ich doch xText durch 'Directory' ersetzen? Ich bin mir unsicher ob Du xText wegen meines obigen Postings benutzt hast wo ich sie als String-Variable mißbraucht hatte oder ob das so dasteht obwohl ich die Zeile
var xText = new XMLHttpRequest();
nach Deinem Vorschlag eingetragen hatte. Ändere ich die Zeile in
fetch('handleFileAction?'+ fileName + ',' + 'Directory')
um dieses Problem zu umgehen kommen aber dieselben Fehlermeldungen.

Erganzung zum 2ten Fehler -Uncaught (in promise) TypeError: ...
zeigt er noch Zeilennummern an:
Zeile 166 ist die fetch-Zeile
Zeile 127 ist: handleFileName(event.target, fileName);
(aus dem "window.addEvent"-Teil und
Zeile 121, das ist direkt die Zeile: window.addEventListener('click', event=> {

So sieht's aus:
Code:
    <script>
        window.addEventListener('click', event=> {
            if (event.target.matches('table button')) {
            const
                row = event.target.closest('tr'),
                nameCell = row.querySelector('.td-filename'),
                fileName = nameCell.innerHTML;
                handleFileName(event.target, fileName);
            }
        });
       
        function handleFileName(btn, fileName) {
            // Jetzt steht der Dateiname als Parameter "fileName" zur Verfügung
            // und Du kannst damit arbeiten.
            //var xText = new XMLHttpRequest();
            var xText = "dir";
            console.log(fileName);
            // Hat der Button die Klasse "dir"?
            if (btn.classList.contains('dir')) {
                console.log('Dir-Button wurde gedrückt');
                fetch('handleFileAction?'+ fileName + ',' + 'Directory')
                    .then(response => { response.text() })
                    .then(text => {
                        document.getElementById("feedback-from-fetch").innerHTML = text;
                    });
            }
        }
    </script>
 

Sclero2004

Mitglied
Was dieses betrifft:
-Quellübergreifende (Cross-Origin) Anfrage blockiert: Die Gleiche-Quelle-Regel verbietet das Lesen der (...)
-Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
vermute ich, dass die HTML-Datei, in der das JS das fetch aufruft, nicht vom Server bzw. Microcontroller ausgeliefert wurde. Kann es sein, dass diese statisch und lokal ist? Beginnt die URL im der Adresszeile des Browser mit file:///?
 

colaholiker

Mitglied
...dass diese statisch und lokal ist? Beginnt die URL im der Adresszeile des Browser mit file:///?
Ja genau, meine Testseite liegt auf dem PC des Browsers. Ich müßte ja sonst jedesmal den Microcontroller programmieren wegen jeder kleinen Änderung.
Wie kann diese Meldung

-Quellübergreifende (Cross-Origin) Anfrage blockiert...

umgangen werden damit das Testen erfolgen kann (console.log())?

Das hatte ich mir aber auch schon gedacht, wollte die Meldung aber nicht unterschlagen.

Aber was ist mit der zweiten:

-Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

Da hatte ja ausführlicher berichtet welche Zeilen dazu angezeigt werden, und nochmal den genutzten Code im Script gepostet.
 

Sclero2004

Mitglied
In der Webentwicklung lädt man einfach die Seite mit Filezilla auf den Server hoch oder hat lokal einen Webserver. Aber in diesem Fall ist das wahrscheinlich nicht so einfach, denn möglicher Weise musst Du auch kompilieren. Bin ich jetzt überfragt weil ich in dieser Welt nicht zu Hause bin aber eigentlich müsste solch ein Problem an der Tagesordnung sein und es müsste eine Lösung geben. Versuche, da mal nachzuforschen. Ich kann mich leider nicht erinnern, wie das bei dem Projekt funktionierte, das ich früher unterstützte.

Was dieses betrifft:
Aber was ist mit der zweiten:

-Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
Vermute ich erst Mal, dass es sich auf das selbe Problem bezieht.
 

Sclero2004

Mitglied
PS: Mir fällt gerade ein, das es bei fetch einen no-cors-Modus gibt:
Code:
fetch('handleFileAction?'+ fileName + ',' + 'Directory', {mode: "no-cors"})
Versuche das mal, dann müsste der Request funktionieren, Du wirst nur keine Antwort zurück bekommen.
 

colaholiker

Mitglied
PS: Mir fällt gerade ein, das es bei fetch einen no-cors-Modus gibt:
Code:
fetch('handleFileAction?'+ fileName + ',' + 'Directory', {mode: "no-cors"})
Versuche das mal, dann müsste der Request funktionieren, Du wirst nur keine Antwort zurück bekommen.
Ich habe gerade den Härtetest per Microcontroller gemacht und ich erreiche dort meine Unterroutine!

Um gleich den "no cors"- Punkt abzuhaken: ich habe gemerkt daß in der fetch- Zeile wohl die Sendung der Daten erfolgt. Das tritt einige Male auf, als wenn der Code keine Rückmeldung hat. Mit "no core" sendet er nur einmal?
Ich kenne dieses Verhalten schon von der C++- Seite her von früher und habe am Ende der jew. Unterroutinen dort
Code:
server.send(200, "text/plane", t_state);
eingetragen, dann kamen die Daten nur einmal in C++ an.

Das werde ich im Anschluß erstmal in die aktuelle Controller- Routine einfügen, ehe ich "no core" versuche.
Es gibt andere Fehlermeldungen jetzt, aber ich möchte erstmal weiter machen solange die Daten durchkommen. Wierden ja evtl. weniger.

Zum Code:
Du hattest ja schlauerweise in

Code:
fetch('handleFileAction?'+ fileName + ',' + xText)

meine Variable xText benutzt, was, wenn richtig angewendet, die ganze Routine

Code:
            if (btn.classList.contains(xText)) {
                //console.log('Dir-Button wurde gedrückt');
                fetch('handleFileAction?'+ fileName + ',' + xText)
                    .then(response => { response.text() })
                    .then(text => {
                        document.getElementById("feedback-from-fetch").innerHTML = text;
                    });
            }
nur einmal benötigt wird. Ich habe sie jetzt für jede Buttonklasse extra im Code.

Um im C++-Code besser klarzukommen, möchte ich den HTML-Teil umstellen:
-der fileName wird gesendet,
-die Buttonklasse wird als String (Zahl) drangehängt, also zB. fileName+1 wäre Directory.
Ich baue das jetzt im Anschluß mal um, und hoffe mal, die Buttonklasse "1" usw. wird nicht beanstandet.
 

colaholiker

Mitglied
Jetzt läuft es so, wie ich es mir wünsche.
Der Microcontroller bekommt jetzt z.B. den String "b-Daten1" gesendet.
b-Daten ist ein Ordner der SD-Karte und die 1 ist der Directory-Button. Damit kann ich auslösen, daß dieser Ordner in einem neuen Directory geöffnet wird usw.

Mein dazu umgestellter HTML-Code brauchte die ID "feedback-from-fetch" (aber mit Hochkommas) dazu:
Code:
    <script>
        window.addEventListener('click', event=> {
            if (event.target.matches('table button')) {
            const
                row = event.target.closest('tr'),
                nameCell = row.querySelector('.td-filename'),
                fileName = nameCell.innerHTML;
                handleFileName(event.target, fileName);
            }
        });
       
        function handleFileName(btn, fileName) {
            xBtn = (btn.classList.value);
           
            if (btn.classList.contains(xBtn)) {
                fetch('handleFileAction?' + 'feedback-from-fetch=' + fileName + xBtn)
                    .then(response => { response.text() })
                    .then(text => {
                        document.getElementById('feedback-from-fetch').innerHTML = text;
                    });
            }
        }
    </script>
Wie erwartet kommen auf der Konsole noch Fehlermeldungen, aber die Antwort
Code:
server.send(200, "text/plane", t_state);
von C++ her tut auch ihre Wirkung.

Naja, jetzt fängt die Arbeit erst an. In HTML wären das Formatierungen. Den Button "Upload" hatte ich schon versucht in den Tabellenfooter zu setzen. Aber der hat ja auch 4 Spalten! Mal sehen was ich da mache. Man kann die wohl auflösen...
Macht Spaß!

Also Sclero2004,
vielen Dank für Deine Hilfe!
 

Sclero2004

Mitglied
Jetzt läuft es so, wie ich es mir wünsche.
Das freut einen immer, wenn man liest, dass etwas funktioniert.
Naja, jetzt fängt die Arbeit erst an. In HTML wären das Formatierungen. Den Button "Upload" hatte ich schon versucht in den Tabellenfooter zu setzen. Aber der hat ja auch 4 Spalten! Mal sehen was ich da mache. Man kann die wohl auflösen...
Damit ist man als Webentwickler mehr vertraut. Immer her mit den Fragen.
 

colaholiker

Mitglied
Naja, ich habe bemerkt, daß manche Input-Arten (?) wohl ganze Programmpakete auslösen. Ich hatte schon mit "Update" zu tun. Aber jetzt merke ich daß "Download", "Upload" usw. scheinbar ähnliche Mechaniken besitzen.

Da ich die Eingabefelder dieser Befehle jetzt nicht mehr nutzen möchte (s. Tread- Thema, ich wolte die Filenamen erst aus der Zwischenablage in diese Textfelder setzen), muß ich mich über die Funktionsweise dieser Input- Arten schlau machen, damit ich den richtigen Code in HTML und C++ hinbekomme.
Immerhin merke ich schon, daß der fileName garnicht zum Prozessor gesendet wird, sondern nur der Befehl "Download" ausgelöst wird. Da muß der Filename nur im Input-Feld stehen.
Na dann kümmere ich mich mal.
Bei weiteren Fragen mache ich ein neues Thema auf.

Dann noch ein schönes Weekend, wie die Franzosen sagen...
 
Oben