Eigenen Prompt entwickeln
Beat
- javascript
hallo
Ich habe viele Funktionen, die etwas erzeugen/konvertieren etc...
Im Stile:
Einige diese Funktionen sollen nun eine zusätzlich prompt Routine aufrufen,
damit Anpassungen von Attributen etc möglich sind.
Ich möchte aber nicht den Standard prompt() verwenden, sondern denke an etwas, das flexibler ist.
myprompt("choice_and_text", "Wählen Sie eines der Attribute oder definieren Sie ein eigenes", "keines", "gelb", "rot", "blau")
myprompt("choice", "Wählen Sie eines der Attribute", "keines", "gelb", "rot", "blau")
myprompt("text", "Schreiben Sie Ihre Attributanagab")
Nun frage ich mich, an was ich da denken muss.
mfg Beat
--
<o(((°> ><o(((°>
<°)))o>< ><o(((°>o
Der Valigator leibt diese Fische
Aber wie mache ich es, dass die prompt routine nicht zu seinem caller zurückkehrt
Das geht nicht, du kannst das nur Eventbasiert umsetzen. Wenn der prompt geöffnet wird, dann wird nichts weiter getan, erst wenn dieses beendet oder abgebrochen wird, geht's weiter.
Struppi.
Lieber Beat,
die "originale" propmpt-Methode hält die Ausführung von JavaScript komplett an. Während das Eingabefenster geöffnet ist, tut sich in JS-Land garnichts.
Du willst nun auch eine Benutzerabfrage tätigen. Dazu musst Du eine Funktion schreiben, die "zweigleisig" fährt. Entweder deshalb, weil Du sie aufrufst, um zu fragen, oder deshalb, weil Du sie zur Auswertung der Antwort aufrufst.
Du brauchst also eine Eigenschaft, die prüft, ob der Aufruf die Frage, oder die Antwort ist.
Ich habe soetwas schonmal in Verbindung mit meinen Inline Popups gemacht. Das Ergebnis findest Du in meiner Dateiverwaltung.
Hier der Code, den ich dafür benutze:
// erstellt ein Popup mit einer Ja/Nein-Frage
// @parameter "frage": String
// @parameter "werte": Array mit zwei Strings (das sind die Werte von und für die Funktion "DateiVerwaltung.abschicken", die nach diesem Popup bei "ja" erneut aufgerufen wird!)
confirm : function (frage, werte) {
if (typeof(InlinePopup) == "undefined")
return window.confirm(frage);
var votum = DateiVerwaltung.confirmation.confirm;
DateiVerwaltung.confirmation.confirm = false;
DateiVerwaltung.confirmation.values = werte;
if (!DateiVerwaltung.confirmation.win) {
frage = frage.replace(/\n/gi, "</p>\r\n<p>");
var fenster = InlinePopup.open("", "confirm", "resizeable=no,statusbar=no,width=400,height=350");
fenster.document.open();
fenster.document.writeln('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
fenster.document.writeln('<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">');
fenster.document.writeln('<head>');
fenster.document.writeln('<title>Bestätigen</title>');
fenster.document.writeln('<link rel="stylesheet" type="text/css" href="' + DateiVerwaltung.cmsRoot + 'css/dateiverwaltung.css" />');
fenster.document.writeln('<script type="text/javascript" src="' + DateiVerwaltung.cmsRoot + 'js/inlinepopup/inlinepopup_close.js"></script>');
fenster.document.writeln('<script type="text/javascript">');
fenster.document.writeln('function ergebnis(str) {');
fenster.document.writeln(' parent.DateiVerwaltung.confirmation.confirm = (str == "ja");');
fenster.document.writeln(' if (str == "ja") {');
fenster.document.writeln(' parent.DateiVerwaltung.xmlhttp.toDo = function () {');
fenster.document.writeln(' var win = self.parent.DateiVerwaltung.confirmation.win;');
fenster.document.writeln(' self.parent.DateiVerwaltung.confirmation.win = null;');
fenster.document.writeln(' win.close();');
fenster.document.writeln(' };');
fenster.document.writeln(' parent.DateiVerwaltung.abschicken(parent.DateiVerwaltung.confirmation.values);');
fenster.document.writeln(' } else {');
fenster.document.writeln(' self.parent.DateiVerwaltung.confirmation.win = null;');
fenster.document.writeln(' self.close();');
fenster.document.writeln(' }');
fenster.document.writeln('}');
fenster.document.writeln('</script>');
fenster.document.writeln('</head><body id="bestaetigungs-fenster">');
fenster.document.writeln('<h1>Sicherheits-Rückfrage</h1>');
fenster.document.writeln('<p><img src="' + DateiVerwaltung.cmsRoot + 'images/cms/warn-frage.gif" alt="" class="linksbuendig" /></p>');
fenster.document.writeln('<p>' + frage + '</p>');
fenster.document.write('<p class="neue-zeile"><button id="ja" type="button" onclick="ergebnis(\'ja\')"><img src="' + DateiVerwaltung.cmsRoot + 'images/cms/haken16x16.gif" alt="" /> Ja</button>');
fenster.document.writeln('<button id="nein" type="button" onclick="ergebnis(\'nein\')"><img src="' + DateiVerwaltung.cmsRoot + 'images/cms/x16x16.gif" alt="" /> Nein</button></p>');
fenster.document.writeln('</body></html>');
fenster.document.close();
DateiVerwaltung.confirmation.win = fenster;
}
return votum;
},
Liebe Grüße,
Felix Riesterer.
Seufz
Danke mal euch beiden.
Felix hat natürlich die Sache auf den springenden Punkt gebracht.
Es wird mir also nichts anderes übrig bleiben, als die Funktionen, welche einen Dialog haben sollen, nach dem Prinzip des Affenformulars zu ändern.
@Felix.
Dein Beispiel ist klar. ich werden das mal eher ohne extra Fenster , aber mit einem absolut platzierten Element im Doc versuchen.
Schliesslich habe ich eh schon alles für die GUI vorhanden.
Das Prinzip wäre demnach:
// User wendet einen Funktionslink an
function somefunc( need ){
// Wenn need=setdialog
Rufe Dialog(caller) mit Werten
return
// wenn need=getdialog
hole die aktuellen Werte im Dialog-Formular
Setze/überschreibe Optionswerten für die Textbehandlung
{---Dies ist mein bisheriger Funktionscode----)
Erledige deine übliche Aufgabe
(--------------------------------------------)
}
function dialog(Werteliste){
Erstelle Formular nach übergebenen Werten
Gib dem Formular den namen der aufzurufenden Function mit
= mein eigener Caller
}
Das Formular dann hat im OK Button den Auslöser-Event.
Hinweis:
Obiger Pseudocode habe ich mal so skizziert, dass der zusätzliche Block für den Dialog (den ich ja nicht für alle Funktionen brauche) geschlossen erscheint.
Das lässt es mir offen, immer noch mit einer einfachen Funktionsschnittstelle zu arbeiten für User-definierte Funktionen.
mfg Beat
<o(((°> ><o(((°>
<°)))o>< ><o(((°>o
Der Valigator leibt diese Fische
Felix hat natürlich die Sache auf den springenden Punkt gebracht.
Es wird mir also nichts anderes übrig bleiben, als die Funktionen, welche einen Dialog haben sollen, nach dem Prinzip des Affenformulars zu ändern.
wieso Affenformular? Du willst doch keine neue Seite aufbauen.
Das Formular dann hat im OK Button den Auslöser-Event.
Eben, Eventbasiert. Du musst eine Umgebung aufbauen, die events auslösen, erzeigen und fangen kann. Das ist exakt das was ich mit Eventbasiert meinte.
Struppi.
Aktuelle Problembeschreibung
Ich habe eine Funktion in einem Array gespeichert:
_ehf.ef[x][++y] = ['Test',
function(mode, opt ){
alert ("MODE"+mode);
if( mode != 1 ){
_ehf.dialog(_ehf.ef[x][y][1], 'Hi test', ['bla','bla']);
return;
else{
alert ("hi"+opt);
var class = ' class="' + opt + '"' ;
_ehf.f.insert('set',
'<p'+class+'>' + _ehf.f.insert('get') + '</p>');
}
) ];
Solche Funktionen arbeiten tadellos. Aber diese hat nun den Aufruf
zu einer Dialog_Funktion.
Der ELSE Zweig wird nicht ausgeführt.
Das Problem liegt hier:
ehf_dialog_collect = function(fx){
var opt = _ehf.dialog_options.getElementsByTagName('input');
var ret = '';
for ( var i=0; i < opt.length; i++){
if( opt[i].checked == true){ ret += opt[i].value + ' '; }
}
//alert(fx + ' \n'+ret); // Funktion wird bis hierher korrekt ausgeführt.
fx( 1, ret );
}
alert( fx ...) gibt mir die Funktion wie oben geschrieben plus den angesammelten Return Wert.
Aber
fx( 1, ret );
führt die Funktion nicht aus. das heisst, ich bekomme den oben geschilderten ELSE Zweig nicht.
Mit diversen alerts schon alles abgescheckt. Wo ist das Problem?
Hinweis: mit fx gebe gebe ich eigentlich jenes Array-Element weiter,
indem die Funktion gespeichert ist.
Die Funktion selbst gibt im IF Zweig sein eigenes Array-Element korrekt an.
Danke für Hilfe
mfg Beat
Ich habe den Fehler herausgefunden.
Die Werte x und y zeigten auf eine falsche Funktion.
Ich verwenden nun in der dialog Function die Methode .caller
Das einzige, was mich etwas beunruhigt:
.caller gehört nicht zum ECMA Standard laut MozDev
mfg Beat
Das einzige, was mich etwas beunruhigt:
.caller gehört nicht zum ECMA Standard laut MozDev
Deshalb würde ich sie auch nicht verwenden. Besser für deinen Zweck eignet sich arguments.callee.
Dei Ansatz ist aber nicht schön. Eine Funktion die eine Eventfunktion auf sich selbst übergibt.
Üblicher in JS ist sowas:
_ehf.ef[x][++y] = ['Test',
function(mode, opt ){
alert ("MODE"+mode);
if( mode != 1 ){
_ehf.dialog.onok = function() {
alert(arguments);
};
_ehf.dialog.onabort = function() {
alert(arguments);
};
_ehf.dialog('Hi test', ['bla','bla']);
return;
else{
alert ("hi"+opt);
var class = ' class="' + opt + '"' ;
_ehf.f.insert('set',
'<p'+class+'>' + _ehf.f.insert('get') + '</p>');
}
) ];
Struppi.
Das einzige, was mich etwas beunruhigt:
.caller gehört nicht zum ECMA Standard laut MozDevDeshalb würde ich sie auch nicht verwenden. Besser für deinen Zweck eignet sich arguments.callee.
Ich habe das jetzt so geändert:
_ehf.dialog = function( mode, text,opt){
var fx = _ehf.dialog.arguments.callee.caller;
//...
}
Dein Ansatz ist aber nicht schön. Eine Funktion die eine Eventfunktion auf sich selbst übergibt.
Was ist die Alternative?
Dass ich jede Funktion spalten muss.
Das gibt mir dann nicht mehr wartbaren Code.
Üblicher in JS ist sowas:
[code lang=javascript] _ehf.ef[x][++y] = ['Test',
function(mode, opt ){
alert ("MODE"+mode);
if( mode != 1 ){
_ehf.dialog.onok = function() {
alert(arguments);
};
Ich arbeite nicht mit dem Standard prompt. Da ist kein onok
Da ist onclick die übergabe der Variable "1"
mfg Beat
Ich habe das jetzt so geändert:
_ehf.dialog = function( mode, text,opt){
var fx = _ehf.dialog.arguments.callee.caller;
//...
}
in callee steckt die Funktion, nicht in caller.
» Dein Ansatz ist aber nicht schön. Eine Funktion die eine Eventfunktion auf sich selbst übergibt.
Was ist die Alternative?
Dass ich jede Funktion spalten muss.
Das gibt mir dann nicht mehr wartbaren Code.
Wieso? So wie du es jetzt machst halte ich es für nicht wartbar.
» Üblicher in JS ist sowas:
» [code lang=javascript] _ehf.ef[x][++y] = ['Test',
» function(mode, opt ){
» alert ("MODE"+mode);
» if( mode != 1 ){
» _ehf.dialog.onok = function() {
» alert(arguments);
» };Ich arbeite nicht mit dem Standard prompt. Da ist kein onok
Da ist onclick die übergabe der Variable "1"
Ich weiß und der Standardprompt bietet ja auch keine Events an, da dieser Modal arbeitet. Diese events musst du in deinem prompt einbauen. D.h. wenn in deinem prompt auf ok gedrückt wird ruft dieser die Funktion onok() auf. Bei cancel oder abbrechen, eben den Event, den du für's abbrechen definieren möchtest. Wie gesagt, das ist so wie du es von anderen Events in JS kennst, onclick, onload, onscroll, .... usw.
Struppi.
Üblicher in JS ist sowas:
_ehf.ef[x][++y] = ['Test',
function(mode, opt ){
alert ("MODE"+mode);
if( mode != 1 ){
_ehf.dialog.onok = function() {
alert(arguments);
};
_ehf.dialog.onabort = function() {
alert(arguments);
};
_ehf.dialog('Hi test', ['bla','bla']);
return;
else{
alert ("hi"+opt);
var class = ' class="' + opt + '"' ;
_ehf.f.insert('set',
'<p'+class+'>' + _ehf.f.insert('get') + '</p>');
}
) ];
Wobei ich hier übersehen habe, dass du hier ja auch noch eine Flag eingebaut hast. Dieser ist unnötig, wenn du mit Events arbeitest.
Der code müßte in etwa so aussehen
~~~javascript
_ehf.ef[x][++y] = ['Test',
function(opt ){
_ehf.dialog.onok = function() {
var opt = arguments[0];
var class = ' class="' + opt + '"' ;
_ehf.f.insert('set',
'<p'+class+'>' + _ehf.f.insert('get') + '</p>');
};
_ehf.dialog.onabort = function() {
alert(arguments);
};
_ehf.dialog('Hi test', ['bla','bla']);
return;
}
) ];
Struppi.