javascript - strip 验证失败时提交按钮不会重新启用

标签 javascript jquery ruby-on-rails stripe-payments

当使用 JQuery/AJAX/JS 提交 form_for() 表单时,提交按钮无法重新启用,即使我编写了将 prop 切换为 disabled false 的代码。

我在控制台成功激活了相同的JS代码行,但是当stripe验证正常失败时,它不起作用。

var StripepayOnestepSubscriptionForm = {
   initialize: function () {
    $(document).off('submit.stripepay-onestep-subscription-form').on(
        'submit.stripepay-onestep-subscription-form', '.stripepay-onestep-subscription-form',
        function () {
            return StripepayOnestepSubscriptionForm.handleSubmit($(this));
        }
    );
},

handleSubmit: function (form) {
    if (!StripepayOnestepSubscriptionForm.validateForm(form)) {
        return false;
    }

    $(form).find('div :submit')
        .prop('disabled', true).change();
    $('.stripepay-spinner').css('visibility', 'visible');

    Stripe.card.createToken(form, function (status, response) {
        StripepayOnestepSubscriptionForm.stripeResponseHandler(form, status, response);
    });
    return false;
},

validateForm: function (form) {
    var cardNumber = $("input[data-stripe='number']").val();
    if (!Stripe.card.validateCardNumber(cardNumber)) {
        StripepayOnestepSubscriptionForm.showError(form, 'The card number is not a valid credit card number.');
        return false;
    }
    if ($("[data-stripe='exp']").length) {
        var valid = !Stripe.card.validateExpiry($("[data-stripe='exp']").val());
    } else {
        var expMonth = $("[data-stripe='exp_month']").val();
        var expYear = $("[data-stripe='exp_year']").val();
        var valid = !Stripe.card.validateExpiry(expMonth, expYear);
    }
    if (valid) {
        StripepayOnestepSubscriptionForm.showError(form, "Your card's expiration month/year is invalid.");
        return false
    }

    var cvc = $("input[data-stripe='cvc']").val();
    if (!Stripe.card.validateCVC(cvc)) {
        StripepayOnestepSubscriptionForm.showError(form, "Your card's security code is invalid.");
        return false;
    }

    return true;
},

stripeResponseHandler: function (form, status, response) {
    if (response.error) {
        StripepayOnestepSubscriptionForm.showError(form, response.error.message);
    } else {
        var email = form.find("[data-stripepay='email']").val();
        var coupon = form.find("[data-stripepay='coupon']").val();
        var quantity = form.find("[data-stripepay='quantity']").val();

        var base_path = form.data('stripepay-base-path');
        var plan_type = form.data('stripepay-plan-type');
        var plan_id = form.data('stripepay-plan-id');

        var action = $(form).attr('action');

        form.append($('<input type="hidden" name="plan_type">').val(plan_type));
        form.append($('<input type="hidden" name="plan_id">').val(plan_id));
        form.append($('<input type="hidden" name="stripeToken">').val(response.id));
        form.append($('<input type="hidden" name="stripeEmail">').val(email));
        form.append($('<input type="hidden" name="coupon">').val(coupon));
        form.append($('<input type="hidden" name="quantity">').val(quantity));
        form.append(StripepayOnestepSubscriptionForm.authenticityTokenInput());
        $.ajax({
            type: "POST",
            url: action,
            data: form.serialize(),
            success: function (data) {
                StripepayOnestepSubscriptionForm.poll(form, 60, data.guid, base_path);
            },
            error: function (data) {
                StripepayOnestepSubscriptionForm.showError(form, jQuery.parseJSON(data.responseText).error);
            }
        });

    }
},

poll: function (form, num_retries_left, guid, base_path) {
    if (num_retries_left === 0) {
        StripepayOnestepSubscriptionForm.showError(form, "This seems to be taking too long. Please contact support and give them transaction ID: " + guid);
    }
    var handler = function (data) {
        if (data.status === "active") {
            window.location = base_path + '/confirm_subscription/' + guid;
        } else {
            setTimeout(function () {
                StripepayOnestepSubscriptionForm.poll(form, num_retries_left - 1, guid, base_path);
            }, 500);
        }
    };
    var errorHandler = function (jqXHR) {
        StripepayOnestepSubscriptionForm.showError(form, jQuery.parseJSON(jqXHR.responseText).error);
    };

    if (typeof guid != 'undefined') {
        $.ajax({
            type: 'GET',
            dataType: 'json',
            url: base_path + '/subscription_status/' + guid,
            success: handler,
            error: errorHandler
        });
    }
},

showError: function (form, message) {
    $('.stripepay-spinner').css('visibility', 'hidden');
    $(form).find('div :submit')
        .prop('disabled', false).change()
        .trigger('error', message);

    var error_selector = form.data('stripepay-error-selector');
    if (error_selector) {
        $(error_selector).text(message);
        $(error_selector).show();
    } else {
        form.find('.stripepay-payment-error').text(message);
        form.find('.stripepay-payment-error').show();
    }
},

authenticityTokenInput: function () {
    return $('<input type="hidden" name="authenticity_token"></input>').val($('meta[name="csrf-token"]').attr("content"));
  }
};

StripepayOnestepSubscriptionForm.initialize();

显示错误验证消息后,提交按钮保持禁用状态。

最佳答案

<%= f.submit “Sign up”, :class => ‘btn’, data: {disable_with: false} %> 

允许 JS 控制按钮何时改变状态。 (Rails 5) 默认激活 disable_with。这是错误的原因。

关于javascript - strip 验证失败时提交按钮不会重新启用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53907239/

相关文章:

javascript - $_SESSION 在 AJAX 请求上丢失

ruby-on-rails - 基于 QueryString 设置 Rails 路由

ruby-on-rails - 在 Ruby on Rails 中有一种方法可以查看模型的属性

javascript - 列出当前用户可以使用 Google Drive API 编辑的文件

javascript - jQuery - 通过各种 dom 级别定位兄弟元素?

javascript - 克隆对象省略嵌套属性

javascript - redis-server 离线导致 Node 崩溃

javascript - 优化设置多个内联 css 样式的性能

javascript - 如何在使用两个滚动条时将拖动的 div 置于所有内容的顶部?

ruby-on-rails - Rails ActiveRecord checkout_timeout 设置被忽略