Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: How to temporarily disable all actions on the page?

On a page with Ajax event, I want to disable all actions until the Ajax call returns (to prevent issues with double-submit etc.)

I tried this by prepending return false; to the current onclick events when "locking" the page, and removing this later on when "unlocking" the page. However, the actions are not active any more after they are "unlocked" -- you just can't trigger them.

Why is this not working? See example page below. Any other idea to achieve my goal?

Example code:
both the link and the button are showing a JS alert; when pressing lock, then unlock the event handler is the same as it was before, but doesn't work...?!?
The code is meant to work with Trinidad in the end, but should work outside as well.

<html><head><title>Test</title>

<script type="text/javascript">
function lockPage()
{
  document.body.style.cursor = 'wait';
  lockElements(document.getElementsByTagName("a"));
  lockElements(document.getElementsByTagName("input"));

  if (typeof TrPage != "undefined")
  {
    TrPage.getInstance().getRequestQueue().addStateChangeListener(unlockPage);
  }
}

function lockElements(el)
{
  for (var i=0; i<el.length; i++)
  {
    el[i].style.cursor = 'wait';
    if (el[i].onclick)
    {
      var newEvent = 'return false;' + el[i].onclick;
      alert(el[i].onclick + "\n\nlock -->\n\n" + newEvent);
      el[i].onclick = newEvent;
    }
  }
}

function unlockPage(state)
{
  if (typeof TrRequestQueue == "undefined" || state == TrRequestQueue.STATE_READY)
  {
    //alert("unlocking for state: " + state);
    document.body.style.cursor = 'auto';
    unlockElements(document.getElementsByTagName("a"));
    unlockElements(document.getElementsByTagName("input"));
  }
}

function unlockElements(el)
{
  for (var i=0; i<el.length; i++)
  {
    el[i].style.cursor = 'auto';
    if (el[i].onclick && el[i].onclick.search(/^return false;/)==0)
    {
      var newEvent = el[i].onclick.substring(13);
      alert(el[i].onclick + "\n\nunlock -->\n\n" + newEvent);
      el[i].onclick = newEvent;
    }
  }
}
</script>

<style type="text/css">
</style>
</head>

<body>

<h1>Page lock/unlock test</h1>

<p>Use these actions to lock or unlock active elements on the page:
<a href="javascript:lockPage()">lock</a>,
<a href="javascript:unlockPage()">unlock</a>.</p>

<p>And now some elements:</p>

<a onclick="alert('This is the action!');return false;" href="#">link action</a> &nbsp;
<input type="button" value="button action" onclick="alert('This is another action!')"/>
</body>
</html>

Thanks guys for your ideas and answers.

Now I see that I have mixed up Strings and functions, which obviously can't work ;(

I should have made clear that we use some Web FW and tag libraries (Trinidad) which create the event handling (and Ajax) code, hence I can't edit that directly or use synchronous Ajax etc.

Moreover, Ajax is only one scenario where this code should be executed. It's purpose is to prevent the user to double-submit a page/action, which is also relevant for non-Ajax pages where you could kind of doulbe-click on a button. I know that this is not really safe, and it's only meant to be a "convenience" thingy to avoid getting the navigation error page too often (we have server-side protection, of course).

So, will try the div overlay, probably.

Thanks again,
Christoph.

like image 243
ami Avatar asked Apr 20 '09 08:04

ami


People also ask

How do you disable a page in HTML?

To disable a HTML anchor element with CSS, we can apply the pointer-events: none style. pointer-events: none will disable all click events on the anchor element. This is a great option when you only have access to class or style attributes. It can even be used to disable all the HTML links on a page.

Can we disable div tag?

If you have a div, and you want to support click or a key event on that div, then you have to do two things: 1) When you want to disable the div, set its disabled attribute as usual (just to comply with the convention) 2) In your div's click and/or key handlers, check if disabled attribute is set on the div.


1 Answers

Put lockPage() at top of activete() function, and unlockPage() at bottom of deactivate().

activate: function() {

    function lockPage()
    {
      lockElements(document.getElementsByTagName("a"));
      lockElements(document.getElementsByTagName("input"));
      lockElements(document.getElementsByTagName("button"));
    };

    function lockElements(el)
    {
      for (var i=0; i<el.length; i++)
      {
        el[i].style.pointerEvents="none";
      }
    };
            
    lockPage();
    
    // ...
},
deactivate: function() {

    // ...

    function unlockPage() {
        unlockElements(document.getElementsByTagName("a"));
        unlockElements(document.getElementsByTagName("input"));
        unlockElements(document.getElementsByTagName("button"));
    };

    function unlockElements(el)
    {
      for (var i=0; i<el.length; i++)
      {
        el[i].style.pointerEvents="auto";
      }
    };

    unlockPage();
    
},
like image 143
Evgene Avatar answered Oct 20 '22 05:10

Evgene