Drupal 8 - Add more rows in table form

By xngo on March 20, 2019


To add more rows in the form table, you have to use the following strategies:

  • Hold globally somewhere the total number of rows, $form_state->set('num_of_rows', $num_of_rows).
  • Make your buildForm() function to build form according to $num_of_rows.

That is it!

Codes below will create the following input form:

Screenshot of table form with add row button

Create routing for your input page

For my case, I added the routing informations of my input page in ./modules/tradesteps/tradesteps.routing.yml as follows:

  path: '/form_table_add_row'
    _form: 'Drupal\tradesteps\Form\FormTableAddMoreRow'
    _title: 'Form Table Add More Rows'
    _permission: 'access content'

Implement the table form with add more row button

Here is how I implement my table form with add more row button in my ./modules/tradesteps/src/Form/FormTableAddMoreRow.php:

namespace Drupal\tradesteps\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class FormTableAddMoreRow extends FormBase {
    public function getFormId() {
        return 'tradesteps_form_table_add_row';
    public function buildForm(array $form, FormStateInterface $form_state) {
        // Get the number of rows, default to 2 rows.
        $num_of_rows = $form_state->get('num_of_rows');
        if (empty($num_of_rows)){
            $form_state->set('num_of_rows', $num_of_rows);
        // Add the headers.
        $form['contacts'] = array(
                                    '#type' => 'table',
                                    '#title' => 'Sample Table',
                                    '#header' => array('Name', 'Phone'),
        // Create rows according to $num_of_rows.
        for ($i=1; $i<=$num_of_rows; $i++) {
            $form['contacts'][$i]['name'] = array(
                                                '#type' => 'textfield',
                                                '#title' => t('Name'),
                                                '#title_display' => 'invisible',
                                                '#default_value' => 'name'.$i,
            $form['contacts'][$i]['phone'] = array(
                                                '#type' => 'tel',
                                                '#title' => t('Phone'),
                                                '#title_display' => 'invisible',
                                                '#default_value' => '763-999-444'.$i,
        // 'Add row' button.
        $form['actions']['add_row'] = [
                                        '#type' => 'submit',
                                        '#value' => $this->t('Add row'),
                                        '#submit' => array('::addRowCallback'),
        // Submit button.
        $form['actions']['submit'] = [
                                        '#type' => 'submit',
                                        '#value' => $this->t('Submit'),
        return $form;
    public function addRowCallback(array &$form, FormStateInterface $form_state) {
        // Increase by 1 the number of rows.
        $num_of_rows = $form_state->get('num_of_rows');
        $form_state->set('num_of_rows', $num_of_rows);
        // Rebuild form with 1 extra row.
    public function submitForm(array &$form, FormStateInterface $form_state) {
        // Find out what was submitted.
        $values = $form_state->getValues();

Test Add row button

  1. Clear your cache.
  2. Open http://your-domain.com/form_table_add_row
  3. Click on Add row button and then on Submit button.

Screenshot after submit of table form with add row button


  • https://github.com/xuanngo2001/drupal-form-table-add-row.git

About the author

Xuan Ngo is the founder of OpenWritings.net. He currently lives in Montreal, Canada. He loves to write about programming and open source subjects.