2016-04-28 79 views
1

我正在写一些东西,如果您选择某个按钮或下拉列表,我想更改某个字段的规则。基本上,逻辑是,检查一个按钮或从选择中选择一个ID,你不需要填充地址字段。我一直在努力做form_validation内的事情,而不是在他那里控制器我可以真正做到这样的事情从MY_Form_validation的codeigniter中删除规则

if(isset($_POST['checkbox'])){ 
    //check rules 
} 

所以,我已经做到了这一点:

public function check_address($str,$prefix=null){ 
    $this->set_message('check_address','Please select an address or fill out a new one'); 
    //var_dump($this->_field_data);exit; 
    $remove=array('address_line1','address_line2','address_line3','city','postcode'); 
    if($prefix!==null){ 
     foreach($remove as &$r){ 
      $r=$prefix.'_'.$r; 
     } 
    } 
    unset($r); 
    foreach($this->_field_data as $key=>$f){ 
     if(in_array($key,$remove)){ 
      unset($this->_field_data[$key]); 
     } 
    } 
} 

这种工作方式我想要它,但我认为我已经干扰了codeiginter的Form_Validation类,因为它会抛出一个错误,指出我的数组中没有设置所需的索引。

错误消息

A PHP Error was encountered 
Severity: Notice 
Message: Undefined index: billing_address_line1 
Filename: libraries/Form_validation.php 
Line Number: 481 

我不是真的太知道我怎么能达到什么我想做的事情没有什么干扰笨的需求?是否有另一个数组我需要删除,以便该键不排序?

我还通过删除所需要的规则,但所需要的功能,我认为一定是已经运行做到了这一点,现在

foreach($this->_field_data as $key=>&$f){ 
     if(in_array($key,$remove)){ 
      //unset($this->_field_data[$key]); 
      //str_replace('/required\|/','',$f['rules']); 
      //str_replace('/required/','',$f['rules']); 
      foreach($f['rules']as$r=>$val){ 
       $val=strtolower($val); 
       if($val=='required')unset($f['rules'][$r]); 
      } 
      var_dump($f); 
     } 
    } 
    unset($f); 

现在,这并不需要什么?

规则

$this->con['validation']['checkout']=array(


     array('field'=>'address_line1','label'=>'Address line 1','rules'=>'required|min_length[3]|max_length[200]|check_basket'), 
     array('field'=>'address_line2','label'=>'Address line 2','rules'=>'min_length[3]|max_length[200]'), 
     array('field'=>'address_line3','label'=>'Address line 3','rules'=>'min_length[3]|max_length[200]'), 
     array('field'=>'city','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[50]'), 
     array('field'=>'postcode','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[9]|valid_postcode'), 

     array('field'=>'shipping_addressID','label'=>'Address','rules'=>'check_address[]'), 


     array('field'=>'billing_address_line1','label'=>'Billing address line 1','rules'=>'required|min_length[3]|max_length[200]'), 
     array('field'=>'billing_address_line2','label'=>'Billing address line 2','rules'=>'min_length[3]|max_length[200]'), 
     array('field'=>'billing_address_line3','label'=>'Billing address line 3','rules'=>'min_length[3]|max_length[200]'), 
     array('field'=>'billing_city','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[50]'), 
     array('field'=>'billing_postcode','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[9]|valid_postcode'), 
     array('field'=>'billing_address_same','label'=>'Billing Address','rules'=>'check_address[billing]'), 
     array('field'=>'billing_addressID','label'=>'Billing address','rules'=>'check_address[billing]') 
    ); 
+0

'* _addressID'字段的用途是什么? – DFriend

+0

@Driend由于我希望能够将地址添加到数据库中,并在同一用户返回时再次选择它们以避免多次输入相同的地址。这就是为什么我有'* _addressID',并且如果没有选择'* _addressID',那么用户需要填写与该地址相关的地址字段,无论是运输还是帐单。 – sourRaspberri

回答

0

阵,我认为最简单的方法是最好的。在控制器中,如果复选框被选中,则添加规则。

if(isset($_POST['checkbox'])){ 
    $this->form_validation->set_rules('billing_address_line1', 'Billing Address Line 1', 'required'); 
} 

添加了评论和问题后编辑

仍在努力为最简单的实现,同时使用大量字符串操作,避免foreach循环和多个规则阵列是几乎相同。

这使得form_validation->set_rules()可以接受第三个参数中的数组(而不是管道分隔字符串)的事实。字符串最终变成了一个数组,因此从数组开始在运行时更有效率。

同样在高效运行时的名称中,在设置规则时使用方法链接。

首先创建可重复使用的“规则”数组传递给set_rules()

$rules_address1 = ['required', 'min_length[3]', 'max_length[200]', 'callback_check_basket']; 
$rules_address_23 = ['min_length[3]', 'max_length[200]']; 
$rules_city = ['required', 'min_length[3]', 'max_length[50]']; 
$rules_postcode = ['required', 'min_length[3]', 'max_length[9]', 'callback_valid_postcode']; 

$this->form_validation->set_message('required', 'You must provide {field}.'); 

$this->form_validation 
    ->set_rules('address_line1', 'Address line 1', $rules_address1) 
    ->set_rules('address_line2', 'Address line 2', $rules_address_23) 
    ->set_rules('address_line3', 'Address line 3', $rules_address_23) 
    ->set_rules('city', 'Town/City', $rules_city) 
    ->set_rules('postcode', 'Postal Code', $rules_postcode); 

if(!isset($_POST['checkbox'])) 
{ 
    unset($rules_address1[0]); 
    unset($rules_address_23[0]); 
    unset($rules_city[0]); 
    unset($rules_postcode[0]); 
} 

$this->form_validation 
    ->set_rules('billing_address_line1', 'Billing Address line 1', $rules_address1) 
    ->set_rules('billing_address_line2', 'Billing Address line 2', $rules_address_23) 
    ->set_rules('billing_address_line3', 'Billing Address line 3', $rules_address_23) 
    ->set_rules('billing_city', 'Town/City', $rules_city) 
    ->set_rules('billing_postcode', 'Postal Code', $rules_postcode); 

我跳过了addressID场(S),因为我不知道它是如何使用的规则。

此外,根据CI SOP,添加了callback_以使我看起来是自定义回调方法。相应地调整。

如您所知,这一切都发生在调用$this->form_validation->run()之前的控制器中。

+0

谢谢,但我想做相反的事:p如果复选框已设置我想删除规则。所以我不得不基本重写规则到一个3个独立的数组中,我不想这样做。我正在扫描form_validation类,看看我能否找到一些东西,但我认为,因为这个函数在不同的函数之间调用可能不起作用? – sourRaspberri

+0

我已经添加了数组,您所谈论的方法涉及在启动'run'函数之前操作数组。所以我要么在运行之前运行一个foreach,要么有3个独立的数组,以不包含我不想包含的不同错误。 (其实我认为这是2嘘) – sourRaspberri

+0

结帐修改答案。 – DFriend

0

从表单验证类中检查它。为您想要删除的规则调用您自己的验证方法。 https://codeigniter.com/user_guide/libraries/form_validation.html#callbacks-your-own-validation-methods

然后在这些方法中,检查复选框是否被选中。如果选中,则跳过所有规则,并从回调函数返回TRUE。类似这样的:

address_line1_callback_function() { 
    CI = &get_instance(); 
    if (CI->input->post('checked')) 
     return true; 
    /// Rules for address line go here 
}