Skip to content

Commit

Permalink
Merge pull request #1279 from tripal/1277-tripal_get_term_lookup_form…
Browse files Browse the repository at this point in the history
…_radios

Issue 1277 convert individual radio to radios
  • Loading branch information
laceysanderson committed Dec 2, 2022
2 parents 3a58f31 + 21210f5 commit cd77520
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 74 deletions.
117 changes: 69 additions & 48 deletions tripal/api/tripal.terms.api.inc
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,9 @@ function tripal_get_vocabularies() {
* The form (or $widget form).
* @param $form_state
* The form state.
* @param $default_name
* The name of a cv term to present as default selection, and optional
* cvterm_id appended using format "termname [id: 1234]".
* @param $title
* The title to give to the field set.
* @param $description
Expand Down Expand Up @@ -631,6 +634,15 @@ function tripal_get_term_lookup_form(&$form, &$form_state, $default_name = '',
$term_name = $form_state['input'][$field_name]['und'][$delta]['term_match' . $delta]['term_name' . $delta];
}

// More than one cv term may have identical names, so optionally allow specifying
// the cvterm_id using the same mechanism as the relationship field
// e.g. "termname" can be disambiguated by "termname [id: 1234]"
$type_id = NULL;
if ($term_name and preg_match('/(.*) \[id: (\d+)\]/', $term_name, $matches)) {
$term_name = $matches[1];
$type_id = $matches[2];
}

if (!$description) {
$description = t('Enter the name of the term that specifies the type. ' .
'The type must be the name of a term in a controlled vocabulary and ' .
Expand Down Expand Up @@ -679,11 +691,12 @@ function tripal_get_term_lookup_form(&$form, &$form_state, $default_name = '',
if ($term_name) {
$submit_disabled = TRUE;
$form['term_match' . $delta]['terms_list' . $delta] = [
'#type' => 'fieldset',
'#type' => 'radios',
'#title' => t('Matching Terms'),
'#description' => t('Please select the best matching term. If the
same term exists in multiple vocabularies you will see more than
one option below.'),
'#after_build' => ['tripal_get_term_lookup_form_options_descriptions'],
];
$match = [
'name' => $term_name,
Expand All @@ -692,35 +705,25 @@ function tripal_get_term_lookup_form(&$form, &$form_state, $default_name = '',
// tripal module.
$terms = chado_generate_var('cvterm', $match, ['return_array' => TRUE]);
$num_terms = 0;
$selected_term = '';
$term_element_name = NULL;

// Let the user select from any matching terms. Sometimes there may be
// more than one that match.
// more than one that matches.
$options = [];
$options_descriptions = [];
foreach ($terms as $term) {
// Save the user a click by setting the default value as 1 if there's
// only one matching term.
$checked = FALSE;
$attrs = [];
if ($num_terms == 0 and count($terms) == 1) {
$checked = TRUE;
$attrs = ['checked' => 'checked'];
}
$term_element_name = 'term-' . $term->cvterm_id . '-' . $delta;
$term = chado_expand_var($term, 'field', 'cv.definition');
$definition = property_exists($term, 'definition') ? $term->definition : '';
$form['term_match' . $delta]['terms_list' . $delta][$term_element_name] = [
'#type' => 'radio',
'#title' => $term->name,
'#default_value' => $checked,
'#attributes' => $attrs,
'#description' => '<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
'<br><b>Term ID: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '. ' .
'<br><b>Definition:</b> ' . $definition,
];

if (array_key_exists('values', $form_state) and array_key_exists($term_element_name, $form_state['values']) and
$form_state['values'][$term_element_name] == 1) {
$selected_term = $term;
$options[$term_element_name] = $term->name;
$options_descriptions[$term_element_name] =
'<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
'<br><b>Term ID: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '. ' .
'<br><b>Definition:</b> ' . $definition;

// If editing and a term was chosen previously, select that radio button as the default.
if ($type_id and $type_id == $term->cvterm_id) {
$form['term_match' . $delta]['terms_list' . $delta][$term_element_name]['#default_value'] = TRUE;
}
$num_terms++;
}
Expand All @@ -734,34 +737,31 @@ function tripal_get_term_lookup_form(&$form, &$form_state, $default_name = '',
// more than one that match.
foreach ($termsyn as $synonym) {
$term = $synonym->cvterm_id;
// Save the user a click by setting the default value as 1 if there's
// only one matching term.
$checked = FALSE;
$attrs = [];
if ($num_terms == 0 and count($terms) == 1) {
$checked = TRUE;
$attrs = ['checked' => 'checked'];
}
$term_element_name = 'term-' . $term->cvterm_id . '-' . $delta;
$definition = property_exists($term, 'definition') ? $term->definition : '';
$form['term_match' . $delta]['terms_list' . $delta][$term_element_name] = [
'#type' => 'checkbox',
'#title' => $term->name,
'#default_value' => $checked,
'#attributes' => $attrs,
'#description' => '<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
'<br><b>Term: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '. ' .
'<br><b>Definition:</b> ' . $definition .
'<br><b>Synonym:</b> ' . $synonym->synonym,
];

if (array_key_exists('values', $form_state) and array_key_exists($term_element_name, $form_state['values']) and
$form_state['values'][$term_element_name] == 1) {
$selected_term = $term;
$options[$term_element_name] = $term->name;
$options_descriptions[$term_element_name] =
'<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
'<br><b>Term ID: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '. ' .
'<br><b>Definition:</b> ' . $definition .
'<br><b>Synonym:</b> ' . $synonym->synonym;

// If editing and a term was chosen previously, select that radio button as the default.
if ($type_id and $type_id == $term->cvterm_id) {
$form['term_match' . $delta]['terms_list' . $delta][$term_element_name]['#default_value'] = TRUE;
}
$num_terms++;
}

// Add the options and their individual descriptions.
$form['term_match' . $delta]['terms_list' . $delta]['#options'] = $options;
$form['term_match' . $delta]['terms_list' . $delta]['#options_descriptions'] = $options_descriptions;

// Save the user a click by setting the default value if
// there is only one matching term among both terms and synonyms.
if ($num_terms == 1) {
$form['term_match' . $delta]['terms_list' . $delta][$term_element_name]['#default_value'] = TRUE;
}

if ($num_terms == 0) {
$form['term_match' . $delta]['terms_list' . $delta]['none' . $delta] = [
Expand All @@ -772,6 +772,27 @@ function tripal_get_term_lookup_form(&$form, &$form_state, $default_name = '',
}
}

/**
* Callback to add a #description to an individual radio in a 'radios' group.
*
* Starting with drupal 8 we can add descriptions to individual elements in a 'radios'
* form element, but for drupal 7 we need a callback to implement this.
*
* @return
* Updated form element.
*
* @ingroup tripal_terms_api
*
*/
function tripal_get_term_lookup_form_options_descriptions($element, &$form_state) {
foreach (element_children($element) as $key) {
if (array_key_exists('#options_descriptions', $element) and array_key_exists($key, $element['#options_descriptions'])) {
$element[$key]['#description'] = t('!description', ['!description' => $element['#options_descriptions'][$key]]);
}
}
return $element;
}

/**
* Returns the terms selected from the tripal_get_term_lookup_form.
*
Expand All @@ -796,7 +817,7 @@ function tripal_get_term_lookup_form_result($form, $form_state, $field_name = ''
if ($field_name) {
if (array_key_exists('term_match' . $delta, $form_state['values'][$field_name]['und'][$delta]) and
array_key_exists('terms_list' . $delta, $form_state['values'][$field_name]['und'][$delta]['term_match' . $delta])) {
$values = $form_state['values'][$field_name]['und'][$delta]['term_match' . $delta]['terms_list' . $delta];
$values[] = $form_state['values'][$field_name]['und'][$delta]['term_match' . $delta]['terms_list' . $delta];
}
}
else {
Expand All @@ -806,7 +827,7 @@ function tripal_get_term_lookup_form_result($form, $form_state, $field_name = ''
if (is_array($values)) {
foreach ($values as $key => $value) {
$matches = [];
if (preg_match("/^term-(\d+)-$delta$/", $key, $matches) and $values['term-' . $matches[1] . '-' . $delta]) {
if (preg_match("/^term-(\d+)-$delta$/", $value, $matches)) {
$cvterm_id = $matches[1];
$selected[] = chado_generate_var('cvterm', ['cvterm_id' => $cvterm_id]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class schema__additional_type_widget extends ChadoFieldWidget {
$default_name = '';
if ($type_id) {
$cvterm = chado_generate_var('cvterm', ['cvterm_id' => $type_id]);
$default_name = $cvterm->name;
$default_name = $cvterm->name . " [id: $type_id]";
}
tripal_get_term_lookup_form($widget, $form_state, $default_name,
$element['#title'], $element['#description'], $element['#required'],
Expand Down Expand Up @@ -144,4 +144,4 @@ class schema__additional_type_widget extends ChadoFieldWidget {
$form_state['values'][$field_name]['und'][$delta]['value'] = $type_id;
}
}
}
}
72 changes: 48 additions & 24 deletions tripal_chado/includes/tripal_chado.semweb.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2213,6 +2213,7 @@ function tripal_chado_semweb_form($form, &$form_state, $chado_table = NULL) {
// ->condition('table_name', $chado_table)
// ->execute()
// ->fetchField();
$cv_default = NULL;
$columns = $schema['fields'];
$headers = [
'Field Name',
Expand Down Expand Up @@ -2330,44 +2331,52 @@ function tripal_chado_semweb_edit_form($form, &$form_state, $table = NULL, $colu
];
if ($term_name) {
$form['terms_list'] = [
'#type' => 'fieldset',
'#type' => 'radios',
'#title' => t('Matching Terms'),
'#description' => t('Please select the term that best matches the
content type you want to create. If the same term exists in
multiple vocabularies you will see more than one option below.'),
'#after_build' => ['tripal_chado_semweb_edit_form_options_descriptions'],
];
$match = [
'name' => $term_name,
];
$terms = chado_generate_var('cvterm', $match, ['return_array' => TRUE]);
$terms = chado_expand_var($terms, 'field', 'cvterm.definition');
$num_terms = 0;
$options = [];
$options_descriptions = [];
$default_value = NULL;

foreach ($terms as $term) {
// Save the user a click by setting the default value as 1 if there's
// Save the user a click by setting the default value if there's
// only one matching term.
$default = FALSE;
$attrs = [];
if ($num_terms == 0 and count($terms) == 1) {
$default = TRUE;
$attrs = ['checked' => 'checked'];
$default_value = $num_terms;
}
$form['terms_list']['term-' . $term->cvterm_id] = [
'#type' => 'radio',
'#title' => $term->name,
'#default_value' => $default,
'#attributes' => $attrs,
'#description' => '<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
'<br><b>Term: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '. ' .
'<br><b>Definition:</b> ' . $term->definition,
];
$term_element_name = 'term-' . $term->cvterm_id;
$options[$term_element_name] = $term->name;
$options_descriptions[$term_element_name] =
'<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
'<br><b>Term: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '. ' .
'<br><b>Definition:</b> ' . $term->definition;
$num_terms++;
}

// Add the options and their individual descriptions, and set default value.
$form['terms_list']['#options'] = $options;
$form['terms_list']['#options_descriptions'] = $options_descriptions;
if (!is_null($default_value)) {
$form['terms_list']['#default_value'] = $default_value;
}

if ($num_terms == 0) {
$form['terms_list']['none'] = [
'#type' => 'item',
'#markup' => '<i>' . t('There is no term that matches the entered text.') . '</i>',
];
}

// Add in the button for the cases of no terms or too many.
$form['submit_button'] = [
'#type' => 'submit',
Expand All @@ -2389,6 +2398,27 @@ function tripal_chado_semweb_edit_form($form, &$form_state, $table = NULL, $colu
return $form;
}

/**
* Callback to add a #description to an individual radio in a 'radios' group.
*
* Starting with drupal 8 we can add descriptions to individual elements in a 'radios'
* form element, but for drupal 7 we need a callback to implement this.
*
* @return
* Updated form element.
*
* @ingroup tripal_terms_api
*
*/
function tripal_chado_semweb_edit_form_options_descriptions($element, &$form_state) {
foreach (element_children($element) as $key) {
if (array_key_exists('#options_descriptions', $element) and array_key_exists($key, $element['#options_descriptions'])) {
$element[$key]['#description'] = t('!description', ['!description' => $element['#options_descriptions'][$key]]);
}
}
return $element;
}


/**
* Implements hook_form_validate()
Expand All @@ -2406,22 +2436,16 @@ function tripal_chado_semweb_edit_form_validate($form, &$form_state) {
$num_selected = 0;
foreach ($form_state['values'] as $key => $value) {
$matches = [];
if (preg_match("/^term-(\d+)$/", $key, $matches) and
$form_state['values']['term-' . $matches[1]]) {
if (preg_match("/^term-(\d+)$/", $value, $matches)) {
$cvterm_id = $matches[1];
$num_selected++;
}
}
if ($num_selected == 0) {
form_set_error('', 'Please select at least one term.');
form_set_error('', 'Please select a term.');
}
else {
if ($num_selected > 1) {
form_set_error('term-' . $cvterm_id, 'Please select only one term from the list below.');
}
else {
$form_state['values']['#selected_cvterm_id'] = $cvterm_id;
}
$form_state['values']['#selected_cvterm_id'] = $cvterm_id;
}
}
else {
Expand Down

0 comments on commit cd77520

Please sign in to comment.