can someone please explain the connection between CForm and CFormModel?
In general my question is related to the Form Builder. My first idea would be, that once you have the model for your form, you should be able the generate some basic HTML code for your form automatically.
However, according to the documentation, I need to create a CForm in a view file.
This whole thing is very counterintuitive to me. Why would I do such things in the view?
Please note, that I’m new to yii, so some things may be obvious to you which are not to me.
No, you don’t have to create a CForm in a view file. This isn’t a good approach at all. You should create your CForm object in your controller action and then you can RENDER the CForm in a view with $form->render(). There is a difference. The configuration of a CForm is always done in a controller action (at least it should be done this way) and the form gets rendered by calling a view script to show the form to the user. So display logic and business logic are seperated.
But maybe you are confusing the relationship between CFormModel and CForm. They are not related to each other even if the name makes it look like that. A CFormModel is a model that isn’t filled with data from a database and isn’t inserting or updating data (that’s the only difference to CActiveRecord). It is used for simple logins for example.
You don’t have to use it in combination with a CForm. CForm is a class that simply allows the creation of forms (for logins or models, that doesn’t matter).
I know that it can be really tricky to understand all that and I had a lot of problems too. The really important thing is to distuingish between the several model classes
CModel - all the model classes extend this base class
CFormModel (extends CModel)- models that hold data in memory only and aren’t used for CRUD operations with a database
CActiveRecord (extends CModel) - models that are used for CRUD operations using a database
CActiveForm - a helper class to create forms in combination with a CFormModel or a CActiveRecord Model
CForm - a helper class to provide better seperation between logic and layout of a form (just another way of creating a form)
I don’t know if this is just slight confusion but in the documentation regarding this topic is suggests creating the form config in a view file. You don’t actually instantiate the object in the view but the CForm config array is read from one, e.g.
$form = new CForm('application.views.site.loginForm', $model);
Taken from that page, I don’t think that’s bad practice but when I read your comment I thought that’s what you were saying and wanted to clear up any potential confusion if it’s not
Ah, ok, now I got what Tohotom ment. Thanks for pointing me in the right direction
Of course you can put the configuration everywhere you want as you just have to return an array. I think the reason that a view file is suggested is that it is more “natural” to describe a form in a view file than anywhere else and it is a bit more flexible than putting it directly in your controller action as different CForm instances could point to one configuration file. What I ment was that the actual CForm object is normally created in a controller action by passing a config file to it and it normally doesn’t get INSTANTIATED in a view.
Ok, after reading all that I can understand why it seems so difficult. I am sorry if I made it even harder to understand
or instead create a CForm and use $form->render();
Correct me please if I’m wrong.
But if I’m right, then why do I need the CForm?
It should be possible to create the HTML code using the model only. Like the gii Form generator, which does just that (creating the “traditional” version). Is it possible to do it on-line? I know this method does not exist, but I’m thinking of something like CFormModel::render().
Hm, maybe it is easier to understand the full potential of CForm if you are more experienced using Yii. If using CActiveForm you are always putting HTML code in a view file like you did above, doing some styling by putting elements into divs, headlines and stuff. But depending on the complexity of the layout it can be tedious work to get everything to look right (multiple nested divs for inputs).
Let me give you an example where I personally use CForm. You may know Twitter Bootstrap (http://twitter.github.com/bootstrap/). This is a set of CSS classes and stuff to make it easy to build nice looking pages and forms. If you want to make use of the classes you can’t use most of the classic CSS styling Yii provides
<input name="Item[price]" id="Item_price" type="text"/>
<span class="help-inline"/>Some help text
To do that with the view file you would now have to do a lot of work to restyle it. But if you know that you will do a lot of forms this way you could extend CForm and define how it will render each form element and you’ll never have to think about any view file again. Every time you add en element to the CForm it will automatically be rendered this way. No copy/pasting anymore. This way you can create very customized and complex forms that perfectly suit your development needs.
And to answer your last question regarding automatic creation of forms. Well, gii was made for really simple tasks and if you are serious you have to rewrite a lot of code it produces (not always, but most of the time). If you are not satisfied with the CActiveForm Yii produces “out of the box” you’ll have to make your hands dirty, that’s developer’s work If you are geeky enough you could create your own gii form creator using CForms. That’s up to you
I understand the power of CForm now somewhat better.
I agree, that for large projects you may want customize all details, add a professional look. However for simple projects, or in the early stage of development, where your goal is to create something working quickly and do the formatting later any default form formatting could do.
So it means I have to write an extend CForm which automatically generates its configuration from its $model if I need this functionality.
Yes, that’s right. In fact that shouldn’t be too difficult to achieve. The only thing that would be tricky is how to create input elements for lists (dropdownlists etc.) and fill them with correct data automatically. Think about foreign key relationships and stuff. If you come up with an algorithm that describes all the scenarios you are more than welcome to create an extension