Organizing a Form with Sections
We now know it’s fairly easy to create form fields with Admin Page Framework (see Create a Form). What happens if you add many fields in a form in a single page? It will get messy and your users will have a hard time finding the right option to fill in.
If you have published a plugin/theme, you may have seen your user having troubles finding the option to change to get their desired results. One way to solve such a problem is to group fields by section. So you can direct your user by telling them which section that the option the user looking for belongs to.
To create form sections with Admin Page Framework, you just need to tell the framework which field belongs to which section. That’s pretty much it.
Steps
- Include the library
- Extend the library class
- Define the setUp() method
- Define sections and fields
- Instantiate the extended class
- Retrieve the saved options
Screenshot
Include the library
The library file needs to be loaded.
12 |
include( dirname( __FILE__ ) . '/library/apf/admin-page-framework.php' ); |
Extend the library class
This time, we use APF_CreateForm for the class name.
1 2 3 |
class APF_CreateForm extends AdminPageFramework { // our code goes here... } |
Define the setUp() method
In the setUp() method, we define the admin pages to be created. For that, we need to decide:
- the root page.
- the sub page title.
- the sub page slug.
We’ve covered this already in the previous tutorial.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class APF_CreateForm extends AdminPageFramework { // Define the setup() method to set how many pages, page titles and icons etc. public function setUp() { // Set the root menu $this->setRootMenuPage( 'Settings' ); // specifies to which parent menu to add. // Add the sub menus and the pages $this->addSubMenuItems( array( 'title' => '5. Adding Forms with Sections', // the page and menu title 'page_slug' => 'my_second_form' // the page slug ) ); |
Define sections and fields
To keep things simple, we only add two sections in this tutorial but it’s not limited to two and you can create sections and fields as many as necessary.
To define sections use the addSettingSecions() method and when you use the addSettingFields() method, tell it which section the field should belong to.
Section Definition Arguments
- section_id – (required, string) the section id.
- page_slug – (optional, string) the page slug that the section belongs to. If the target page slug is set, it can be omitted.
- and more. (for more details check out the documentation page for the method: addSettingSections())
Pass the target page slug to the first parameter and the section definition argument arrays to the rest.
31 32 33 34 35 36 37 38 39 40 41 42 43 |
$this->addSettingSections( 'my_second_form', array( 'section_id' => 'my_first_section', 'title' => 'My First Form Section', 'description' => 'This section is for text fields.', ), array( 'section_id' => 'my_second_section', 'title' => 'My Second Form Section', 'description' => 'This section is for selectors.', ) ); |
Next add fields to the sections we just added. Pass the target section ID to the first parameter and the field definition array to the rest. Notice the first field definition array contains empty arrays to create sub-fields. This is used to create multiple fields that share the same field settings with in a field. You can add as many sub-fields as you need.
For the first section, notice that the second field definition array has the repeatable key set to true. This makes the field repeatable, that is, the user can dynamically add/remove a copy of the field by pressing the add/remove button.
For the second section, we add the checkbox, select, radio, and submit types of fields. The last one has the show_title_column key set to false. This disables the title column of the field row. So the field output starts from the beginning of the row.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
$this->addSettingFields( 'my_first_section', array( 'field_id' => 'my_text_field', 'type' => 'text', 'title' => 'Text', 'description' => 'To create multiple fields of the same type, add arrays with numeric keys.', array(), // sub-field array(), // sub-field ), array( 'field_id' => 'my_repeatable_text_field', 'type' => 'text', 'title' => 'Text', 'repeatable' => true, ) ); $this->addSettingFields( 'my_second_section', array( 'field_id' => 'my_checkbox', 'type' => 'checkbox', 'title' => __( 'Checkbox', 'admin-page-framework-demo' ), 'label' => __( 'Check me.', 'admin-page-framework-demo' ), 'default' => false, ), array( 'field_id' => 'my_dropdown_list', 'title' => __( 'Drop-down List', 'admin-page-framework-demo' ), 'type' => 'select', 'default' => 1, // the index key of the label array below which yields 'Two'. 'label' => array( 0 => 'One', 1 => 'Two', 2 => 'Three', ), ), array( 'field_id' => 'radio', 'title' => __( 'Radio Button', 'admin-page-framework-demo' ), 'type' => 'radio', 'label' => array( 'a' => 'Apple', 'b' => 'Banana', 'c' => 'Cherry' ), 'default' => 'c', // yields Cherry; its key is specified. 'after_label' => '<br />', ), array( // Submit button 'field_id' => 'submit_button_b', 'type' => 'submit', 'show_title_column' => false, ) ); |
Instantiate the extended class
Finally, we instantiate the class. Unless it is instantiated, it will do nothing.
123 |
new APF_CreateForm; |
Retrieve the saved options
To retrieve the options, we can use the get_option() function. We’ve already covered it in a previous tutorial (see Create a Form). But now we have sections. When a section is set, the framework adds the section dimension to the saved option array and field values will be stored in the section dimension.
So the code to retrieve the option array in this particular tutorial project would be $data = get_option( ‘APF_CreateForm’ ); to retrieve the field value, say, my_text_field of the my_first_section section, you would do something like this.
1 2 3 4 |
$data = get_option( ‘APF_CreateForm’ ); $value = isset( $data['my_first_section']['my_text_field'] ) ? $data['my_first_section']['my_text_field'] : null; |
Alternatively, the framework has the method to retrieve the option data and it reduces the necessity to call the isset() function to check the existence of the key. We’ve covered this also in the previous tutorial but this time, there is the section dimension. So let’s see how the method is used to specify the section and the field.
115 116 |
echo '<pre>APF_CreateForm[my_first_section][my_text_field][0]: ' . AdminPageFramework::getOption( 'APF_CreateForm', array( 'my_first_section', 'my_text_field', 0 ), 'default' ) . '</pre>'; echo '<pre>APF_CreateForm[my_second_section][my_dropdown_list]: ' . AdminPageFramework::getOption( 'APF_CreateForm', array( 'my_second_section', 'my_dropdown_list' ), 'default' ) . '</pre>'; |
Notice that the second parameter is an array and it represents the keys of the each dimension.
Code
Try the code below and post comments if you get a problem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
<?php /* Plugin Name: Admin Page Framework Tutorial 05 - Organize a Form with Sections Plugin URI: http://en.michaeluno.jp/admin-page-framework Description: Organize a form with sections with Admin Page Framework v3 Author: Michael Uno Author URI: http://michaeluno.jp Version: 1.0.1 Requirements: PHP 5.2.4 or above, WordPress 3.4 or above. Admin Page Framework 3.0.0 or above */ include( dirname( __FILE__ ) . '/library/apf/admin-page-framework.php' ); // Extend the class class APF_CreateForm extends AdminPageFramework { // Define the setup() method to set how many pages, page titles and icons etc. public function setUp() { // Set the root menu $this->setRootMenuPage( 'Settings' ); // specifies to which parent menu to add. // Add the sub menus and the pages $this->addSubMenuItems( array( 'title' => '5. Adding Forms with Sections', // the page and menu title 'page_slug' => 'my_second_form' // the page slug ) ); $this->addSettingSections( 'my_second_form', array( 'section_id' => 'my_first_section', 'title' => 'My First Form Section', 'description' => 'This section is for text fields.', ), array( 'section_id' => 'my_second_section', 'title' => 'My Second Form Section', 'description' => 'This section is for selectors.', ) ); // Add form fields $this->addSettingFields( 'my_first_section', array( 'field_id' => 'my_text_field', 'type' => 'text', 'title' => 'Text', 'description' => 'To create multiple fields of the same type, add arrays with numeric keys.', array(), // sub-field array(), // sub-field ), array( 'field_id' => 'my_repeatable_text_field', 'type' => 'text', 'title' => 'Text', 'repeatable' => true, ) ); $this->addSettingFields( 'my_second_section', array( 'field_id' => 'my_checkbox', 'type' => 'checkbox', 'title' => __( 'Checkbox', 'admin-page-framework-demo' ), 'label' => __( 'Check me.', 'admin-page-framework-demo' ), 'default' => false, ), array( 'field_id' => 'my_dropdown_list', 'title' => __( 'Drop-down List', 'admin-page-framework-demo' ), 'type' => 'select', 'default' => 1, // the index key of the label array below which yields 'Two'. 'label' => array( 0 => 'One', 1 => 'Two', 2 => 'Three', ), ), array( 'field_id' => 'radio', 'title' => __( 'Radio Button', 'admin-page-framework-demo' ), 'type' => 'radio', 'label' => array( 'a' => 'Apple', 'b' => 'Banana', 'c' => 'Cherry' ), 'default' => 'c', // yields Cherry; its key is specified. 'after_label' => '<br />', ), array( // Submit button 'field_id' => 'submit_button_b', 'type' => 'submit', 'show_title_column' => false, ) ); } /** * @callback action do_ + page slug */ public function do_my_second_form() { // Show the saved option value. // The extended class name is used as the option key. This can be changed by passing a custom string to the constructor. echo '<h3>Saved Values</h3>'; echo '<h3>Show as an Array</h4>'; echo $this->oDebug->getArray( get_option( 'APF_CreateForm' ) ); echo '<h3>Retrieve individual field values</h4>'; echo '<pre>APF_CreateForm[my_first_section][my_text_field][0]: ' . AdminPageFramework::getOption( 'APF_CreateForm', array( 'my_first_section', 'my_text_field', 0 ), 'default' ) . '</pre>'; echo '<pre>APF_CreateForm[my_second_section][my_dropdown_list]: ' . AdminPageFramework::getOption( 'APF_CreateForm', array( 'my_second_section', 'my_dropdown_list' ), 'default' ) . '</pre>'; } } // Instantiate the class object. new APF_CreateForm; |
Hi.
Is there a possibility to display form sections as tabs?
Tried to mixup tutorials 4 & 5, but it aint easy.
Much thanks.
Hi,
You can try the tutorial 6 and change the
repeatable
andsortable
arguments value tofalse
.I am getting “Not all form fields could not be sent. Please check your server settings of PHP max_input_vars and consult the server administrator to increase the value. max input vars: 10000. $_POST count: 38” on a simple form with only a few options.
Hi,
Post some example code that illustrates the problem on Gist or something similar so that I can reproduce the problem. And this site doesn’t send notifications for new replies so please use the wordpress.org support forum as I often miss them.
Thank you.