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

后端 未结 8 2343
天命终不由人
天命终不由人 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: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:仅仅对表单元素,按钮等起作用,会阻止其上的事件触发

    
    
    
    

    others:

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

    Redis.current.lock("#{current_user.id}.action_name") do
       # Some code
    end
    

提交回复
热议问题