Yii Framework Forum: CForm without model - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

CForm without model Rate Topic: -----

#1 User is offline   Trejder 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,257
  • Joined: 06-October 10
  • Location:Southern Poland

Posted 07 December 2010 - 08:58 AM

Hi there,

I need to build up a form basing on app configuration (array, not a model) and I wonder is there any way to hire CFrom (Form Builder) for this purpose or do I have to use CHtml instead? Using Form Builder chapter in Official Guide seems to be focused on using model.

I've looked into source code of CForm->__construct() method and found out that model is NULL there by default, which lead me to a conclusion that it is possible to use CForm without a model. But when I used code like this:

$form_config = array
(
    	'title'=>'Please provide your login credential',

    	'elements'=>array
    	(
            	'username'=>array
            	(
                    	'type'=>'text',
                    	'maxlength'=>32,
            	),
            	'password'=>array
            	(
                    	'type'=>'password',
                    	'maxlength'=>32,
            	),
    	)
);

$form = new CForm($form_config);
$form->render();


All I got is "Fatal error: Call to a member function isAttributeSafe() on a non-object". Which seems to be telling me that using CForm without model isn't that good idea.
Proud Cookbook author, though still learning powerful Yii! :] See my generic profile for more information. Cheers!
0

#2 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,462
  • Joined: 04-October 10

Posted 07 December 2010 - 09:07 AM

Hi Trej

I was wondering why don't you create a widget that based on the property attributes, renders a Form using a view or CHtml.

Just an idea
0

#3 User is online   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,591
  • Joined: 10-October 10
  • Location:Denmark

Posted 07 December 2010 - 09:22 AM

Use a form model.
I use one :
class ConfigForm extends CFormModel
{
	public $pagesize;
    	public $hg_executable;
    	public $python_path;
    	public $default_scm;
    	public $default_timezone;

	/**
	 * Declares the validation rules.
	 */
	public function rules()
	{
		return array(
			array('pagesize, hg_executable, python_path, default_scm, default_timezone', 'required'),
		);
	}

	/**
	 * Declares customized attribute labels.
	 * If not declared here, an attribute would have a label that is
	 * the same as its name with the first letter in upper case.
	 */
	public function attributeLabels()
	{
        	return array(
            	'pagesize'=>'Page Size',
            	'hg_exectutable' => 'Path to hg exectuable',
            	'python_path' => 'Python path environment variable',
            	'default_scm' => 'Default Source Control Provider',
            	'default_timezone' => 'Default Timezone',
        	);
	}
    	public function save() {
        	Yii::app()->config->set('hg_executable', $this->hg_executable);
        	Yii::app()->config->set('defaultPagesize', $this->pagesize);
        	Yii::app()->config->set('python_path', $this->python_path);
        	Yii::app()->config->set('default_timezone', $this->default_timezone);
        	Yii::app()->config->set('default_scm', $this->default_scm);
        	return true;
    	}
}

As you can see, you can do anything. :)
"Less noise - more signal"
0

#4 User is offline   Trejder 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,257
  • Joined: 06-October 10
  • Location:Southern Poland

Posted 07 December 2010 - 09:32 AM

View PostAntonio Ramirez, on 07 December 2010 - 09:07 AM, said:

I was wondering why don't you create a widget that based on the property attributes, renders a Form using a view or CHtml.

ANY idea is worth exploring. Can you be a bit more specific or point me to some example (sorry, the coffee machine is down today and so do I! :/)...
Proud Cookbook author, though still learning powerful Yii! :] See my generic profile for more information. Cheers!
0

#5 User is offline   Trejder 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,257
  • Joined: 06-October 10
  • Location:Southern Poland

Posted 07 December 2010 - 09:48 AM

View Postjacmoe, on 07 December 2010 - 09:22 AM, said:

As you can see, you can do anything.

Since I'm at a very early stage of application development my configuration structure (divided into groups, therefore not so simple as in your example) may and will change a lot. That is main reason, why I don't want to use model, as I will have to update it's definition each time something will change in configuration structure.

When using array + foreach for form contents generation approach I have this luck, that any change to configuration structure file will be automatically reflected to form. I.e. I only need to change configuration structure file in my approach (form is auto-generated) and I have to change both model declaration and form viewthat relies on it, when using yours - i.e. model-based approach.

Plus the fact that building configuration groups, subgroups and items using model would in my opinion cost much more coding time than achieving it via arrays and auto-form generation.

But since the approach of using CHtml also seems to be failing (with such basic problems like, how to process forms generated this way) I see that I will not be probably able to avoid using models, which isn't the thing that makes me really happy! :/ Plus that broken coffee machine, aarrgh! :/
Proud Cookbook author, though still learning powerful Yii! :] See my generic profile for more information. Cheers!
0

#6 User is offline   Trejder 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,257
  • Joined: 06-October 10
  • Location:Southern Poland

Posted 07 December 2010 - 09:54 AM

View Postjacmoe, on 07 December 2010 - 09:22 AM, said:

class ConfigForm extends CFormModel
{
    	public $pagesize;
    	public $hg_executable;
    	public $python_path;
    	public $default_scm;
    	public $default_timezone;
...
		return array(
			array('pagesize, hg_executable, python_path, default_scm, default_timezone', 'required'),
		);
}


This seems to be the worst part. Is there any way to have a form model declared the way all its properties will be not as separate variables but as an array (I know, I'm dreaming right now!)? I.e.:

class ConfigForm extends CFormModel
{
    	public $config_fields = array('pagesize', 'hg_executable', 'python_path', 'default_scm', 'default_timezone');
...
		return array(
			array(array('pagesize', 'hg_executable', 'python_path', 'default_scm', 'default_timezone'), 'required'),
		);
}

Where array in both cases could be generated dynamically?

No, it isn't possible, right?
Proud Cookbook author, though still learning powerful Yii! :] See my generic profile for more information. Cheers!
0

