1
\$\begingroup\$

I am building an application full of forms and so I thought it is good idea to create a class to populate form fields.

Here is my class and I am sure it can be optimized more than now and could be better.

class JS_Forms
{

    public function __construct()
    {
        //$this->register_fields($fields);
    }

    public function register_fields($fields)
    {
        $text_array = array_flip(array('type', 'name', 'id', 'placeholder', 'required', 'data-length', 'class', 'value'));
        $uploads = array_flip(array('type', 'name'));

        foreach ($fields as $value)
        {

            switch ($value['type'])
            {
                case 'text':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['id'], array('class' => $value['label_class']));

                    unset($value['label_class']);
                    unset($value['label']);
                    $value['value'] = set_value($value['id'], is_null($value['obj']) ? $value['std'] : $value['obj']);
                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;                                                           
                    echo form_input(array_intersect_key($value, $text_array));
                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';

                    break;

                case 'upload':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['name'], array('class' => $value['label_class']));

                    unset($value['label_class']);
                    unset($value['label']);
                    unset($value['value']);
                    //$value['value'] = set_value($value['id'], is_null($value['obj']) ? $value['std'] : $value['obj']);
                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;                                                           
                    echo form_upload(array_intersect_key($value, $uploads));
                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';                    

                    break;

                case 'jupload':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['name'], array('class' => $value['label_class']));

                    unset($value['label_class']);
                    unset($value['label']);
                    unset($value['value']);

                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;

                    echo '<div class="fileinput fileinput-new" data-provides="fileinput">';
                    echo '<div class="input-group">';
                    echo '<div class="form-control uneditable-input" data-trigger="fileinput">';
                    echo '<i class="fa fa-file fileinput-exists"></i>&nbsp;<span class="fileinput-filename"></span>';
                    echo '</div>';
                    echo '<span class="input-group-addon btn btn-default btn-file">';
                    echo '<span class="fileinput-new">Select file</span>';
                    echo '<span class="fileinput-exists">Change</span>';

                    echo form_upload(array_intersect_key($value, $uploads));             
//                  
                    echo '</span>';
                    echo '<a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>';
                    echo '</div>';
                    echo '</div>';

                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';

                    break;

