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 befo开发者_运维知识库re 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();
?>
EDIT:I've found an inline form validation plugin that is ideal for this. Link is here. http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/
So far so good.
EDIT2: Ok, the inline validator is working really well. What I've decided to do is to put basic validation in the model before it submits to the database. This prevents anything bad actually getting to the database. But I'm using the form validator to provide instant feedback.
I have build something similar before.
What i did is develop a Validation_lib Class, which is a class build on top of Kohana Validation.
It is something similar like:
class Validation_lib {
static private $instance = NULL;
private function __construct()
{
// Can overload Configs here
}
public static function instance()
{
if (self::$instance === NULL)
{
self::$instance = new self;
}
return self::$instance;
}
public function validate_dynamic($post)
{
$validate = new Validation($post);
foreach ($post as $dynamic_key => $value)
{
switch ($dynamic_key)
{
// Do switch + regex matching for your $post['dynamic_name']
// You can have maybe prepended 'phone_' for field of phone type
// You can have maybe prepended 'mail_' for field of mail type..
case (//regex match mailhere):
$validate->add_rules($key ,'required', valid::Email);
break;
}
}
}
}
Hope this helps :)
精彩评论