فهرست منبع

Addition of a cvterm linking field is now working. It uses an 'adder' field to allow the site admin to add different 'classes' of annotation similar to the way new property fields are added

Stephen Ficklin 9 سال پیش
والد
کامیت
970d4c35b1

+ 2 - 0
tripal_chado/api/modules/tripal_chado.cv.api.inc

@@ -130,6 +130,8 @@ function tripal_get_cv_select_options() {
   $results = chado_select_record('cv', array('cv_id', 'name'), array(), array('order_by' => array('name' => 'ASC')));
 
   $options = array();
+  $options[] = 'Select a Vocabulary';
+
   foreach ($results as $r) {
     $options[$r->cv_id] = $r->name;
   }

+ 0 - 3
tripal_chado/api/modules/tripal_chado.db.api.inc

@@ -541,14 +541,11 @@ function tripal_autocomplete_dbxref($db_id, $string = '') {
     ORDER by accession
     LIMIT 25 OFFSET 0
   ";
-  drupal_debug($string);
-  drupal_debug($db_id);
   $results = chado_query($sql, array(':db_id' => $db_id, ':accession' => $string . '%'));
   $items = array();
   foreach ($results as $ref) {
     $items[$ref->accession] = $ref->accession;
   }
-  drupal_debug($items);
 
   drupal_json_output($items);
 }

+ 182 - 172
tripal_chado/includes/fields/cvterm.inc

@@ -13,22 +13,58 @@
 function tripal_chado_cvterm_formatter(&$element, $entity_type, $entity, $field,
     $instance, $langcode, $items, $display) {
 
-/*   $chado_table = $field['settings']['chado_table'];
+  $headers = array('Term', 'Definition', 'Is Not', 'Reference');
+  $rows = array();
+
+  $chado_table = $field['settings']['chado_table'];
   foreach ($items as $delta => $item) {
-    $accession = '';
     if ($item[$chado_table . '__cvterm_id']) {
       $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $item[$chado_table . '__cvterm_id']));
       $dbxref = $cvterm->dbxref_id;
+
+      // Build the accession.
       $accession = $dbxref->db_id->name . ':' . $dbxref->accession;
       if ($dbxref->db_id->urlprefix) {
         $accession = l($accession, $dbxref->db_id->urlprefix . '/' . $dbxref->accession, array('attributes' => array('target' => '_blank')));
       }
+
+      // Build the publication reference.
+      $pub_ref = '';
+      $pub_id = $item[$chado_table . '__pub_id'];
+      if ($pub_id) {
+        $pub = chado_generate_var('pub', array('pub_id' => $pub_id));
+        $pub_ref = $pub->title;
+      }
+      $rows[] = array(
+        $accession,
+        $cvterm->definition,
+        $item[$chado_table . '__is_not'] ? 'Yes' : '',
+        '',
+      );
     }
-    $element[$delta] = array(
-      '#type' => 'markup',
-      '#markup' => $accession,
-    );
-  } */
+  }
+
+  // the $table array contains the headers and rows array as well as other
+  // options for controlling the display of the table.  Additional
+  // documentation can be found here:
+  // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+  $table = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(
+      'id' => "$chado_table-table-terms",
+      'class' => 'tripal-data-table'
+    ),
+    'caption' => '',
+    'sticky' => FALSE,
+    'colgroups' => array(),
+    'empty' => 'There are no annotations of this type',
+  );
+
+  $element[$delta] = array(
+    '#type' => 'markup',
+    '#markup' => theme_table($table),
+  );
 }
 /**
  *
@@ -46,8 +82,19 @@ function tripal_chado_cvterm_formatter(&$element, $entity_type, $entity, $field,
 function tripal_chado_cvterm_widget(&$widget, $form, $form_state, $field,
     $instance, $langcode, $items, $delta, $element) {
 
+  $entity = $form['#entity'];
   $field_name = $field['field_name'];
 
+  $matches = array();
+  preg_match('/(.*?)__(\d+)/', $field_name, $matches);
+  // If the field name is not properly formatted then we can't tell what
+  // table and type this is.  So just return.
+  if (count($matches) != 3) {
+    return $widget;
+  }
+  $table_name = $matches[1];
+  $cv_id = $matches[2];
+
   // Get the FK column that links to the base table.
   $chado_table = $field['settings']['chado_table'];
   $base_table = $field['settings']['base_table'];
@@ -58,128 +105,87 @@ function tripal_chado_cvterm_widget(&$widget, $form, $form_state, $field,
   // Get the field defaults.
   $record_id = '';
   $fkey_value = $element['#entity']->chado_record_id;
-  $dbxref_id = '';
-  $db_id = '';
-  $accession = '';
-  $version = '';
-  $description = '';
+  $cvterm_name = '';
+  $cvterm_id = '';
+  $is_not = '';
+  $cvterm = NULL;
 
   // If the field already has a value then it will come through the $items
   // array.  This happens when editing an existing record.
   if (array_key_exists($delta, $items)) {
     $record_id = $items[$delta]['value'];
-    $fkey_value = $items[$delta][$field_name . '__' . $fkey];
-    $dbxref_id = $items[$delta][$field_name . '__dbxref_id'];
-    $db_id = $items[$delta][$field_name . '--dbxref__db_id'];
-    $accession = $items[$delta][$field_name . '--dbxref__accession'];
-    $version = $items[$delta][$field_name . '--dbxref__version'];
-    $description = $items[$delta][$field_name . '--dbxref__description'];
+    $fkey_value = $items[$delta][$table_name . '__' . $fkey];
+    $cvterm_name = $items[$delta][$table_name . '--cvterm__name'];
+    $is_not = $items[$delta][$table_name . '__is_not'];
+    $cvterm_id = $items[$delta][$table_name . '__cvterm_id'];
   }
 
   // Check $form_state['values'] to see if an AJAX call set the values.
   if (array_key_exists('values', $form_state)) {
-    $record_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name);
-    $fkey_value = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '__' . $fkey);
-    $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '__dbxref_id');
-    $db_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__db_id');
-    $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__accession');
-    $version = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__version');
-    $description = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__description');
+    $record_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name);
+    $fkey_value = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__' . $fkey);
+    $is_not = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_not');
+    $cvterm_name = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--cvterm__name');
   }
 
-  // If we are here because our parent was triggered in a form submit
-  // then that means an ajax call was made and we don't want the fieldset to
-  // be closed when it returns from the ajax call.
-  $collapsed = TRUE;
-  if (array_key_exists('triggering_element', $form_state) and
-      $form_state['triggering_element']['#parents'][0] == $field_name) {
-    $collapsed = FALSE;
-  }
-  if ($dbxref_id) {
-    $collapsed = FALSE;
+  if ($cvterm_name) {
+    $cvterm = chado_generate_var('cvterm', array('cv_id' => $cv_id, 'name' => $cvterm_name));
   }
 
-  $schema = chado_get_schema('dbxref');
-  $options = tripal_get_db_select_options();
+  $schema = chado_get_schema('cvterm');
+  $options = tripal_get_cv_select_options();
 
   $widget['#table_name'] = $chado_table;
   $widget['#fkey_field'] = $fkey;
   $widget['#element_validate'] = array('tripal_chado_cvterm_widget_validate');
   $widget['#theme'] = 'tripal_chado_cvterm_widget';
-  $widget['#prefix'] =  "<span id='$field_name-dbxref--db-id-$delta'>";
+  $widget['#prefix'] =  "<span id='$table_name-$delta'>";
   $widget['#suffix'] =  "</span>";
 
-  // A temporary element used for theming the fieldset.
-  $widget['#theme_settings'] = array(
-    '#title' => $element['#title'],
-    '#description' =>  $element['#description'],
-    '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
-    '#theme' => 'tripal_chado_cvterm_widget',
-    '#collapsible' => TRUE,
-    '#collapsed' => $collapsed,
-  );
-
   $widget['value'] = array(
     '#type' => 'value',
     '#default_value' => $record_id,
   );
-  $widget[$field_name . '__dbxref_id'] = array(
+  $widget[$table_name . '--cvterm__cv_id--cv__cv_id'] = array(
     '#type' => 'value',
-    '#default_value' => $dbxref_id,
+    '#default_value' => $cv_id,
   );
-  $widget[$field_name . '__' . $fkey] = array(
+  $widget[$table_name . '__cvterm_id'] = array(
     '#type' => 'value',
-    '#default_value' => $fkey_value,
+    '#default_value' => $cvterm ? $cvterm->cvterm_id : '',
   );
-  $widget[$field_name . '--dbxref__dbxref_id'] = array(
+  $widget[$table_name . '__' . $fkey] = array(
     '#type' => 'value',
-    '#default_value' => $dbxref_id,
+    '#default_value' => $fkey_value,
   );
-  $widget[$field_name . '--dbxref__db_id'] = array(
-    '#type' => 'select',
-    '#title' => t('Database'),
-    '#options' => $options,
+
+  $widget[$table_name . '--cvterm__name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Term Name'),
+    '#default_value' => $cvterm_name,
     '#required' => $element['#required'],
-    '#default_value' => $db_id,
+    '#maxlength' => array_key_exists('length', $schema['fields']['name']) ? $schema['fields']['name']['length'] : 255,
+    '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/cvterm/' . $cv_id,
     '#ajax' => array(
       'callback' => "tripal_chado_cvterm_widget_form_ajax_callback",
-      'wrapper' => "$field_name-dbxref--db-id-$delta",
+      'wrapper' => "$table_name-$delta",
       'effect' => 'fade',
       'method' => 'replace'
     ),
   );
-  $widget[$field_name . '--dbxref__accession'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Accession'),
-    '#default_value' => $accession,
+
+  $widget[$table_name . '__is_not'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Is Not'),
+    '#default_value' => $is_not,
     '#required' => $element['#required'],
-    '#maxlength' => array_key_exists('length', $schema['fields']['accession']) ? $schema['fields']['accession']['length'] : 255,
-    '#size' => 15,
-    '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/dbxref/' . $db_id,
-    '#ajax' => array(
-      'callback' => "tripal_chado_cvterm_widget_form_ajax_callback",
-      'wrapper' => "$field_name-dbxref--db-id-$delta",
-      'effect' => 'fade',
-      'method' => 'replace'
-    )
-  );
-  $widget[$field_name . '--dbxref__version'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Version'),
-    '#default_value' => $version,
-    '#maxlength' => array_key_exists('length', $schema['fields']['version']) ? $schema['fields']['version']['length'] : 255,
-    '#size' => 5,
-  );
-  $widget[$field_name . '--dbxref__description'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Description'),
-    '#default_value' => $description,
-    '#size' => 20,
   );
-  $widget['links'] = array(
+
+  $widget[$table_name . '--cvterm__definition'] = array(
     '#type' => 'item',
-    '#markup' => l('Add a new database', 'admin/tripal/chado/tripal_db/add', array('attributes' => array('target' => '_blank')))
+    '#markup' => '',
   );
+
 }
 /**
  * An Ajax callback for the dbxref widget.
@@ -188,19 +194,7 @@ function tripal_chado_cvterm_widget_form_ajax_callback($form, $form_state) {
 
   $field_name = $form_state['triggering_element']['#parents'][0];
   $delta = $form_state['triggering_element']['#parents'][2];
-  $db_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__db_id');
-  $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__accession');
-  if ($db_id and $accession) {
-    $values = array(
-      'db_id' => $db_id,
-      'accession' => $accession,
-    );
-    $options = array('is_duplicate' => TRUE);
-    $has_duplicate = chado_select_record('dbxref', array('*'), $values, $options);
-    if (!$has_duplicate) {
-      drupal_set_message('The selected cross reference is new and will be added for future auto completions.');
-    }
-  }
+
 
   return $form[$field_name]['und'][$delta];
 }
@@ -223,44 +217,36 @@ function tripal_chado_cvterm_widget_validate($element, &$form_state) {
   }
 
   // Get the field values.
-  $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '__dbxref_id');
-  $db_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__db_id');
-  $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__accession');
-  $version = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__version');
-  $description = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__description');
-
-  // Make sure that if a database ID is provided that an accession is also
-  // provided.  Here we use the form_set_error function rather than the
-  // form_error function because the form_error will add a red_highlight
-  // around all of the fields in the fieldset which is confusing as it's not
-  // clear to the user what field is required and which isn't. Therefore,
-  // we borrow the code from the 'form_error' function and append the field
-  // so that the proper field is highlighted on error.
-  if (!$db_id and $accession) {
-    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__db_id', t("A database and the accession must both be provided for the primary cross reference."));
-  }
-  if ($db_id and !$accession) {
-    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__accession', t("A database and the accession must both be provided for the primary cross reference."));
-  }
-  if (!$db_id and !$accession and ($version or $description)) {
-    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__db_id', t("A database and the accession must both be provided for the primary cross reference."));
-  }
+  $cvterm_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '__cvterm_id');
+  $cv_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '--cvterm__cv_id--cv__cv_id');
+  $cvterm_name = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '--cvterm__name');
+  $cvterm_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '__cvterm_id');
+  $pub_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '__pub_id');
 
-  // If user did not select a database, we want to remove dbxref_id from the
-  // field.
-  if (!$db_id) {
-    tripal_chado_set_field_form_values($field_name, $form_state, '__NULL__');
-  }
-  // If the dbxref_id does not match the db_id + accession then the user
-  // has selected a new dbxref record and we need to update the hidden
-  // value accordingly.
-  if ($db_id and $accession) {
-    $dbxref = chado_generate_var('dbxref', array('db_id' => $db_id, 'accession' => $accession));
-    if ($dbxref and $dbxref->dbxref_id != $dbxref_id) {
-      tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, $delta, $table_name . '__dbxref_id');
-      tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, $delta, $table_name . '--dbxref__dbxref_id');
+  // If the user provided a cv_id and a name then we want to set the
+  // foreign key value to be the chado_record_idd
+  if ($cvterm_name) {
+
+    $fkey_value = $element['#entity']->chado_record_id;
+    tripal_chado_set_field_form_values($field_name, $form_state, $fkey_value, $delta, $table_name . '__' . $fkey);
+
+    // Get the cvterm ID. If one is not available because it's a newly added
+    // record, then we need to retrieve it and set the form element.
+    if (!$cvterm_id) {
+      $cvterm = tripal_get_cvterm(array('cv_id' => $cv_id, 'name' => $cvterm_name));
+      tripal_chado_set_field_form_values($field_name, $form_state, $cvterm->cvterm_id, $delta, $table_name . '__cvterm_id');
+    }
+
+    if (!$pub_id) {
+      $pub = chado_generate_var('pub', array('uniquename' => 'null'));
+      tripal_chado_set_field_form_values($field_name, $form_state, $pub->pub_id, $delta, $table_name . '__pub_id');
     }
   }
+  else {
+    // If the $cv_id and name are not set, then remove the linker FK value to the base table.
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__' . $fkey);
+  }
+
 }
 /**
  * Theme function for the dbxref_id_widget.
@@ -276,20 +262,16 @@ function theme_tripal_chado_cvterm_widget($variables) {
   $fkey = $element['#fkey_field'];
 
   $layout = "
-    <div class=\"secondary-dbxref-widget\">
-      <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__db_id']) . "
-      </div>
+    <div class=\"annotation-cvterm-widget\">
       <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__accession']) . "
+        drupal_render($element[$table_name . '--cvterm__cv_id--cv__cv_id']) . "
       </div>
-      <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__version']) . "
+      <div class=\"annotation-cvterm-widget-item\">" .
+        drupal_render($element[$table_name . '--cvterm__name']) . "
       </div>
-      <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__description']) . "
+      <div class=\"annotation-cvterm-widget-item\">" .
+        drupal_render($element[$table_name . '__is_not']) . "
       </div>
-      <div class=\"secondary-dbxref-widget-links\">" . drupal_render($element['links']) . "</div>
     </div>
   ";
 
@@ -313,41 +295,69 @@ function tripal_chado_cvterm_field_load($field, $entity, $base_table, $record) {
 
   $field_name = $field['field_name'];
   $field_type = $field['type'];
-  $chado_table = $field['settings']['chado_table'];
-  $schema = chado_get_schema($chado_table);
+  $field_table = $field['settings']['chado_table'];
+  $field_column = $field['settings']['chado_column'];
+
+  $matches = array();
+  preg_match('/(.*?)__(\d+)/', $field_name, $matches);
+  $table_name = $matches[1];
+  $cv_id = $matches[2];
+
+  // Get the FK that links to the base record.
+  $schema = chado_get_schema($field_table);
   $pkey = $schema['primary key'][0];
-  $fkey = array_values($schema['foreign keys'][$base_table]['columns'])[0];
+  $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
+  $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
 
   // Set some defaults for the empty record.
   $entity->{$field_name}['und'][0] = array(
     'value' => '',
-    $chado_table . '__' . $fkey => '',
-    $chado_table . '__' . 'cvterm_id' => '',
-    $chado_table . '__' . 'pub_id' => '',
-    $chado_table . '__' . 'is_not' => '',
-    $chado_table . '__' . 'rank' => '',
-    $chado_table . '--' . 'cvterm__name' => '',
-    $chado_table . '--' . 'cvterm__cvterm_id' => '',
+    $field_table . '__' . $fkey_lcolumn => '',
+    $field_table . '__' . 'cvterm_id' => '',
+    // The pub column is present in the cell_line_cvterm, feature_cvterm,
+    // library_cvterm, phenotype_comparision_cvterm, phenotype_cvterm,
+    // stock_cvterm, and stock_relationship_cvterm.
+    $field_table . '__' . 'pub_id' => '',
+    // The is_not column is present in feature_cvterm and stock_cvterm tables.
+    $field_table . '__' . 'is_not' => '',
+    // The rank column is present in the cell_line_cvterm, expression_cvterm,
+    // feature_cvterm, phenotype_comparision_cvterm, phenotype_cvterm,
+    // and stock_cvterm tables.
+    $field_table . '__' . 'rank' => '',
+    // The cvterm_type_id is present in the expression_cvterm table.
+    $field_table . '--' . 'cvterm_type_id' => '',
+    // The following field are to help link the cvterm.
+    $field_table . '--' . 'cvterm__cv_id--cv__cv_id' => '',
+    $field_table . '--' . 'cvterm__name' => '',
   );
 
-  $linker_table = $base_table . '_cvterm';
-  /* $options = array('return_array' => 1);
-  $record = chado_expand_var($record, 'table', $linker_table, $options);
-  $i = 0;
-  foreach ($record->$linker_table as $index => $linker) {
-    $cvterm = $linker->cvterm_id;
+  // Get the annotations associated with this base record for this fields type.
+  $columns = array('*');
+  $match = array(
+    $fkey_lcolumn => $record->$fkey_rcolumn,
+    'cvterm_id' => array(
+      'cv_id' => $cv_id,
+    ),
+  );
+  $options = array(
+    'return_array' => TRUE,
+    'order_by' => array('rank' => 'ASC')
+  );
+  $fcvterms = chado_select_record($field_table, $columns, $match, $options);
+  for ($i = 0; $i < count($fcvterms); $i++) {
+    $linker = $fcvterms[$i];
+    $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $linker->cvterm_id));
     $entity->{$field_name}['und'][$i] = array(
       'value' => $linker->$pkey,
-      $chado_table . '__' . $fkey => $linker->$fkey->$fkey,
-      $chado_table . '__' . 'cvterm_id' => $linker->cvterm_id->cvterm_id,
-      $chado_table . '__' . 'pub_id' => property_exists($linker, 'pub_id') ? $linker->pub_id : '',
-      $chado_table . '__' . 'is_not' => property_exists($linker, 'is_not') ? $linker->is_not : '',
-      $chado_table . '__' . 'rank' => property_exists($linker, 'rank') ? $linker->rank : '',
-      $chado_table . '__' . 'cvterm_type_id' => property_exists($linker, 'cvterm_type_id') ? $linker->cvterm_type_id : '',
-      $chado_table . '--' . 'cvterm__name' => $cvterm->name,
-      $chado_table . '--' . 'cvterm__cvterm_id' => $cvterm->cvterm_id,
+      $field_table . '__' . $fkey_lcolumn => $linker->$fkey_lcolumn,
+      $field_table . '__' . 'cvterm_id' => $linker->cvterm_id,
+      $field_table . '__' . 'pub_id' => property_exists($linker, 'pub_id') ? $linker->pub_id : '',
+      $field_table . '__' . 'is_not' => property_exists($linker, 'is_not') ? $linker->is_not : '',
+      $field_table . '__' . 'rank' => property_exists($linker, 'rank') ? $linker->rank : '',
+      $field_table . '__' . 'cvterm_type_id' => property_exists($linker, 'cvterm_type_id') ? $linker->cvterm_type_id : '',
+      $field_table . '--' . 'cvterm__cv_id--cv__cv_id' => $cvterm->cv_id->cv_id,
+      $field_table . '--' . 'cvterm__name' => $cvterm->name,
     );
-    $i++;
-  } */
+  }
 }
 

