代码之家  ›  专栏  ›  技术社区  ›  omukiguy

WooCommerce签出的时间循环从日期选择器输入字段中选择选项

  •  1
  • omukiguy  · 技术社区  · 7 年前

    输入字段1-交货日期附加了日期选择器。这将填写客户要求的日期。此字段确定在其旁边的选择字段中填充的交付时间选项。

    但是,这些选项基于一些规则

    1. 时间间隔为30分钟,从上午11点到下午4点。
    2. 如果选择的日期=今天,交货开始时间=当前时间+一小时。
    3. 如果日期是将来,交货时间为上午11点至下午4点。间隔30分钟

    我需要帮助根据上述参数从所选日期为woocommerce选项制作数组。谢谢

    Screenshot is descriptive.

    示例代码:首先,我使用日期选择器在中选择日期时更新选择字段选项。使用下面的代码。

    add_action( 'wp_footer', 'woocommerce_update_on_date_select', 21 );
    
    function woocommerce_update_on_date_select() {
        if (is_checkout()) {
        ?>
        <script type="text/javascript">
            $(document).ready(function() {
              function updateCart() {
                var d = $("#billing_country").val(),
                  e = $("#billing_state").val(),
                  f = $("input#billing_postcode").val(),
                  g = $("#billing_city").val(),
                  h = $("input#billing_address_1").val(),
                  i = $("input#billing_address_2").val(),
                  j = d,
                  k = e,
                  l = f,
                  m = g,
                  n = h,
                  o = i;
                $("#ship-to-different-address").find("input").is(":checked") && (j = $("#shipping_country").val(), k = $("#shipping_state").val(), l = $("input#shipping_postcode").val(), m = $("#shipping_city").val(), n = $("input#shipping_address_1").val(), o = $("input#shipping_address_2").val());
                var p = {
                  security: wc_checkout_params.update_order_review_nonce,
                  payment_method: $("#order_review").find('input[name="payment_method"]:checked').val(),
                  country: d,
                  state: e,
                  postcode: f,
                  city: g,
                  address: h,
                  address_2: i,
                  s_country: j,
                  s_state: k,
                  s_postcode: l,
                  s_city: m,
                  s_address: n,
                  s_address_2: o,
                  post_data: $("form.checkout").serialize()
                };
                var c  = {update_shipping_method: !0};
                if (!1 !== c.update_shipping_method) {
                  var q = {};
                  $('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function() {
                    q[$(this).dat$("index")] = $(this).val()
                  }), p.shipping_method = q
                }
                $.ajax({
                  type: "POST",
                  url: wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%", "update_order_review"),
                  data: p,
                  success: function(c) {
                    var d = $('.woocommerce-checkout input[name="payment_method"]:checked').attr("id");
                    if ("true" === c.reload) return void window.location.reload();
                    $(".woocommerce-NoticeGroup-updateOrderReview").remove();
                    var e = $("#terms").prop("checked");
                    if (c && c.fragments && $.each(c.fragments, function(b, c) {
                        $(b).replaceWith(c)
                      }), e && $("#terms").prop("checked", !0), "failure" === c.result) {
                      var f = $("form.checkout");
                      $(".woocommerce-error, .woocommerce-message").remove(), c.messages ? f.prepend('<div class="woocommerce-NoticeGroup-updateOrderReview">' + c.messages + "</div>") : f.prepend(c), f.find(".input-text, select, input:checkbox").blur(), $("html, body").animate({
                        scrollTop: $("form.checkout").offset().top - 100
                      }, 1e3)
                    }
                  }
                });
              }
    
              $('#billing_delivery_date').attr('readonly', true);
              $('#billing_serving').on('change', function(){
                  updateCart();
              });
    
              $( "#billing_delivery_date" ).on('change', function() {
                updateCart();
              });
          });
        </script>
        <?php
        }
    }
    

    然后使用从日期选择器中选择的日期,我尝试将数组发送到表单中的select字段。

    add_filter( 'woocommerce_checkout_fields' , 'brown_remove_billing_postcode_checkout' );
    
            function brown_remove_billing_postcode_checkout( $fields ) {
                $error = '';
    
                if (isset($_POST['post_data'])) {
                    parse_str( $_POST['post_data'], $post_data );
                } else {
                    $post_data = $_POST;
                }
    
                $billing_delivery_date = $post_data['billing_delivery_date'];
    
                if ( $billing_delivery_date = !NULL ) { 
    
                    $date = new DateTime();
                    $date->setTimezone(new DateTimeZone('Africa/Kampala'));
                    $order_day = $date->format('Y-m-d H:i:s');
    
                    $date = new DateTime(date('Y-m-d', strtotime(str_replace('/' , '-', $billing_delivery_date))));
    
                    //If the date picked is greater than the current date
                    if (strtotime($order_day) > strtotime($date) {
                        //Make an array of values from 11am to 4pm to pass to $fields['billing']['billing_serving'] options array
    
                    } elseif ($order_day == $date) {
                        //If the Make an array of values from 11am to 4pm to pass to $fields['billing']['billing_serving'] options array
                        //Get the current time + one hour. Append hour intervals from next top of the hour until 4pm.
                    }
    
                }
    
                // Add New Fields
                $fields['billing']['billing_serving'] = array(
                    'label'     => __('Delivery Time', 'woocommerce'),
                    'placeholder'   => _x('Time for your delivery', 'placeholder', 'woocommerce'),
                    'required'  => true,
                    'class'     => array('form-row-last'),
                    'clear'     => false,
                    'autocomplete' => false,
                    'type'        => 'select',
                    'options'     => array(
                               //Generated array goes here.
                               '11am'    => __('11:00am', 'woocommerce' ),
                               '1130am'  => __('11:30am', 'woocommerce' ),
                               '12noon'  => __('12:00pm', 'woocommerce' ),
                               '1230pm'  => __('12:30pm', 'woocommerce' ),
                               '1pm'     => __('1:00pm', 'woocommerce' ),
                               '130pm'   => __('1:30pm', 'woocommerce' ),
                               '2pm'     => __('2:00pm', 'woocommerce' ),
                               '230pm'   => __('2:30pm', 'woocommerce' ),
                               '3pm'     => __('3:00pm', 'woocommerce' ),
                               '330pm'   => __('3:30pm', 'woocommerce' ),
                               '4pm'     => __('4:00pm', 'woocommerce' )
                        )
                 );
    
                return $fields;
    
            }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   LoicTheAztec    4 年前

    作为 交货日期 缺少,我已启用jQuery ui日期选择器 (您应该使用自己的CSS) .

    我没有使用您的jQuery代码,因为我的方法完全不同,而且我对您的代码有点松懈。我的PHP代码也非常不同。选择字段 <options> 在php中几乎为空,因为javascript会动态构建它。

    这里php代码正在向Javascript/jQuery传递一些数据:

    • 交货开始日期。
    • 对于选择选项键/值对(可用时隙+默认时隙)。

    这里,jQuery/Javascript位于自定义签出字段代码之后的同一挂钩函数中

    的html <option> jQuery根据开始日期和当前时间动态构建“交货时间选择”字段中的标记。

    尊重您的所有要求:

    • 时间间隔为30分钟,从上午11点到下午4点。
    • 如果选择的日期是今天,我们会在时间段中添加+1小时的偏移量
    • 如果选择的日期不是今天,我们将获得默认的时间段(11个可用)

    现在,您应该禁用相关代码以尝试此代码:

     // Enable available jQuery datepicker script in Wordpress
    add_action( 'wp_enqueue_scripts', 'enabling_date_picker' );
    function enabling_date_picker() {
    
        // Only on front-end and checkout page
        if( is_admin() || ! is_checkout() ) return;
    
        // Load available datepicker jQuery-ui plugin script
        wp_enqueue_script( 'jquery-ui-datepicker' );
    }
    
    // Add and display custom checkout fields + jQuery script
    add_filter( 'woocommerce_checkout_fields' , 'brown_remove_billing_postcode_checkout' );
    function brown_remove_billing_postcode_checkout( $fields ) {
        // Your Settings
        $start_hour = 11; // start time (in hours)
        $end_hour = 16; // end time (in hours)
        $offset = 1; // One hour before slot time (can be a float number like 1.5)
        date_default_timezone_set ('Africa/Kampala'); // The timezone
    
        // Initializing variables
        $hour = 3600; // 1 hour in seconds
        $day = $hour * 24; // 1 day in seconds
        $now = strtotime("now"); // Now time
        $real_now = $now + ($offset * $hour); // Now time + offset
        $today_date = date("Y-m-d"); // today date
        $tomorrow_date = date("Y-m-d", strtotime("+1 day")); // tomorow date
        $today_time = strtotime($today_date); // Today time at 00:00 in seconds
        $tomorrow_time = strtotime($tomorrow_date); // Tomorrow time at 00:00 in seconds
        $start_time = $today_time + ( $start_hour * $hour ); // Start datetime in seconds
        $end_time = $today_time + ( $end_hour * $hour ); // End datetime in seconds
        $today_slots = $default_slots = $option_days = array();
    
        // Add Delivery day field (with jquery-ui datepicker enabled)
        $fields['billing']['billing_delivery_day'] = array(
            'label'         => __('Delivery Day', 'woocommerce'),
            'placeholder'   => _x('Date for your delivery', 'placeholder', 'woocommerce'),
            'required'      => true,
            'id'            => 'datepicker', // Enable jQuery datepicker for this field
            'class'         => array('form-row-first'),
            'clear'         => false,
            'autocomplete'  => false,
            'type'          => 'text'
        );
       // Add Delivery hour slots
        $fields['billing']['billing_delivery_hour'] = array(
            'label'        => __('Delivery Time', 'woocommerce'),
            'required'     => true,
            'class'        => array('form-row-last'),
            'clear'        => false,
            'autocomplete' => false,
            'type'         => 'select',
            'options'      => array( '' => __('Select time for your delivery') ),
        );
    
        // Making the delivery hour slots <option> arrays for Javascript
        for($i = $start_time; $i <= $end_time; $i += 1800 ){ // 1800 seconds is half an hour
            $key     = date('H:i', $i);
            $value   = date('h:ia', $i);
    
            // Today available hour slots array
            if($real_now < $i)
                $today_slots[$key] = $value;
    
            // Default hour slots array
            $default_slots[$key] = $value;
        }
    
        // The correct start date and time (today or tomorow) for Javascript
        $date = $real_now < $end_time ? $today_date : $tomorrow_date;
        $dtime = $real_now < $end_time ? date("Y-m-d\TH:i:s", $today_time) : date("Y-m-d\TH:i:s", $tomorrow_time);
    
        ?>
        <script>
            jQuery(function($){
                var offsetDate = 15, // Number of days enabled in the datepicker (optional and disabled in the datepicker code)
                    startingDate = new Date('<?php echo $dtime; ?>'), // Starting day (dynamic)
                    endingDate = new Date('<?php echo $dtime; ?>'), // End date (calculated below)
                    todaySlots = <?php echo json_encode($today_slots); ?>,
                    defaultSlots = <?php echo json_encode($default_slots); ?>,
                    sDay = 'input[name ="billing_delivery_day"]',
                    sHour = 'select[name ="billing_delivery_hour"]',
                    defaultOption = $(sHour+' > option').text(),
                    todaySlotsLength = Object.keys(todaySlots).length;
    
                // ------ 1). Dates and Date picker ------ //
    
                // Set the default field start date
                $(sDay).val('<?php echo $date; ?>');
                $('#datepicker_field').addClass('woocommerce-validated');
    
                // Max date calculation (optional and diasabeld in the datepicker code)
                endingDate.setDate(startingDate.getDate()+offsetDate);
    
                // Jquery-ui datepicker
                $("#datepicker").datepicker({
                    dateFormat: "yy-mm-dd",
                    minDate: startingDate,
                    // maxDate: endingDate, // optional, can be enabled.
                    setDate: startingDate,
                });
    
                // ------ 2). HOUR slots select field (dynamic <option>) ------ //
    
                // Build the <option> html html in the select field dynamically
                function dynamic_select_options_buid( slotsType ){
                    $.each( slotsType, function( index, value ){
                        $(sHour).append('<option value="'+index+'">'+value+'</option>');
                    });
                }
                // Replace and Build the <option> html in the select field dynamically
                function dynamic_select_options_replace( slotsType ){
                    $(sHour+' > option').remove();
                    $(sHour).append('<option value="">'+defaultOption+'</option>');
                    dynamic_select_options_buid( slotsType );
                }
                
                console.log(defaultOption);
                console.log(todaySlotsLength);
                if(todaySlotsLength != 0 && todaySlotsLength < 11 ){
                    // Loaded at start
                    dynamic_select_options_buid( todaySlots );
    
                    // Live date selection event
                    $(sDay).change( function(){
                        console.log('day changed: '+$(this).val());
                        if( $(this).val() != '<?php echo $date; ?>' )
                            dynamic_select_options_replace( defaultSlots );
                        else
                            dynamic_select_options_replace( todaySlots );
                    })
                } else {
                    dynamic_select_options_buid( defaultSlots );
                }
            });
        </script>
        <?
        return $fields;
    }
    

    代码进入功能。活动子主题(或活动主题)的php文件。

    已测试并正常工作。