1

I have a custom field on contact in radio type format, not required field. I'd like to set up custom error on this field by using hook_civicrm_validateForm when the field is null.

// hook in extension
function hook_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors) {}

$fields array doesn't contain a key for this custom field. After setting $error['custom_xx'] the form is reloaded without displaying the error.

What I found:

$form->_elementIndex contains all needed keys, including this for radio. So I suppose this is not a problem.

I think that problem is caused by using _submitValues[] as a list of fields because _submitValues doesn't contain null radio custom fields:

// CRM_Core_Form->validate():
CRM_Utils_Hook::validateForm(
  get_class($this),
  $this->_submitValues,
  $this->_submitFiles,
  $this,
  $hookErrors
);

// my hook
function example_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors) {
  if ($formName == 'CRM_Contact_Form_Contact') {
    if (in_array('AA', $fields['contact_sub_type'])) {
      $fieldIndex = 'custom_70-1';
      if (!in_array($fieldIndex, array_keys($fields)) || !$fields[$fieldIndex]) {
        $errors[$fieldIndex] = 'For AA contact type this field is required';
      }
    }
  }
}

Edit:

Here is my workaround - add missing keys to _submitValues[] array https://github.com/caltha-eu/civicrm-core/commit/b4ee607334f3f091bffc2c32a87d862e4a3d7493

foreach ($this->_elementIndex as $elementIndex => $index) {
  if (!in_array($elementIndex, array_keys($this->_submitValues))) {
    $this->_submitValues[$elementIndex] = NULL;
  }
}
7
  • If I understand this correctly you do get a value in fields if the radio is checked? So if it is not required, what are you actually checking? Commented Feb 19, 2019 at 15:24
  • This field is not required in general but in some cases (like one of contact type AA) it is required. I checked contact type and I'd like to set error when this is my AA type.
    – Scardinius
    Commented Feb 19, 2019 at 15:30
  • I added code of my hook.
    – Scardinius
    Commented Feb 19, 2019 at 15:39
  • 1
    A workaround, which is not ideal but should work, is just use a different field name in the $errors array, one that does exist. It will visually hilite the wrong field, but your wording will say the right thing. Use contact_sub_type for example, since then the context here will still make sense.
    – Demerit
    Commented Feb 19, 2019 at 16:23
  • 1
    Another workaround is to make the field required all the time, but have one of the radio choices' text be "Not Required".
    – Demerit
    Commented Feb 19, 2019 at 18:36

1 Answer 1

1

Make the field required all the time. Add another choice to the radio called "Not Required". In your validate hook check if the contact subtype is AA and if they chose Not Required set the $errors variable on your radio field to show your error. Since you made it a required field it will be in the fields array.

For inline edit the formName is CRM_Contact_Form_Inline_CustomData and you will need to look up the contact subtype using the api, e.g. civicrm_api3('Contact', 'get'...). Use the contact id from $fields['cid']. (Go to /civicrm/api in your browser - it's very handy for getting the api syntax correct.)

Also note your custom field in edit mode will have a different name. It won't be custom_70-1 it will be custom_70-3838 or something like that, so you'll need to either look it up from $form first (e.g. in the groupTree element) or do something like loop through the $fields keys and compare substr($key, 0, 9) == 'custom_70'.

3
  • thank you for tips. Finally I found a workaround in civicrm-core
    – Scardinius
    Commented Feb 20, 2019 at 15:12
  • "Not Required" choice is not an option to me. I can't modify data structure.
    – Scardinius
    Commented Feb 20, 2019 at 15:16
  • Huh? You can not add an option value to your option group? That is weird :-) And certainly not a reason to change core code IMO Commented Feb 20, 2019 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.