                case 'textarea':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['id'], array('class' => $value['label_class']));

                    unset($value['label_class']);
                    unset($value['label']);
                    $value['value'] = set_value($value['id'], is_null($value['obj']) ? $value['std'] : $value['obj']);
                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;
                    echo form_textarea($value);
                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';

                    break;

                case 'select':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['id'], array('class' => $value['label_class']));

                    unset($value['label_class']);
                    unset($value['label']);

                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;
                    // Important! here you need to set selected item value using core helper 'set_selected()'
                    echo form_dropdown($value['name'], $value['options'], set_value($value['id'], is_null($value['obj']) ? $value['std'] : $value['obj']), 'class="' . $value['class'] . '"');
                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';

                    break;


                case 'multiselect':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['id'], array('class' => $value['label_class']));

                    unset($value['label_class']);
                    unset($value['label']);

                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;

                    //---
                    $id    = array_key_exists('id', $value) ? 'id="' . $value['id'] . '"' : NULL;
                    $class = array_key_exists('class', $value) ? 'class="' . $value['class'] . '"' : 'class="multi-select"';
                    $name  = array_key_exists('name', $value) ? $value['name'] : NULL;



                    echo '<select multiple="multiple" ' . $class . $id . ' name="' . $name . '[]">';
                    $items   = $value['options'];
                    $selects = explode(',', $value['obj']);

                    echo '<option value="null" selected class="disabled" style="display:none">Selected</option>';

                    foreach ($items as $key => $item)
                    {

                        $selected = in_array($key, $selects) ? 'selected="selected"' : NULL;
                        echo '<option value="' . $key . '" ' . $selected . '>' . $item . '</option>';
                    }

                    echo '</select>';

                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';

                    break;

                case 'radio':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['name'], array('class' => $value['label_class'], 'style' => $value['style']));

                    $options = $value['options'];

                    unset($value['label_class']);
                    unset($value['label']);

                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;
                    foreach ($value['options'] as $key => $radio)
                    {
                        echo (array_key_exists('block', $value) && $value['block'] == TRUE) ? '<div class="radio">' : NULL;

                        echo form_label(form_radio(array('name' => $value['name'], 'id' => $value['name'] . '-' . $key), $key, $value['std'] == $key ? TRUE : FALSE, ($key == $value['obj']) ? set_radio($value['name'], $value['obj'], TRUE) : set_radio($value['name'], $key)) . $radio, $value['name'] . '-' . $key, ((array_key_exists('block', $value) && $value['block'] == TRUE) ? NULL : array('class' => $value['radio_lable_class'])));

                        echo (array_key_exists('block', $value) && $value['block'] == TRUE) ? '</div>' : NULL;
                    }
                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';

                    break;

                case 'checkbox':

                    echo '<div class="form-group">';
                    echo form_label(lang($value['label']), $value['name'], array('class' => $value['label_class'], 'style' => $value['style']));

                    $options = $value['options'];

                    unset($value['label_class']);
                    unset($value['label']);

                    echo array_key_exists('field_class', $value) ? '<div class="' . $value['field_class'] . '">' : NULL;

                    echo (array_key_exists('required', $value) && $value['required'] == TRUE) ? form_hidden($value['name'] . '[]', 'null') : NULL;

                    foreach ($value['options'] as $key => $checkbox)
                    {
                        $checked = explode(',', $value['obj']);
                        echo (array_key_exists('block', $value) && $value['block'] == TRUE) ? '<div class="checkbox">' : NULL;
                        echo form_label(form_checkbox(array('name' => $value['name'] . '[]', 'id' => $value['name'] . '-' . $key), $key, in_array($key, $checked) ? set_checkbox($value['name'], $key, TRUE) : FALSE) . $checkbox, $value['name'] . '-' . $key, ((array_key_exists('block', $value) && $value['block'] == TRUE) ? NULL : array('class' => $value['checkbox_lable_class'])));
                        echo (array_key_exists('block', $value) && $value['block'] == TRUE) ? '</div>' : NULL;
                    }
                    echo array_key_exists('field_class', $value) ? '</div>' : NULL;
                    echo '</div>';

                    break;

                default:
                    break;
            }
        }
    }

}

Usage

$fields = array(
    array(
        'type'           => 'text',
        'label'          => 'emp_employee_id',
        'label_class'    => 'col-sm-3 control-label',
        'field_class'    => 'col-sm-9',
        'name'           => 'employee_id',
        'id'             => 'employee_id',
        'placeholder'    => 'e.g. 912',
        'required'       => 'required',
        'data-minlength' => 3,
        'class'          => 'form-control',
        'std'            => '',
        'obj'            => segment_is_num(4, $employee, 'first_name', NULL),
    ),
    array(
        'type'           => 'text',
        'label'          => 'emp_firstname',
        'label_class'    => 'col-sm-3 control-label',
        'field_class'    => 'col-sm-9',
        'name'           => 'first_name',
        'id'             => 'first_name',
        'placeholder'    => 'The Place Holder',
        'required'       => 'required',
        'data-minlength' => 3,
        'class'          => 'form-control',
        'std'            => 'Jatin',
        'obj'            => segment_is_num(4, $employee, 'first_name', NULL),
    ),
    array(
        'type'        => 'select',
        'label'       => 'emp_lastname',
        'label_class' => 'col-sm-3 control-label',
        'field_class' => 'col-sm-9',
        'name'        => 'last_name',
        'id'          => 'last_name',
        'class'       => 'form-control',
        'options'     => array('one' => 'One', 'two' => 'Two', 'three' => 'Three'),
        'std'         => 'three',
        'obj'         => segment_is_num(4, $employee, 'last_name', NULL),
    ),
    array(
        'type'              => 'radio',
        'label'             => 'emp_gender',
        'label_class'       => 'col-sm-3 control-label',
        'field_class'       => 'col-sm-9',
        'radio_lable_class' => 'radio-inline',
        'name'              => 'gender',
        'options'           => array('male' => 'Male', 'female' => 'Female'),
        'std'               => 'male',
        'style'             => 'display: block',
        'obj'               => segment_is_num(4, $employee, 'gender', NULL),
    ),
    array(
        'type'                 => 'checkbox',
        'block'                => false,
        'label'                => 'emp_country',
        'label_class'          => 'col-sm-3 control-label',
        'field_class'          => 'col-sm-9',
        'checkbox_lable_class' => 'checkbox-inline',
        'name'                 => 'country',
        'options'              => array('india' => 'India', 'mauritius' => 'Mauritius', 'japan' => 'Japan'),
        'std'                  => 'india',
        'style'                => 'display: block',
        'required'             => TRUE,
        'obj'                  => segment_is_num(4, $employee, 'country', NULL),
    ),
    array(
        'type'        => 'textarea',
        'label'       => 'emp_attrition_comment',
        'label_class' => 'col-sm-3 control-label',
        'field_class' => 'col-sm-9',
        'name'        => 'attrition_comment',
        'id'          => 'attrition_comment',
        'placeholder' => 'The Place Holder',
        'class'       => 'form-control',
        'std'         => 'Soni',
        'obj'         => segment_is_num(4, $employee, 'attrition_comment', NULL),
    ),
    array(
        'type'        => 'multiselect',
        'label'       => 'emp_nationality',
        'label_class' => 'col-sm-3 control-label',
        'field_class' => 'col-sm-9',
        'name'        => 'nationality',
        'id'          => 'nationality',
        'class'       => 'form-control',
        'options'     => array('indian' => 'Indian', 'mauritian' => 'Mauritian', 'american' => 'American'),
        'std'         => 'indian',
        'obj'         => segment_is_num(4, $employee, 'nationality', NULL),
    ),
    array(
        'type'           => 'jupload',
        'label'          => 'emp_nid',
        'label_class'    => 'col-sm-3 control-label',
        'field_class'    => 'col-sm-9',
        'name'           => 'employee_snap',
    ),
);

