diff --git a/docs/user_guide/example_genomics/genomes_genes.5.png b/docs/user_guide/example_genomics/genomes_genes.5.png index c84246f6e..535df4c15 100644 Binary files a/docs/user_guide/example_genomics/genomes_genes.5.png and b/docs/user_guide/example_genomics/genomes_genes.5.png differ diff --git a/docs/user_guide/example_genomics/genomes_genes.6.png b/docs/user_guide/example_genomics/genomes_genes.6.png new file mode 100644 index 000000000..04ea4cec7 Binary files /dev/null and b/docs/user_guide/example_genomics/genomes_genes.6.png differ diff --git a/docs/user_guide/example_genomics/genomes_genes.7.png b/docs/user_guide/example_genomics/genomes_genes.7.png new file mode 100644 index 000000000..ef9a2cbc7 Binary files /dev/null and b/docs/user_guide/example_genomics/genomes_genes.7.png differ diff --git a/docs/user_guide/example_genomics/genomes_genes.8.png b/docs/user_guide/example_genomics/genomes_genes.8.png new file mode 100644 index 000000000..bee518040 Binary files /dev/null and b/docs/user_guide/example_genomics/genomes_genes.8.png differ diff --git a/docs/user_guide/example_genomics/genomes_genes.9.png b/docs/user_guide/example_genomics/genomes_genes.9.png new file mode 100644 index 000000000..8ba0cace1 Binary files /dev/null and b/docs/user_guide/example_genomics/genomes_genes.9.png differ diff --git a/docs/user_guide/example_genomics/genomes_genes.rst b/docs/user_guide/example_genomics/genomes_genes.rst index 2494d45dd..8d325bd80 100644 --- a/docs/user_guide/example_genomics/genomes_genes.rst +++ b/docs/user_guide/example_genomics/genomes_genes.rst @@ -191,7 +191,7 @@ Now the scaffold sequence and mRNA sequences are loaded! It is not required to load the mRNA sequences as those can be derived from their alignments with the scaffold sequence. However, in Chado the **feature** table has a **residues** column. Therefore, it is best practice to load the sequence when possible. Creating Gene Pages ----------------------- +------------------- Now that we've loaded our feature data, we must publish them. This is different than when we manually created our Organism and Analysis pages. Using the GFF and FASTA loaders we imported our data into Chado, but currently there are no published pages for this data that we loaded. To publish these genomic features, navigating to Structure → Tripal Content Types and click the link titled Publish Chado Content. The following page appears: .. image:: genomes_genes.3.png @@ -252,3 +252,29 @@ Next find an mRNA page to view. Remember when we loaded our FASTA file for mRNA - We associated the Phytozome accession with the features using a regular expression when importing the FASTA file. All data that appears on the page is derived from the GFF file and the FASTA files we loaded. + + +Customizing Transcripts on Gene Pages +------------------------------------- +By default the gene pages provided by Tripal will have a link in the sidebar table of contents named **Transcripts** and when clicked a table appears that lists all of the transcripts (or mRNA) that belong to the gene. The user can click to view more information about each published transcript. + +.. image:: genomes_genes.6.png + +Sometimes however, more than just a listing of transcripts is desired on a gene page. You can customize the information that is presented about each transcript by navigating to the gene content type at **Structure → Tripal Content Types** and clicking **mange fields** in the **Gene** row. This page allows you to customize the way fields are displayed on the gene page. Scroll down the page to the **Transcript** row and click the **edit** button. The following page should appear. + +.. image:: genomes_genes.7.png + +Open the field set titled **Transcript (mRNA) Field Selection** to view a table that lists all of the available fields for a transcript. + +.. image:: genomes_genes.8.png + +On this page you can check the boxes next to the field that you want to show for a transcript on the gene page. For this example, we will select the fields **Name**, **Identifier**, **Resource Type**, **Anotations**, and **Sequences** (they may not be in this order on your own site). You can control the order in which fields will be shown by dragging them using the crosshairs icon next to each one. Scroll to the bottom of the page and click the **Save Settings** button. + +Next return to the gene page, reload it, and click on the **Transcripts** link. Now you are provided a select box with the transcript names. When a transcript is selected, the pane below will populate with the fields that you selected when editing in the Transcript field. + +.. image:: genomes_genes.9.png + +You can return to the Transcript field edit page under the Gene content type at any time to add, remove or change the order of fields that appear for the transcript. + +.. note:: + Transcripts on a gene page can only be customized if all of them are published. If not, the default table listing is shown. diff --git a/tripal/includes/TripalFields/TripalField.inc b/tripal/includes/TripalFields/TripalField.inc index e6c8f5315..8fa45a152 100755 --- a/tripal/includes/TripalFields/TripalField.inc +++ b/tripal/includes/TripalFields/TripalField.inc @@ -633,9 +633,16 @@ class TripalField { } /** + * Validates the instance settings form. + * + * Remember if you used the 'themeable' option for form elements you + * must copy the values correctly. See the description in hte + * `instanceSettingsForm()` function for details. * * @param $form + * The form object. * @param $form_state + * The form_state object. */ public function settingsFormValidate($form, &$form_state) { @@ -656,6 +663,17 @@ class TripalField { * $element = parent::instanceSettingsForm(); * @endcode * + * Additinally, theming of the instance setting form is not supported by + * Drupal, but Tripal will allow you to theme form elements if you + * place them in the $element['themeable'] variable. However, if you place + * form elements there you must set corresponding form elements of type + * 'value' at the base level of the element array and copy appropriate + * settings values from the + * $form_state['values']['instance']['settings']['themeable'] variable into + * the + * $form_state['values']['instance']['settings'] variable. Do this in the + * `instanceSettingsFormValidate()` function. + * * Please note, the form generated with this function does not easily * support AJAX calls in the same way that other Drupal forms do. If you * need to use AJAX you must manually alter the $form in your ajax call. @@ -668,10 +686,47 @@ class TripalField { $element['#field'] = $this->field; $element['#instance'] = $this->instance; + $element['themeable'] = []; + $element['themeable']['#field'] = $this->field; + $element['themeable']['#instance'] = $this->instance; + $element['themeable']['#theme'] = 'tripal_field_settings_default'; $element['#element_validate'][] = 'tripal_field_instance_settings_form_validate'; return $element; } + /** + * The theme function for the instance settings form. + * + * @param $element + * A form element array containing basic properties for the widget: + * - #entity_type: The name of the entity the field is attached to. + * - #bundle: The name of the field bundle the field is contained in. + * - #field_name: The name of the field. + * - #language: The language the field is being edited in. + * - #field_parents: The 'parents' space for the field in the form. Most + * widgets can simply overlook this property. This identifies the location + * where the field values are placed within $form_state['values'], and is + * used to access processing information for the field through the + * field_form_get_state() and field_form_set_state() functions. + * - #columns: A list of field storage columns of the field. + * - #title: The sanitized element label for the field instance, ready for + * output. + * - #description: The sanitized element description for the field instance, + * ready for output. + * - #required: A Boolean indicating whether the element value is required; + * for required multiple value fields, only the first widget's values are + * required. + * - #delta: The order of this item in the array of subelements; see + * $delta above + * + * @return + * A drupal renderable array or HTML or an empty string if no + * theming is to be applied. + */ + public function settingsTheme($element) { + + } + /** * Provides validation of the instance settings form. * diff --git a/tripal/includes/tripal.fields.inc b/tripal/includes/tripal.fields.inc index ab8a2aa7f..7f48c69b9 100644 --- a/tripal/includes/tripal.fields.inc +++ b/tripal/includes/tripal.fields.inc @@ -445,7 +445,8 @@ function tripal_field_instance_settings_form($field, $instance) { $field_class = $field['type']; if (tripal_load_include_field_class($field_class)) { $field = new $field_class($field, $instance); - return $field->instanceSettingsForm(); + $form = $field->instanceSettingsForm(); + return $form; } } @@ -827,7 +828,6 @@ function tripal_field_formatter_settings_form($field, $instance, $formatter = new $formatter_class($field, $instance); $elements = $formatter->settingsForm($view_mode, $form, $form_state); } - return $elements; } @@ -928,6 +928,7 @@ function tripal_form_field_ui_display_overview_form_alter(&$form, &$form_state, * @param $variables */ function theme_tripal_field_default($variables) { + $element = $variables['element']; $field = $element['#field']; $instance = $element['#instance']; @@ -940,3 +941,21 @@ function theme_tripal_field_default($variables) { return $widget->theme($element); } } + +/** + * Theme function for all TripalFieldWidget objects. + * + * @param $variables + */ +function theme_tripal_field_settings_default($variables) { + + $element = $variables['element']; + $field = $element['#field']; + $instance = $element['#instance']; + $field_class = $element['#field']['field_name']; + tripal_load_include_field_class($field_class); + if (class_exists($field_class)) { + $field = new $field_class($field, $instance); + return $field->settingsTheme($element); + } +} diff --git a/tripal/tripal.module b/tripal/tripal.module index 1b4b29186..ccf191d98 100755 --- a/tripal/tripal.module +++ b/tripal/tripal.module @@ -817,6 +817,11 @@ function tripal_theme($existing, $type, $theme, $path) { 'render element' => 'element', 'file' => 'includes/tripal.fields.inc', ), + // Theming for all field settings forms. + 'tripal_field_settings_default' => array( + 'render element' => 'element', + 'file' => 'includes/tripal.fields.inc', + ), // Themed forms 'tripal_views_handler_area_collections_fields_fset' => array( 'render element' => 'form', @@ -1657,7 +1662,7 @@ function tripal_job_describe_args($callback, $args) { /** * Returns the current version of Tripal, according to the tripal.info file - * + * * @return string * The version string of Tripal. Ex. 7.x-3.1 */ diff --git a/tripal_chado/includes/TripalFields/ChadoField.inc b/tripal_chado/includes/TripalFields/ChadoField.inc index ef0b86455..168d08fad 100755 --- a/tripal_chado/includes/TripalFields/ChadoField.inc +++ b/tripal_chado/includes/TripalFields/ChadoField.inc @@ -323,6 +323,8 @@ class ChadoField extends TripalField { * @see TripalField::instanceSettingsForm() */ public function instanceSettingsForm() { + $element = parent::instanceSettingsForm(); + // Make sure we don't lose our Chado table mappings when the settings // are updated. Setting them as values in the form ensures they don't // get accidentally overwritten. diff --git a/tripal_chado/includes/TripalFields/data__accession/data__accession_widget.inc b/tripal_chado/includes/TripalFields/data__accession/data__accession_widget.inc index 592fae222..015a1a462 100755 --- a/tripal_chado/includes/TripalFields/data__accession/data__accession_widget.inc +++ b/tripal_chado/includes/TripalFields/data__accession/data__accession_widget.inc @@ -178,7 +178,7 @@ class data__accession_widget extends ChadoFieldWidget { $fieldset = [ '#title' => $element['#title'], '#value' => '', - '#description' => $element['#description'], + '#description' => $element['#description'], '#children' => $layout, ]; diff --git a/tripal_chado/includes/TripalFields/so__transcript/so__transcript.inc b/tripal_chado/includes/TripalFields/so__transcript/so__transcript.inc index 8dfac1a4d..b47f836a6 100755 --- a/tripal_chado/includes/TripalFields/so__transcript/so__transcript.inc +++ b/tripal_chado/includes/TripalFields/so__transcript/so__transcript.inc @@ -35,6 +35,10 @@ class so__transcript extends ChadoField { // type. This will create form elements when editing the field instance // to allow the site admin to change the term settings above. 'term_fixed' => FALSE, + // Contains the list of fields on the transcript child that the + // user wants to have displayed for the transcript. The + // `so__transcript_expanded_formatter will display these. + 'transcript_fields' => [] ]; // The default widget for this field. @@ -183,4 +187,169 @@ class so__transcript extends ChadoField { } } -} \ No newline at end of file + /** + * @see TripalField::globalSettingsForm() + */ + public function instanceSettingsForm() { + $element = parent::instanceSettingsForm(); + + $settings = $this->instance['settings']; + + + $element['transcript_fields'] = [ + '#type' => 'value', + '#default_value' => $settings['transcript_fields'], + ]; + + // Get the content type for the mRNA term (SO:0000234) and it's feilds. + // If it isn't published then don't show the form below. + $bundle = tripal_load_bundle_entity(['accession' => 'SO:0000234']); + if (!$bundle) { + return $element; + } + + $fields = field_info_instances('TripalEntity', $bundle->name); + + foreach ($fields as $field_name => $details) { + + $defaults = []; + if (array_key_exists($field_name, $settings['transcript_fields'])) { + $defaults = $settings['transcript_fields'][$field_name]; + } + + $weight = array_key_exists('weight', $defaults) ? $defaults['weight'] : $details['display']['default']['weight']; + $checked = array_key_exists('show', $defaults) ? $defaults['show'] : 0; + $element['themeable']['field-'. $weight] = [ + '#type' => 'value', + '#value' => $field_name, + '#weight' => $weight, + ]; + $element['themeable']['field-'. $weight . '-check'] = [ + '#type' => 'checkbox', + '#weight' => $weight, + '#default_value' => $checked, + ]; + $element['themeable']['field-'. $weight . '-label'] = [ + '#type' => 'markup', + '#markup' => t($details['label']), + '#weight' => $weight, + ]; + $element['themeable']['field-'. $weight . '-description'] = [ + '#type' => 'markup', + '#markup' => t($details['description']), + '#weight' => $weight, + ]; + $element['themeable']['field-'. $weight . '-weight'] = [ + '#type' => 'textfield', + '#default_value' => $weight, + '#weight' => $weight, + '#size' => 3, + '#attributes' => [ + 'class' => ['tripal-field-settings-table-weights'], + ], + ]; + } + return $element; + } + + /** + * @see TripalField::instanceSettingsFormValidate() + */ + public function instanceSettingsFormValidate($form, &$form_state) { + $settings = $form_state['values']['instance']['settings']['themeable']; + + // Iterate through the themable elements to get the weights and + // checks for each field. Store that info in a temp array. + $temp = []; + foreach ($settings as $element => $value) { + $matches = []; + if (preg_match('/^field-(\d+)-check$/', $element, $matches)) { + $orig_weight = $matches[1]; + $new_weight = $settings['field-' . $orig_weight . '-weight']; + $field_name = $settings['field-' . $orig_weight]; + $temp[$new_weight]['name'] = $field_name; + $temp[$new_weight]['show'] = $value; + } + } + + // Sort and resstart the weights from zero. + ksort($temp); + $temp = array_values($temp); + + // Now build the transcirpt_fields setting value. + $transcript_fields = []; + foreach ($temp as $weight => $field) { + $field_name = $field['name']; + $transcript_fields[$field_name] = [ + 'weight' => $weight, + 'show' => $field['show'], + ]; + } + + // Now store the values for the setting properly and remove the unwanted. + $form_state['values']['instance']['settings']['transcript_fields'] = $transcript_fields; + unset($form_state['values']['instance']['settings']['themeable']); + } + + /** + * @see TripalField::settingsTheme() + */ + public function settingsTheme($element) { + + $headers = ['', 'Field', 'Description', '']; + $rows = []; + foreach (element_children($element) as $child) { + $matches = []; + if (preg_match('/^field-(\d+)-(.+)$/', $child, $matches)) { + $weight = $matches[1]; + switch ($matches[2]) { + case 'check': + $rows[$weight]['data'][0] = drupal_render($element[$child]); + break; + case 'label': + $rows[$weight]['data'][1] = drupal_render($element[$child]); + break; + case 'description': + $rows[$weight]['data'][2] = drupal_render($element[$child]); + break; + case 'weight': + $rows[$weight]['data'][3] = drupal_render($element[$child]); + break; + } + ksort($rows[$weight]['data']); + $rows[$weight]['class'] = ['draggable']; + } + } + ksort($rows); + + $table = [ + 'header' => $headers, + 'rows' => $rows, + 'attributes' => ["id" => 'tripal-field-settings-table'], + 'sticky' => TRUE, + 'caption' => t('Content Panes Available in the TOC'), + 'colgroups' => [], + 'empty' => t('There are no content panes for this page. The mRNA content type must exist to customize.'), + ]; + drupal_add_tabledrag('tripal-field-settings-table', 'order', 'sibling', 'tripal-field-settings-table-weights'); + + $fset = []; + $fset['fields'] = [ + '#type' => 'fieldset', + '#title' => 'Transcript (mRNA) Field Selection', + '#description' => t('Here, you can customize what information is provided to the end-user about transcripts. Select the fields that you want displayed on the page. If no fields are selected then a default display is provided. All mRNA for a gene must be published or the default display will be provided.'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#attributes' => ['class' => ['collapsible', 'collapsed']], + ]; + drupal_add_library('system', 'drupal.collapse'); + + $fset['fields']['table'] = [ + '#type' => 'markup', + '#markup' => theme_table($table), + ]; + + return drupal_render($fset['fields']); + } + +} diff --git a/tripal_chado/includes/TripalFields/so__transcript/so__transcript_formatter.inc b/tripal_chado/includes/TripalFields/so__transcript/so__transcript_formatter.inc index 4324bdbef..4160e41ef 100755 --- a/tripal_chado/includes/TripalFields/so__transcript/so__transcript_formatter.inc +++ b/tripal_chado/includes/TripalFields/so__transcript/so__transcript_formatter.inc @@ -14,34 +14,314 @@ class so__transcript_formatter extends ChadoFieldFormatter { */ public function view(&$element, $entity_type, $entity, $langcode, $items, $display) { - // Get the settings - $settings = $display['settings']; + $mRNA_fieldset = []; - $headers = ['Transcript Name', 'Identifier', 'Type', 'Location']; - $rows = []; + // If there are no items return an empty element. + if (count($items) == 0) { + return $this->returnEmpty($element); + } + + // Get the list of fields that are t o be shown + $fields_to_show = []; + if (array_key_exists('transcript_fields', $this->instance['settings'])) { + $fields_to_show = $this->fieldsToShow($this->instance['settings']['transcript_fields']); + } + + // For backwards compatibility if the 'transcript_fields' setting + // is not available then return the default table. + if (count($fields_to_show) == 0) { + return $this->returnDefaultTable($element, $items); + } + + // If any of the transcripts are not published then just provide the + // default view foreach ($items as $delta => $item) { + // Skip empty items; if (!$item['value']) { continue; } - $transcript = $item['value']; - // Get the field values - $feature_name = $transcript['schema:name']; - $feature_uname = $transcript['data:0842']; - $loc = $transcript['SO:0000735']; - $type = $transcript['rdfs:type']; + // If any transcript is not published (i.e. it doesn't have an entity) + // then we want to just return the default table and stop. + if (!array_key_exists('entity', $item['value'])) { + return $this->returnDefaultTable($element, $items); + } + } + + // Iterate through the list of fields so that we can load the mRNA + // entity with all of the field requested by the site admin. If we + // don't do this first then auto_attach fields won't be added. + $field_ids = []; + foreach ($fields_to_show as $field_name) { + $field_info = field_info_field($field_name); + $field_ids[] = $field_info['id']; + } + + // For backwards compatibility if no field IDs were provided then + // return the original table of four rows. + if (count($field_ids) == 0) { + return $this->returnDefaultTable($element, $items); + } + + #return $this->returnFieldsets($items, $element, $field_ids, $fields_to_show); + return $this->returnDropDown($items, $element, $field_ids, $fields_to_show); + + } + + /** + * Returns a list of fields names that the site admin wants to show. + */ + private function fieldsToShow($transcript_fields) { + $to_show = []; + foreach($transcript_fields as $field_name => $details) { + if ($details['show'] == 1) { + $to_show[] = $field_name; + } + } + return $to_show; + } + + /** + * + */ + private function returnDropDown($items, &$element, $field_ids, $fields_to_show) { + + drupal_add_js(drupal_get_path ('module', 'tripal_chado') . '/theme/js/so__transcript.js'); + + // Iterate through each mRNA (transcript). + $options = [0 => '--Select a transcript to view--']; + $transcripts = []; + foreach ($items as $delta => $item) { + + // Skip empty items; + if (!$item['value']) { + continue; + } + + list($entity_type, $mRNA_entity_id) = explode(':', $item['value']['entity']); + $result = tripal_load_entity('TripalEntity', [$mRNA_entity_id], FALSE, $field_ids); + reset($result); + $mRNA_entity = $result[$mRNA_entity_id]; + $options[$mRNA_entity_id] = $mRNA_entity->title; + + // Create the fieldset for this transcript. + $transcripts[$mRNA_entity_id] = [ + '#type' => 'markup', + '#prefix' => '
', + '#suffix' => '
', + ]; + + // Add a link to the mRNA page. + $feature_name = $mRNA_entity->title; + $feature_name = l($feature_name, "bio_data/" . $mRNA_entity->id, ['attributes' => ['target' => "_blank"]]); + $transcripts[$mRNA_entity_id]['mRNA_link'] = [ + '#type' => 'markup', + '#markup' => "Click, " . $feature_name . ", for the full transcript page.", + '#weight' => -102 + ]; + + // Now add all fields to the fieldset. + $this->addFields($mRNA_entity, $fields_to_show, $transcripts[$mRNA_entity_id]); + + } + $transcripts['transcript_dropdown'] = [ + '#type' => 'select', + '#title' => 'Transcripts for this gene', + '#options' => $options, + '#weight' => -100, + '#description' => 'Select a transcript to view more details.', + '#attributes' => ['class' => ['tripal-chado-so__transcript-select']] + ]; + $element[0] = $transcripts; + } + + /** + * + */ + private function returnFieldsets($items, &$element, $field_ids, $fields_to_show) { + + // Iterate through each mRNA (transcript). + $transcripts = []; + foreach ($items as $delta => $item) { + + // Skip empty items; + if (!$item['value']) { + continue; + } + + list($entity_type, $mRNA_entity_id) = explode(':', $item['value']['entity']); + + // Now load the mRNA entity with all of the fields. + $result = tripal_load_entity('TripalEntity', [$mRNA_entity_id], FALSE, $field_ids); + reset($result); + $mRNA_entity = $result[$mRNA_entity_id]; + + // Create the fieldset for this transcript. + $transcripts[$mRNA_entity_id] = [ + '#type' => 'fieldset', + '#title' => $mRNA_entity->title, + '#description' => '', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#attributes' => ['class' => ['collapsible', 'collapsed']], + ]; + drupal_add_library('system', 'drupal.collapse'); + + + // Add a link to the mRNA page. + $feature_name = $mRNA_entity->title; + $feature_name = l($feature_name, "bio_data/" . $mRNA_entity->id, ['attributes' => ['target' => "_blank"]]); + $transcripts[$mRNA_entity_id]['mRNA_link'] = [ + '#type' => 'markup', + '#markup' => "Click, " . $feature_name . ", for the full transcript page.", + ]; + + // Now add all fields to the fieldset. + $this->addFields($mRNA_entity, $fields_to_show, $transcripts[$mRNA_entity_id]); + + } + $element[0] = $transcripts; + } + + /** + * Builds a fieldset for the entity. + */ + private function addFields($mRNA_entity, $fields, &$fieldset) { + + // Get some settings about the transcript content type. + $mRNA_bundle = tripal_load_bundle_entity(['name'=> $mRNA_entity->bundle]); + $hide_empty = tripal_get_bundle_variable('hide_empty_field', $mRNA_bundle->id); + + // Get the Entity ID for the transcript. + $entity_id = $mRNA_entity->id; + + // We will use a summary table to house the fields that have a + // cardinality of one. These will appear at the top of the fieldset. + $summary_rows = []; + + // Iterate through the list of fields that the site admin has indicated + // that they want to show in the transcript fieldset. They are provided + // in order that they should be shown. + foreach ($fields as $field_name) { + + // Load the field instance info. We'll need this to determine the + // cardinality of the field and to render it for display. + $field_info = field_info_field($field_name); + $field_instance = field_info_instance('TripalEntity', $field_name, $mRNA_entity->bundle); + + // For the display we want to honor the site admin's wishes and not + // show fields that are empty if they have that setting turned on. + $field_items = field_get_items('TripalEntity', $mRNA_entity, $field_name); + $field_is_empty = tripal_field_is_empty($field_info, $field_items); + if ($field_is_empty and $hide_empty) { + continue; + } + + // If the default display is to hide this field then skip it too. + if ($field_instance['display']['default']['type'] == 'hidden') { + continue; + } + + // Get the render array for this field. + $field_element = field_view_field('TripalEntity', $mRNA_entity, $field_name, $field_instance['display']['default']); + $field_element['#label_display'] = 'hidden'; + + // We need to know the cardinality of this field. If it has a + // cardinatliy of 1 we'll put it in the summary table for the + // transcript that appears at the top of the fieldset. If not we'll + // let it render as is, in the order it's provided to us here. + $cardinality = array_key_exists('cardinality', $field_info) ? $field_info['cardinality'] : 1; + if ($cardinality == 1) { - // Add a link if there is an entity. + // add field to a special transcripts table, where fields have cardinality of 1 + $summary_rows[] = [ + [ + 'data' => $field_instance['label'], + 'header' => TRUE, + ], + [ + 'data' => drupal_render($field_element), + ] + ]; + } + // Else add the field as is. + else { + $fieldset[$field_name . '_header'] = [ + '#type' => 'markup', + '#markup' => '

