开发者

Confirm replacement in JavaScript

开发者 https://www.devze.com 2023-02-05 08:12 出处:网络
Yes, I\'ve searched high and low on Stack Overflow and seen some great solutions to this problem that\'s been solved time and time again with things like SimpleModal, jQuery.confirm and the like.

Yes, I've searched high and low on Stack Overflow and seen some great solutions to this problem that's been solved time and time again with things like SimpleModal, jQuery.confirm and the like.

Problem is, I am developing for this low level device that doesn't allow for a JS framework to be utilized AND I am having to shoehorn this modal confirm into existing JS.

There is an existing script that I am at liberty to edit (but not rewrite) that does a few things like validate, concatenate a few inputs into a single variable, and more.

The script was written to:

  1. Take some session variables and assign new variable names to them and format accordingly
  2. Present a confirm to the user to see whether they want to use those variables to pre-populate the form on the page
  3. Get some functions ready to validate inputs.
  4. other stuff, like offer an abandonment scenario, among other things

Now, all was good when the "confirm" was in plac开发者_StackOverflowe as the script would pause until an OK or Cancel was provided. I am now presenting a modal on the page that I want to mock this behavior and the only way I can think of doing it is to remove that reliance on the line that goes through the confirm thing and NOT run the script until the user interacts with the modal.

Does anyone have an idea how to take what's in place and "wrap" it in a "listening" if/else scenario for each of the YES or NO possibilities?

Sorry if this is jumbled... my brain is all blended up at the moment, too.


As far as I know there is - so far - no way to halt scripts like the Browser specific alert() or confirm() Dialog does.

Frameworks like dojo for example try to mock this behaviour by putting a transparent DIV over the whole window to prevent clicks or other input while the Dialog is showing.

This is quite tricky as I have experienced, since Keyboard-Input may be able to activate Input Fields or Buttons behind this curtain. Keyboard Shortcuts or Field-Tabbing for example. One sollution is to disable active Elements manually, which works quite well with me in most cases.

One or more function is passed to this "mock" Dialog to execute when an option was chosen. Escpecially with ajax background activity the responsibilty to stop conflicting function calls while the Dialog is open lies with the developer.

Here is an example I came up with:

 <html>
<head>
<title>Modal Dialog example</title>
<script type="text/javascript">
<!--

var ModalDialog = function(text,choices){
    this._text = text;
    this._choices = choices;
    this._panel = null;
    this._modalDialog = null;

    this._disableElements = function(tag){
        var elements = document.getElementsByTagName(tag);
        for(i=0; i < elements.length; i++){
            elements[i].disabled = true;
        }
    };

    this._enableElements = function(tag){
        var elements = document.getElementsByTagName(tag);
        for(i=0; i < elements.length; i++){
            elements[i].disabled = false;
        }
    };

    this._disableBackground = function(){
        if(this._panel){
            this._panel.style.display = 'block';
        }
        else{
            // lower the curtain
            this._panel = document.createElement('div');
            this._panel.style.position = 'fixed';
            this._panel.style.top = 0;
            this._panel.style.left = 0;
            this._panel.style.backgroundColor = 'gray';
            this._panel.style.opacity = '0.2';
            this._panel.style.zIndex = 99; // make sure the curtain is in front existing Elements
            this._panel.style.width = '100%';
            this._panel.style.height = '100%';
            document.body.appendChild(this._panel);

            // Disable active Elements behind the curtain
            this._disableElements('INPUT');
            this._disableElements('BUTTON');
            this._disableElements('SELECT');
            this._disableElements('TEXTAREA');
        }
    };

    this.close = function(){
        // Hide Curtain
        this._panel.style.display = 'none';
        // Hide Dialog for later reuse - could also be removed completely
        this._modalDialog.style.display = 'none';
        // reactivate disabled Elements
        this._enableElements('INPUT');
        this._enableElements('BUTTON');
        this._enableElements('SELECT');
        this._enableElements('TEXTAREA');
    };

    this.open = function(){
        var _this = this;
        this._disableBackground();
        if(this._modalDialog){
            this._modalDialog.style.display = 'block';
        }
        else{
            // create the Dialog
            this._modalDialog = document.createElement('div');
            this._modalDialog.style.position = 'absolute';
            this._modalDialog.style.backgroundColor = 'white';
            this._modalDialog.style.border = '1px solid black';
            this._modalDialog.style.padding = '10px';
            this._modalDialog.style.top = '40%';
            this._modalDialog.style.left = '30%';
            this._modalDialog.style.zIndex = 100; // make sure the Dialog is in front of the curtain

            var dialogText = document.createElement('div');
            dialogText.appendChild(document.createTextNode(this._text));

            // add Choice Buttons to the Dialog
            var dialogChoices = document.createElement('div');      
            for(i = 0; i < this._choices.length; i++){
                var choiceButton = document.createElement('button');
                choiceButton.innerHTML = this._choices[i].label;
                var choiceAction = _this._choices[i].action
                var clickAction = function(){
                    _this.close();
                    if(choiceAction)choiceAction();
                };
                choiceButton.onclick = clickAction;
                dialogChoices.appendChild(choiceButton);
            } 

            this._modalDialog.appendChild(dialogText);
            this._modalDialog.appendChild(dialogChoices);

            document.body.appendChild(this._modalDialog);
        }
    };
};

