Change the text field maximum length in Drupal 8

Submitted by on

Once a text field has data stored, it is not very easy or obvious how to change its maximum length. In the UI there is a message warning you that the field cannot be changed, because there is existing data. Sometimes it is necessary to change these values. It seems that there are a few ways and some resources to do this in Drupal 7, but I could not find a way to do this in Drupal 8. I decided to create a small function to do it:

Caution: Any change in the database needs to be done carefully. Before you continue please create a backup of your database.

/**
 * Update the length of a text field which already contains data.
 *
 * @param string $entity_type_id
 * @param string $field_name
 * @param integer $new_length
 */
function _module_change_text_field_max_length ($entity_type_id, $field_name, $new_length) {
  $name = 'field.storage.' . $entity_type_id . "." . $field_name;

  // Get the current settings
  $result = \Drupal::database()->query(
    'SELECT data FROM {config} WHERE name = :name',
    [':name' => $name]
  )->fetchField();
  $data = unserialize($result);
  $data['settings']['max_length'] = $new_length;

  // Write settings back to the database.
  \Drupal::database()->update('config')
    ->fields(['data' => serialize($data)])
    ->condition('name', $name)
    ->execute();

  // Update the value column in both the _data and _revision tables for the field
  $table = $entity_type_id . "__" . $field_name;
  $table_revision = $entity_type_id . "_revision__" . $field_name;
  $new_field = ['type' => 'varchar', 'length' => $new_length];
  $col_name = $field_name . '_value';
  \Drupal::database()->schema()->changeField($table, $col_name, $col_name, $new_field);
  \Drupal::database()->schema()->changeField($table_revision, $col_name, $col_name, $new_field);

  // Flush the caches.
  drupal_flush_all_caches();
}

This method needs the name of the entity, the name of the field, and the name and the new length.

And we can use it like this:

   _module_change_text_field_max_length('node', 'field_text', 280);
  

Usually, this code should be placed in (or called from) a hook_update so it will be executed automatically in the update.

And if the new length is too long to be placed in a regular input area, you can use the Textarea widget for text fields which will allow you to use the larger text area form element for text fields.

Comments

Submitted by Hamza on Tue, 12/05/2017 - 01:50

Thanks for the to-the-point tutorial. This looks like a small thing but can prove to be quite helpful in a lot of situations.

Submitted by gambry on Wed, 12/06/2017 - 08:44

If what you want to achieve is just changing the field maxlength to affect the field widget (form element), you should not alter the database but simply create your custom widget: https://gist.github.com/gambry/87fc6b4be05713addc4694de407bc1a6

Of course the maximum size is still limited by the table field size.

Submitted by on Thu, 12/07/2017 - 14:30

Yes, I think that is exactly what the `textarea widget for text` module does: https://www.drupal.org/project/textarea_widget_for_text

Thanks for sharing.

Submitted by Marcelo on Thu, 12/14/2017 - 14:22

Thanks!!!!

Add new comment