// populate form firles using the 'js_forms' library
$this->js_forms->register_fields($fields);
\$\endgroup\$
7
  • 2
    \$\begingroup\$ Is your intent to auto populate a form from a database row? You've not provided any example of how this would be used. As far as coding best practices goes, this leaves a little to be desired. \$\endgroup\$
    – B2K
    Apr 16, 2014 at 13:58
  • \$\begingroup\$ why is there a commented part in your constructor that is floating there. If its useless please remove it - if it serves purpose you need to attach or explain what is the purpose. \$\endgroup\$
    – azngunit81
    Apr 16, 2014 at 22:59
  • \$\begingroup\$ @B2K Please see my updated question with Usage code. I am using array to populate the form. But may be in future I can store such thing into database and populate using rows as well. \$\endgroup\$ Apr 17, 2014 at 5:34
  • \$\begingroup\$ @azngunit81 please ignore the commented part. Nothing to deal with that. In fact I may remove the __construct() as well \$\endgroup\$ Apr 17, 2014 at 5:35
  • \$\begingroup\$ please provide a possible output. \$\endgroup\$
    – azngunit81
    Apr 17, 2014 at 6:14

1 Answer 1

2
\$\begingroup\$

One of the issues you will run into in the future is the coupling of your presentation output (HTML) to the functionality of the class. You also have many sections of repeating output which should likely be outside of each case statement, but within the loop.

You wish to optimize the class, but haven't really chosen what to optimize it for. I'll repeat the cliche of "Premature optimization is the root of all evil".

Where you have separated out the fields into an array...great! That is a good step towards reuse. You should be able to take this config, paste it into another project and be able to generate a similar form field. Assuming you have the form class available as well. If you look into some of the available frameworks their Form and Field classes can operate in a similar manner. Take a config (an array possibly) and pass it to a Form class which will take each 'field' part of the config and create a new Field class and make sure all the parts are tied together.

One good starting point to help make the code more readable is instead of the switch statement, make a second set of classes which has one class for each field type you wish to have available. Once you have separated the 'types' into classes, then you will likely see the similarities between all the different types. That becomes a good opportunity to create a parent field class that all the other fields can extend. This will further reduce the code you need to manage.

You can continue to move your class forward, but you may find it beneficial to look at the available frameworks, review their code and either pull in the best elements, or, pull in their code and use it in your project. That way you gain all the insights from others as to what makes a good form management solution.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.