How to structure a Kohana MVC application with dynamically added fields and provide validation and f
- by Matt H
I've got a bit of a problem.
I have a Kohana application that has dynamically added fields.
The fields that are added are called DISA numbers.
In the model I look these up and the result is returned as an array.
I encode the array into a JSON string and use JQuery to populate them
The View knows the length of the array and so creates as many DISA elements as required before display. See the code below for a summary of how that works.
What I'm finding is that this is starting to get difficult to manage. The code is becoming messy. Error handling of this type of dynamic content is ending up being
spread all over the place. Not only that, it doesn't work how I want.
What you see here is just a small snippet of code.
For error handling I am using the validation library. I started by using add_rules on all the fields that come back in the post. As they are always phone numbers I set a required rule (when it's there) and a digit rule on the validation-as_array() keys. That works.
The difficulty is actually giving it back to the view.
i.e. dynamically added javascript field. Submits back to form. Save contents into a session. View has to load up fields from database + those from the previous post and signal the fields that have problems. It's all quite messy and I'm getting this code spread through both the view the controller and the model.
So my question is. Have you done this before in Kohana and how have you handled it?
There must be an easier way right?
Code snippet.
-- edit.php --
public function phone($id){
...
$this->template->content->disa_numbers =
$phones->fetch_disa_numbers($this->account, $id);
...
}
-- phones.php --
public function fetch_disa_numbers($account, $id)
{
$query = $this->db->query("SELECT id, cid_in FROM disa WHERE owner_ext=?", array($id));
if (!$query){
return '';
}
return $query;
}
-- edit_phones.php ---
<script type="text/javascript">
var disaId = 1;
function delDisaNumber(element){
/* Put 'X_' on the front of the element name to mark this for deletion */
$(element).prev().attr('name', 'X_'+$(element).prev().attr('name'));
$(element).parent().hide();
}
function addDisaNumber(){
/* input name is prepended with 'N_' which means new */
$("#disa_numbers").append("<li><input name='N_disa"+disaId+"' id='disa'"+
"type='text'/><a class='hide' onClick='delDisaNumber(this)'></a></li>");
disaId++;
}
</script>
...
<php
echo form::open("edit/saveDisaNumbers/".$phone, array("class"=>"section", "id"=>"disa_form"));
echo form::open_fieldset(array("class"=>"balanced-grid"));
?>
<ul class="fields" id="disa_numbers">
<?php
$disaId = 1;
foreach ( $disa_numbers as $disa_number ){
echo '<li>';
echo form::input('disa'.$disaId, $disa_number->cid_in);
echo'<a class="hide" onclick="delDisaNumber(this)"></a>';
echo "</li>";
$disaId++;
}
?>
</ul>
<button type="button"onclick="addDisaNumber()"><a class="add"></a>Add number</button>
<?php
echo form::submit('submit', 'Save');
echo form::close();
?>