Break database field into multiple form fields

Hi, I have a table which has a field for storing telephone numbers, could be anything but it has to be in E.164 format. I don't want to split the number field into multiple ones as that would create a big form instead I want my form to show it in E.164 format and store it as number then later on I can show it as that format. How can I make the field to have multiple inputs? I have tried with $fields['tel'][] = {assigning original field with changing name attribute to array} but didn't worked.

Comments

  • Are you wanting the field to act similar to the datetime field in which it has multiple fields that get concatenated (date, hour, min, am/pm) into a single value? If that's the case, I would look into using something like a "custom" field:

    $fields['tel'] = array('type' => 'custom', 'value' => '<input type="text" name="tel_1"> '<input type="text" name="tel_2">');
    

    And then use the on_before_save() hook on your model to concatenate:

    public function on_before_save($values = array())
    {
         if (!empty($values['tel_1'] AND !empty($values['tel_2))
         {
              $values['tel'] = $values['tel_1'] . $values['tel_2'];
         }
    
         return $values;
    }
    
  • Yes you got it correct and thanks for the solution, i'll try that.

  • Hey there, I have tried your solution and it worked perfectly, but now when I go to edit the field, I get the custom field as string in td, although I have tried to recreate it by checking if $values is not empty and filling the values for the custom field, same as I have done for the create form field, but I still get my values as static i.e. not editable inputs but a string in td

  • I tried to edit and save the form as it as and after first save it returns back with error for my custom field value not being there and then they are rendered correctly i.e. they are shown as editable in the form and then when I click save they are saved correctly. What's happening?

  • In the example above, there looks to be an extra single quote in the example provided. Could you paste in your current code implementation with the correction?

  • public function form_fields($values = array(), $related = array())
        {
            $fields = parent::form_fields($values, $related);
            // put in your own specific code to manipulate the fields here
            if (!empty($values)) {
                $telValue = explode('-', explode('+', $values['tel'])[1]);
                $telValue = '<label for="tel[]">+</label><input type="text" name="tel[]" size="4" value="' . $telValue[0] . '"><label>-</label><input type="text" name="tel[]" size="3" value="' . $telValue[1] . '"><label>-</label><input type="text" name="tel[]" size="4" value="' . $telValue[2] . '"><label>-</label><input type="text" name="tel[]" size="4" value="' . $telValue[3] . '">';
                $faxValue = explode('-', explode('+', $values['fax'])[1]);
                $faxValue = '<label for="fax[]">+</label><input type="text" name="fax[]" size="4" value="' . $faxValue[0] . '"><label>-</label><input type="text" name="fax[]" size="3" value="' . $faxValue[1] . '"><label>-</label><input type="text" name="fax[]" size="4" value="' . $faxValue[2] . '"><label>-</label><input type="text" name="fax[]" size="4" value="' . $faxValue[3] . '">';
            } else {
                $telValue = '<label for="tel[]">+</label><input type="text" name="tel[]" size="4"><label>-</label><input type="text" name="tel[]" size="3"><label>-</label><input type="text" name="tel[]" size="4"><label>-</label><input type="text" name="tel[]" size="4">';
                $faxValue = '<label for="fax[]">+</label><input type="text" name="fax[]" size="4"><label>-</label><input type="text" name="fax[]" size="3"><label>-</label><input type="text" name="fax[]" size="4"><label>-</label><input type="text" name="fax[]" size="4">';
            }
            $fields['tel'] = array('type' => 'custom','value' => $telValue,'label' => 'Tel: +XX-XXX-XXXX-XXX');
            $fields['fax'] = array('type' => 'custom','value' => $faxValue,'label' => 'Fax: +XX-XXX-XXXX-XXX');
            return $fields;
        }
    

    Hope you can understand by it.

  • And what does your on_before_save look like?

  • this is the on_before_save

    public function on_before_save($values = array()) {
            if (isset($values['tel'][0]) && isset($values['tel'][1]) && isset($values['tel'][2]) &&
                isset($values['tel'][3])) {
                $values['tel'] = '+' . $values['tel'][0] . '-' . $values['tel'][1] . '-' . $values['tel'][2] . '-' .
                    $values['tel'][3];
            }
            if (isset($values['fax'][0]) && isset($values['fax'][1]) && isset($values['fax'][2]) &&
                isset($values['fax'][3])) {
                $values['fax'] = '+' . $values['fax'][0] . '-' . $values['fax'][1] . '-' . $values['fax'][2] . '-' .
                    $values['fax'][3];
            }
            return $values;
        }
    

    but I want the edit form to come as same as create form where I have field broken in parts

  • The reason that is happening is because the saved value overwrites the $telValue and $faxValue upon rendering and so the inputs get lost. I would recommend in this case using a field name that doesn't match the saved field's name (e.g. tel_parts[], fax_parts[]) and then assemble in the on_before_save with those values. To get all posted data (and not just the values specific to the model, you can use the following in on_before_save():

    public function on_before_save($values = array()) {
    
            $data = $this->normalize_data($values);
    
            if (isset($values['tel_parts'][0]) && isset($values['tel_parts'][1]) && isset($values['tel_parts'][2]) &&
                isset($values['tel_parts'][3])) {
                $values['tel'] = '+' . $values['tel_parts'][0] . '-' . $values['tel_parts'][1] . '-' . $values['tel_parts'][2] . '-' .
                    $values['tel_parts'][3];
            }
            if (isset($values['fax_parts'][0]) && isset($values['fax_parts'][1]) && isset($values['fax_parts'][2]) &&
                isset($values['fax_parts'][3])) {
                $values['fax'] = '+' . $values['fax_parts'][0] . '-' . $values['fax_parts'][1] . '-' . $values['faxfax_parts][2] . '-' .
                    $values['fax_parts'][3];
            }
    
            return $values;
        }
    
  • Will the above work for when editing the form? As I don't get inputs of tel or fax when editing a form

  • Sorry... you will need to adjust your form_fields method to use the "tel_parts" and "fax_parts" as well. The on_before_save should be used to assemble them into their true storable values.

  • I think I did not explain clearly last time as what I was asking is that if I try your above method, will this bring the tel and fax fields as editable when I want to edit an already saved entry? As right now I am getting all entries editable except these two when editing a saved entry

  • I'm not quite sure I understand what you mean by "getting all entries editable except these two". Do mean the values you are entering are not saving? If so, if you do a print_r($values); exit(); at the end of the on_before_save method, is your properly formatted value correct?

  • Hmm... okay. Let's say I create a new entry with the custom fields I have made, this works fine and I can save it correctly, problem occurs when I go to edit the same entry that I just saved, as I can edit or delete the entries I create for a module, right? When I edit it, except the custom fields, all fields come in input filled with the values currently saved, but the custom fields come as text and not in an input, like in a simple <td>custom field saved value here</td>. I want it to come as the same custom field that comes when I am creating a new entry. Is that understandable?

  • What about this:

    public function form_fields($values = array(), $related = array())
        {
            $fields = parent::form_fields($values, $related);
            // put in your own specific code to manipulate the fields here
            if (!empty($values)) {
                $telValue = explode('-', explode('+', $values['tel'])[1]);
                $telValue = '<label for="tel_parts[]">+</label><input type="text" name="tel_parts[]" size="4" value="' . $telValue[0] . '"><label>-</label><input type="text" name="tel_parts[]" size="3" value="' . $telValue[1] . '"><label>-</label><input type="text" name="tel_parts[]" size="4" value="' . $telValue[2] . '"><label>-</label><input type="text" name="tel_parts[]" size="4" value="' . $telValue[3] . '">';
                $faxValue = explode('-', explode('+', $values['fax'])[1]);
                $faxValue = '<label for="fax_parts[]">+</label><input type="text" name="fax_parts[]" size="4" value="' . $faxValue[0] . '"><label>-</label><input type="text" name="fax_parts[]" size="3" value="' . $faxValue[1] . '"><label>-</label><input type="text" name="fax_parts[]" size="4" value="' . $faxValue[2] . '"><label>-</label><input type="text" name="fax_parts[]" size="4" value="' . $faxValue[3] . '">';
            } else {
                $telValue = '<label for="tel_parts[]">+</label><input type="text" name="tel_parts[]" size="4"><label>-</label><input type="text" name="tel_parts[]" size="3"><label>-</label><input type="text" name="tel_parts[]" size="4"><label>-</label><input type="text" name="tel_parts[]" size="4">';
                $faxValue = '<label for="fax_parts[]">+</label><input type="text" name="fax_parts[]" size="4"><label>-</label><input type="text" name="fax_parts[]" size="3"><label>-</label><input type="text" name="fax_parts[]" size="4"><label>-</label><input type="text" name="fax_parts[]" size="4">';
            }
            $fields['tel_parts'] = array('type' => 'custom','value' => $telValue,'label' => 'Tel: +XX-XXX-XXXX-XXX');
            $fields['fax_parts'] = array('type' => 'custom','value' => $faxValue,'label' => 'Fax: +XX-XXX-XXXX-XXX');
            return $fields;
        }
    
  • Great! I'll try this

Sign In or Register to comment.