String-Problem mit dem Zeichen '
Linuchs
- javascript
0 Gunnar Bittersmann0 Linuchs1 klawischnigg
0 dedlfix0 Rolf B0 MudGuard1 Raketensehnix
Moin,
ich sitze jetzt vier Stunden (inkl. Formulierung dieses Fadens) an diesem Problem und komm nicht auf die Lösung. Geschlossene Benutzergruppe, kann das nicht öffentlich verlinken, da Kenn- und Passwort notwendig.
Einer der von Ajax besorgten Vorschlagswerte soll bei Klick in das zugehörige input-Feld übernommen werden:
doch bei Sailors' Crew klappt das nicht wegen des Zeichens '
. Fehlermeldung in der Console: „SyntaxError: unterminated string literal
getMitgliederInteressentenPut(%20"1019",%20"",%20"Singing%20Sailors:1:43“
Zeile 1 dieser Funktion lautet:
function getMitgliederInteressentenPut( adress_id, interessent_id, firma1, ort_id, land_kz, plz, ort_name ) {
Spalte 43 wäre das r
von adress_id - keine Ahnung, wie mir diese Meldung helfen könnte.
Was hindert Javascript daran, einen beliebigen String in ein input-Feld zu kopieren?
@@Linuchs
Zeile 1 dieser Funktion lautet:
Interessant wäre vielleicht auch, was die anderen Zeilen tun und was die Funktion überhaupt tun soll. Kannst du das mal in Worte fassen?
Wenn dabei das Wort „und“ auftaucht, ist das ein sicheres Zeichen von schlechtem Software-Design. Eine Funktion soll genau eine Sache tun.
Und interessant wäre zu wissen, wie und mit welchen Parametern die Funktion aufgerufen wird.
Was hindert Javascript daran, einen beliebigen String in ein input-Feld zu kopieren?
Dass du den Kontextwechsel nicht beachtest.
😷 LLAP
Hallo Gunnar,
Interessant wäre vielleicht auch, was die anderen Zeilen tun und was die Funktion überhaupt tun soll. Kannst du das mal in Worte fassen?
Für eine Veranstaltung, die zuvor als Festival definiert wurde, kann man in Fünfergruppen teilnehmende Chöre eingeben. Also fünf absenden, dann die nächsten fünf.
So sieht dann die öffentliche Seite aus: https://remso.eu/30449
Und interessant wäre zu wissen, wie und mit welchen Parametern die Funktion aufgerufen wird.
Der Ajax-Abruf wird mit einer CSV-Datei beantwortet, die schnellste mir bekannte Art der Datenübermittlung:
https://remso.eu/ajax/getMitgliederInteressenten.php?teilnehmer_name_9=roma
lfd;adress_id;interessent_id;firma1;firma1_markiert;ort_id;land_kz;plz;ort_name
1;;210;SC "Romantik Sailors" Iserlohn;SC "<i class=crot>Roma</i>ntik Sailors" Iserlohn;8941;D;58642;Iserlohn
2;1019;;Singing Sailors' Crew Romanshorn;Singing Sailors' Crew <i class=crot>Roma</i>nshorn;13354;CH;8590;Romanshorn
Im aufpoppenden Vorschlagsfeld werden die Daten gezeigt und bei Klick wird der String namens firma1 (1. Zeile Firmen- / Vereinsname) in das zugehörige Input-Feld kopiert. Das klappt nicht, wenn firma1 das Zeichen '
enthält.
Dass du den Kontextwechsel nicht beachtest.
Problem ist mir bewusst, aber die Lösung nicht. Wie müsste ich das Zeichen '
per Javascript codieren, damit es als '
im HTML input-Feld erscheint?
Gruß, Linuchs
@@Linuchs
Für eine Veranstaltung, die zuvor als Festival definiert wurde, kann man in Fünfergruppen teilnehmende Chöre eingeben. Also fünf absenden, dann die nächsten fünf.
Warum fünf? Was haben die fünf Chöre einer Gruppe gemeinsam? Was unterscheidet sie von den Chören der anderen Fünfergruppen?
Der Ajax-Abruf wird mit einer CSV-Datei beantwortet
Warum kein vernünftiges Format? Warum nicht JSON?
Das klappt nicht, wenn firma1 das Zeichen
'
enthält.
Das Zeichen ' sollte sowieso in keinem Namen vorkommen. Ein Apostroph sieht so aus: ’. Aber für falsche Nutzereingaben kannst du nichts.
Vielleicht willst du ' aber nicht escapen, sondern in Apostrophen umwandeln?
😷 LLAP
Hallo
Der Ajax-Abruf wird mit einer CSV-Datei beantwortet, die schnellste mir bekannte Art der Datenübermittlung:
… und eine der unzuverlässigsten Arten zudem. Einem Fallstrick begegnest du gerade. Mit JSON wäre das nicht passiert™️ und dass die Aufbereitung und Anieferung von JSON merklich langsamer wäre, kann ich mir auch nicht vorstellen. Aber jeder schafft sich seine eigenen, unnötigen Baustellen.
lfd;adress_id;interessent_id;firma1;firma1_markiert;ort_id;land_kz;plz;ort_name 1;;210;SC "Romantik Sailors" Iserlohn;SC "<i class=crot>Roma</i>ntik Sailors" Iserlohn;8941;D;58642;Iserlohn 2;1019;;Singing Sailors' Crew Romanshorn;Singing Sailors' Crew <i class=crot>Roma</i>nshorn;13354;CH;8590;Romanshorn
Warum zum Henker sind deine Strings nicht einfach in Anführungszeichen eingefasst?
"lfd";"adress_id";"interessent_id";"firma1";"firma1_markiert";"ort_id";"land_kz";"plz";"ort_name"
1;;210;"SC \"Romantik Sailors\" Iserlohn";"SC \"<i class=crot>Roma</i>ntik Sailors\" Iserlohn";8941;"D";"58642";"Iserlohn"
2;1019;;"Singing Sailors' Crew Romanshorn";"Singing Sailors' Crew <i class=crot>Roma</i>nshorn";13354;"CH";"8590";"Romanshorn"
Alles, was ein String ist oder sein soll, ist in doppelte Anführungszeichen eingefasst. Somit würde der Fehler bei „Singing Sailors'“ erst überhaupt nicht auftreten. Allerdings müsstest du, wie oben bei „"Romantik Sailors"“ zu sehen, die „"“ innerhalb des Strings maskieren.
Die JSON-Funktionen von PHP und JS würden dir diesen Teil aber abnehmen.
Tschö, Auge
Tach!
Allerdings müsstest du, wie oben bei „"Romantik Sailors"“ zu sehen, die „"“ innerhalb des Strings maskieren.
Ja, aber nicht wie oben mit vorangestelltem Backslash sondern durch Verdopplung der Anführungszeichen.
Feld davor;"Text ""mit"" Anführungszeichen";Feld danach
dedlfix.
@@dedlfix
Allerdings müsstest du, wie oben bei „"Romantik Sailors"“ zu sehen, die „"“ innerhalb des Strings maskieren.
Ja, aber nicht wie oben mit vorangestelltem Backslash sondern durch Verdopplung der Anführungszeichen.
Das zu ' Gesagte gilt auch für ": Wenn man sich schon dranmacht, diese Zeichen zu behandeln, sollte man das gleich richtig tun und durch Anführungszeichen ersetzen.
Wobei die richtigen Anführungszeichen von der Sprache abhängen. Deutsch: „“, englisch: “”.
😷 LLAP
Tach!
Das zu ' Gesagte gilt auch für ": Wenn man sich schon dranmacht, diese Zeichen zu behandeln, sollte man das gleich richtig tun und durch Anführungszeichen ersetzen.
Es ging hier um Maskierung. Natürlich ist die Vermeidung des Problems auch eine Strategie. Aber lässt die sich technisch problemlos durchführen? Was ist mit den Fällen, wo nicht eindeutig bestimmt werden kann, welches der beiden "richtigen" Anführungszeichen anstelle eines "falschen" stehen soll? Maskierung wird jedenfalls nicht komplett überflüssig, vor allem nicht die Korrektur einer falschen Maskierung.
Ich freue mich ja immer, wenn ein automatisches Textverarbeitungssytem Anführungszeichen in Code-Zitaten durch die typografisch falschen ersetzt.
dedlfix.
@@dedlfix
Es ging hier um Maskierung. Natürlich ist die Vermeidung des Problems auch eine Strategie. Aber lässt die sich technisch problemlos durchführen?
Mit „" am Anfang oder nach Leerzeichen (o.a. Whitespace) → öffnendes Anführungszeichen; sonst → schließendes Anführungszeichen“ sollte man auf der ziemlich sicheren Seite sein.
Maskierung wird jedenfalls nicht komplett überflüssig, vor allem nicht die Korrektur einer falschen Maskierung.
Ja.
Ich freue mich ja immer, wenn ein automatisches Textverarbeitungssytem Anführungszeichen in Code-Zitaten durch die typografisch falschen ersetzt.
Ja, das nervt. Das sollte aber in @Linuchs’ Anwendungsfall keine Rolle spielen.
Not-so-fun fact: Slack denkt, es wäre klüger als ich. Immer, wenn ich korrekte deutsche Anführungszeichen setze (also hinten Doppel-6), macht das mir aus dem schließenden Anführungszeichen ein ” (Doppel-9).
😷 LLAP
Tach!
Mit „" am Anfang oder nach Leerzeichen (o.a. Whitespace) → öffnendes Anführungszeichen; sonst → schließendes Anführungszeichen“ sollte man auf der ziemlich sicheren Seite sein.
Durchaus, Betonung aber auf „sollte“. Automatismen, und seien sie noch so gut gemeint, werden wohl nie vollständig die Intention des Autors erkennen. Automatismen, die ohne ein Opt-In durch die Nutzer irgendetwas tun, können auch ein ziemlich großes Manko in der Benutzererfahrung sein. Und selbst wenn sie wissentlich eingeschaltet sind, müssen die Autoren ihre Arbeitsweise kennen und kontrollieren, ob sie auch das intentionsgemäß richtige gemacht haben. Kann man es den Nutzern zumuten, sich mit solchen technischen Details und Überwachungsaufgaben zu befassen, wenn sie eigentlich nur ihre Arbeit tun wollen? Das sollte man auch in die Wägschale werfen, wenn man solche Automatismen einbaut.
Rechtschreibkorrekturen, die sinnentstellend korrigiert haben, wird wohl jeder schon mal erlebt haben, um nur ein Beispiel für eines dieser Ärgernisse solcher Automatismen zu nennen.
dedlfix.
@@dedlfix
Mit „" am Anfang oder nach Leerzeichen (o.a. Whitespace) → öffnendes Anführungszeichen; sonst → schließendes Anführungszeichen“ sollte man auf der ziemlich sicheren Seite sein.
Durchaus, Betonung aber auf „sollte“.
Ich hätte die Betonung auf „ziemlich“ gesetzt. 😉
Und wenn der Automatismus in einem von hundert Fällen das Falsche tut? Na dann steht ein “ statt eines „ (bzw. andersrum), nicht schön, aber auch nicht wirklich schlimm – in diesem Anwendungsfall.
In anderen Anwendungsfällen mag sowas weitreichendere Konsequenzen haben und man müsste da mehr Gehirnschmalz reinstecken, um dem entgegenzuwirken. Hier aber sollte o.g. Regel gut genug sein.
😷 LLAP
Tach!
Und wenn der Automatismus in einem von hundert Fällen das Falsche tut? Na dann steht ein “ statt eines „ (bzw. andersrum), nicht schön, aber auch nicht wirklich schlimm – in diesem Anwendungsfall.
Ja, ich seh das aber andersherum genauso. Wichtig für mich beim Lesen ist nur, dass ich erkenne, dass der Autor etwas beabsichtigt. Ob die Tüdelchen dazu nun oben oder unten stehen oder nach rechts, links oder gerade nach unten zeigen, ist für mich nicht von Belang. Das ist für mich so unwichtig, dass es mir normalerweise noch nicht mal auffällt.
Ich finde die Lösung hier im Forum besser als die automatische Ersetzung. Hier wird mir nur ungezwungen angeboten, die sonst nicht auf der Tastatur erreichbaren Zeichen einzufügen.
dedlfix.
Hallo,
Automatismen, und seien sie noch so gut gemeint, werden wohl nie vollständig die Intention des Autors erkennen. Automatismen, die ohne ein Opt-In durch die Nutzer irgendetwas tun, können auch ein ziemlich großes Manko in der Benutzererfahrung sein.
das merke ich jedesmal, wenn ich mit einem frisch installierten MS Office arbeiten soll. Da sind gefühlt alle nur erdenklichen Automatikfunktionen aktiviert. Rechtschreibprüfung, Auto-Vervollständigung, Auto-Formatierung und vieles mehr. Die meisten dieser vermutlich gut gemeinten Funktionen finde ich ausgesprochen lästig und stelle sie daher ab.
Und selbst wenn sie wissentlich eingeschaltet sind, müssen die Autoren ihre Arbeitsweise kennen
Genau. Und das ist beim gemeinen Office-User eher nicht der Fall.
Rechtschreibkorrekturen, die sinnentstellend korrigiert haben, wird wohl jeder schon mal erlebt haben
Oh ja ...
Live long and pros healthy,
Martin
Hi there,
Wenn dabei das Wort „und“ auftaucht, ist das ein sicheres Zeichen von schlechtem Software-Design. Eine Funktion soll genau eine Sache tun.
Sorry, aber das ist ziemlicher Unfug. Eine Funktion soll das tun, was der Programmierer damit im Sinn hatte.
Ich erspar' Dir jetzt die Frage, was genau im programmiertechnischen Sinn mit "einer Sache" gemeint ist, aber "Sachen" können jedenfalls sehr komplex werden, das hat mit der Aufgabenstellung etwas zu tun, und nicht notwendigerweise etwas mit "Software-Design". Wenn Du meinst, daß eine Funktion einen Wert zurück geben soll, dann bin ich schon eher bei Dir, aber dann heben schon wieder meine Zweifel an und ich frag' mich, ob Funktionen, die ein Array zurückgeben, aus Deiner Sicht ebenfalls "schlechtes Software-Design" sind...
Tach!
Wenn dabei das Wort „und“ auftaucht, ist das ein sicheres Zeichen von schlechtem Software-Design. Eine Funktion soll genau eine Sache tun.
Sorry, aber das ist ziemlicher Unfug. Eine Funktion soll das tun, was der Programmierer damit im Sinn hatte.
Es ist zwar immer noch des Programmierers Entscheidung, was die Software tut. Es ist aber auch so, dass sich eine hohe Komplexität üblicherweise schwer verstehen und pflegen lässt. Deswegen ist es eigentlich sinnvoll, diese Komplexität in kleinere einfacher zu verstehende und zu wartende Teile herunterzubrechen. Die Aussage mit dem "und" ist natürlich kein Gesetz, sondern eher eine Faustregel, dass man mal darüber nachdenken könnte, den Code besser zu strukturieren. Die Komplexität insgesamt bleibt gleich, solange man nicht zu umständliche Lösungen drin hat, die bei weniger Aufwand dasselbe Ergebnis bringen würden. Aber die Überschaubarkeit sollte steigen, besonders wenn man sprechende Namen für die Teilstücke verwendet. Das erhöht idealerweise die Lesbarkeit des Codes auch ohne Kommentare.
Es ist auch eine Frage der Kombinatorik beim Testen. Je mehr ein Softwareteil tut, desto höher werden auch die Kombinationsmöglichkeiten, die man alle testen müsste.
Ich erspar' Dir jetzt die Frage, was genau im programmiertechnischen Sinn mit "einer Sache" gemeint ist, aber "Sachen" können jedenfalls sehr komplex werden, das hat mit der Aufgabenstellung etwas zu tun, und nicht notwendigerweise etwas mit "Software-Design".
Du kannst ja mal in die Wirtschaft schauen. Je komplexer ein Produkt herzustellen ist, desto feingliedriger wird der Produktionsprozess. Da ist nicht ein einzelner Mitarbeiter, der das Ding von Anfang bis Ende herstellt, sondern viele, die jeweils eine mehr oder weniger spezialisierte Aufgabe erledigen.
Wenn Du meinst, daß eine Funktion einen Wert zurück geben soll, dann bin ich schon eher bei Dir, aber dann heben schon wieder meine Zweifel an und ich frag' mich, ob Funktionen, die ein Array zurückgeben, aus Deiner Sicht ebenfalls "schlechtes Software-Design" sind...
Jetzt begibst du dich so langsam in die Unsinnsfalle, wenn du das auf diese Weise rhetorisch zu überspitzen versuchst. Da könntest du dich dann auch fragen, ob man die Elemente des Arrays nicht gleich byteweise oder sogar bitweise zurückgeben sollte. Natürlich kann man das so formulieren, dass das "ein Bit und noch ein Bit und ..." sind. (Was ja auch sinnvoll wäre, wenn man eine Routine zur seriellen Datenübertragung schreibt.) Die "und"-Regel verbietet jedenfalls nicht, dass man nach oben hin abstrahiert. Eine Liste von Records ist am Ende immer noch eine Einheit, auch wenn es in den tieferen Ebenen mehrere Schritte gebraucht hat, diese zu erstellen. Diese Schritte kann man jedenfalls auch so zu kapseln versuchen, dass man gut sehen kann, welche Teilaufgaben sie zu erledigen haben.
dedlfix.
Hallo,
Diese Schritte kann man jedenfalls auch so zu kapseln versuchen, dass man gut sehen kann, welche Teilaufgaben sie zu erledigen haben.
genau hier liegt der Hase im Pfeffer. Das erwähnte "und-Dogma" ist als Faustregel völlig in Ordnung, aber man sollte beim Herunterbrechen in Teilaufgaben mit Fingerspitzengefühl vorgehen und nicht mit dem Bulldozer. Übertreibt man es mit der Granularität, hat man zwar wunderbar übersichtliche Einzelschritte, aber man verliert den Überblick, was die Funktion als Ganzes eigentlich tut.
Vor allem dann, wenn mehrere Schritte prinzipbedingt streng sequentiell ablaufen (müssen), bietet es sich an, sie auch sequentiell in einer Funktion zu notieren - auch wenn die Prosa-Beschreibung dann mehrmals "und dann" enthält.
Daher halte ich dem "und-Dogma" zum Ausgleich eine andere Faustregel entgegen: Nicht zerreißen, was eigentlich zusammengehört.
Live long and pros healthy,
Martin
Hallo Martin,
Daher halte ich dem "und-Dogma" zum Ausgleich eine andere Faustregel entgegen: Nicht zerreißen, was eigentlich zusammengehört.
"Eine Funktion sollte eine Sache tun" ist eine durchaus gängige Lehre. Und es ist wichtig, denn andernfalls wird das mit den Unit Tests eine schwierige bis unmögliche Sache.
Eine "große" Funktion, die viele Dinge nacheinander tut, schreit nach Zerschlagung in kleinere Teile, die separat getestet werden können. Und wenn diese Teile zusammengehören, dann schreit das auch nach einer Ausgliederung in eine Worker-Klasse. Die wird bei Bedarf erzeugt, bekommt ggf. Objekte für Logging, DB-Zugriff und ähnliches injiziert, und kann dann schön autark vor sich hin wurschteln. Und man kann schön autark Unittests dafür schreiben.
Ich hab schon Funktionen von Kollegen gesehen, die 2000 Zeilen lang waren. Nachdem ich die Brechstange angesetzt hatte, wurden eine Menge kleinerer Funktionen draus, und eine Hauptfunktion, die alles gesteuert hat (das war ihre "eine Sache"). Nach etwas mehr Codeinspektion fand ich dann auch, dass diese kleineren Funktionen sich teilweise so sehr ähnelten, dass man sie gemeinsam implementieren konnte und nur passend zu parametrieren brauchte. Nachher waren es 500 Zeilen. Durch gutes Benennen der Teilfunktionen wusste man auch, was die einzelnen Codeteile taten und konnte sich top-down in den Code einlesen.
Pflichtlektüre ist hier Clean Code von Robert C. Martin. Problem ist nur, dass es scheinbar out of print ist und nur schlechte Nachdrucke erhältlich sind; bei Amazon beschweren sich etliche Käufer bitterlich über schlechten Kontrast und riesige weiße Ränder.
Rolf
@@Rolf B
Ich hab schon Funktionen von Kollegen gesehen, die 2000 Zeilen lang waren. Nachdem ich die Brechstange angesetzt hatte […] waren es 500 Zeilen.
“One of my most productive days was throwing away 1,000 lines of code.”
— Ken Thompson
😷 LLAP
Hallo Rolf,
Daher halte ich dem "und-Dogma" zum Ausgleich eine andere Faustregel entgegen: Nicht zerreißen, was eigentlich zusammengehört.
"Eine Funktion sollte eine Sache tun" ist eine durchaus gängige Lehre ...
... gegen die ich auch nichts einzuwenden habe. Nur ist sie nicht in jedem Fall sinnvoll.
Eine "große" Funktion, die viele Dinge nacheinander tut, schreit nach Zerschlagung in kleinere Teile, die separat getestet werden können.
Eine große Funktion, die viele Dinge nacheinander tut, entsteht normalerweise Schritt für Schritt. Testen, ggf. nachbessern, nächsten Schritt hinzufügen, wieder testen.
Ich hab schon Funktionen von Kollegen gesehen, die 2000 Zeilen lang waren.
Ich auch.
Nachdem ich die Brechstange angesetzt hatte, wurden eine Menge kleinerer Funktionen draus, und eine Hauptfunktion, die alles gesteuert hat (das war ihre "eine Sache").
Wenn man die Teilschritte für sich sinnvoll kapseln kann, ist das auch gut. Das kann man aber nicht immer. Die Fensterprozeduren in einer Windows-Anwendung sind in der Regel lange switch-Anweisungen, die anhand der Message-ID entscheiden, was gerade zu tun ist. Das können schon mal mehrere Dutzend verschiedene Messages sein, die bearbeitet werden müssen. Da ist es vorteilhaft und üblich, alles zusammenzuhalten, was zu einem Fenster gehört. Die einzelnen case-Zweige sind dann in der Regel kurze Blöcke mit wenigen Zeilen, manchmal nur einem Funktionsaufruf.
Nach etwas mehr Codeinspektion fand ich dann auch, dass diese kleineren Funktionen sich teilweise so sehr ähnelten, dass man sie gemeinsam implementieren konnte und nur passend zu parametrieren brauchte.
Gleichen oder fast gleichen Code identifizieren und als separate Funktion auslagern ist gut.
Nachher waren es 500 Zeilen. Durch gutes Benennen der Teilfunktionen wusste man auch, was die einzelnen Codeteile taten und konnte sich top-down in den Code einlesen.
Ja. "Lange" Funktionen finde ich bei rein linearem Programmablauf dennoch übersichtlicher.
Kannst du dich an Apache 2.0 erinnern? Da gab es in der Standardinstallation eine Konfigurationsdatei httpd.conf. Ab 2.2 oder 2.4 wurde die dann in viele Fragmente heruntergebrochen, die includiert wurden. Ich fand das katastrophal unübersichtlich.
Live long and pros healthy,
Martin
Hallo Martin,
Die Fensterprozeduren in einer Windows-Anwendung
Ja. Der Switch gehört dann in eine Funktion. Und die ruft pro Message einen Handler auf. Diese Funktion tut dann genau ein Ding: Message Dispatch. Und jeder Handlerfunktion behandelt eine Windows Message.
Da ist es vorteilhaft und üblich, alles zusammenzuhalten
Alles in einer Funktion? Sicher nicht. Das ist nicht vorteilhaft, wenn die Handler mehr tun müssen als in 3 Zeilen passt. Vor allem nicht, wenn Du ein Fenster mit 20 Controls hast und jedes Eingabefeld unterschiedliche Verarbeitungen braucht. Entweder registrierst Du für jedes Control eine eigene Windowklasse mit eigenem Dispatch
Es ist vorteilhaft und üblich, Komponenten zu bilden, und mit Subclassing oder Message Forwarding zu arbeiten. Gerne auch mit Frameworks wie MFC. Und dann zerteilt sich wieder alles.
Rolf
Hallo,
Die Fensterprozeduren in einer Windows-Anwendung
Ja. Der Switch gehört dann in eine Funktion. Und die ruft pro Message einen Handler auf. Diese Funktion tut dann genau ein Ding: Message Dispatch. Und jeder Handlerfunktion behandelt eine Windows Message.
das ist aber nicht die gängige Praxis bei Windows-Anwendungen.
Da ist es vorteilhaft und üblich, alles zusammenzuhalten
Alles in einer Funktion? Sicher nicht. Das ist nicht vorteilhaft, wenn die Handler mehr tun müssen als in 3 Zeilen passt. Vor allem nicht, wenn Du ein Fenster mit 20 Controls hast und jedes Eingabefeld unterschiedliche Verarbeitungen braucht. Entweder registrierst Du für jedes Control eine eigene Windowklasse mit eigenem Dispatch
Das ist aber nicht die gängige Praxis bei Windows-Anwendungen.
Es ist vorteilhaft und üblich, Komponenten zu bilden, und mit Subclassing oder Message Forwarding zu arbeiten. Gerne auch mit Frameworks wie MFC. Und dann zerteilt sich wieder alles.
Frameworks wie MFC oder .NET meide ich wie der Teufel das Weihwasser, weil sie das Ganze unnötig aufwendig, umständlich und kompliziert machen. Und erschreckend schlecht dokumentiert sind (zumindest MFC).
Und damit bin ich nicht allein.
Live long and pros healthy,
Martin
Hallo Martin,
Das ist aber nicht die gängige Praxis bei Windows-Anwendungen.
Das ist aber nicht die gängige Praxis bei Windows-Anwendungen.
Nun gut. Ich habe davon nicht viele geschrieben, bevor ich gezwungen wurde, zuerst Smalltalk (🤮) und dann .net (😍) zu verwenden.
Aber für eine umfangreichere Win32-Anwendung würde ich mich intensiv bemühen, NICHT alles mit einer Dispatch-Funktion zu erschlagen. Computersekunden sind billig. Programmierersekunden sind kostbar.
Für Doku musst Du Bücher kaufen. Es gab mal Zeiten, da war die Online-Doku im MDSN okay. Mittlerweile ist es grottig, bzw. sie dokumentieren nur den heißen Scheiß von heute, der morgen abgekühlt vor sich hinstinkt. Der alte Kram, auf den mal Leute gesetzt haben, wird depubliziert. Es ist ein Jammer 😕
Rolf
Hallo Rolf,
Das ist aber nicht die gängige Praxis bei Windows-Anwendungen.
Das ist aber nicht die gängige Praxis bei Windows-Anwendungen.Nun gut. Ich habe davon nicht viele geschrieben, bevor ich gezwungen wurde, zuerst Smalltalk (🤮) und dann .net (😍) zu verwenden.
ich habe einige davon selbst geschrieben, und viele von Fremdautoren als Anschauungsobjekt betrachtet. Aktuell bin ich dabei, eine Komponente zu evaluieren - da muss ich allerdings viel "reparieren" und versäubern - das ist ein Paradebeispiel dafür, wie man es nicht machen sollte. Angefangen beim Sauerkraut-Indenting: Teils mit Tabs, teils mit Spaces, mal gemischt, und daher völlig durcheinander.
Aber für eine umfangreichere Win32-Anwendung würde ich mich intensiv bemühen, NICHT alles mit einer Dispatch-Funktion zu erschlagen. Computersekunden sind billig. Programmierersekunden sind kostbar.
Da kann ich zum Glück andere Maßstäbe anlegen. Für mich ist Softwareentwicklung vor allem ein Hobby, und ob ich für ein Projekt 20 Stunden mehr investiere, ist belanglos. Der Idealismus wiegt schwerer.
Für Doku musst Du Bücher kaufen. Es gab mal Zeiten, da war die Online-Doku im MDSN okay. Mittlerweile ist es grottig, bzw. sie dokumentieren nur den heißen Scheiß von heute, der morgen abgekühlt vor sich hinstinkt.
Die Dokumentation zum Windows-API ist dagegen heute besser als noch vor 10 Jahren. Das kommt mir entgegen, weil ich eher der Bare-Metal-Programmierer bin und im Fall von Windows ausschließlich auf API-Ebene unterwegs bin.
Live long and pros healthy,
Martin
Hi there,
Wenn dabei das Wort „und“ auftaucht, ist das ein sicheres Zeichen von schlechtem Software-Design. Eine Funktion soll genau eine Sache tun.
Sorry, aber das ist ziemlicher Unfug. Eine Funktion soll das tun, was der Programmierer damit im Sinn hatte.
Es ist zwar immer noch des Programmierers Entscheidung, was die Software tut. Es ist aber auch so, dass sich eine hohe Komplexität üblicherweise schwer verstehen und pflegen lässt. Deswegen ist es eigentlich sinnvoll, diese Komplexität in kleinere einfacher zu verstehende und zu wartende Teile herunterzubrechen. Die Aussage mit dem "und" ist natürlich kein Gesetz,[...]
Nein, aber auch kein Zeichen von schlechtem Softwaredesign. Und um darauf hinzuweisen ist es mir in meiner Replik auf das Posting von Gunnar gegangen. Ebenso bin ich auf die von Dir erwähnte Komplexität weiter unten eingegangen. Es hängt eben praktisch immer vom Einzelfall und von der Aufgabenstellung ab, deswegen halte ich so "allgemeingültig wertende" Aussagen schlicht und ergreifend für falsch und unnötig.
Es ist auch eine Frage der Kombinatorik beim Testen. Je mehr ein Softwareteil tut, desto höher werden auch die Kombinationsmöglichkeiten, die man alle testen müsste.
Ja, das ist unbestritten richtig, dem gegenüber steht aber erstens der Umstand, daß das eher die Praxis betrifft als das Softwaredesign und zweitens können bestens ausgetestete, auf Einzelproblematik heruntergebrochen Funktionen im Zusammenwirken dann durchaus auch noch Fehler beinhalten oder verursachen. Es kommt, wie oben beschrieben, auch hier auf den speziellen Fall an.
Ich erspar' Dir jetzt die Frage, was genau im programmiertechnischen Sinn mit "einer Sache" gemeint ist, aber "Sachen" können jedenfalls sehr komplex werden, das hat mit der Aufgabenstellung etwas zu tun, und nicht notwendigerweise etwas mit "Software-Design".
Du kannst ja mal in die Wirtschaft schauen.
Das mach' ich seit über dreissig Jahren, ich lebe davon.
Wenn Du meinst, daß eine Funktion einen Wert zurück geben soll, dann bin ich schon eher bei Dir, aber dann heben schon wieder meine Zweifel an und ich frag' mich, ob Funktionen, die ein Array zurückgeben, aus Deiner Sicht ebenfalls "schlechtes Software-Design" sind...
Jetzt begibst du dich so langsam in die Unsinnsfalle, wenn du das auf diese Weise rhetorisch zu überspitzen versuchst.
Zugegeben...😉
Tach!
doch bei Sailors' Crew klappt das nicht wegen des Zeichens
'
. Fehlermeldung in der Console: „SyntaxError: unterminated string literal
getMitgliederInteressentenPut(%20"1019",%20"",%20"Singing%20Sailors:1:43“
Das sieht mir erstmal so aus, als ob der gesamte Funktionsaufruf als in einem String steckend angesehen wird. Vielleicht baust du Code per Stringverknüpfung zusammen und hast dabei nicht korrekt maskiert? Generell sollte man sowas vermeiden. Wenn man Daten in einen Javascript-Kontext bringen muss, sollte man diese Json-encodieren und schön getrennt vom Programmcode transportieren. Es kann sich in deinem Fall aber auch um was anderes handeln, so genau kann ich das aus dem Beitrag nicht entnehmen.
dedlfix.
Hallo Linuchs,
Was hindert Javascript daran, einen beliebigen String in ein input-Feld zu kopieren?
Die Art und Weise, wie Du es tust.
Die Fehlermeldung bezieht sich nicht auf die Deklaration, sondern auf den Aufruf der Funktion. Wie rufst Du sie auf?
Wenn ich die %20 durch " " ersetze, steht da
getMitgliederInteressentenPut( "1019", "", "Singing Sailors:1:43“`
0....*....1....*....2....*....3....*....4....*....5....*....
bei Spalte 43 beginnt genau der String, der das ' enthält, und der reklamierte Code endet genau dort, wo das ' steht.
Du müsstest schon vorzeigen, wie dieser Aufruf zu Stande kommt.
Rolf
Hallo Rolf,
Du müsstest schon vorzeigen, wie dieser Aufruf zu Stande kommt.
Okay, Ajax fragt und PHP sendet diese drei Zeilen:
lfd;adress_id;interessent_id;firma1;firma1_markiert;ort_id;land_kz;plz;ort_name
1;;210;SC "Romantik Sailors" Iserlohn;SC "<i class=crot>Roma</i>ntik Sailors" Iserlohn;8941;D;58642;Iserlohn
2;1019;;Singing Sailors' Crew Romanshorn;Singing Sailors' Crew <i class=crot>Roma</i>nshorn;13354;CH;8590;Romanshorn
Die werden von JS umgesetzt in:
Und hier die zugehörige Funktion in Datei https://remso.eu/ajax/getMitgliederInteressenten.js:
/* ************************************************
*
* getMitgliederInteressentenPut
* angeklickten Vorschlag in Felder uebernehmen
*
* ************************************************ */
function getMitgliederInteressentenPut( adress_id, interessent_id, firma1, ort_id, land_kz, plz, ort_name ) {
console.log( "obj.name=[" +getMitgliederInteressentenVar.obj.name +"] adress_id=[" +adress_id +"]" +" interessent_id=[" +interessent_id +"] firma1=[" +firma1 +"]" );
getMitgliederInteressentenVar.obj.value = firma1;
// 2021-02-02 p502 fuenf Neueinmgaben moeglich
var arr = getMitgliederInteressentenVar.obj.name.split( "_" ); // teilnehmer_name_8
var ndx = arr[ arr.length -1 ];
console.log( "ndx=[" +ndx +"]" );
if ( document.getElementsByName("adress_id_" +ndx )[0] ) document.getElementsByName("adress_id_" +ndx )[0].value = adress_id;
if ( document.getElementsByName("interessent_id_" +ndx )[0] ) document.getElementsByName("interessent_id_" +ndx )[0].value = interessent_id;
if ( document.getElementsByName("adress_id")[0] ) document.getElementsByName("adress_id")[0].value = adress_id;
if ( document.getElementsByName("interessent_id")[0] ) document.getElementsByName("interessent_id")[0].value = interessent_id;
if ( document.getElementsByName("such_firma1")[0] ) document.getElementsByName("such_firma1")[0].value = firma1;
if ( document.getElementsByName("ort_id")[0] ) document.getElementsByName("ort_id")[0].value = ort_id;
if ( document.getElementsByName("such_land_kz")[0] ) document.getElementsByName("such_land_kz")[0].value = land_kz;
if ( document.getElementsByName("such_plz")[0] ) document.getElementsByName("such_plz")[0].value = plz;
if ( document.getElementsByName("such_ort_name")[0] ) document.getElementsByName("such_ort_name")[0].value = ort_name;
}
Gruß, Linuchs
Hallo Linuchs,
wie gesagt - die Implementierung der Funktion getMitgliederInteressentenPut ist unschuldig. Das brauchen wir nicht.
Das Syntaxhighlighting zeigt das Problem. Und Du hättest den Screenshot nicht im Inspektor, sondern im DOM machen sollen. Aus dem Screenshot errate ich, dass Du im PHP mutmaßlich <a href='javascript...'>
verwendest und nicht, wie der Inspektor behauptet, <a href="javascript...">
Das einzelne Apostroph beendet dann das Attribut und dadurch geht der Rest in die Binsen. Oder den Strandhafer.
Aus der Hüfte geschossen: Behandle im PHP den href-String mit
htmlentities(str_replace('"', '\\"', $href), ENT_QUOTES)
Das sind zwei Kontextbehandlungen. htmlentities sorgt dafür, dass der Attributstring das HTML nicht ungültig macht. Unter anderem ersetzt die Funktion "'" durch "'".
Aber du könntest auch den Chor „Shantyclub "Die Brüllaffen"“ haben. Und dann würden Dir die " den JavaScript-Aufruf ruinieren. Denen musst Du deshalb ein \ voranstellen. Und weil PHP das \ als eigenes Escapezeichen verwendet, musst Du es verdoppeln.
Was Du tust, ist gruselig kompliziert. Du hast drei Kontexte: PHP, HTML und dazu noch Javascript in einem HTML String. Das alles richtig zu maskieren... Es gibt Dinge, die noch nicht einmal dem Teufel einfallen würden. Aber Dir 😉
Testfälle:
Wie kann man es besser machen? Es gibt mehrere Kritikpunkte.
<button type="button"><i class='red'>Sail</i>or's Moon</button>
Wenn Du die Suchtreffer immer rot hervorhebst, solltest Du keine class="red" setzen, sondern korrekt <em></em> verwenden und das innerhalb der Suchliste per CSS erröten lassen (die Fett/Kursiv-Ambitionen von em musst Du dann natürlich verhindern).
Den Buttons kannst Du data-Attribute mitgeben, wo die Daten für die Klickbehandlung drinstehen. Das sind 7 Parameter. Du kannst sieben data-Attribute je Button verwenden, oder alle 7 als json-String codieren und in ein Attribut schreiben. Den müsstest Du dann beim Klick auf den Button zerlegen und an deine Funktion übergeben. Auf diese Weise vermeidest Du geschachtelte Kontexte; JavaScript in einem HTML Attribut ist schon tricky genug. Das mit PHP zu generieren sollte man vermeiden.
Für die Buttons registrierst einen Click-Handler - und zwar nicht auf jedem Button, sondern auf dem mitgliederInteressentenVorschlaege div. Der Click bubbelt dann dorthin. Wenn Du HTML im Button-Text hast, musst Du noch ein bisschen aufpassen, weil Du als event.target dann nicht zwingend den Button, sondern das <i> (oder <em>) Elememt bekommst. Dafür gibt's die closest-Methode am HTML Element (nicht im IE) oder du gehst so lange die parent-Kette hoch, bis Du einen Button oder mitgliederInteressentenVorschlaege findest.
Rolf
Hallo Rolf,
Stop - so geht's nicht. Update folgt.
Rolf
Hallo Rolf,
Update ist erfolgt.
Rolf
Hallo Rolf,
Und Du hättest den Screenshot nicht im Inspektor, sondern im DOM machen sollen.
Ist nicht gelungen. Das Vorschlagsfeld wird ja erst mit JS eingehängt und ist damit per [Strg][U] nicht erreichbar:
// Vorschlagsfeld hinter <body> einhaengen
var erster = document.getElementsByTagName( "body" )[0].firstChild;
document.body.insertBefore( newDiv, erster );
console.log( "ajax/getMitgliederInteressenten.js: Feld id='mitgliederInteressentenVorschlaege' eingehaengt" );
Den Inhalt des Vorschlags-divs markieren, um dann mit Mausrechts View Selected Source zu machen, geht auch nicht, weil Mausrechts den div sofort auf display none setzt.
@@Rolf B
- Wenn Du die Suchtreffer immer rot hervorhebst, solltest Du keine class="red" setzen
Korrekt.
sondern korrekt <em></em> verwenden
Nein, em
ist nicht korrekt – das würde ja eine Betonung repräsentieren.
Zur Auszeichnung von Suchtreffern ist mark
angebracht.
😷 LLAP
Hi,
getMitgliederInteressentenPut(%20"1019",%20"",%20"Singing%20Sailors:1:43“
steht dieser Aufruf in einem mit ' begrenzten Attribut? Das sieht mit den %20 jedenfalls seltsam aus …
cu,
Andreas a/k/a MudGuard
Du hast in einer Variable foo einen String mit einem ' darin und baust den in ein neues Javascript ein.
Unmittelbar:
Du denkst:
<a href="javascript: foo">
Es ist aber:
<a href="javascript: un'geschickt">
Lösungsrichtung:
foo.replace("'", "\\'");
Es liegt also am Kontextwechsel.
Langfristig:
Wenn ich die „Bockstürze“ sehe, die Du durch das Senden als CSV machen musst, wird mir mit jeder Zeile JS unklarer, warum Du das Senden als JSON so sorgfältig vermeiden willst. Was Du an Zeit zu gewinnen glaubst zerrinnt dann bei der Verarbeitung.
Ohnehin ist das <a href="Javascript: ... ">
ersetzungsbedürftig.
Du weißt ja: Event hinzufügen, welches auf den Click lauschen soll.
Hallo,
Du denkst:
<a href="javascript: foo">
Es ist aber:
<a href="javascript: un'geschickt">
wenn es denn so wäre. Das wäre ja noch der unschädliche Fall. Zwei verschiedene Anführungszeichen, also kein Problem.
foo.replace("'", "\\'");
Es liegt also am Kontextwechsel.
Ja, alles deutet darauf hin.
Wenn ich die „Bockstürze“ sehe, die Du durch das Senden als CSV machen musst, wird mir mit jeder Zeile JS unklarer, warum Du das Senden als JSON so sorgfältig vermeiden willst. Was Du an Zeit zu gewinnen glaubst zerrinnt dann bei der Verarbeitung.
Das ist mir auch nicht wirklich klar.
Live long and pros healthy,
Martin