+ 128 - 0
tripal_chado/includes/fields/cvterm_class_adder.inc

@@ -0,0 +1,128 @@
+<?php
+
+/**
+ *
+ * @param unknown $entity_type
+ * @param unknown $entity
+ * @param unknown $field
+ * @param unknown $instance
+ * @param unknown $langcode
+ * @param unknown $items
+ * @param unknown $display
+ */
+function tripal_chado_cvterm_class_adder_formatter(&$element, $entity_type, $entity, $field,
+  $instance, $langcode, $items, $display) {
+
+  foreach ($items as $delta => $item) {
+    // Do nothing, this field is only meant for the form.
+  }
+}
+/**
+ *
+ */
+function tripal_chado_cvterm_class_adder_widget(&$widget, &$form, &$form_state,
+    $field, $instance, $langcode, $items, $delta, $element) {
+
+  // This field has no value field.  Just a fieldset for adding new annotation types.
+
+  $widget['#element_validate'] = array('tripal_chado_cvterm_class_adder_widget_validate');
+
+  $widget['#type'] = 'fieldset';
+  $widget['#title'] = $element['#title'];
+  $widget['#description'] = $element['#description'];
+  $widget['#group'] = 'entity_form_vtabs';
+
+  $widget['cvterm_class_adder_instructions'] = array(
+    '#type' => 'item',
+    '#markup' => t('You may add annotation types to this form by
+        providing a vocabulary name in the field below
+        and clicking the "Add Annotation Type" button.  This will add a
+        new field to the form above for the vocabulary you entered which
+        will allow users to associate terms from that vocabulary to
+        this record.'),
+  );
+
+  $options = tripal_get_cv_select_options();
+  $widget['value'] = array(
+    '#type' => 'select',
+    '#title' => t('Vocabulary'),
+    '#options' => $options,
+    '#description' => t("Please enter the vocabulary that contains terms
+        you want to allow users to use for annotations."),
+  );
+
+  // When this button is clicked, the form will be validated and submitted.
+  // Therefore, we set custom submit and validate functions to override the
+  // default form submit.  In the validate function we set the form_state
+  // to rebuild the form so the submit function never actually gets called,
+  // but we need it or Drupal will run the default validate anyway.
+  // we also set #limit_validation_errors to empty so fields that
+  // are required that don't have values won't generate warnings.
+  $widget['cvterm_class_adder_button'] = array(
+    '#value' => t('Add Annotation Type'),
+    '#type' => 'submit',
+    '#name' => 'cvterm_class_adder_button',
+    '#submit' => array('tripal_chado_cvterm_class_adder_widget_submit'),
+    '#limit_validation_errors' => array(array($field['field_name'])),
+  );
+}
+/**
+ * Callback function for validating the tripal_chado_cvterm_class_adder_widget.
+ */
+function tripal_chado_cvterm_class_adder_widget_validate($element, &$form_state) {
+
+   // Add the new field to the entity
+   if (array_key_exists('triggering_element', $form_state) and
+       $form_state['triggering_element']['#name'] == 'cvterm_class_adder_button') {
+
+     $form_state['rebuild'] = TRUE;
+     $field_name = $element['#field_name'];
+     $entity_type = $element['#entity']->type;
+     $bundle = $element['#entity']->bundle;
+
+     // Get the base table name from the field annotations.
+     $field = field_info_field($field_name);
+     $base_table = $field['settings']['base_table'];
+
+     // Get the vocabulary.
+     $cvterm_class_adder = tripal_chado_get_field_form_values($field_name, $form_state);
+     $cv = chado_generate_var('cv', array('cv_id' => $cvterm_class_adder));
+
+     if (!$cv) {
+       form_set_error(implode('][', $element ['#parents']) . '][value', t("Please select a vocabulary."));
+       return;
+     }
+
+     $type_field_name = $field_name . '__' . $cv->cv_id;
+
+     // The field name is the table name in this case. We want to get the
+     // primary key as this should be the field that maps th the value.
+     $schema = chado_get_schema($field_name);
+     $pkey = $schema['primary key'][0];
+
+     $field_info = array(
+       'field_type' => 'cvterm',
+       'widget_type' => 'tripal_chado_cvterm_widget',
+       'field_settings' => array(
+         'chado_table' => $field_name,
+         'chado_column' => $pkey,
+         'base_table' => $base_table,
+       ),
+       'storage' => 'field_chado_storage',
+       'widget_settings' => array(),
+       'description' => "Annotations from the $cv->name vocabulary",
+       'label' => ucfirst(preg_replace('/_/', ' ', $cv->name)),
+       'is_required' => FALSE,
+       // All annotations are unlimited.
+       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+     );
+     tripal_add_bundle_field($type_field_name, $field_info, $entity_type, $bundle);
+
+   }
+}
+/**
+ * Callback function for submitting the tripal_chado_cvterm_class_adder_widget.
+ */
+function tripal_chado_cvterm_class_adder_widget_submit($element, &$form_state) {
+
+}

+ 17 - 30
tripal_chado/includes/fields/dbxref.inc

@@ -86,18 +86,6 @@ function tripal_chado_dbxref_widget(&$widget, $form, $form_state, $field,
     $description = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__description');
   }
 
-  // If we are here because our parent was triggered in a form submit
-  // then that means an ajax call was made and we don't want the fieldset to
-  // be closed when it returns from the ajax call.
-  $collapsed = TRUE;
-  if (array_key_exists('triggering_element', $form_state) and
-      $form_state['triggering_element']['#parents'][0] == $field_name) {
-    $collapsed = FALSE;
-  }
-  if ($dbxref_id) {
-    $collapsed = FALSE;
-  }
-
   $schema = chado_get_schema('dbxref');
   $options = tripal_get_db_select_options();
 
@@ -108,16 +96,6 @@ function tripal_chado_dbxref_widget(&$widget, $form, $form_state, $field,
   $widget['#prefix'] =  "<span id='$field_name-dbxref--db-id-$delta'>";
   $widget['#suffix'] =  "</span>";
 
-  // A temporary element used for theming the fieldset.
-  $widget['#theme_settings'] = array(
-    '#title' => $element['#title'],
-    '#description' =>  $element['#description'],
-    '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
-    '#theme' => 'tripal_chado_dbxref_widget',
-    '#collapsible' => TRUE,
-    '#collapsed' => $collapsed,
-  );
-
   $widget['value'] = array(
     '#type' => 'value',
     '#default_value' => $record_id,
@@ -160,7 +138,8 @@ function tripal_chado_dbxref_widget(&$widget, $form, $form_state, $field,
       'wrapper' => "$field_name-dbxref--db-id-$delta",
       'effect' => 'fade',
       'method' => 'replace'
-    )
+    ),
+    '#disabled' => $db_id ? FALSE : TRUE,
   );
   $widget[$field_name . '--dbxref__version'] = array(
     '#type' => 'textfield',
@@ -168,17 +147,21 @@ function tripal_chado_dbxref_widget(&$widget, $form, $form_state, $field,
     '#default_value' => $version,
     '#maxlength' => array_key_exists('length', $schema['fields']['version']) ? $schema['fields']['version']['length'] : 255,
     '#size' => 5,
+    '#disabled' => $db_id ? FALSE : TRUE,
   );
   $widget[$field_name . '--dbxref__description'] = array(
     '#type' => 'textfield',
     '#title' => t('Description'),
     '#default_value' => $description,
     '#size' => 20,
+    '#disabled' => $db_id ? FALSE : TRUE,
   );
-  $widget['links'] = array(
-    '#type' => 'item',
-    '#markup' => l('Add a new database', 'admin/tripal/chado/tripal_db/add', array('attributes' => array('target' => '_blank')))
-  );
+  if (!$db_id) {
+    $widget['links'] = array(
+      '#type' => 'item',
+      '#markup' => l('Add a database', 'admin/tripal/chado/tripal_db/add', array('attributes' => array('target' => '_blank')))
+    );
+  }
 }
 /**
  * An Ajax callback for the dbxref widget.
@@ -187,6 +170,9 @@ function tripal_chado_dbxref_widget_form_ajax_callback($form, $form_state) {
 
   $field_name = $form_state['triggering_element']['#parents'][0];
   $delta = $form_state['triggering_element']['#parents'][2];
+
+  // Check to see if this dbxref already exists. If not then
+  // give a notice to the user that the dbxref will be added.
   $db_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__db_id');
   $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__accession');
   if ($db_id and $accession) {
@@ -236,13 +222,13 @@ function tripal_chado_dbxref_widget_validate($element, &$form_state) {
   // we borrow the code from the 'form_error' function and append the field
   // so that the proper field is highlighted on error.
   if (!$db_id and $accession) {
-    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__db_id', t("A database and the accession must both be provided for the primary cross reference."));
+    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__db_id', t("A database and the accession must both be provided."));
   }
   if ($db_id and !$accession) {
-    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__accession', t("A database and the accession must both be provided for the primary cross reference."));
+    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__accession', t("A database and the accession must both be provided."));
   }
   if (!$db_id and !$accession and ($version or $description)) {
-    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__db_id', t("A database and the accession must both be provided for the primary cross reference."));
+    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--dbxref__db_id', t("A database and the accession must both be provided."));
   }
 
   // If the dbxref_id does not match the db_id + accession then the user
@@ -257,6 +243,7 @@ function tripal_chado_dbxref_widget_validate($element, &$form_state) {
       tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, $delta, $table_name . '__dbxref_id');
       tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, $delta, $table_name . '--dbxref__dbxref_id');
     }
+
   }
   else {
     // If the db_id and accession are not set, then remove the linker FK value to the base table.

+ 4 - 1
tripal_chado/includes/fields/dbxref_id.inc

@@ -131,7 +131,8 @@ function tripal_chado_dbxref_id_widget(&$widget, $form, $form_state, $field, $in
       'wrapper' => "$field_name-dbxref--db-id",
       'effect' => 'fade',
       'method' => 'replace'
-    )
+    ),
+    '#disabled' => $db_id ? FALSE : TRUE,
   );
   $widget['dbxref__version'] = array(
     '#type' => 'textfield',
@@ -139,12 +140,14 @@ function tripal_chado_dbxref_id_widget(&$widget, $form, $form_state, $field, $in
     '#default_value' => $version,
     '#maxlength' => array_key_exists('length', $schema['fields']['version']) ? $schema['fields']['version']['length'] : 255,
     '#size' => 5,
+    '#disabled' => $db_id ? FALSE : TRUE,
   );
   $widget['dbxref__description'] = array(
     '#type' => 'textfield',
     '#title' => t('Description'),
     '#default_value' => $description,
     '#size' => 20,
+    '#disabled' => $db_id ? FALSE : TRUE,
   );
   $widget['links'] = array(
     '#type' => 'item',

+ 6 - 1
tripal_chado/includes/fields/kvproperty_adder.inc

@@ -75,13 +75,18 @@ function tripal_chado_kvproperty_adder_widget_validate($element, &$form_state) {
        $form_state['triggering_element']['#name'] == 'kvproperty_adder_button') {
 
      $form_state['rebuild'] = TRUE;
-     $field_name = $element['#parents'][0];
+     $field_name = $element['#field_name'];
      $entity_type = $element['#entity']->type;
      $bundle = $element['#entity']->bundle;
 
+     // Get the base table name from the field properties.
+     $field = field_info_field($field_name);
+     $base_table = $field['settings']['base_table'];
+
      // Get the term for the property
      $kvproperty = tripal_chado_get_field_form_values($field_name, $form_state);
      $term = chado_generate_var('cvterm', array('name' => $kvproperty), $options = array('return_array' => TRUE));
+
      if (count($term) == 1) {
        $prop_field_name = $field_name . '__' . $term[0]->cvterm_id;
 

+ 1 - 0
tripal_chado/includes/fields/residues.inc

@@ -47,6 +47,7 @@ function tripal_chado_residues_textarea_widget(&$widget, $form, $form_state, $fi
     '#default_value' => count($items) > 0 ? $items[0]['value'] : '',
     '#delta' => $delta,
     '#element_validate' => array('tripal_chado_residues_textarea_widget_validate'),
+    '#cols' => 30,
   );
 }
 /**

+ 0 - 20
tripal_chado/includes/tripal_chado.publish.inc

@@ -47,26 +47,6 @@ function tripal_chado_publish_form($form, &$form_state) {
       '#collapsible' => TRUE,
     );
 
-    // Get the form for this bundle (content type).  Then iterate through
-    // the fields and include only those that are Chado fields.
-/*     $bundle_name = 'bio-data_' . $term_id;
-    $entity = entity_get_controller('TripalEntity')->create(array('bundle' => $bundle_name, 'term_id' => $term_id));
-    field_attach_form('TripalEntity', $entity, $form['filters'], $form_state);
-    foreach (element_children($form['filters']) as $field_name) {
-      $field = field_info_field($field_name);
-      if ($field and $field['storage']['type'] != 'field_chado_storage') {
-        unset($form['filters'][$field_name]);
-      }
-      // Ignore the KVPoperty field as this is just a field to
-      // allow the user to add new properties which isn't appropriate
-      // here.
-      if ($field['type'] == 'kvproperty_adder') {
-        unset($form['filters'][$field_name]);
-      }
-      // None of the fields should be required.
-
-    } */
-
     $form['publish_btn'] = array(
       '#type' => 'submit',
       '#name' => 'publish_btn',

+ 76 - 44
tripal_chado/tripal_chado.module

@@ -357,6 +357,14 @@ function tripal_chado_menu() {
     'file path' => drupal_get_path('module', 'tripal_chado'),
     'type' => MENU_CALLBACK,
   );
+  $items['admin/tripal/storage/chado/auto_name/cvterm/%/%'] = array(
+    'page callback' => 'tripal_autocomplete_cvterm',
+    'page arguments' => array(6, 7),
+    'access arguments' => array('access content'),
+    'file' => 'api/modules/tripal_chado.db.api.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 
 }
@@ -407,7 +415,6 @@ function tripal_chado_field_info() {
         'active' => TRUE
       ),
     ),
-
     'dbxref_id' => array(
       'label' => t('Cross reference'),
       'description' => t('This record can be cross referenced with a record in
@@ -510,7 +517,23 @@ function tripal_chado_field_info() {
         'active' => TRUE
       ),
     ),
-
+    // The field provides a widget for adding new vocabularies for cvterm
+    // linker tables. This will allow cvterms to be grouped by vocabulary
+    // ('category').
+    'cvterm_class_adder' => array(
+      'label' => t('Add an Annotation Type'),
+      'description' => t('This record may have any number of types of
+          annotations. Use this field to first add the type.'),
+      'default_widget' => 'tripal_chado_cvterm_class_adder_widget',
+      //'default_formatter' => 'tripal_chado_cvterm_class_adder_formatter',
+      'default_formatter' => 'hidden',
+      'settings' => array(),
+      'storage' => array(
+        'type' => 'field_chado_storage',
+        'module' => 'tripal_chado',
+        'active' => TRUE
+      ),
+    ),
     // The field provides form elements for adding multiple cvterms to an
     // entity that in turn get stored in a [base]_cvterm table of Chado
     // (e.g. feature_cvterm).
@@ -556,6 +579,10 @@ function tripal_chado_field_widget_info() {
         prominent reference.  At a minimum, the database and accession
         must be provided.'),
     ),
+    'tripal_chado_cvterm_class_adder_widget' => array(
+      'label' => t('Add an Annotation'),
+      'field types' => array('cvterm_class_adder'),
+    ),
     'tripal_chado_cvterm_widget' => array(
       'label' => t('Annotations'),
       'field types' => array('cvterm'),
@@ -601,6 +628,10 @@ function tripal_chado_field_formatter_info() {
       'label' => t('Cross references'),
       'field types' => array('dbxref')
     ),
+    'tripal_chado_cvterm_class_adder_formatter' => array(
+      'label' => t('Add an Annotation'),
+      'field types' => array('cvterm_class_adder')
+    ),
     'tripal_chado_cvterm_formatter' => array(
       'label' => t('Annotations'),
       'field types' => array('cvterm')
@@ -684,6 +715,11 @@ function tripal_chado_field_formatter_view($entity_type, $entity, $field,
       tripal_chado_dbxref_formatter($element, $entity_type, $entity, $field,
           $instance, $langcode, $items, $display);
       break;
+    case 'tripal_chado_cvterm_class_adder_formatter':
+      module_load_include('inc', 'tripal_chado', 'includes/fields/cvterm_class_adder');
+      tripal_chado_cvterm_class_adder_formatter($element, $entity_type, $entity, $field,
+          $instance, $langcode, $items, $display);
+      break;
     case 'tripal_chado_cvterm_formatter':
       module_load_include('inc', 'tripal_chado', 'includes/fields/cvterm');
       tripal_chado_cvterm_formatter($element, $entity_type, $entity, $field,
@@ -743,6 +779,11 @@ function tripal_chado_field_widget_form(&$form, &$form_state, $field,
       module_load_include('inc', 'tripal_chado', 'includes/fields/dbxref');
       tripal_chado_dbxref_widget($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
       break;
+    case 'tripal_chado_cvterm_class_adder_widget':
+      form_load_include($form_state, 'inc', 'tripal_chado', 'includes/fields/cvterm_class_adder');
+      module_load_include('inc', 'tripal_chado', 'includes/fields/cvterm_class_adder');
+      tripal_chado_cvterm_class_adder_widget($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
+      break;
     case 'tripal_chado_cvterm_widget':
       form_load_include($form_state, 'inc', 'tripal_chado', 'includes/fields/cvterm');
       module_load_include('inc', 'tripal_chado', 'includes/fields/cvterm');
@@ -783,8 +824,8 @@ function tripal_chado_field_widget_form(&$form, &$form_state, $field,
  * The field_ui_display_overview_form is used for formatting the display
  * or layout of fields attached to an entity and shown on the entity view page.
  *
- * This function removes the property adder field as that is really not meant
- * for users to show or manage.
+ * This function removes the cvterm class and property adder field as those are
+ * really not meant for users to show or manage.
  */
 function tripal_chado_form_field_ui_display_overview_form_alter(&$form, &$form_state, $form_id) {
   // Remove the kvproperty_addr field as it isn't ever displayed. It's just used
@@ -795,6 +836,9 @@ function tripal_chado_form_field_ui_display_overview_form_alter(&$form, &$form_s
     if ($field_info['type'] == 'kvproperty_adder') {
       unset($form['fields'][$field_name]);
     }
+    if ($field_info['type'] == 'cvterm_class_adder') {
+      unset($form['fields'][$field_name]);
+    }
   }
 }
 /**
@@ -815,6 +859,9 @@ function tripal_chado_form_field_ui_field_overview_form_alter(&$form, &$form_sta
     if ($field_info['type'] == 'kvproperty_adder') {
       unset($form['fields'][$field_name]);
     }
+    if ($field_info['type'] == 'cvterm_class_adder') {
+      unset($form['fields'][$field_name]);
+    }
   }
 }
 /**
@@ -856,6 +903,9 @@ function tripal_chado_get_field_form_values($field_name, $form_state, $delta = 0
 
   // Iterate through the values looking for the field_name provided.
   foreach ($form_state['values'][$field_name] as $langcode => $items) {
+    if (!array_key_exists($delta, $items)) {
+      continue;
+    }
     $item = $items[$delta];
     if ($child){
       if(array_key_exists($child, $item) and $item[$child] != '') {
@@ -907,6 +957,10 @@ function tripal_chado_theme($existing, $type, $theme, $path) {
       'render element' => 'element',
       'file' => 'includes/fields/dbxref.inc',
     ),
+    'tripal_chado_cvterm_widget' => array(
+      'render element' => 'element',
+      'file' => 'includes/fields/cvterm.inc',
+    ),
     'tripal_chado_kvproperty_addr_widget' => array(
       'render element' => 'element',
       'file' => 'includes/fields/dbxref_id.inc',
@@ -1041,7 +1095,7 @@ function tripal_chado_add_bundle_fields($entity_type, $bundle, $term) {
   // base table. If so, add the fields for that type of table.
   $cvterm_table = $bundle_data['data_table'] . '_cvterm';
   if (chado_table_exists($cvterm_table)) {
-    tripal_chado_add_bundle_cvterm_field($entity_type, $bundle_name, $cvterm_table, $bundle_data['data_table']);
+    tripal_chado_add_bundle_cvterm_class_adder_field($entity_type, $bundle_name, $cvterm_table, $bundle_data['data_table']);
   }
 }
 
@@ -1096,50 +1150,29 @@ function tripal_chado_add_bundle_dbxref_field($entity_type_name, $bundle_name, $
   }
   tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
 }
-
 /**
- * Adds the fields for managing xrefs that are stored in a [base]_dbxref table.
+ * Adds the fields for managing properties that are stored in a prop table.
  *
- * @param $entity_type
+ * @param $entity_type_name
  * @param $bundle_name
- * @param $base_table
- * @param $dbxref_table
+ * @param $kv_table
  */
-function tripal_chado_add_bundle_cvterm_field($entity_type_name, $bundle_name, $cvterm_table, $base_table) {
-  // We already have a dbxref_id field.
-  $field_name = $cvterm_table;
-  $schema = chado_get_schema($cvterm_table);
-  $pkey = $schema['primary key'][0];
+function tripal_chado_add_bundle_kvproperty_adder_field($entity_type_name, $bundle_name, $kv_table, $base_table) {
+  $field_name = $kv_table;
 
   // Initialize the field array.
   $field_info = array(
-    'field_type' => 'cvterm',
-    'widget_type' => 'tripal_fields_cvterm_widget',
-    'widget_settings' => array('display_label' => 1),
-    'description' => '',
-    'label' => 'Annotations',
-    'is_required' => 0,
-    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-    'storage' => 'field_chado_storage',
+    'field_type' => 'kvproperty_adder',
+    'widget_type' => 'tripal_fields_kvproperty_adder_widget',
     'field_settings' => array(
-      // The Chado table that this field maps to.
-      'chado_table' => $cvterm_table,
-      // The column in the chado table that this field maps to.
-      'chado_column' => $pkey,
-      // The base table that this field is connected to.
       'base_table' => $base_table,
-      'semantic_web' => array(
-        // The type is the term from a vocabulary that desribes this field..
-        'type' => '',
-        // The namepsace for the vocabulary (e.g. 'foaf').
-        'ns' => '',
-        // The URL for the namespace.  It must be that the type can be
-        // appended to the URL.
-        'nsurl' => '',
-      ),
     ),
+    'storage' => 'field_chado_storage',
+    'widget_settings' => array('display_label' => 1),
+    'description' => '',
+    'label' => 'Additional Properties',
+    'is_required' => 0,
   );
-
   tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
 }
 /**
@@ -1149,26 +1182,25 @@ function tripal_chado_add_bundle_cvterm_field($entity_type_name, $bundle_name, $
  * @param $bundle_name
  * @param $kv_table
  */
-function tripal_chado_add_bundle_kvproperty_adder_field($entity_type_name, $bundle_name, $kv_table, $base_table) {
+function tripal_chado_add_bundle_cvterm_class_adder_field($entity_type_name, $bundle_name, $cvterm_table, $base_table) {
   // First add a generic property field so that users can add new property types.
-  $field_name = $kv_table;
+  $field_name = $cvterm_table;
 
   // Initialize the field array.
   $field_info = array(
-    'field_type' => 'kvproperty_adder',
-    'widget_type' => 'tripal_fields_kvproperty_adder_widget',
+    'field_type' => 'cvterm_class_adder',
+    'widget_type' => 'tripal_fields_cvterm_class_adder_widget',
     'field_settings' => array(
       'base_table' => $base_table,
     ),
     'storage' => 'field_chado_storage',
     'widget_settings' => array('display_label' => 1),
     'description' => '',
-    'label' => 'Additional Properties',
+    'label' => 'Additional Annotation Types',
     'is_required' => 0,
   );
   tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
 }
-
 /**
  * Adds the fields for the base table to the entity.
  */

+ 5 - 0
tripal_panes/tripal_panes.module

@@ -303,6 +303,11 @@ function tripal_panes_form_field_ui_display_overview_form_pane_configure (&$form
         ->condition('id', $field->field_id)
         ->execute()
         ->fetchObject();
+      // If the table gets out of sync (e.g. field are deleted manually)
+      // the the object may be empty.
+      if (!$field_obj) {
+        continue;
+      }
       $field_arr = unserialize($field_obj->data);
       $fname = $field_obj->field_name;
       if($fname == 'featureprop' || $fname == 'projectprop' || $fname == 'analysisprop' || $fname == 'organismprop') {