From a2eb61520b685cf139a829d65015b2579caed27d Mon Sep 17 00:00:00 2001 From: Andrew Hunt Date: Mon, 14 Sep 2020 14:38:27 -0400 Subject: [PATCH] Select placeholders should always say what kind of thing they select --- CRM/ACL/Form/ACL.php | 13 ++--- CRM/ACL/Form/EntityRole.php | 3 +- CRM/Activity/BAO/Query.php | 2 +- CRM/Activity/Form/Activity.php | 6 ++- CRM/Contribute/Form/ManagePremiums.php | 11 ++-- CRM/Core/BAO/CustomField.php | 10 ++-- CRM/Core/BAO/UFGroup.php | 71 ++++++++++---------------- CRM/Core/Form.php | 47 +++++++++++++---- CRM/SMS/Form/Provider.php | 2 +- 9 files changed, 89 insertions(+), 76 deletions(-) diff --git a/CRM/ACL/Form/ACL.php b/CRM/ACL/Form/ACL.php index de1665dcd4..1c7af2a095 100644 --- a/CRM/ACL/Form/ACL.php +++ b/CRM/ACL/Form/ACL.php @@ -96,11 +96,12 @@ class CRM_ACL_Form_ACL extends CRM_Admin_Form { $this->add('text', 'name', ts('Description'), CRM_Core_DAO::getAttribute('CRM_ACL_DAO_ACL', 'name'), TRUE); - $operations = ['' => ts('- select -')] + CRM_ACL_BAO_ACL::operation(); $this->add('select', 'operation', ts('Operation'), - $operations, TRUE + CRM_ACL_BAO_ACL::operation(), + TRUE, + ['placeholder' => TRUE] ); $objTypes = [ @@ -129,22 +130,22 @@ class CRM_ACL_Form_ACL extends CRM_Admin_Form { $this->add('select', 'entity_id', $label, $role, TRUE); $group = [ - '-1' => ts('- select -'), + '-1' => ts('- select group -'), '0' => ts('All Groups'), ] + CRM_Core_PseudoConstant::group(); $customGroup = [ - '-1' => ts('- select -'), + '-1' => ts('- select set of custom fields -'), '0' => ts('All Custom Groups'), ] + CRM_Core_PseudoConstant::get('CRM_Core_DAO_CustomField', 'custom_group_id'); $ufGroup = [ - '-1' => ts('- select -'), + '-1' => ts('- select profile -'), '0' => ts('All Profiles'), ] + CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id'); $event = [ - '-1' => ts('- select -'), + '-1' => ts('- select event -'), '0' => ts('All Events'), ] + CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )"); diff --git a/CRM/ACL/Form/EntityRole.php b/CRM/ACL/Form/EntityRole.php index d12686fe43..7d599deff4 100644 --- a/CRM/ACL/Form/EntityRole.php +++ b/CRM/ACL/Form/EntityRole.php @@ -26,9 +26,8 @@ class CRM_ACL_Form_EntityRole extends CRM_Admin_Form { return; } - $aclRoles = ['' => ts('- select -')] + CRM_Core_OptionGroup::values('acl_role'); $this->add('select', 'acl_role_id', ts('ACL Role'), - $aclRoles, TRUE + CRM_Core_OptionGroup::values('acl_role'), TRUE, ['placeholder' => TRUE] ); $label = ts('Assigned to'); diff --git a/CRM/Activity/BAO/Query.php b/CRM/Activity/BAO/Query.php index d432467e8d..0aa2df666a 100644 --- a/CRM/Activity/BAO/Query.php +++ b/CRM/Activity/BAO/Query.php @@ -478,7 +478,7 @@ class CRM_Activity_BAO_Query { 'multiple' => 'multiple', 'class' => 'crm-select2', - 'placeholder' => ts('- select -'), + 'placeholder' => ts('- select tags -'), ] ); } diff --git a/CRM/Activity/Form/Activity.php b/CRM/Activity/Form/Activity.php index 4d457aafda..c6b07c4a39 100644 --- a/CRM/Activity/Form/Activity.php +++ b/CRM/Activity/Form/Activity.php @@ -628,10 +628,11 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task { $this->assign('suppressForm', FALSE); $element = $this->add('select', 'activity_type_id', ts('Activity Type'), - ['' => '- ' . ts('select') . ' -'] + $this->_fields['followup_activity_type_id']['attributes'], + $this->_fields['followup_activity_type_id']['attributes'], FALSE, [ 'onchange' => "CRM.buildCustomData( 'Activity', this.value, false, false, false, false, false, false, {$this->_currentlyViewedContactId});", 'class' => 'crm-select2 required', + 'placeholder' => TRUE, ] ); @@ -695,7 +696,8 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task { $responseOptions = CRM_Campaign_BAO_Survey::getResponsesOptions($surveyId); if ($responseOptions) { $this->add('select', 'result', ts('Result'), - ['' => ts('- select -')] + array_combine($responseOptions, $responseOptions) + array_combine($responseOptions, $responseOptions), + FALSE, ['placeholder' => TRUE] ); } $surveyTitle = NULL; diff --git a/CRM/Contribute/Form/ManagePremiums.php b/CRM/Contribute/Form/ManagePremiums.php index 3a4a97e0ec..85b8ad03c9 100644 --- a/CRM/Contribute/Form/ManagePremiums.php +++ b/CRM/Contribute/Form/ManagePremiums.php @@ -108,18 +108,17 @@ class CRM_Contribute_Form_ManagePremiums extends CRM_Contribute_Form { $this->add('textarea', 'options', ts('Options'), ['cols' => 60, 'rows' => 3]); $this->add('select', 'period_type', ts('Period Type'), [ - '' => '- select -', 'rolling' => 'Rolling', 'fixed' => 'Fixed', - ]); + ], FALSE, ['placeholder' => TRUE]); $this->add('text', 'fixed_period_start_day', ts('Fixed Period Start Day'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'fixed_period_start_day')); - $this->add('Select', 'duration_unit', ts('Duration Unit'), ['' => '- select period -'] + CRM_Core_SelectValues::getPremiumUnits()); + $this->add('Select', 'duration_unit', ts('Duration Unit'), CRM_Core_SelectValues::getPremiumUnits(), FALSE, ['placeholder' => ts('- select period -')]); $this->add('text', 'duration_interval', ts('Duration'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'duration_interval')); - $this->add('Select', 'frequency_unit', ts('Frequency Unit'), ['' => '- select period -'] + CRM_Core_SelectValues::getPremiumUnits()); + $this->add('Select', 'frequency_unit', ts('Frequency Unit'), CRM_Core_SelectValues::getPremiumUnits(), FALSE, ['placeholder' => ts('- select period -')]); $this->add('text', 'frequency_interval', ts('Frequency'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'frequency_interval')); @@ -157,7 +156,9 @@ class CRM_Contribute_Form_ManagePremiums extends CRM_Contribute_Form { 'select', 'financial_type_id', ts('Financial Type'), - ['' => ts('- select -')] + $financialType + $financialType, + FALSE, + ['placeholder' => TRUE] ); $this->add('checkbox', 'is_active', ts('Enabled?')); diff --git a/CRM/Core/BAO/CustomField.php b/CRM/Core/BAO/CustomField.php index 030c88b17c..a8614578e2 100644 --- a/CRM/Core/BAO/CustomField.php +++ b/CRM/Core/BAO/CustomField.php @@ -667,6 +667,10 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { $element = NULL; $customFieldAttributes = []; + if (!isset($label)) { + $label = $field->label; + } + // DAO stores attributes as a string, but it's hard to manipulate and // CRM_Core_Form::add() wants them as an array. $fieldAttributes = self::attributesFromString($field->attributes); @@ -680,7 +684,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { $widget = 'Text'; } - $placeholder = $search ? ts('- any -') : ($useRequired ? ts('- select -') : ts('- none -')); + $placeholder = $search ? ts('- any %1 -', [1 => $label]) : ts('- select %1 -', [1 => $label]); if (in_array($widget, [ 'Select', @@ -715,10 +719,6 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { $rangeDataTypes = ['Int', 'Float', 'Money']; - if (!isset($label)) { - $label = $field->label; - } - // at some point in time we might want to split the below into small functions switch ($widget) { diff --git a/CRM/Core/BAO/UFGroup.php b/CRM/Core/BAO/UFGroup.php index 88d84f04af..543560b969 100644 --- a/CRM/Core/BAO/UFGroup.php +++ b/CRM/Core/BAO/UFGroup.php @@ -1869,7 +1869,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } } elseif (substr($fieldName, 0, 7) === 'country') { - $form->add('select', $name, $title, ['' => ts('- select -')] + CRM_Core_PseudoConstant::country(), $required, $selectAttributes); + $form->add('select', $name, $title, CRM_Core_PseudoConstant::country(), $required, $selectAttributes); $config = CRM_Core_Config::singleton(); if (!in_array($mode, [CRM_Profile_Form::MODE_EDIT, CRM_Profile_Form::MODE_SEARCH]) && $config->defaultContactCountry @@ -1895,16 +1895,12 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) $providerName = substr($name, 0, -1) . '-provider_id]'; } $form->add('select', $providerName, NULL, - [ - '' => ts('- select -'), - ] + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required ); } else { $form->add('select', $name . '-provider_id', $title, - [ - '' => ts('- select -'), - ] + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required ); } @@ -1916,7 +1912,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) elseif (CRM_Utils_Array::value('name', $field) == 'membership_type') { list($orgInfo, $types) = CRM_Member_BAO_MembershipType::getMembershipTypeInfo(); $sel = &$form->addElement('hierselect', $name, $title); - $select = ['' => ts('- select -')]; + $select = ['' => ts('- select membership type -')]; if (count($orgInfo) == 1 && $field['is_required']) { // we only have one org - so we should default to it. Not sure about defaulting to first type // as it could be missed - so adding a select @@ -1932,9 +1928,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } elseif (CRM_Utils_Array::value('name', $field) == 'membership_status') { $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label'), $required + CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label'), $required ); } elseif (in_array($fieldName, ['gender_id', 'communication_style_id'])) { @@ -1999,7 +1993,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) 'contact_type' => $profileType, 'greeting_type' => $fieldName, ]; - $form->add('select', $name, $title, ['' => ts('- select -')] + CRM_Core_PseudoConstant::greeting($greeting), $required); + $form->add('select', $name, $title, CRM_Core_PseudoConstant::greeting($greeting), $required, ['placeholder' => TRUE]); // add custom greeting element $form->add('text', $fieldName . '_custom', ts('Custom %1', [1 => ucwords(str_replace('_', ' ', $fieldName))]), NULL, FALSE @@ -2019,7 +2013,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) $form->add('select', $name, $title, CRM_Core_SelectValues::pmf()); } elseif ($fieldName === 'preferred_language') { - $form->add('select', $name, $title, ['' => ts('- select -')] + CRM_Contact_BAO_Contact::buildOptions('preferred_language'), $required); + $form->add('select', $name, $title, CRM_Contact_BAO_Contact::buildOptions('preferred_language'), $required, ['placeholder' => TRUE]); } elseif ($fieldName == 'external_identifier') { $form->add('text', $name, $title, $attributes, $required); @@ -2078,35 +2072,29 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) elseif ($fieldName === 'product_name') { list($products, $options) = CRM_Contribute_BAO_Premium::getPremiumProductInfo(); $sel = &$form->addElement('hierselect', $name, $title); - $products = ['0' => ts('- select -')] + $products; + $products = ['0' => ts('- select %1 -', [1 => $title])] + $products; $sel->setOptions([$products, $options]); } elseif ($fieldName === 'payment_instrument') { $form->add('select', $name, $title, - ['' => ts('- select -')] + CRM_Contribute_PseudoConstant::paymentInstrument(), $required); + CRM_Contribute_PseudoConstant::paymentInstrument(), $required, ['placeholder' => TRUE]); } elseif ($fieldName === 'financial_type') { $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Contribute_PseudoConstant::financialType(), $required + CRM_Contribute_PseudoConstant::financialType(), $required, ['placeholder' => TRUE] ); } elseif ($fieldName === 'contribution_status_id') { $contributionStatuses = CRM_Contribute_BAO_Contribution_Utils::getContributionStatuses(); $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + $contributionStatuses, $required + $contributionStatuses, $required, ['placeholder' => TRUE] ); } elseif ($fieldName === 'soft_credit_type') { $name = "soft_credit_type[$rowNumber]"; $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Core_OptionGroup::values("soft_credit_type") + CRM_Core_OptionGroup::values("soft_credit_type"), ['placeholder' => TRUE] ); //CRM-15350: choose SCT field default value as 'Gift' for membership use //else (for contribution), use configured SCT default value @@ -2124,23 +2112,20 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } elseif ($fieldName == 'contribution_page_id') { $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Contribute_PseudoConstant::contributionPage(), $required, 'class="big"' + CRM_Contribute_PseudoConstant::contributionPage(), $required, [ + 'class' => 'big', + 'placeholder' => TRUE, + ] ); } elseif ($fieldName == 'activity_status_id') { $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Core_PseudoConstant::activityStatus(), $required + CRM_Core_PseudoConstant::activityStatus(), $required, ['placeholder' => TRUE] ); } elseif ($fieldName == 'activity_engagement_level') { $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Campaign_PseudoConstant::engagementLevel(), $required + CRM_Campaign_PseudoConstant::engagementLevel(), $required, ['placeholder' => TRUE] ); } elseif ($fieldName == 'participant_status') { @@ -2149,9 +2134,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) $cond = 'visibility_id = 1'; } $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Event_PseudoConstant::participantStatus(NULL, $cond, 'label'), $required + CRM_Event_PseudoConstant::participantStatus(NULL, $cond, 'label'), $required, ['placeholder' => TRUE] ); } elseif ($fieldName == 'participant_role') { @@ -2160,9 +2143,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } else { $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Event_PseudoConstant::participantRole(), $required + CRM_Event_PseudoConstant::participantRole(), $required, ['placeholder' => TRUE] ); } } @@ -2181,9 +2162,11 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) $form->_componentCampaigns )); $form->add('select', $name, $title, + $campaigns, $required, [ - '' => ts('- select -'), - ] + $campaigns, $required, 'class="crm-select2 big"' + 'class' => 'crm-select2 big', + 'placeholder' => TRUE, + ] ); } } @@ -2196,10 +2179,8 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } elseif ($fieldName == 'case_status') { $form->add('select', $name, $title, - [ - '' => ts('- select -'), - ] + CRM_Case_BAO_Case::buildOptions('case_status_id', 'create'), - $required + CRM_Case_BAO_Case::buildOptions('case_status_id', 'create'), + $required, ['placeholder' => TRUE] ); } else { diff --git a/CRM/Core/Form.php b/CRM/Core/Form.php index f15287eee9..2cd2c226b5 100644 --- a/CRM/Core/Form.php +++ b/CRM/Core/Form.php @@ -436,7 +436,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { // Add placeholder option for select if (isset($extra['placeholder'])) { if ($extra['placeholder'] === TRUE) { - $extra['placeholder'] = $required ? ts('- select -') : ts('- none -'); + $extra['placeholder'] = ts('- select %1 -', [1 => $label]); } if (($extra['placeholder'] || $extra['placeholder'] === '') && empty($extra['multiple']) && is_array($attributes) && !isset($attributes[''])) { $attributes = ['' => $extra['placeholder']] + $attributes; @@ -1498,8 +1498,8 @@ class CRM_Core_Form extends HTML_QuickForm_Page { $info = civicrm_api3($props['entity'], 'getoptions', $props); $options = $info['values']; } - if (!array_key_exists('placeholder', $props)) { - $props['placeholder'] = $required ? ts('- select -') : (CRM_Utils_Array::value('context', $props) == 'search' ? ts('- any -') : ts('- none -')); + if (!array_key_exists('placeholder', $props) && $placeholder = self::selectOrAnyPlaceholder($props, $required)) { + $props['placeholder'] = $placeholder; } // Handle custom field if (strpos($name, 'custom_') === 0 && is_numeric($name[7])) { @@ -1534,6 +1534,34 @@ class CRM_Core_Form extends HTML_QuickForm_Page { return $this->add('select', $name, $label, $options, $required, $props); } + /** + * Handles a repeated bit supplying a placeholder for entity selection + * + * @param string $props + * The field properties, including the entity and context. + * @param bool $required + * If the field is required. + * @return string + * The placeholder text. + */ + private static function selectOrAnyPlaceholder($props, $required) { + if (empty($props['entity'])) { + return NULL; + } + $daoToClass = CRM_Core_DAO_AllCoreTables::daoToClass(); + if (array_key_exists($props['entity'], $daoToClass)) { + $daoClass = $daoToClass[$props['entity']]; + $tsPlaceholder = $daoClass::getEntityTitle(); + } + else { + $tsPlaceholder = ts('option'); + } + if (($props['context'] ?? '') == 'search' && !$required) { + return ts('- any %1 -', [1 => $tsPlaceholder]); + } + return ts('- select %1 -', [1 => $tsPlaceholder]); + } + /** * Adds a field based on metadata. * @@ -1690,8 +1718,8 @@ class CRM_Core_Form extends HTML_QuickForm_Page { case 'Select': case 'Select2': $props['class'] = CRM_Utils_Array::value('class', $props, 'big') . ' crm-select2'; - if (!array_key_exists('placeholder', $props)) { - $props['placeholder'] = $required ? ts('- select -') : ($context == 'search' ? ts('- any -') : ts('- none -')); + if (!array_key_exists('placeholder', $props) && $placeholder = self::selectOrAnyPlaceholder($props, $required)) { + $props['placeholder'] = $placeholder; } // TODO: Add and/or option for fields that store multiple values return $this->add(strtolower($widget), $name, $label, $options, $required, $props); @@ -2061,14 +2089,14 @@ class CRM_Core_Form extends HTML_QuickForm_Page { public function addEntityRef($name, $label = '', $props = [], $required = FALSE) { // Default properties $props['api'] = CRM_Utils_Array::value('api', $props, []); - $props['entity'] = CRM_Core_DAO_AllCoreTables::convertEntityNameToCamel(CRM_Utils_Array::value('entity', $props, 'Contact')); + $props['entity'] = CRM_Core_DAO_AllCoreTables::convertEntityNameToCamel($props['entity'] ?? 'Contact'); $props['class'] = ltrim(($props['class'] ?? '') . ' crm-form-entityref'); if (array_key_exists('create', $props) && empty($props['create'])) { unset($props['create']); } - $props['placeholder'] = CRM_Utils_Array::value('placeholder', $props, $required ? ts('- select %1 -', [1 => ts(str_replace('_', ' ', $props['entity']))]) : ts('- none -')); + $props['placeholder'] = $props['placeholder'] ?? self::selectOrAnyPlaceholder($props, $required); $defaults = []; if (!empty($props['multiple'])) { @@ -2400,6 +2428,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * @return HTML_QuickForm_Element */ public function addChainSelect($elementName, $settings = []) { + $label = strpos($elementName, 'rovince') ? CRM_Core_DAO_StateProvince::getEntityTitle() : CRM_Core_DAO_County::getEntityTitle(); $props = $settings += [ 'control_field' => str_replace(['state_province', 'StateProvince', 'county', 'County'], [ 'country', @@ -2408,12 +2437,12 @@ class CRM_Core_Form extends HTML_QuickForm_Page { 'StateProvince', ], $elementName), 'data-callback' => strpos($elementName, 'rovince') ? 'civicrm/ajax/jqState' : 'civicrm/ajax/jqCounty', - 'label' => strpos($elementName, 'rovince') ? ts('State/Province') : ts('County'), + 'label' => $label, 'data-empty-prompt' => strpos($elementName, 'rovince') ? ts('Choose country first') : ts('Choose state first'), 'data-none-prompt' => ts('- N/A -'), 'multiple' => FALSE, 'required' => FALSE, - 'placeholder' => empty($settings['required']) ? ts('- none -') : ts('- select -'), + 'placeholder' => ts('- select %1 -', [1 => $label]), ]; CRM_Utils_Array::remove($props, 'label', 'required', 'control_field', 'context'); $props['class'] = (empty($props['class']) ? '' : "{$props['class']} ") . 'crm-select2'; diff --git a/CRM/SMS/Form/Provider.php b/CRM/SMS/Form/Provider.php index c78f55fcd4..a9daf14057 100644 --- a/CRM/SMS/Form/Provider.php +++ b/CRM/SMS/Form/Provider.php @@ -70,7 +70,7 @@ class CRM_SMS_Form_Provider extends CRM_Core_Form { $providerNames = CRM_Core_OptionGroup::values('sms_provider_name', FALSE, FALSE, FALSE, NULL, 'label'); $apiTypes = CRM_Core_OptionGroup::values('sms_api_type', FALSE, FALSE, FALSE, NULL, 'label'); - $this->add('select', 'name', ts('Name'), ['' => '- select -'] + $providerNames, TRUE); + $this->add('select', 'name', ts('Name'), $providerNames, TRUE, ['placeholder' => TRUE]); $this->add('text', 'title', ts('Title'), $attributes['title'], TRUE -- 2.25.1