Craft Commerce: make address phone telephone field required without JavaScript Because I used a similar address model to the one supplied in the Craft Commerce templates, which essentially uses the same form partials for both address and billing, and also hides and shows the form using JavaScript, I can't use HTML required attributes.

Is there an easy way to add in the config files a way to make 'shipping.phone' required and return an error in the same way the default required fields work?

&lt;div class="inputGroup{% if model and model.hasErrors('phone') %} error{% endif%}"&gt;
    &lt;h3 class="small"&gt;Contact details&lt;/h3&gt;
    &lt;div class="inputWrap"&gt;
        &lt;input type="text" id="{{ modelName }}-phone" class="u-full-width" name="{{ modelName }}[phone]" value="{{ model ? model.phone : '' }}"&gt;
        &lt;span class="highlight"&gt;&lt;/span&gt;
        &lt;span class="bar"&gt;&lt;/span&gt;
        &lt;label for="{{ modelName }}-phone"&gt;Telephone number&lt;/label&gt;
        &lt;span class="flash"&gt;{% if model and model.hasErrors('phone') %}{{ model.getError('phone') }}{% else %}Required{% endif %}&lt;/span&gt;
    &lt;/div&gt;
    &lt;p class="footnote"&gt;In case we need to contact you about important details regarding your order.&lt;/p&gt;
&lt;/div&gt;
The way to do address validation with Commerce in gneral is using a plugin and listening to the onBeforeSaveAddress event.

Set up a listener with something like this:



    craft()-&gt;on('commerce_addresses.onBeforeSaveAddress',
        [
            craft()-&gt;businessLogic_logic,
            'onBeforeSaveAddressHandler'
        ]
    ); 


And here's an example of a function that does some validation:

public function onBeforeSaveAddressHandler($event){

    $address = $event-&gt;params['address'];

    if(!$address-&gt;firstName){
        $address-&gt;addError('firstName','First name must not be empty');
        $event-&gt;performAction = false;
    }
    if(!$address-&gt;lastName){
        $address-&gt;addError('lastName','Last name must not be empty');
        $event-&gt;performAction = false;
    }
    if(!$address-&gt;phone){
        $address-&gt;addError('phone','Phone number must not be empty');
        $event-&gt;performAction = false;
    }
    if(!$address-&gt;address1){
        $address-&gt;addError('address1','Street Address line 1 must not be empty');
        $event-&gt;performAction = false;
    }
    if(!$address-&gt;city){
        $address-&gt;addError('city','Suburb must not be empty');
        $event-&gt;performAction = false;
    }
    if(!$address-&gt;zipCode){
        $address-&gt;addError('zipCode','Postcode must not be empty');
        $event-&gt;performAction = false;
    }     
    if(!$address-&gt;countryId){
        $address-&gt;addError('countryId','Country ID must not be empty');
        $event-&gt;performAction = false;
    }          
}