In rails controllers, how to prevent double submit (when user double-clic submit button or hit enter twice)?

后端 未结 8 2195
天命终不由人
天命终不由人 2021-02-19 09:50

Well, everything\'s in the title but I\'ll explain a little more :-)

My rails app contain many forms (Ajaxified or not).

To prevent users to submit twice or more

相关标签:
8条回答
  • 2021-02-19 10:17

    1) It's nice to also show some moving indicator to let user know that something's going on, that their request is being processed. It should eliminate lots of double submits.

    2) If user has disabled javascript, how're you gonna submit 'ajaxified' forms? If site becomes not functional without javascript, then it's probably best to just notify user (like Eimantas suggests).

    edit One example of such indicator, just to be clear what I mean in 1.
    http://www.netzgesta.de/busy/

    0 讨论(0)
  • 2021-02-19 10:22

    I use 4 method for 4 scenarios, please firstly prefer my awnser here: Prevent double submits in a Rails AJAX form

    only click limitation for users:

    use stopImmediatePropagation and add a click event to the target dom.

      /**
       * 防止按钮重复点击。
       * NOTICE: #1 需要在作用点之前调用此方法 #2 stopImmediatePropagation 会阻止后面的所有事件包括事件冒泡
       * @delay_duration 两次点击的间隔时间
       */
      $.fn.preventMultipleClick = function (delay_duration) {
        delay_duration = delay_duration || 3000;
        var last_click_time_stamp = 0;
        var time_duration = 0;
        $(this).bind('click', function (event) {
          time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
          //console.debug("preventMultipleClick", last_click_time_stamp, time_duration);
          if (time_duration && time_duration < delay_duration) {
            event.stopImmediatePropagation();
          } else {
            //console.debug("skip preventMultipleClick~");
            last_click_time_stamp = event.timeStamp;
          }
        });
      };
    

    limit the submit such as ajax:

    use ajax's beforeSend attribut.

      /**
       * 使用:
       *   在jquery的ajax方法中加入参数:beforeSend
       *   例如:beforeSend: function(){return $.preventMultipleAjax(event, 5000)}
       *
       * @param event
       * @param delay_duration
       * @returns {boolean}
       */
      $.preventMultipleAjax = function (event, delay_duration) {
        delay_duration = delay_duration || 3000;
        var target = $(event.target);
        var last_click_time_stamp = target.attr("_ajax_send_time_stamp") || 0;
        var time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
        //console.debug("preventMultipleAjax", last_click_time_stamp, time_duration);
        if (time_duration && time_duration < delay_duration) {
          return false;
        } else {
          //console.debug("skip preventMultipleAjax~");
          target.attr("_ajax_send_time_stamp", event.timeStamp);
          return true;
        }
      };
    

    only for form:

    <%= f.submit "Save annotation", :disable_with => "Saving...", :class => "btn btn-primary", :id => "annotation-submit-button" %>
    

    or: disable:仅仅对表单元素,按钮等起作用,会阻止其上的事件触发

    <input type="submit" value="submit" />
    <input type="button" value="button" />
    <input type="image" value="image" />
    

    others:

    This is the gem:https://github.com/mlanett/redis-lock

    Redis.current.lock("#{current_user.id}.action_name") do
       # Some code
    end
    
    0 讨论(0)
提交回复
热议问题