Support » Plugin: WooCommerce » Make a custom field required on checkout

  • Resolved briangelhaus

    (@briangelhaus)


    I have a basic wordpress install on latest version of woocommerce.

    My goal is to throw an error if my custom field is empty. This field is in a different location than normal fields, it is in the shipping section of the checkout.

    I have code in my functions.php that displays a “pickup_location” field on the checkout page.

    This is what it what it looks like on the front end: https://www.dropbox.com/s/9bpcwnwg20xgayf/shipping.jpg?dl=0

    Currently the user can checkout with my custom field empty. I’d like to show an error instead.

    // add shipping fields if user selects local pickup on checkout
    add_action('woocommerce_after_shipping_rate', function( $method ) {
    	
    	if($method->label == 'Local pickup') {
    		if ( isset($_POST['shipping_method']) && $_POST['shipping_method'][0] === 'local_pickup:2'  ){
    ?>
    			<style>
    				.shipping_location_box { margin: 15px 15px 10px 15px; }
    				.shipping_location_box p { margin: 0 0 10px 20px; }
    			</style>
    			<div class="shipping_location_box">
    				<p>Choose your prefered pickup location</p>
    				<select name="pickup_location" required>
    					<option value="none">-- Select Location</option>
    					<?php
    					$my_wp_query = new WP_Query();
    					$all_wp_pages = $my_wp_query->query(array('post_type' => 'page', 'posts_per_page' => '-1'));
    					$page_children = get_page_children(6, $all_wp_pages);
    					foreach($page_children as $location):
    				?>
    					<option value="<?php echo $location->post_title; ?>"><?php echo $location->post_title; ?></option>
    				<?php endforeach; ?>
    				</select>
    			</div>
    <?php 
    		} // if post
    	} // if local pickup
    });

    Now I have a function that actually saves this field I created in the database. But I want to make this field required.

    add_action('woocommerce_checkout_update_order_meta', function( $orderid, $data ) {
    	if ( isset( $_POST['pickup_location'] ) && $_POST['pickup_location'] != 'none') {
    		update_post_meta($orderid, 'pickup_location', htmlspecialchars($_POST['pickup_location']));
    	}else{
    // need help here showing the error on checkout
    // this order still goes through when this field is empty
    // on the thank you page, this notice runs
    // id like this checkout process to throw and error and display this notice on the checkout page
    		wc_add_notice( __( 'Please select a pickup location.' ), 'error' );
    		// exit();
    	}
    }, 10, 2);
Viewing 3 replies - 1 through 3 (of 3 total)
  • Caleb Burks

    (@icaleb)

    Automattic Happiness Engineer

    woocommerce_checkout_update_order_meta is too late to do validation.

    woocommerce_after_checkout_validation is the correct place I believe: https://github.com/woocommerce/woocommerce/blob/1f16ad0a03237d19d41d2b237c0ed6df81ea8dd8/includes/class-wc-checkout.php#L729. If your field isn’t chosen, add an error.

    It looks like woocommerce_after_checkout_validation only gets the billing/shipping order fields. Since my field is in the shipping box its in a whole different location. I think i need a some hook for shipping fields. Here is where my field is: https://www.dropbox.com/s/9bpcwnwg20xgayf/shipping.jpg?dl=0

    add_action( 'woocommerce_after_checkout_validation', 'checkout_validate' );
    function checkout_validate($data){
    	echo '<pre>'; print_r($data); echo '</pre>';
    	exit();
    }

    When I debug this data I don’t get my “pickup_location” field that I created

    <pre>Array
    (
        [terms] => 0
        [createaccount] => 0
        [payment_method] => cod
        [shipping_method] => Array
            (
                [0] => local_pickup:2
            )
    
        [ship_to_different_address] => 
        [woocommerce_checkout_update_totals] => 
        [billing_first_name] => Brian
        [billing_last_name] => 
        [billing_company] => 
        [billing_country] => US
        [billing_address_1] => 123 test
        [billing_address_2] => 
        [billing_city] => 
        [billing_state] => OH
        [billing_postcode] => 12345
        [billing_phone] => 1231231234
        [billing_email] => my@email.com
        [order_comments] => 
        [shipping_first_name] => Brian
        [shipping_last_name] =>
        [shipping_company] => 
        [shipping_country] => US
        [shipping_address_1] => 123 test
        [shipping_address_2] => 
        [shipping_city] =>
        [shipping_state] => OH
        [shipping_postcode] => 12345
        [shipping_phone] => 1231231234
    )
    </pre>
    • This reply was modified 2 years, 7 months ago by briangelhaus.
    • This reply was modified 2 years, 7 months ago by briangelhaus.
    • This reply was modified 2 years, 7 months ago by briangelhaus.
    Caleb Burks

    (@icaleb)

    Automattic Happiness Engineer

    Yea, I don’t think you’ll get to use the data arg. Will need to look for your data being posted if possible.

    Before woocommerce_after_checkout_validation is called, shipping methods themselves are brought in via $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );

    So maybe save your custom fields to the session then access that way?

    I did a quick looksy, and seems that is how the Local Pickup Plus extension goes about doing things with their custom fields in the same area. The WooCommerce Mailchimp plugin might be another one to look at as I think it also adds a field outside the traditional area.

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Make a custom field required on checkout’ is closed to new replies.