#7 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,462
  • Joined: 04-October 10

Posted 07 December 2010 - 10:25 AM

Hi there Trej,

We could create a class that actually renders a form. I try to build a simple skeleton, you develop from there:

class EDynamicForm extends CWidget{

   // attribute = array('name'=>'','value'=>'',
   // 'type'=>'text|radio|textarea|select',
   // 'items'=>array()<--if select,
   // 'htmlOptions'=>array())
   public $attributes = array();
   public $id = null;
   public $enctype = null;
   public $action = null;
   public $model_name = '';
   public $method = 'post';
  
   // you put as many properties as needed
   public function init(){
     // init procedures here
   }

   public function run(){
     // here render procedures 
     echo CHtml::beginForm($this->action,
          $this->method,
          array('id'=>$this->id,
          'enctype'=>$this->enctype,
          'target'=>$this->target));

     // you better create a function but
     // for the sake of the example...
     foreach($this->attributes as $attr)
     {
       // here we can actually say i
       // this is very simple but you get the idea
       if($attr['type']=='text')
         echo CHtml::textField(ucfirst(strtolower($this->model_name)).'['.$attr['name'].']',$attr['value'],$attr['htmlOptions']);
       // do more here
     }
     echo CHtml::endForm();
   }
}


That way you have a dynamic Form widget that you can set as:

$this->widget('EDynamicForm',array('id'=>....

On submission

$model->attributes = $_POST['model_name'];

I do not know if it helps... good luck with the Coffee


Update:

You know what? I think this could a be a great extension (having form elements displayed with item view templates).
0

#8 User is online   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,591
  • Joined: 10-October 10
  • Location:Denmark

Posted 07 December 2010 - 11:13 AM

I am wondering if one could do this by using the technique described here:
Collecting Tabular Input
If every config entry is a formmodel this should work, shouldn't it?
When my configuration grows, I am probably going to need this too. :)

<edit>
And that's pretty much what you were proposing, Antonio.
</edit>
"Less noise - more signal"
0

#9 User is offline   Trejder 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,257
  • Joined: 06-October 10
  • Location:Southern Poland

Posted 08 December 2010 - 02:32 AM

Hi Antonio,

View PostAntonio Ramirez, on 07 December 2010 - 10:25 AM, said:

We could create a class that actually renders a form. I try to build a simple skeleton, you develop from there:

...

You know what? I think this could a be a great extension (having form elements displayed with item view templates).

Yes, your idea is really good and for sure it needs my further investigation! Thank you! I just wonder if we are not developing a new version of Form Builder or something similar to it! :)
Proud Cookbook author, though still learning powerful Yii! :] See my generic profile for more information. Cheers!
0

#10 User is offline   Trejder 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,257
  • Joined: 06-October 10
  • Location:Southern Poland

Posted 08 December 2010 - 02:35 AM

View Postjacmoe, on 07 December 2010 - 11:13 AM, said:

I am wondering if one could do this by using the technique described here:
Collecting Tabular Input
If every config entry is a formmodel this should work, shouldn't it?

Well... I investigated that, but found it less useful. A new form model for each config entry? Wouldn't be that a waste of time and coding? What if you'll have 500 config entries like in application I'm developing? I think you could die doing this on form model and tabular input approach...
Proud Cookbook author, though still learning powerful Yii! :] See my generic profile for more information. Cheers!
0

#11 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,462
  • Joined: 04-October 10

Posted 08 December 2010 - 06:56 AM

View PostTrejder, on 08 December 2010 - 02:32 AM, said:

Hi Antonio,
Yes, your idea is really good and for sure it needs my further investigation! Thank you! I just wonder if we are not developing a new version of Form Builder or something similar to it! :)


That is exactly what I was wondering... I think that speed is key for all of us, can you imagine creating a form with a snap. I have my head thinking around this and I think that a Form *also* -would be nice to have two ways of doing it, could be actually created just by having a model as a parameter too.

Imagine the model is a property and the Form loops through its metaData and creates the fields according to the types describes on its columns (http://www.yiiframew...CDbColumnSchema). Of course, user could overwrite field render properties by forcing a form element type...

What do you think? Am I going to far? But Imagine one view like this:

Yii::import('EForm');

EForm::render($model,array('action'=>'controller/action')); // I do not include anything related to forcing field types

or

$this->widget('EForm',array('model'=>$model,'action'=>'controller/action'));


woaw....
0

#12 User is offline   Trejder 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,257
  • Joined: 06-October 10
  • Location:Southern Poland

Posted 08 December 2010 - 08:09 AM

View PostAntonio Ramirez, on 08 December 2010 - 06:56 AM, said:

What do you think? Am I going to far? But Imagine one view like this:

They say, the only sky is the limit! :) And in Star Trek it is said, that only space is the final frontier! :)

In other words, if you have time and are enough enthusiastic to write such extension I will greet you with all my hands up. This will for sure add something to Yii community. For me personally this is too much. Similarly to you, I got, what I wanted to get, with using CHtml and processing such forms with $_POST array. I don't need anything more and even if I would need, I unfortunately haven't got time for that! :(

Keeping my thumbs up for you! You're doing wonderful job for Yii community. Cheers!
Proud Cookbook author, though still learning powerful Yii! :] See my generic profile for more information. Cheers!
0

#13 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,462
  • Joined: 04-October 10

Posted 08 December 2010 - 09:36 AM

Thanks Trej, there are a lot of members doing so much... (couple of them already helped me to solve tons of issues)

Anyway, I write this idea down... I may jump on it as I think that, for lazy guys like me, could speed up the way we do things.

Cheers!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users