00001 <?php 00008 class CollectionField extends AbstractField 00009 { 00010 protected $fields; 00011 protected $autoAdvance; 00012 private static $skipFieldTypes = array('HiddenField', 'LabelField'); 00013 protected static $jsDrawn; 00014 protected $arrangement; 00015 00022 public function __construct($name, Form &$parentForm, array $attribs = array()) 00023 { 00024 $this->fields = array(); 00025 parent::__construct($name, $parentForm, $attribs); 00026 self::$jsDrawn = false; 00027 if(!$this->arrangement) 00028 $this->arrangement = 'horizontal'; 00029 } 00030 00036 public function __set($name, $value) 00037 { 00038 switch($name) 00039 { 00040 case 'parentForm': 00041 foreach($this->fields as $field) 00042 $field->parentForm = $value; 00043 break; 00044 00045 case 'arrangement': 00046 $this->arrangement = $value; 00047 break; 00048 00049 case 'fields': 00050 self::assertAttributeIsArray($value); 00051 foreach($value as $param) 00052 { 00053 self::assertAttributeIsArray($param); 00054 $this->add($param[0], $param[1], is_array($param[2]) ? $param[2] : array($param[2])); 00055 } 00056 break; 00057 00058 default: 00059 parent::__set($name, $value); 00060 } 00061 } 00062 00063 00071 public function &add($type, $name, array $options = array()) 00072 { 00073 if($this->parentForm->hasField($name)) 00074 throw new Exception("Field name $name is not unique."); 00075 00076 $field = new $type($name, $this->parentForm, $options); 00077 $this->fields[] = $field; 00078 return $field; 00079 } 00080 00088 public function hasField($name) 00089 { 00090 foreach ($this->fields AS $field) 00091 if ($field->name == $name) 00092 return true; 00093 00094 return false; 00095 } 00096 00102 public function setFieldsData($data) 00103 { 00104 foreach ($this->fields AS $field) 00105 { 00106 if(isset($data[$field->name])) 00107 $field->setData($data[$field->name]); 00108 } 00109 } 00110 00114 public function drawInput() 00115 { 00116 for($i = 0; $i < count($this->fields); $i++) 00117 { 00118 if($this->autoAdvance) 00119 { 00120 $this->fields[$i]->addAttributes(array( 00121 'onfocus' => 'this.formCollectionLength = this.value.length', 00122 'onkeydown' => 'formCollectionKD(this)', 00123 'onkeyup' => sprintf("formCollectionKU(window.event ? window.event : event, this, %s, %s)", $this->getPrevFieldId($i), $this->getNextFieldId($i)) 00124 )); 00125 } 00126 $this->fields[$i]->drawInput(); 00127 00128 echo ($this->arrangement == 'vertical') ? '<br/>' : " "; 00129 } 00130 } 00131 00139 public function setDataFromRequest() 00140 { 00141 foreach($this->fields as $field) 00142 $field->setDataFromRequest(); 00143 } 00144 00148 public function validate() 00149 { 00150 foreach($this->fields as $field) 00151 $field->validate(); 00152 } 00153 00158 public function hasError() 00159 { 00160 $ret = false; 00161 foreach($this->fields as $field) 00162 $ret = ($field->hasError() || $ret); 00163 00164 return $ret || $this->hasError; 00165 } 00166 00171 public function getSqlImpl() 00172 { 00173 $ret = array(); 00174 foreach($this->fields as $field) 00175 $ret[] = $field->getSqlImpl(); 00176 00177 return implode(',', array_diff($ret, array(''))); 00178 } 00179 00180 00186 private function getNextFieldId($num) 00187 { 00188 if($num >= count($this->fields)) 00189 return 'null'; 00190 00191 if(array_search(get_class($this->fields[$num + 1]), self::$skipFieldTypes) !== false) 00192 return $this->getNextFieldId($num + 1); 00193 00194 return "'" . $this->fields[$num + 1]->id . "'"; 00195 } 00196 00202 private function getPrevFieldId($num) 00203 { 00204 if($num == 0) 00205 return 'null'; 00206 00207 if(array_search(get_class($this->fields[$num - 1]), self::$skipFieldTypes) !== false) 00208 return $this->getPrevFieldId($num - 1); 00209 00210 return "'" . $this->fields[$num - 1]->id . "'"; 00211 } 00212 00217 public function getJs() 00218 { 00219 $subFields = null; 00220 00221 foreach($this->fields as $field) 00222 $subFields .= $field->getJs(); 00223 00224 if(self::$jsDrawn || !$this->autoAdvance) 00225 return $subFields; 00226 00227 self::$jsDrawn = true; 00228 return <<<EOJAVASCRIPT 00229 var formCollectionSave = null; 00230 00231 function formCollectionKD(field) 00232 { 00233 field.formCollectionLength = field.value.length; 00234 formCollectionSave = field; 00235 } 00236 00237 function formCollectionKU(evt, field, prev, next) 00238 { 00239 var len; 00240 00241 if (field == formCollectionSave) 00242 { 00243 if (evt.keyCode == 8) 00244 { 00245 if (prev && !(len = field.value.length) && len < field.formCollectionLength) 00246 { 00247 field = document.getElementById(prev); 00248 field.focus(); 00249 field.value += ''; 00250 } 00251 } 00252 else 00253 { 00254 if (next && (len = field.value.length) > field.formCollectionLength && len >= field.maxLength) 00255 { 00256 field = document.getElementById(next); 00257 field.focus(); 00258 field.select(); 00259 } 00260 } 00261 } 00262 00263 formCollectionSave = null; 00264 } 00265 00266 $subFields 00267 EOJAVASCRIPT; 00268 } 00269 00270 00275 public function getCss() 00276 { 00277 $css = null; 00278 00279 foreach($this->fields as $field) 00280 $css .= $field->getCss(); 00281 00282 return $css; 00283 } 00284 00285 00290 public function allFieldsHaveData() 00291 { 00292 $ret = true; 00293 foreach($this->fields as $field) 00294 { 00295 if(array_search(get_class($field), self::$skipFieldTypes) === false) 00296 $ret = (($field->getData() != '') && $ret); 00297 } 00298 00299 return $ret; 00300 } 00301 00302 00307 public function noFieldsHaveData() 00308 { 00309 $ret = true; 00310 foreach($this->fields as $field) 00311 { 00312 if(array_search(get_class($field), self::$skipFieldTypes) === false) 00313 $ret = (($field->getData() == '') && $ret); 00314 } 00315 00316 return $ret; 00317 } 00318 00319 public function getData() 00320 { 00321 $ret = array(); 00322 foreach($this->fields as $field) 00323 { 00324 if(array_search(get_class($field), self::$skipFieldTypes) === false) 00325 $ret[$field->name] = $field->getData(); 00326 } 00327 00328 return $ret; 00329 } 00330 } 00331 00332 ?>