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 ?>