var myConfirm = function(text,okAction){
    var dialog = new ModalDialog(text,[
        {
            label:'ok',
            action : function(){ 
                console.log('ok')
                okAction();
            }
        },
        {   
            label:'cancel'
        }
    ]);
    dialog.open();  
};
-->
</script>

</head>
<body>
    <form name="identity" action="saveIdentity.do">
        <label>Firstname</label><input name="name" type="text"><br>
        <label>Lastname</label><input name="name" type="text"><br>
        <input type="button" 
            value="submit" 
            onclick="if(myConfirm('Do you really want to Commit?',function(){ document.forms['identity'].submit();}));">
    </form>
</body>
 </html>

In this code there is still an error concerning the availability of the stored choice-function (undefined) at execution time. The function variable is no longer available in the closure. If anyone has a sollution for this you are welcome to add to it.

Hope that comes near to what you need to know.


Updated version: fixed choiceAction undefined, added IE compatibility. Internet Explorer is one main reason to use this, since confirm() is now blocked by default.

<!doctype html>
<html><head>
<title>Modal Dialog example</title>

<script type="text/javascript"><!-- //http://stackoverflow.com/questions/4739740/yet-another-confirm-replacement-quesiton

var ModalDialog = function(text,choices) {
    this._text = text;
    this._choices = choices;
    this._panel = null;
    this._modalDialog = null;

    this._disableElements = function(tag) {
        var elements = document.getElementsByTagName(tag);
        for(i=0; i < elements.length; i++) {
            elements[i].disabled = true;
        }
    };

    this._enableElements = function(tag) {
        var elements = document.getElementsByTagName(tag);
        for(i=0; i < elements.length; i++) {
            elements[i].disabled = false;
        }
    };

    this._disableBackground = function() {
        if(this._panel) {
            this._panel.style.display = 'block';
        }
        else {
            // lower the curtain
            this._panel = document.createElement('div');
            this._panel.style.position = 'fixed';
            this._panel.style.top = 0;
            this._panel.style.left = 0;
            this._panel.style.backgroundColor = '#000';
            this._panel.style.opacity = '0.3';
            this._panel.style.filter = 'alpha(opacity=30)'; //ie7+
            this._panel.style.zIndex = 99; // make sure the curtain is in front existing Elements
            this._panel.style.width = '100%';
            this._panel.style.height = '100%';
            document.body.appendChild(this._panel);

            // Disable active Elements behind the curtain
            this._disableElements('INPUT');
            this._disableElements('BUTTON');
            this._disableElements('SELECT');
            this._disableElements('TEXTAREA');
        }
    };

    this.close = function() {
        // Hide Curtain
        this._panel.style.display = 'none';
        // Hide Dialog for later reuse - could also be removed completely
        this._modalDialog.style.display = 'none';
        // reactivate disabled Elements
        this._enableElements('INPUT');
        this._enableElements('BUTTON');
        this._enableElements('SELECT');
        this._enableElements('TEXTAREA');
    };

    this.open = function() {
        var _this = this;
        this._disableBackground();
        if(this._modalDialog) {
            this._modalDialog.style.display = 'block';
        }
        else {
            // create the Dialog
            this._modalDialog = document.createElement('div');
            this._modalDialog.style.position = 'absolute';
            this._modalDialog.style.backgroundColor = 'white';
            this._modalDialog.style.border = '1px solid black';
            this._modalDialog.style.padding = '16px';
            this._modalDialog.style.top = '35%';
            this._modalDialog.style.left = '30%';
            this._modalDialog.style.zIndex = 100; // make sure the Dialog is in front of the curtain

            var dialogText = document.createElement('div');
            dialogText.style.padding = '0 10px 10px 0';
            dialogText.style.fontFamily = 'Arial,sans-serif';
            dialogText.appendChild(document.createTextNode(this._text));

            // add Choice Buttons to the Dialog
            var dialogChoices = document.createElement('div');
            for(i = 0; i < this._choices.length; i++) {
                var choiceButton = document.createElement('button');
                choiceButton.style.marginRight = '8px';
                choiceButton.name = i;
                choiceButton.innerHTML = this._choices[i].label;
                var clickAction = function() {
                    _this.close();
                    if(_this._choices[this.name].action) _this._choices[this.name].action();
                };
                choiceButton.onclick = clickAction;
                dialogChoices.appendChild(choiceButton);
            }

            this._modalDialog.appendChild(dialogText);
            this._modalDialog.appendChild(dialogChoices);

            document.body.appendChild(this._modalDialog);
        }
    };
};

var myConfirm = function(text,okAction){
    var dialog = new ModalDialog(text,[
        {
            label  : 'OK',
            action : function() {
                console.log('ok');
                okAction();
            }
        },
        {
            label : 'Cancel'
        }
    ]);
    dialog.open();
};
-->
</script>

</head>
<body>
    <form name="identity" action="saveIdentity.do">
        <label>Firstname</label><input name="name" type="text"><br>
        <label>Lastname</label><input name="name" type="text"><br>
        <input type="button" value="submit"
            onclick="if(myConfirm('Do you really want to Commit?',function(){ alert('submitted') }));">
        <!-- document.forms['identity'].submit(); -->
    </form>
</body>
</html>
0

精彩评论

暂无评论...
验证码 换一张
取 消