Feedback

Nested Elements

#Group Element

Group elements are used when elements should be groupped on a schema level but their data structure should remain flat. Let's see an example:

<?php

namespace App\Laraform;

class GroupForm extends \Laraform
{
  public function schema() {
    return [
      'name' => [
        'type' => 'group',
        'label' => 'Name',
        'schema' => [
          'firstname' => [
            'type' => 'text',
            'placeholder' => 'First name',
            'columns' => 6
          ],
          'lastname' => [
            'type' => 'text',
            'placeholder' => 'Last name',
            'columns' => 6
          ]
        ]
      ]
    ];
  }
}

This is a typical example how name is usually visualized in forms: there's a single label for the row, but two elements within, firstname and lastname.

While we group the element on the schema level their data structure does not become groupped or nested, but remain flat. This is how the data object would look like if you submitted the form:

data: {
  firstname: 'John',
  lastname: 'Doe'
}

#Object Element

Object element is very similiar to Group, except for one thing: it not only groups the elements on a schema level, but the elements within will have a nested data structure.

Let's take another example, but this time use object as a type for name:

<?php

namespace App\Laraform;

class ObjectForm extends \Laraform
{
  public function schema() {
    return [
      'name' => [
        'type' => 'object',
        'label' => 'Name',
        'schema' => [
          'firstname' => [
            'type' => 'text',
            'placeholder' => 'First name',
            'columns' => 6
          ],
          'lastname' => [
            'type' => 'text',
            'placeholder' => 'Last name',
            'columns' => 6
          ]
        ]
      ]
    ];
  }
}

If you submit the form now, you'll notice that the data object will be nested:

data: {
  name: {
    firstname: 'John',
    lastname: 'Doe'
  }
}

#List Element

List allows you to repeat certain elements. Let's say you have a football team and you want to add the name of different players. This is how a form would look like for that:

<?php

namespace App\Forms;

class TeamForm extends \Laraform
{
  public function schema() {
    return [
      'name' => [
        'type' => 'text',
        'label' => 'Team name'
      ],
      'members' => [
        'type' => 'list',
        'label' => 'Team members',
        'element' => [
          'type' => 'text',
          'placeholder' => 'Name'
        ]
      ]
    ];
  }
}

The list type element contains the names of the players and define the repeatable element under its element property. This way members will be an array of team member names:

data: {
  name: 'Purple Cobras',
  members: ['Josh', 'John', 'James']
}

Saving Single Element Lists To Database

If you want to save the members to a single column in the database you can use Laravel model's $casts property to cast it as an array:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Team extends Model
{
    protected $casts = [
      'member' => 'array'
    ];

    // ...
}

#Repeat Objects

What if we need other informations about the players like their shirt numbers or birthdays? They can be defined by using the object property instead of element:

<?php

namespace App\Forms;

class TeamForm extends \Laraform
{
  public function schema() {
    return [
      'name' => [
        'type' => 'text',
        'label' => 'Team name'
      ],
      'members' => [
        'type' => 'list',
        'label' => 'Team members',
        'object' => [
          'label' => 'Member'
          'schema' => [
            'name' => [
              'type' => 'text',
              'placeholder' => 'Name'
            ],
            'shirt_number' => [
              'type' => 'text',
              'placeholder' => 'Shirt number'
            ],
            'birthday' => [
              'type' => 'date',
              'placeholder' => 'Birthday'
            ]
          ]
        ]
      ]
    ];
  }
}

Now each member of the team will be an object in the members array:

data: {
  name: 'Purple Cobras',
  members: [
    {
      name: 'Josh',
      shirt_number: 7,
      birthday: '21/03/1988'
    },
    {
      name: 'John',
      shirt_number: 21,
      birthday: '18/05/1973'
    },
    {
      name: 'James',
      shirt_number: 9,
      birthday: '19/11/1983'
    },
  ]
}

Saving Object Element Lists To Database

To save object lists to database we can either use the same solution as with single element lists or handle them as relationships. In the next chapter we'll learn about dealing with Relationships.

#Sorting List Items

In some cases it might be important to enable the user to sort the items of the list. To do that set sort property to true:

<?php

namespace App\Forms;

class SortableForm extends \Laraform
{
  public function schema() {
    return [
      'todo' => [
        'type' => 'list',
        'label' => 'To-Do',
        'sort' => true,
        'element' => [
          'type' => 'text'
        ] 
      ]
    ];
  }
}

If you render this form you'll notice that the list items will can be dragged and sorted.

Storing Order

In case you want to store the order as an actual number, you need to use object listing type and add meta element, which will contain the order:

<?php

namespace App\Forms;

class SortableForm extends \Laraform
{
  public function schema() {
    return [
      'todo' => [
        'type' => 'list',
        'label' => 'To-Do',
        'sort' => true,
        'storeOrder' => 'order',
        'object' => [
          'schema' => [
            'name' => [
              'type' => 'text'
            ],
            'order' => [
              'type' => 'meta',
            ]
          ]
        ]
      ]
    ];
  }
}

Notice that we defined storeOrder option which instructs the list to store the order in the element called order.