' . $field_instance['label'] . '

', + ]; + $fieldset[$field_name] = [ + '#type' => 'markup', + '#markup' => drupal_render($field_element), + ]; + } + } // End looping over fields. + + // If the summary table has values then + if (count($summary_rows) > 0) { + // display fields of single cardinality in a special transcripts table + $summary_table = [ + 'header' => [], + 'rows' => $summary_rows, + 'attributes' => [ + 'id' => 'tripal_feature-table-transcript-fields-object', + 'class' => 'tripal-data-table', + ], + 'sticky' => FALSE, + 'caption' => "", + 'colgroups' => [], + 'empty' => 'This feature has no single cardinality transcript fields', + ]; + + $fieldset['summary_header'] = [ + '#type' => 'markup', + '#markup' => '

Transcript ' . $mRNA_entity->title . '

', + '#weight' => -101, + ]; + $fieldset['summary_table'] = [ + '#type' => 'markup', + '#markup' => theme_table($summary_table), + '#weight' => -100, + ]; + } + } + + /** + * Returns the default table. + * + * For backwards compatibility this function returns a table + * of four columns and one row per transcript. + */ + private function returnDefaultTable(&$element, $items) { + + $default_headers = ['Transcript Name', 'Identifier', 'Type', 'Location']; + $default_rows = []; + + foreach ($items as $delta => $item) { + + if (!$item['value']) { + continue; + } + + // Get the field values. + $feature_name = $item['value']['schema:name']; + $feature_uname = $item['value']['data:0842']; + $loc = $item['value']['SO:0000735']; + $type = $item['value']['rdfs:type']; if (array_key_exists('entity', $item['value']) and $item['value']['entity']) { list($entity_type, $entity_id) = explode(':', $item['value']['entity']); $feature_name = l($feature_name, "bio_data/" . $entity_id, ['attributes' => ['target' => "_blank"]]); } - $rows[] = [$feature_name, $feature_uname, $type, $loc]; + + + $default_rows[] = [$feature_name, $feature_uname, $type, $loc]; } - $table = [ - 'header' => $headers, - 'rows' => $rows, + + // Build the default table + $default_table = [ + 'header' => $default_headers, + 'rows' => $default_rows, 'attributes' => [ 'id' => 'tripal_feature-table-transcripts-object', 'class' => 'tripal-data-table', @@ -51,15 +331,21 @@ class so__transcript_formatter extends ChadoFieldFormatter { 'colgroups' => [], 'empty' => 'This feature has no transcripts', ]; - $content = theme_table($table); - // once we have our table array structure defined, we call Drupal's theme_table() - // function to generate the table. - if (count($items) > 0) { - $element[0] = [ - '#type' => 'markup', - '#markup' => $content, - ]; - } + $element[0] = [ + '#type' => 'markup', + '#markup' => theme_table($default_table), + ]; + } + + /** + * Returns an empty element for the view. + */ + private function returnEmpty(&$element){ + $element[0] = [ + '#type' => 'markup', + '#markup' => '', + ]; } } + diff --git a/tripal_chado/theme/css/tripal_chado.css b/tripal_chado/theme/css/tripal_chado.css index 30a6b3fee..338cb386b 100755 --- a/tripal_chado/theme/css/tripal_chado.css +++ b/tripal_chado/theme/css/tripal_chado.css @@ -49,6 +49,9 @@ height: 10px; } +.tripal-chado-gene-transcript-fieldset-item { + border-bottom: 1px solid #AAAAAA; +} #edit-feature-pub #autocomplete li { white-space: normal; diff --git a/tripal_chado/theme/js/so__transcript.js b/tripal_chado/theme/js/so__transcript.js new file mode 100644 index 000000000..862f760af --- /dev/null +++ b/tripal_chado/theme/js/so__transcript.js @@ -0,0 +1,14 @@ +// Using the closure to map jQuery to $. +(function ($) { + // Store our function as a property of Drupal.behaviors. + Drupal.behaviors.so__transcript = { + attach: function (context, settings) { + + $(".tripal-chado-so__transcript-box").hide() + $(".tripal-chado-so__transcript-select").change(function() { + $(".tripal-chado-so__transcript-box").hide() + $("#tripal-chado-so__transcript-" + this.value).show(600) + }); + } + } +}) (jQuery); \ No newline at end of file