简体   繁体   English

如何确保在 ajax 请求 100% 完成之前禁用按钮

[英]How to make sure a button is disabled until an ajax request is 100% finished

I've got a function that refreshes some json when a plus or a minus button is clicked.我有一个函数可以在单击加号或减号按钮时刷新一些 json。 Below is a big button that I disable until the refresh is done.下面是一个大按钮,在刷新完成之前我会禁用该按钮。

Currently I do it like this:目前我这样做:

My refresh function:我的刷新功能:

function refreshform(force, element, orderline){
    $.ajax({
     type:'post',
     url:"payprocess/refreshform.php",
     data:({orderline:orderline}),
     success:function(data){
         $(element).empty().append( data );
     }
 });
}

My plus minus button functions:我的加减按钮功能:

$('.pluscheckout').click(function(e) {
    e.preventDefault();
    var $button = $(this).prop('disabled', true);
    var $input = $(this).closest('.quantitybtns').siblings('.aantal');
    var productid = $(this).closest('.quantitybtns').siblings('.productid').val();
    var $pricediv = $(this).closest('.prodinfoquantity').siblings('.prodinfoprice');
    var thiselement = $(this).closest('.productblocktop').siblings('.orderlineloop').find('.editorform');
    var orderline = $(this).closest('.productblocktop').siblings('.orderlineloop').find('.refreshform').attr('id');
    var $uploadbtn = $(this).closest('.productblocktop').siblings('.orderlineloop').find('.uploadbtn');
    $uploadbtn.prop('disabled', true);
    $uploadbtn.addClass('disabledbtn');
    var currentValue = parseInt($input.val());
    var quantity = parseInt($input.val()) + 1;
    $input.val(currentValue + 1);
    $.ajax({
        type: 'post',
        url: "checkout/prices.php",
        data: ({ quantity: quantity, productid: productid }),
        success: function(data) {
            $($pricediv).empty().append( data );
        },
        complete: function(data) {
            refreshform(true, thiselement, orderline);
            $button.prop('disabled', false);
            $uploadbtn.prop('disabled', false);
            $uploadbtn.removeClass('disabledbtn');
        }
    });
});

$('.mincheckout').click(function(e) {
    e.preventDefault();
    var $button = $(this).prop('disabled', true);
    var $input = $(this).closest('.quantitybtns').siblings('.aantal');
    var productid = $(this).closest('.quantitybtns').siblings('.productid').val();
    var $pricediv = $(this).closest('.prodinfoquantity').siblings('.prodinfoprice');
    var thiselement = $(this).closest('.productblocktop').siblings('.orderlineloop').find('.editorform');
    var orderline = $(this).closest('.productblocktop').siblings('.orderlineloop').find('.refreshform').attr('id');
    var $uploadbtn = $(this).closest('.productblocktop').siblings('.orderlineloop').find('.uploadbtn');
    var currentValue = parseInt($input.val());
    var quantity = parseInt($input.val()) - 1;
    if(quantity > 0){
        $uploadbtn.prop('disabled', true);
        $uploadbtn.addClass('disabledbtn');
        $input.val(currentValue - 1);
        $.ajax({
         type:'post',
         url:"checkout/prices.php",
         data:({quantity: quantity, productid: productid}),
         success:function(data){
             $($pricediv).empty().append( data );
             couponpost(true, 'true');
         },
        complete: function(data) {
            refreshform(true, thiselement, orderline);
            $button.prop('disabled', false);
            $uploadbtn.prop('disabled', false);
            $uploadbtn.removeClass('disabledbtn');
        }
     });
 }else{
     $button.prop('disabled', false);
 }
});

$uploadbtn is the button that needs to be disabled until the ajax call has completed. $uploadbtn是在ajax调用完成之前需要禁用的按钮。 So when clicking either the plus or minus button, I disable the button and enable it again in the complete of the ajax call.因此,当单击加号或减号按钮时,我禁用该按钮并在 ajax 调用complete时再次启用它。

But for some strange reason, the button becomes active again while refreshform is still running.但是出于某种奇怪的原因,当refreshform仍在运行时,该按钮再次变为活动状态。 If I spam click plus or minus, I can see the button become active and after that the result of refreshform is still refreshing.如果我垃圾点击加号或减号,我可以看到按钮变为活动状态,之后refreshform的结果仍在刷新。

I made a video to show what I mean:我制作了一个视频来展示我的意思:

https://streamable.com/2wzkah https://streamable.com/2wzkah

I thought maybe I should add a complete in my refreshform function like this:我想也许我应该在我的refreshform函数中添加一个complete ,如下所示:

function refreshform(force, element, orderline){
    $.ajax({
     type:'post',
     url:"payprocess/refreshform.php",
     data:({orderline:orderline}),
     success:function(data){

     },
     complete: function() {
        $(element).empty().append( data );
     }
 });
}

