public function renderDataCellContent($row, $data) { $isModel = $data instanceof CModel; if ($isModel) { $widgetClass = 'TbEditableField'; $options = array('model' => $data, 'attribute' => empty($this->editable['attribute']) ? $this->name : $this->editable['attribute']); //if value defined in column config --> we should evaluate it //and pass to widget via `text` option: set flag `passText` = true $passText = !empty($this->value); } else { $widgetClass = 'TbEditable'; $options = array('pk' => $data[$this->grid->dataProvider->keyField], 'name' => empty($this->editable['name']) ? $this->name : $this->editable['name']); $passText = true; //if autotext will be applied, do not pass `text` option (pass `value` instead) if (empty($this->value) && TbEditable::isAutotext($this->editable, isset($this->editable['type']) ? $this->editable['type'] : '')) { $options['value'] = $data[$this->name]; $passText = false; } } //for live update $options['liveTarget'] = $this->grid->id; $options = CMap::mergeArray($this->editable, $options); //if value defined for column --> use it as element text if ($passText) { ob_start(); parent::renderDataCellContent($row, $data); $text = ob_get_clean(); $options['text'] = $text; $options['encode'] = false; } //apply may be a string expression, see https://github.com/vitalets/x-editable-yii/issues/33 if (isset($options['apply']) && is_string($options['apply'])) { $options['apply'] = $this->evaluateExpression($options['apply'], array('data' => $data, 'row' => $row)); } //evaluate htmlOptions inside editable config as they can depend on $data //see https://github.com/vitalets/x-editable-yii/issues/40 if (isset($options['htmlOptions']) && is_array($options['htmlOptions'])) { foreach ($options['htmlOptions'] as $k => $v) { if (is_string($v) && (strpos($v, '$data') !== false || strpos($v, '$row') !== false)) { $options['htmlOptions'][$k] = $this->evaluateExpression($v, array('data' => $data, 'row' => $row)); } } } $this->grid->controller->widget($widgetClass, $options); }
/** *### .init() * * initialization of widget * */ public function init() { if (!$this->model) { throw new CException('Parameter "model" should be provided for EditableField'); } if (!$this->attribute) { throw new CException('Parameter "attribute" should be provided for EditableField'); } // set name $this->name = $this->attribute; parent::init(); // set value $this->value = $this->model->{$this->attribute}; /** * set data-pk only for existing records */ if (!$this->model->isNewRecord) { $this->pk = is_array($this->model->primaryKey) ? CJSON::encode($this->model->primaryKey) : $this->model->primaryKey; } $originalText = strlen($this->text) ? $this->text : CHtml::value($this->model, $this->attribute); /** * if apply set manually to false --> just render text, no js plugin applied */ if ($this->apply === false) { $this->text = $originalText; return; } else { $this->apply = true; } /** * resolve model and attribute for related model */ $resolved = self::resolveModel($this->model, $this->attribute); if ($resolved === false) { //cannot resolve related model (maybe no related models for this record) $this->apply = false; $this->text = $originalText; return; } else { list($this->model, $this->attribute) = $resolved; } /** * for security reason only safe attributes can be editable (e.g. defined in rules of model) * just print text (see 'run' method) */ if (!$this->model->isAttributeSafe($this->attribute)) { $this->apply = false; $this->text = $originalText; return; } /** * try to detect type from metadata if not set */ if ($this->type === null) { $this->type = 'text'; if (array_key_exists($this->attribute, $this->model->tableSchema->columns)) { $dbType = $this->model->tableSchema->columns[$this->attribute]->dbType; if ($dbType == 'date' || $dbType == 'datetime') { $this->type = 'date'; } if (stripos($dbType, 'text') !== false) { $this->type = 'textarea'; } } } /** * If text not defined, generate it from model attribute for types except lists ('select', 'checklist' etc) * For lists keep it empty to apply autotext */ if (!strlen($this->text) && !$this->_prepareToAutoText) { $this->text = $originalText; } }
public function getSelector() { return str_replace('\\', '_', get_class($this->staticModel)) . '_' . parent::getSelector(); }