Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 4 of 4
  1. #1
    Regular Coder
    Join Date
    Aug 2010
    Location
    Southern Oregon
    Posts
    305
    Thanks
    63
    Thanked 1 Time in 1 Post

    Having to click twice to dismiss a dialog panel?

    This is related to my last post regarding calculating element position when width and height styles are set to auto.
    It is a different issue having to do with the same code + a bit.

    The issue:
    I have code used to generate a dialog panel that is positioned absolutely on top of other content.
    In one mode there is a masking layer applied to the whole document, then the dialog panel is
    placed on top of that.
    In another mode, there is no masking layer. The dialog panel is placed on top of the document
    elements.
    I each case I have a close button applied with a click event handler that removes the dialog, and if
    applicable, the mask.

    Essentially the same code is used for each mode.

    In the panel without the mask I have to click the close button twice to get it to close.
    And in the case of having a mask behind the dialog panel I only have to click once.

    I can't figure out why;

    Code:
    // inside constructor function
            var applyMask = function()
                  {
                   var mask = document.createElement('div')
                       mask.id = 'mask';
                       maskId = mask.id;
                       mask.style.position = "absolute";
                       mask.style.left = '0';
                       mask.style.top = '0';
                       mask.style.width = screen.width+"px";
                      
                       mask.style.height = "200%";
                       mask.style.background = 'rgba(0,0,0, 0.5)';
                   document.body.appendChild(mask)
                  }
    
              var removeMask = function(e)
                  {
                   if(maskId != '') // if mask is present this will have the id
                     {
                      var rmMask = document.getElementById(maskId)
                      if(rmMask)
                        {
                         rmMask.parentNode.removeChild(rmMask)
                         maskId = '';
                        }
                     }
                  }
    
            var unSet = function()
                  {
                   /*
                    either removes dialog elements altogether or sets the visibility to hidden.
                   */
                   var dialog = document.getElementById('dialog')
                   if(dialog)
                     {
                      for(var i = dialog.childNodes.length -1; i >=0; i--)
                        {
                         dialog.removeChild(dialog.childNodes[i]);
                        }
                      dialog.parentNode.removeChild(dialog)
                     }
                  }
    
    var panelId = 'dialog'
              var setDialog = function(message)
                  {
                   /*
                    bring all the elements together and produce
                    a hidden field should be used to indicate that the dialog panel
                    is showing with value set to true/false. In that way this function
                    can determine if a dialog is already showing:
                    So it can:
                    1: set the initial position to avoid covering the existing dialogs
                    2: remove existing dialogs
                    3: warn user to respond to or dismiss existing dialogs
                   */
                   var panel = document.createElement('div')
                       panel.style.border = styleDefaults.border;
                       panel.style.margin = styleDefaults.margin;;
                       panel.style.padding = styleDefaults.padding;
                       if(styleDefaults.background != 'img')
                         {
                          panel.style.background = styleDefaults.background;
                         }
                       panel.style.position = styleDefaults.position;
                       panel.id = 'dialog';
                   var titleElem = document.createElement('pre')
                       titleElem.className = "title";
                   switch(type)
                     {
                      case 'error': //{'title':{"size":"2em", "color":"#990000"},
                      titleElem.style.color = styleDefaults.title.color;
                      break;
                      case 'warning':
                      titleElem.style.color = styleDefaults.title.color;
                      titleElem.style.fontSize = styleDefaults.title.size;
                      titleElem.style.letterSpacing = styleDefaults.title.spacing;
                      break;
                     }
                   var title = document.createTextNode(typeDefaults.title);
                       titleElem.appendChild(title)
                   var messageElem = document.createElement('pre')
                       messageElem.className = 'norm';
                   var message = document.createTextNode(message)
                       messageElem.appendChild(message)
                   var controlElem = document.createElement('pre')
                       controlElem.className = 'norm';
                   var button = document.createElement("input");
                       button.type ="button";
                       button.id = "lifter";
                       button.value = "Close";
                   controlElem.appendChild(button)
                   panel.appendChild(titleElem)
                   panel.appendChild(document.createElement('hr'))
                   panel.appendChild(messageElem)
                   panel.appendChild(controlElem)
                   if(typeDefaults.mask === true)
                     {
                      applyMask();
                      var msk = document.getElementById(maskId)
                          button.addEventListener('click', removeMask, false) // mask situation calls removeMask
                          panel.style.left = ((parseInt(window.innerWidth)/3 - parseInt(panel.offsetWidth)) + window.pageXOffset)+'px';
                          panel.style.top = ((parseInt(window.innerHeight)/3 - parseInt(panel.offsetHeight)) + window.pageYOffset)+'px';
                          msk.appendChild(panel)
                     }
                   else
                     {
                      button.addEventListener('click', unSet, false) // No mask situation, calls unSet: <<< Here I have to click twice
                      panel.style.left = ((parseInt(window.innerWidth)/3 - parseInt(panel.offsetWidth)) + window.pageXOffset)+'px';
                      panel.style.top = ((parseInt(window.innerHeight)/3 - parseInt(panel.offsetHeight)) + window.pageYOffset)+'px';
                      document.body.appendChild(panel)
                     }
                  }

  2. #2
    New Coder
    Join Date
    Jun 2016
    Posts
    13
    Thanks
    0
    Thanked 1 Time in 1 Post
    I had the same problem, so I thought I'd offer my solution.
    I was building jquery comboboxes on the fly using PHP.
    Some of the comboboxes would be placed on a form that would be a pop up dialog.
    When the dialog popped up, the script which created the combobox (which was placed right in line with the form) would execute a second time. There would be a 2nd combobox placed in the same location as the first and would prevent proper operation of the form control.

    I modified the jquery combobox code to add the name of each comboox it creates to a global array. That way it can check the array before creating a combobox to prevent creating the same one twice.

    Here's the code snippet:

    var combo_created = new Array();
    var combo_box_count = 0;
    jQuery.fn.combobox = function(select){
    if ($.inArray(this.attr('name'), combo_created) != -1) return;

    combo_created[combo_box_count++] = this.attr('name');

    This logic can easily be extended to any script you don't want to run twice on a page.
    Simply set a variable


    var fooHasRun=false;

    Then in your function do this:


    function foo(){
    if (fooHasRun) return;
    fooHasRun = true;
    // put foo code here
    }
    Last edited by vinyl-junkie; Jul 13th, 2016 at 08:10 AM. Reason: self-promotional link removed

  3. #3
    Senior Coder
    Join Date
    Aug 2010
    Posts
    1,296
    Thanks
    46
    Thanked 286 Times in 284 Posts
    I wanted to reply to
    your previous post
    but I can't seem
    to find it ?

    Code:
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Davey's Place</title>
    <style type="text/css">
    </style>
    
    
    </head>
    <body>
    
    
    <button onclick="modalAlert('theTitle','theMessage',true)"> Modal Message   </button>
    <button onclick="modalAlert('theTitle','theMessage')"> nonModalAlert Message   </button>
    <script>
    modalAlert = (function (){
            var mask = document.createElement('div');
         mask.style.position = 'absolute';
         mask.style.top = '0';
         mask.style.left = '0';
         mask.style.width = '100%';
         mask.style.height = '100%';
         mask.style.backgroundColor = 'silver';
         mask.style.opacity = "0.5";
            var panel = document.createElement('div');
                       panel.style.border = "1px solid #000033";
                       panel.style.top = '50%';
         panel.style.left = '50%';
         panel.style.transform = 'translate(-50%, -50%)';
                       panel.style.width = "200px";
                       panel.style.height = 'auto'; 
                       panel.style.padding = '10px';
                       panel.style.background = '#ccccff';
                       panel.style.position = 'fixed';
                       //
                   var titleElem = document.createElement('pre');                   
                   var messageElem = document.createElement('pre');             
                   var controlElem = document.createElement('pre');                   
                   var button = document.createElement("input");
                       button.type ="button";
                       button.value = "Close";
                       button.addEventListener('click', function(e){
           document.body.removeChild(mask);
            document.body.removeChild(panel);
            document.body.style.overflow="";  
            mask.style.display="block"; 
          }, false) ;
                   controlElem.appendChild(button);
                   panel.appendChild(titleElem);
                   panel.appendChild(document.createElement('hr'));
                   panel.appendChild(messageElem);
                   panel.appendChild(controlElem);
            return function(title,message,modal){
       titleElem.innerHTML = title;
       messageElem.innerHTML = message;
       document.body.appendChild(mask);
       document.body.appendChild(panel);   
       if(modal){
        document.body.style.overflow = 'hidden';     
       } else {
        mask.style.display="none";
       }
       
            }               
    })();
    </script>
    </body>
    </html>
    Last edited by DaveyErwin; Jul 11th, 2016 at 06:56 PM.

  4. Users who have thanked DaveyErwin for this post:

    anotherJEK (Jul 12th, 2016)

  5. #4
    Regular Coder
    Join Date
    Aug 2010
    Location
    Southern Oregon
    Posts
    305
    Thanks
    63
    Thanked 1 Time in 1 Post
    Edit update: Actually, the need to click the panel without mask behind it twice only occurs the first time the panel is
    displayed. Once the second (not double) click closes (removes) the panel, if I re display the panel, one click will close it
    again.

    Re response from DaveyErwin: That issues is solved and I have moved on to this. Yes I couldn't find the last post either. After I replied to the first response
    I tried to contact codingforums.com and got their database error info page. After that I couldn't find the post.
    The one response I got and responded to has included a link to a similar query posted on StackOverflow. Perhaps
    forum competition?
    edit update: DaveyErwin: Thanks, I took a line from your example code:
    Code:
    document.body.removeChild(panel);
    Only, since I have the click event handler in a separate function def, I pass it as an argument to the
    event handler function:
    Code:
    // etc....
         button.addEventListener('click', function(e){ unSet(e, panel)}, false)
    // etc .....
            var unSet = function(e, b)
                  {
                   document.body.removeChild(b)
                  }
    And it has solved the problem. THANKS.

    Re response from davidstephan:
    I see what you mean, but displaying or even generating more than one dialog panel in test/dev page is impossible. As a matter of fact, the user will have
    to create separate object instances for each type of dialog. So in order to take down one type test and put up another type test I have to reload the page.
    For each type instance, once it is configured the only change that can be made dynamically are the message text to be displayed. So it works somewhat like and alert or confirm dialog. But the other types are error, warning, and special for completely customizable dialogs that could hold adds or other resources.
    I have been ignoring jQuery since from the beginning I have been learning to code from scratch. I also have been doing a lot of server side php development to compliment the client side development. Lately, as well I have been getting my feet wet with node.js.

    It would be nice to have a forum category here for node.js (I have had trouble with stackoverflow, so avoid it. It doesn't like me either for some
    undetermined reason)

    Here is a line to put in javascript source files that will allow use in both client and node.js
    Code:
    if(typeof(module) != 'undefined')
      {
       module.exports // what ever you want to make available to node.js that DOESN'T contain client specific function calls such as DOM methods
      }
    Last edited by anotherJEK; Jul 12th, 2016 at 04:55 AM.


 

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •