In Yii, I have a view belonging to class A, and in a view corresponding to this class, I want to add a form to create a model of another class.
So, in protected/views/pictures/myview.php, I have:
<?php
/* #var $this PicturesController */
/* #var $model Pictures */
$objectForm = new Objects();
$newForm = ObjectsController::renderPartial('create',array('model'=>$objectForm),true);
?>
And I am trying to add a form to render protected/views/objects/create.php. But the above code doesn't work since the view is still trying to load the create form from the Pictures class. Since I am obtaining errors saying that same properties of Objects are not defined, because the system is loading the Pictures create form.
How can I add the create form of the Objects model?
Note: I added "applications.controllers.*" to the import array in main.php, but I understand this is a bad practice. Is there any possible solutions that doesn't involve me to do this?
Thanks.
In this case you just needed to link the correct view in the renderPartial:
$objectForm = new Objects();
$newForm = ObjectsController::renderPartial('/objects/create',array('model'=>$objectForm),true); // "/objects/create", and not "create".
Those errors were giving because Yii understood you were rendering to the create view of pictures, and you gave it the model of Objects (rather than the model of Pictures).
If we were talking about a render call in the controller, and you want to render a view from another action that belongs to another controller, you do not render to this view directly. You have to "redirect" to the action of this other controller (that belongs to the other class).
try like this this
$this->renderPartial('application.staff.views.default.create',array());
this is the format
$this->renderPartial('context_text.views.display._display_text');
Related
In a joomla custom made component there are multiple posts on a page, and every post contains multiple comment, so in view i want to call comments by post id. please suggest a good method to make it working.
You have two options. The first, is to attach the comment id as a URL paramater and retrieve it within the model as needed like so:
$comment_id = JRequest::getApplication()->input->get('comment_id');
If you wish to pass in a parameter when calling the model from the view class, you need to get an instance of the MVC path model instead of using the short cut method. So, instead of using this in the JView class:
$this->items = $this->get('Items');
You would do this instead:
$model = $this->getModel();
$this->items = $model->getItems($comment_id);
Hope this helps.
I'm making a page for adverts. An advert can be of different types and therefore have different data. For instance, a vehicle would have the make and the model as extra data.
Right now, I've got one base doctrine entity Advert which contains the data that every advert requires. Different adverts in turn innherits this data (doctrine2 discriminatormap)
I need to populate the form dynamically (with ajax and symfony2 forms) if the user choose to create a vehicle ad I want to display the options for a vehicle advert. But I also need to change the entity to be of the form AdvertVehicle.
Is this possible? I did read the cookbook entry at the symfony2 homepage
"How to Dynamically Modify Forms Using Form Events":
This should be handled by making an AJAX call back to your application. In that controller, you can submit your form, but instead of processing it, simply use the submitted form to render the updated fields. The response from the AJAX call can then be used to update the view.
I understand how to make an ajax call back to my controller, and i understand how to use the form-events but how do I get the response of a rendered select-box (containing vehicle models for instance) back? With a new AbstractType? or formbuilder?
And then when the user actually submits the form I need to use the entity of the selected advert type. Can I change the entity according to the users choice in the form dynamically?
Edit
I checked the form innheritance out that's great, thank you. I extend the AdvertType and override the buildForm() method and before I add the items I need for the AdvertVehicleType I call the parent method.
Futher Explanation
Every advert entity contains price, description, title and category. Some adverts contains more, such as make and model. They are differentiated by the discriminatormap (doctrine2)
Example:
// -- Entity
class CarAdvert extends Advert {
protected $model;
protected $make;
}
// -- Entity
// -- This uses discriminator mapping
class Advert {
protected $title;
protected $description;
protected $price;
protected $category;
}
if the user selects the category cars I want to use the CarAdvert entity (for validation and persistance) if the user selects the house hold itemcategory I just want to use the normal Advert entity.
One major problem is still that I cannot figure out how to render the extended form via ajax. Any tips on this part? When the user selects car as a category, I want the form to be updated (via jQuery/ajax) but how do I make a controller that retrieves just the extended part of the form and sends the html back as a response (without using twig and rendering it in a view, is this possible)?
Solution:
See answer below!
Solution:
The solution to my problem was to create a few extra functions in the controller to solve the issue where I want to be able to change the entity and form "on the fly" from a selection by the user..
public function indexAction(Request $request)
{
$form = $this->getForm($request);
$form->handleRequest($request);
return array(
'form' => $form->createView(),
'request' => $request->request,
);
}
Where getForm retrieves the form, (e.g AdvertVehicleType for vehicles or AdvertType for a "default" advert).
The getForm method looks like this:
private function getForm(Request $request)
{
$categoryTitle = 'NONE';
$categoryId = $request->request->get('advert', false)['category'];
if ($categoryId) {
$categoryTitle = $this->getDoctrine()->getRepository('Bundle:Category')->find($categoryId)->getTitle();
}
return $this->createForm($this->getFormType($categoryTitle), $this->getEntity($categoryTitle));
}
here I retrieve the categoryID (that is selected in the form in the request) and retreives the formType with getFormTypeand the entity with getEntity.
private function getEntity($categoryTitle)
{
$entity = new Advert();
switch ($categoryTitle) {
case Category::CARS:
$entity = new AdvertCar();
}
return $entity;
}
private function getFormType($categoryTitle)
{
switch ($categoryTitle) {
case Category::CARS:
return new AdvertCarType();
default:
return new AdvertType();
}
}
To be able to update this "on the fly" with ajax (but it also works if the user tries to submit the form) I created another action in the controller.
This action renders the parts of the form that I want to update (on ajax call), I do this by actually picking out what I don't need in the form with twig setting the form objects to rendered like so:
{% do form.title.setRendered %}
(this is just an example I actually do this for all the form objects that I don't want to render.
I then simply just call:
{{ form_rest(form) }}
which will retrieve the "rest" of the form which is different for different categories.
Now let's say you have state and than town to select. First select the state then you render the towns for that state in twig (but then you can actually just render the part you need, e.g {{ form_row(form.towns) }} and you return this rendered template as a json-response and just put it in the div you want with jquery.
$html = $this->renderView('#Bundle/NewAddPage/filter_area.twig', array('form' => $form->createView()));
and then returning the $html variable in the response.
I hope this helps, and that the explanation is good enough, if not just make a comment and I'll update this with my answer!
I know there are several similar topics around but I read and tried most of them but still can't figure out how to do this.
I have a written a component in Joomla 2.5 and it works so far. I have different views and I can load the views using the controller.php.
One of the views shows a table out of my data base (data about teams).
Now I'd like to have another layout of the same view which would display the data base table as a form so can change the content.
That's the file structure:
views/
- teams/
- - tmpl/
- - - default.php
- - - modify.php
- - view.html.php
That's out of the view.html.php file:
...
// Overwriting JView display method
function display($tpl = null) {
...
$this->setLayout('modify');
echo $this->getLayout();
// Display the view
parent::display($tpl);
}
I tried different combinations of setLayout, $tpl = ..., default_modify.php, etc.
but I always either get the default layout or some error like 'can't find layout modify'
I load the site with .../index.php?option=com_test&task=updateTeams
And the controller.php looks like this:
function updateTeams(){
$model = $this->getModel('teams');
$view = $this->getView('teams','html');
$view->setModel($model);
$view->display();
}
I had a similar problem, I created some kind of user profile view and wanted them to be able to edit the fields without having to create a new model for it (would have similar functions, hate redundancy...). What worked for me is to simply call the layout like this:
index.php?option=com_mycomponent&view=myview&layout=edit ("edit" would be "modify" in your case)
To do this I didn't touch the view.html.php (well I did at first but I didn't have to.). And you don't need to use the controller either. If you want to load the modify view, just add a button to your regular view linking to the modify layout. No need to change anything else.
I happen to have written a blog article about it, check it out if you want: http://violetfortytwo.blogspot.de/2012/11/joomla-25-multiple-views-one-model.html
Hope this helps.
Ok this is the problem .. you don't want another layout, you want a new MVC triad that is based on forms rather than rendering. So if you look at any of the core content components you will see in the backend they have a mvc for say ... contacts and one for contact and contact is the editor. If in the front end you will notice that com_content and com_weblinks have mvc for artice/weblink and then separate ones for editing.
You need a really different model and layout and set of actions for editng than for just rendering.
Old topic, but it might still help.
It seems that when one wants to change the layout, the $tpl must not be included in the display() or must be null.
So the previous code would be:
function display($tpl = null) {
/* ... */
$this->setLayout('modify');
// Display the view without the $tpl (or be sure it is null)
parent::display();
}
I've started development on a CakePHP project since a few weeks now. Since the beginning I was struggling with the amount of code inside the controllers. The controllers have, in most cases more lines of code than the models. By knowing the expression "Skinny controller, fat model" I'm searching for some days now for a way to put more code in the models.
The question arises at this point is, "where to draw the line". What should the controller do and what should the model do. There are already some questions/answers on this only I'm searching for a more practical explanation. For example I've put a function below which is now inside the controller. I think a part of this code must and can be moved to the model. So my question is: what part can I move to the model and what can remain in the controller.
/**
* Save the newly added contacts and family members.
*/
public function complete_contacts()
{
if ($this->request->is('post')) {
if (isset($this->data['FamilyMembers'])) {
$selected_user = $this->Session->read('selected_user');
$family_members = $this->data['FamilyMembers'];
$this->ContactsConnection->create();
foreach ($family_members as $family_member) {
// connection from current user to new user
$family_member['ContactsConnection']['contact_family_member_id'] = $selected_user['id'];
$family_member['ContactsConnection']['nickname'] = $selected_user['first_name'];
$this->ContactsConnection->saveAll($family_member);
// inverted connection from new user to current user
$inverted_connection['ContactsConnection']['family_member_id'] = $selected_user['id'];
$inverted_connection['ContactsConnection']['contact_family_member_id'] = $this->FamilyMember->inserted_id;
$inverted_connection['ContactsConnection']['nickname'] = $family_member['FamilyMember']['nickname'];
$this->ContactsConnection->saveAll($inverted_connection);
}
}
}
}
Should I create a function in the FamilyMember model called: "save_new_family_member($family_member, $selected_user)"?
As far as the purposes of the M and the C
The model manages the behavior and data of the application domain,
responds to requests for information about its state (usually from the
view), and responds to instructions to change state (usually from the
controller).
The controller receives user input and initiates a response by making
calls on model objects. A controller accepts input from the user and
instructs the model and a view port to perform actions based on that
input.
I would suggest you can pass
$selected_user = $this->Session->read('selected_user');
To your Model and perform your for each inside of your Model. You may want to change rules as to how the data is stored or perform some transformations on it and the Controller should be blind to this. Basically use the Controller to get your information [from the View often] to the Model. Don't directly manipulate the Model from the Controller. In short YES create the function that you suggested :)
That being said sometimes I find myself in a position where my Controller has to do more than I'd like, in which case at least break the task down into helper methods that way your controller is more manageable and you can reuse code where needed.
You are doing it right.
You can of course create some methods in model and make it fat with:
function updateContactFamilyMemberId($id){}
function updateNickname($nickname){}
...
In my opinion it still will be correct, but unnecessary.
Hey all, have a slight problem here. In CakePHP I have a controller that uses several models. When creating a form in a view, the view will always name my UI elements based on what the first model is when I specify $uses = array('Model') so for instance if my User model is the first in my array then my UI elements will receive id="User(fieldname)" and name="data['User'][fieldname]"
Anybody know how I switch the models my views are using so I can name them properly according to the data I am manipulating?
When creating a form use the full dot notation:
echo $this->Form->create('ModelName');
echo $this->Form->text('ModelName.field_name');
echo $this->Form->input('ModelName.field_name');