How to do double-click prevention in JSF

前端 未结 7 1093
生来不讨喜
生来不讨喜 2020-11-29 02:56

We have a few search pages that run against a lot of data and take a while to complete. When a user clicks on the search button, we\'d like to not allow them to submit the s

相关标签:
7条回答
  • 2020-11-29 03:17

    i came upon this question, having the same problem. The solution did not work for me - after a brief look at primefaces.js i guess they do not use jsf.ajax there anymore.

    so i had to work something out myself and here is my solution, for people who also can not use the one in the answer by BalusC:

    // we override the default send function of
    // primeFaces here, so we can disable a button after a click
    // and enable it again after     
    
    var primeFacesOriginalSendFunction = PrimeFaces.ajax.AjaxUtils.send;
    
    PrimeFaces.ajax.AjaxUtils.send = function(cfg){    
      var callSource = '';
    
      // if not string, the caller is a process - in this case we do not interfere
    
      if(typeof(cfg.source) == 'string') {
    
        callSource = jQuery('#' + cfg.source);
        callSource.attr('disabled', 'disabled');
    
      }
    
    
    
      // in each case call original send
      primeFacesOriginalSendFunction(cfg);
    
      // if we disabled the button - enable it again
      if(callSource != '') {
    
        callSource.attr('disabled', 'enabled');
    
      }
    
    };
    
    0 讨论(0)
  • 2020-11-29 03:26

    For me works this way:

    <h:commandLink ... onclick="jQuery(this).addClass('ui-state-disabled')">
    
    0 讨论(0)
  • 2020-11-29 03:26

    very useful solution jsf-primefaces, used with facelets template spreads to other pages consumers

    <f:view>
        <Script language="javascript">
            function checkKeyCode(evt)
            {
                var evt = (evt) ? evt : ((event) ? event : null);
                var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
                if(event.keyCode==116)
                {
                    evt.keyCode=0;
                    return false
                }
            }
            document.onkeydown=checkKeyCode;
    
            function handleDisableButton(data) {
                if (data.source.type != "submit") {
                    return;
                }
    
                switch (data.status) {
                    case "begin":
                        data.source.disabled = true;
                        break;
                    case "complete":
                        data.source.disabled = false;
                        break;
                }    
            }
            jsf.ajax.addOnEvent(handleDisableButton);
        </Script>
    
    </f:view>
    
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link href="./resources/css/default.css" rel="stylesheet" type="text/css" />
        <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" />
        <title>infoColegios - Bienvenido al Sistema de Administracion</title>
    </h:head>
    
    <h:body onload="#{login.validaDatos(e)}">
        <p:layout fullPage="true">
    
            <p:layoutUnit position="north" size="120" resizable="false" closable="false" collapsible="false">                   
                <p:graphicImage value="./resources/images/descarga.jpg" title="imagen"/> 
                <h:outputText value="InfoColegios - Bienvenido al Sistema de Administracion" style="font-size: large; color: #045491; font-weight: bold"></h:outputText>                    
            </p:layoutUnit>
    
            <p:layoutUnit position="west" size="175" header="Nuestra Institución" collapsible="true" effect="drop" effectSpeed="">
                <p:menu> 
                    <p:submenu>
                        <p:menuitem value="Quienes Somos" url="http://www.primefaces.org/showcase-labs/ui/home.jsf" />
    
                    </p:submenu>
                </p:menu>
            </p:layoutUnit>
    
            <p:layoutUnit position="center">
                <ui:insert name="content">Content</ui:insert>
            </p:layoutUnit>
    
        </p:layout>
    </h:body>
    

    0 讨论(0)
  • 2020-11-29 03:31

    None of alternatives above has worked for me (I've really tried each one of them). My form was always sent twice when user double-clicked the login button. I'm working with JSF (Mojarra 2.1.6) on Glassfish 3.1.2.

    Consider that it was a non-AJAX login page.

    So here's the way I solved it:

    1. define a global JavaScript var to control submition in the page header or anywhere outside your form:
    var submitting = false;
    
    1. set it to true when submit h:form onsubmit event is fired:
    <h:form onsubmit="submitting = true">
    
    1. Check the var's value on h:commandLink's click event:
    <h:commandLink ... onclick="if(submitting){return false}">
    

    This is just another simple alternative and it was tested in Chrome [Version 47.0.2526.106 (64-bit)], Mozilla Firefox (37.0.2) and Internet Explorer 11. I hope it helps someone.

    0 讨论(0)
  • 2020-11-29 03:32

    If you're using solely ajax requests, you could use jsf.ajax.addOnEvent handler of the JSF JavaScript API for this. The below example will apply on all buttons of type="submit".

    function handleDisableButton(data) {
        if (data.source.type != "submit") {
            return;
        }
    
        switch (data.status) {
            case "begin":
                data.source.disabled = true;
                break;
            case "complete":
                data.source.disabled = false;
                break;
        }    
    }
    
    jsf.ajax.addOnEvent(handleDisableButton);
    

    Alternatively, if you need this on specific buttons only, use the onevent attribute of <f:ajax>.

    <h:commandButton ...>
        <f:ajax ... onevent="handleDisableButton" />
    </h:commandButton>
    

    If you also need to apply this on synchronous requests, then you need to take into account that when you disable a button during onclick, then the button's name=value pair won't be sent as request parameter and hence JSF won't be able to identify the action and invoke it. You should thus only disable it after the POST request has been sent by the browser. There is no DOM event handler for this, you'd need to use the setTimeout() hack which disables the button ~50ms after click.

    <h:commandButton ... onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);" />
    

    This is only rather brittle. It might be too short on slow clients. You'd need to increase the timeout or head to another solution.

    That said, keep in mind that this only prevents double submits when submitting by a web page. This does not prevent double submits by programmatic HTTP clients like URLConnection, Apache HttpClient, Jsoup, etc. If you want to enforce uniqueness in the data model, then you should not be preventing double submits, but preventing double inserts. This can in SQL easily be achieved by putting an UNIQUE constraint on the column(s) of interest.

    See also:

    • Pure Java/JSF implementation for double submit prevention
    • How to handle multiple submits before response is rendered?
    0 讨论(0)
  • 2020-11-29 03:39

    You can use 'onclick' and 'oncomplete' listeners. When user click on button - disable it. When action completed - enable.

    <p:commandButton id="saveBtn" onclick="$('#saveBtn').attr('disabled',true);" oncomplete="$('#saveBtn').attr('disabled',false);" actionListener="#{myBean.save}" />
    
    0 讨论(0)
提交回复
热议问题