BTW: I did some research about slugs. Interesting concept, but not what I’m trying to accomplish.
Thank you!
BTW: I did some research about slugs. Interesting concept, but not what I’m trying to accomplish.
Thank you!
I think I understand now.
Try comparing $data->representingColumn() and $column->name inside the foreach.
Tried that, but $data in fact is not present at view creation time in Giix, it’s just there as text.
I think GiixCrudCode is who have to provide the representingColumn data.
I don’t remember exactly and I’m out of time to research this, but I think that this is the path to your solution.
I think this would count as a feature request (sorry about the bug report, mentel, I’m gathering you’d like feature requests here?)
I’m hoping to be able to call a model method for each $clients before outputting a string for a dropdown list:
echo $form->dropDownList($model,'id',GxHtml::listDataEx($clients,'id','nameForList'));
Without a patch, I end up needing to do something like this:
$clientList = array();
foreach($clients as $client) {
$clientList[$client->id] = $client->nameForList();
}
echo $form->dropDownList($model,'id',$clientList);
But I’d much rather use GxHtml’s listDataEx
Attached is the diff to GxHtml that I worked out that would allow easy calling of a model’s
--- a/protected/extensions/giix-components/GxHtml.php
+++ b/protected/extensions/giix-components/GxHtml.php
@@ -143,6 +143,8 @@ class GxHtml extends CHtml {
return $model->__toString();
else
return $defaultValue;
+ } elseif(method_exists($model, $attribute)) {
+ return $model->$attribute();
} else {
return parent::value($model, $attribute, $defaultValue);
}
Hey fr0d0z, I’m sorry about the question I made on the issue you opened.
After replying, I read the title of the issue and there it was clear that it was indeed a feature request.
Didn’t the suggestion I made help?
Another suggestion is to explore the usage of representingColumn, __toString and how these are used by listDataEx.
This feature request is too focused, I’ll maintain the “won’t fix” status of the issue.
Hi mentel,
Yes, the __toString / representingColumn work for most of my normal use cases. However, in this case, I’ve got two different types of clients (larger businesses and home owners) where I can’t necessarily use representingColumn. __toString works (and I’m using it for now), but what I was realizing is there are some cases where __toString might be a more complete representation of the model but you’d like to abbreviate / shorten the model name for this particular dropdown.
9 times out of 10, representingColumn and __toString will work fine. This suggestion was for those 10th times so that I didn’t need to build a whole separate list
If it seems too specialized, I’m ok with that, just thought I’d suggest it to see what you thought.
You can try using, only for the dropdows that are needed, a different attribute. This attributed can be backed up by a magic getAttributeName that builds the string you want.
That’s a slick idea. I hadn’t thought of that before. Just did a search for the getAttributeName, but don’t see it anywhere in Yii (or your extension). Would I generate the model attribute using the model’s init method or is there a better way to do it?
It was just an example. In this case, the part "AttributeName" is the name of the (magic) attribute you will use for this.
You can read about PHP magic methods and how CActiveRecord::__get (and its parent class CComponent) work.
Thanks, I didn’t know about that. I knew CComponent had that built in, but hadn’t realized that CActiveRecord extended CComponent.
Oh boy, all the cool things I can do now!
Happy to help
Hi Folks I’m brand new to Yii and Giix. I think it’s great stuff! One problem though, when I navigate to my newly created giix view, I get this:
CException
PromoRewards and its behaviors do not have a method or closure named "label".
I can see that the label method is implemented. What could be the cause of this error?
Many thanks.
I know this is an old post, but I found it when I had the same question, and then it dawned on me that there’s a better solution than copying the entire attributeLabels function from the base model. This is equally applicable to the rules function, by the way.
Base Model Class (partial):
public function attributeLabels() {
return array(
'id' => Yii::t('app', 'ID'),
'SSN' => Yii::t('app', 'Ssn'),
'email' => Yii::t('app', 'Email'),
'First_Name' => Yii::t('app', 'First Name'),
'Middle_Initial' => Yii::t('app', 'Middle Initial'),
'Last_Name' => Yii::t('app', 'Last Name'),
'Address1' => Yii::t('app', 'Address1'),
'Address2' => Yii::t('app', 'Address2'),
'City' => Yii::t('app', 'City'),
'State' => Yii::t('app', 'State'),
'Postal_Code' => Yii::t('app', 'Postal Code'),
);
}
Model Class (extends base model class):
public function attributeLabels() {
$oldLabels = parent::attributeLabels();
$newLabels = array(
'SSN' => Yii::t('app', 'SSN'),
);
return array_merge($oldLabels, $newLabels);
}
Forgive me if this solution has already been posted elsewhere. I’m sure I’m not the first one to have thought of it.
Dear,
I’m pleased to announce that giix has a new home at GitHub.
https://github.com/rcoelho/giix
You can open new issues, fork and open pull requests there.
I hope you enjoy this good news!
I believe I found the issue. I am using WAMP also. I was getting the 101 Error, I looked at the code and the problem was not with the scandir function. The problem was that I had no Models that were created by the Giix Model creator. One of the lines of codes checks:
is_subclass_of($fileClassName, ‘GxActiveRecord’);
However since none of my models had been created by Giix I was getting an empty array which apparently bombs the Autocomplete function. So go and create one model with Giix and suddenly it should start working.
This issue appears because of the following line in giix-core\giixCrud\views\index.php
<?php echo $form->error($model,'baseControllerClass'); ?>
It’s strange but the issue is solved when I comment that line. Any idea?
NEW QUESTION - Update Related record on creation of a parent, has_many relationship
@fr0d0z sorry for having post on the extension page. I start again here trying to be more precise. Do you want me to remove my comment on the extension page ?
I use the latest yii (v1.1.10)
Tables:
Object Purchase
----- --------
id (PK) id (PK)
name title
Purchase_id (FK) price
Here is my sqlite database
CREATE TABLE "Object"(
"id" INTEGER PRIMARY KEY NOT NULL,
"name" VARCHAR(45),
"Purchase_id" INTEGER,
CONSTRAINT "fk_Object_Purchase"
FOREIGN KEY("Purchase_id")
REFERENCES "Purchase"("id")
);
CREATE INDEX "Object.fk_Object_Purchase" ON "Object"("Purchase_id");
CREATE TABLE "Purchase"(
"id" INTEGER PRIMARY KEY NOT NULL,
"title" VARCHAR(45),
"price" VARCHAR(45)
);
I use MAMP on my mac.
Opening Giix, I create the models and then the CRUD.
Purchase Controller as generated by Giix:
<?php
class PurchaseController extends GxController {
public function actionView($id) {
$this->render('view', array(
'model' => $this->loadModel($id, 'Purchase'),
));
}
public function actionCreate() {
$model = new Purchase;
if (isset($_POST['Purchase'])) {
$model->setAttributes($_POST['Purchase']);
if ($model->save()) {
if (Yii::app()->getRequest()->getIsAjaxRequest())
Yii::app()->end();
else
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('create', array( 'model' => $model));
}
public function actionUpdate($id) {
$model = $this->loadModel($id, 'Purchase');
if (isset($_POST['Purchase'])) {
$model->setAttributes($_POST['Purchase']);
if ($model->save()) {
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('update', array(
'model' => $model,
));
}
public function actionDelete($id) {
if (Yii::app()->getRequest()->getIsPostRequest()) {
$this->loadModel($id, 'Purchase')->delete();
if (!Yii::app()->getRequest()->getIsAjaxRequest())
$this->redirect(array('admin'));
} else
throw new CHttpException(400, Yii::t('app', 'Your request is invalid.'));
}
public function actionIndex() {
$dataProvider = new CActiveDataProvider('Purchase');
$this->render('index', array(
'dataProvider' => $dataProvider,
));
}
public function actionAdmin() {
$model = new Purchase('search');
$model->unsetAttributes();
if (isset($_GET['Purchase']))
$model->setAttributes($_GET['Purchase']);
$this->render('admin', array(
'model' => $model,
));
}
}
Object Controller as generated by Giix:
<?php
class ObjectController extends GxController {
public function actionView($id) {
$this->render('view', array(
'model' => $this->loadModel($id, 'Object'),
));
}
public function actionCreate() {
$model = new Object;
if (isset($_POST['Object'])) {
$model->setAttributes($_POST['Object']);
if ($model->save()) {
if (Yii::app()->getRequest()->getIsAjaxRequest())
Yii::app()->end();
else
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('create', array( 'model' => $model));
}
public function actionUpdate($id) {
$model = $this->loadModel($id, 'Object');
if (isset($_POST['Object'])) {
$model->setAttributes($_POST['Object']);
if ($model->save()) {
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('update', array(
'model' => $model,
));
}
public function actionDelete($id) {
if (Yii::app()->getRequest()->getIsPostRequest()) {
$this->loadModel($id, 'Object')->delete();
if (!Yii::app()->getRequest()->getIsAjaxRequest())
$this->redirect(array('admin'));
} else
throw new CHttpException(400, Yii::t('app', 'Your request is invalid.'));
}
public function actionIndex() {
$dataProvider = new CActiveDataProvider('Object');
$this->render('index', array(
'dataProvider' => $dataProvider,
));
}
public function actionAdmin() {
$model = new Object('search');
$model->unsetAttributes();
if (isset($_GET['Object']))
$model->setAttributes($_GET['Object']);
$this->render('admin', array(
'model' => $model,
));
}
}
_form.php in Purchase Views
<div class="form">
<?php $form = $this->beginWidget('GxActiveForm', array(
'id' => 'purchase-form',
'enableAjaxValidation' => false,
));
?>
<p class="note">
<?php echo Yii::t('app', 'Fields with'); ?> <span class="required">*</span> <?php echo Yii::t('app', 'are required'); ?>.
</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'title'); ?>
<?php echo $form->textField($model, 'title', array('maxlength' => 45)); ?>
<?php echo $form->error($model,'title'); ?>
</div><!-- row -->
<div class="row">
<?php echo $form->labelEx($model,'price'); ?>
<?php echo $form->textField($model, 'price', array('maxlength' => 45)); ?>
<?php echo $form->error($model,'price'); ?>
</div><!-- row -->
<label><?php echo GxHtml::encode($model->getRelationLabel('objects')); ?></label>
<?php echo $form->checkBoxList($model, 'objects', GxHtml::encodeEx(GxHtml::listDataEx(Object::model()->findAllAttributes(null, true)), false, true)); ?>
<?php
echo GxHtml::submitButton(Yii::t('app', 'Save'));
$this->endWidget();
?>
</div><!-- form -->
PROBLEM
I create 3 objects.
Then I create a Purchase. in the Create View Purchase,
I see a checkbox for each existing object: (see image below)
I select the 2 first objects to be linked to this purchase.
I click SAVE.
The Purchase is saved but no object is linked: (see image below)
I expect to see this: (which I brain by updating each object and selecting the Purchase) : (see image below)
To establish a link, I have to go to each Object and update it while selecting the Purchase.
What am I missing ? How can I have the selected Objects linked to the Purchase while creating the Purchase ?
thanxs for your help.
best regards
olivier.
UPDATE:
Here is the BASEPurchase.php
<?php
abstract class BasePurchase extends GxActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'Purchase';
}
public static function label($n = 1) {
return Yii::t('app', 'Purchase|Purchases', $n);
}
public static function representingColumn() {
return 'title';
}
public function rules() {
return array(
array('title, price', 'length', 'max'=>45),
array('title, price', 'default', 'setOnEmpty' => true, 'value' => null),
array('id, title, price', 'safe', 'on'=>'search'),
);
}
public function relations() {
return array(
'objects' => array(self::HAS_MANY, 'Object', 'Purchase_id'),
);
}
public function pivotModels() {
return array(
);
}
public function attributeLabels() {
return array(
'id' => Yii::t('app', 'ID'),
'title' => Yii::t('app', 'Title'),
'price' => Yii::t('app', 'Price'),
'objects' => null,
);
}
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('title', $this->title, true);
$criteria->compare('price', $this->price, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
}
The Relation is HAS_MANY. That’s correct for me.
SO I don’t understand why in GiixCrudCode.php, line 145
case GxActiveRecord::MANY_MANY:
return "echo \$form->checkBoxList(\$model, '{$relationName}', GxHtml::encodeEx(GxHtml::listDataEx({$relationModel}::model()->findAllAttributes(null, true)), false, true))";
break;
the case is triggered… and the checkBoxList inserted in the _form.php…
BUT in the controller there is no code about $relatedDate and saveWithRelated() or saveRelated()…
any help VERY welcome
I needed to add some scopes to the search() method of a model. So I’ve overridden the method from the base class in following way:
public function search($scopes = false) {
$dataProvider = parent::search();
if ($scopes) {
if (is_string($scopes))
$scopes = array($scopes);
$criteria = $dataProvider->getCriteria();
if (empty($criteria->scopes))
$criteria->scopes = $scopes;
elseif (is_array($criteria->scopes))
$criteria->scopes = array_merge($criteria->scopes, $scopes);
elseif (is_string($criteria->scopes))
$criteria->scopes = array_merge(array($criteria->scopes), $scopes);
$dataProvider->setCriteria($criteria);
}
return $dataProvider;
}
I hope this is the right place to share the idea if someone needs the same thing one day.