Feature Request - Conditional Required

7 posts by 3 authors in: Forums > CMS Builder
Last Post: December 15   (RSS)

By KennyH - October 18

Something that seems to be coming up more and more is needing a way to make a field required, but only if another field is checked or has content.

For example, let's say we have the following fields:

  • Warranty Serviced (checkbox)
  • Date of Service (date/time)
  • Repair Type (dropdown)
  • Description (wysiwyg)

I want these three fields to be required ONLY if Warranty Serviced has been checked:

  • Date of Service (date/time)
  • Repair Type (dropdown)
  • Description (wysiwyg)

If Warranty Serviced has not been checked, then none of those fields would be required to have content.

What do you think?

Kenny H

By Dave - October 19

Hi Kenny, 

You could do it with a plugin, check out the attached code.  

Give it a try and let me know any questions.  You'll need to make sure the tablename and field names match.

Hope that helps!

Dave Edis - Senior Developer
interactivetools.com

By KennyH - October 19

Amazing! This works perfectly!

I changed the name of the file and plugin so if I ever needed to add more than one it should work without conflict. However, shouldn't I just be able to add more tables / fields to this plugin? 

Thanks so much for putting this together.

Kenny H

By Dave - October 19

Hi Kenny, 

Ok great, glad that's working!

Yes, could can just modify the code a bit to add additional tables.  Here's an example:

function conditionalErrorChecking($tableName, $recordExists, $oldRecord) {
    $errors = [];

    // table 1
    if ($tableName === 'your_table_here') {

        // conditional error checking rules
        $isWarrantyServiced = !empty($_REQUEST['warranty_serviced']);
        if ($isWarrantyServiced) {
            if (empty($_REQUEST['date_of_service:string'])) { // add :string prefix to date entire date string (if set)
                $errors[] = "Please fill out the date of service field.";
            }
            if (empty($_REQUEST['repair_type'])) {
                $errors[] = "Please fill out the repair type field.";
            }
            $wysiwygWithoutTagsOrWhitespace = trim(strip_tags($_REQUEST['description'] ?? ''));
            if (empty($wysiwygWithoutTagsOrWhitespace)) { // wysiwyg, remove all tags and check if empty after that
                $errors[] = "Please fill out the description type field.";
            }
        }
    }

    // table 2
    if ($tableName === 'another_table') {
        // error checking code goes here
    }

    // show errors
    if ($errors) {
        $errorsHTML = implode("\n", $errors);
        die($errorsHTML);
    }
}

I previously added some extra variables for readability, they're not strictly necessary.  

Let me know if you have any questions about how it works or how to add another table/field.

Dave Edis - Senior Developer
interactivetools.com

By KennyH - October 20

This is great and opens up so many more possibilities. I have added multiple tables and conditions along with modifying the error messages. Here's one for an example for anyone else who needs it.

<?php
/*
Plugin Name: conditionalErrorChecking
Description: Custom hierarchical error checking rules
Version: 1.00
CMS Version Required: 3.59
*/

// register callbacks
addAction( 'record_save_errorchecking', 'conditionalErrorChecking', null, 3 );

function conditionalErrorChecking( $tableName, $recordExists, $oldRecord ) {

  $errors = [];

  if ( $tableName === 'estimates' ) { // Check for 'estimates' table and associated rules

    // Check if pricing_approval or shipping_approval is set to "Approved"
    $isPriceApproved = ( isset( $_REQUEST[ 'pricing_approval' ] ) && $_REQUEST[ 'pricing_approval' ] == 'Approved' );
    $isShippingApproved = ( isset( $_REQUEST[ 'shipping_approval' ] ) && $_REQUEST[ 'shipping_approval' ] == 'Approved' );

    $wysiwygApprovalNotes = trim( strip_tags( $_REQUEST[ 'approval_notes' ] ?? '' ) );
    if ( empty( $wysiwygApprovalNotes ) && ( $isPriceApproved || $isShippingApproved ) ) {
      $errors[] = "Please fill out your approval notes!";
    }

    if ( $isPriceApproved && empty( $_REQUEST[ 'approved_by_pricing' ] ) ) {
      $errors[] = "Who approved the pricing for this estimate?";
    }

    if ( $isShippingApproved && empty( $_REQUEST[ 'approved_by_shipping' ] ) ) {
      $errors[] = "Who approved the shipping for this estimate?";
    }

    // Check if item_name has content and width_x_height is empty
    for ( $i = 1; $i <= 6; $i++ ) {
      if ( !empty( $_REQUEST[ "item_name_$i" ] ) && empty( $_REQUEST[ "width_x_height_$i" ] ) ) {
        $errors[] = "Please fill out width x height for item {$i}!";
      }
    }

  } elseif ( $tableName === 'projects' ) { // Check for 'projects' table and associated rules

    $status = $_REQUEST[ 'project_status' ] ?? '';
    $statusesToCheck = [ "Printing", "Awaiting Pickup", "Complete" ];

    if ( in_array( $status, $statusesToCheck ) ) {
      if ( empty( $_REQUEST[ 'date_ordered:string' ] ) ) { // add :string prefix to date entire date string (if set)
        $errors[] = "Please fill out the date ordered!";
      }
    }

  } elseif ( $tableName === 'paper_inventory' ) { // Check for 'paper_inventory' table and associated rules

      // Helper function to convert snake_case field names to Title Case for user-friendly display
      function makeFriendlyFieldName( $snakeCaseString ) {
        $words = str_replace( '_', ' ', $snakeCaseString ); // Replace underscores with spaces
        $titleCasedWords = ucwords( $words ); // Convert to Title Case
        return $titleCasedWords;
      }

      // Check rules for brand_1 to brand_3
      for ( $i = 1; $i <= 3; $i++ ) {
        if ( !empty( $_REQUEST[ "brand_$i" ] ) ) {
          $fieldsToCheck = [ "supplier_$i", "lead_time_$i", "purchase_price_$i", "purchase_url_$i" ];
          foreach ( $fieldsToCheck as $field ) {
            if ( empty( $_REQUEST[ $field ] ) ) {
              $friendlyFieldName = makeFriendlyFieldName( $field );
              $errors[] = "Please fill out $friendlyFieldName!";
            }
          }
        }
      }
    }
    // show errors
  if ( $errors ) {
    $errorsHTML = implode( "\n", $errors );
    die( $errorsHTML );
  }
}

By kitsguru - December 15

This is great, Thanks for sharing. I have several use cases for this. I am adding it to my arsenal.

Jeff Shields