But with that code the following line stops working: $(element).empty().append( data );但是使用该代码,以下行停止工作: $(element).empty().append( data ); . . $(element) is empty. $(element)为空。

How can I fix this?我怎样才能解决这个问题?

The button needs to be disabled until the quantity from the json matches the quantity in the input field.该按钮需要禁用,直到 json 中的数量与输入字段中的数量匹配。 Don't worry I check for the rest also on the server side.别担心,我也在服务器端检查其余部分。

HTML: HTML:

<div class="productblock">
    <div class="productblocktop">
        <div class="prodinfoleft">
            <img class="previewprodthumb" src="cms/images/producten/textiel_producten/textielwand/1288_9936468fbe050be8_1.jpg" alt="" onerror="this.src='assets/images/custom/noimgprint.jpg'" />
            <div class="">
                <a href="https://printzelf.nl/textiel/textielframe"><h4>Textielframe</h4></a>

                <ul class="refreshspecs">
                    <a href="javascript:void(0);" id="togglespecscheckout" class="prodinfocheckout">Specificaties <i class="fas fa-chevron-down"></i></a>
                    <span class="speclist">
                        <li>Hoogte : 90cm</li>
                        <li>Breedte : 90cm</li>
                        <li>Samenstellling : Frame</li>
                        <li>Frame : Met LED verlichting</li>
                        <li>Ontwerp : PRO ontwerpcontrole</li>
                    </span>
                </ul>

                <form class="controleopties">
                    <span class="controltip" aria-expanded="false">
                        <label>
                            <input type="radio" value="basis" name="ontwerpcontrole" />
                            <span>AUTO ontwerpcontrole - Gratis</span>
                        </label>
                    </span>

                    <span class="controltip1" aria-expanded="false">
                        <label>
                            <input type="radio" value="pro" name="ontwerpcontrole" checked="" />
                            <span>PRO ontwerpcontrole - € 9,-</span>
                        </label>
                    </span>
                </form>
            </div>
        </div>
        <div class="prodinforight">
            <div class="prodinfoquantity">
                <input class="productid" type="hidden" name="productid" value="60eea4b1a615d" />
                <input type="number" class="form-control aantal" value="39" min="1" />
                <div class="quantitybtns">
                    <button class="mincheckout">−</button>
                    <button class="pluscheckout">+</button>
                </div>
            </div>
            <div class="prodinfoprice">
                <span><b>€ 8.188,91</b></span>
            </div>
        </div>
        <div class="actionbtns">
            <span class="orderlinetip" aria-expanded="false">
                <a href="javascript:void(0);" class="deleteproduct" id="60eea4b1a615d"><i class="icon-trash"></i></a>
            </span>
        </div>
    </div>
    <span class="orderlineloop">
        <input type="hidden" class="order_id_input" value="59.1495" />
        <input type="hidden" class="orderline_id_input" value="60eea4b1a615d" />
        <span class="refreshform" id="60eea4b1a615d">
            <form class="editorform" method="post" target="_blank">
                <input
                    type="hidden"
                    name="json"
                    value='{"customer_id":"59","order_id":"59.1495","quantity":"39","rulers":"cm","canvas_size":"900x900","bleed":"","safety_margin":"","dpi":50,"procheck":"y","multiple_pages":"1","product_name":"Textielframe","product_thumbnail":"https:\/\/printzelf.nl\/cms\/images\/producten\/textiel_producten\/textielwand\/1288_9936468fbe050be8_1.jpg","orderline":"60eea4b1a615d"}'
                />
            </form>
        </span>

        <div class="productblockbottom">
            <span>
                <b>Hoe lever je jouw ontwerp aan?</b>
                <span class="tooltippy_nostyle" aria-expanded="false">
                    <img class="infosvg" src="assets/images/custom/icon_info.svg" />
                </span>
            </span>
            <div class="productblockbtns">
                <a href="javascript:void(0);">
                    <button class="btnstyle uploadbtn gapfixbtn" type="button" name="button"><span>Lever je bestanden aan</span> <i class="icon-upload"></i></button>
                </a>
            </div>
        </div>
        <span class="unfinished editstatuscheck"></span>
    </span>
</div>

You can achieve this by returning the jqXHR object from the $.ajax() call in refreshForm() .您可以通过从refreshForm()$.ajax()调用返回 jqXHR 对象来实现这一点。 You can then perform the actions on the buttons when the promise in that object is resolved.然后,您可以在解决该对象中的承诺时对按钮执行操作。 Try this:试试这个:

function refreshform(force, element, orderline) {
  return $.ajax({
    type: 'post',
    url: "payprocess/refreshform.php",
    data: { orderline: orderline }, // note: parentheses not needed here
    success: function(data) {
      $(element).empty().append(data);
    }
  });
}

// inside the complete handler:
complete: function(data) {
  refreshform(true, thiselement, orderline).then(() => {
    $button.prop('disabled', false);
    $uploadbtn.prop('disabled', false);
    $uploadbtn.removeClass('disabledbtn');
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM