I have a Merchant entity with the following fields and associations:-
/**
* @ORM\ManyToMany(targetEntity="Category", inversedBy="merchants")
*/
public $categories;
/**
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="merchants")
*/
public $tags;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="merchants")
*/
protected $primaryCategory;
/**
* @ORM\ManyToOne(targetEntity="Tag", inversedBy="merchants")
*/
protected $primaryTag;
The Tags and Categories also have a ManyToMany mapping. So we have Tag_Category, Merchant_Tag, Merchant_Category mapping tables.
Now I want to perform some ajax on these fields.
I want to allow the user to select the Primary Tag first. On the basis of the Primary Tag, ajax refresh the categories to only those which belong to this Tag and some more operations.
How can I achieve this?
Thanks!
Very detailed post, just to update the way of override and use the edit template in the Admin class.
Now, you should do it this way:
Or inject it in the service definition used the provided method, to keep the Admin class as cleaner as possible:
At step 1 of Amit and Lumbendil answer you should change
into
if you get an error like
in the block javascripts, you have to change
"liszt:updated"
to"chosen:updated"
hope it helps someone ;)
I was able to make this work a few months back. While what a.aitboudad has shared is accurate. There are a few gotcha's that first timers with Symfony/Sonata might face.
Here are the steps.
1> Extend Sonata CRUD's
edit.html.twig
/base_edit.html.twig
. For simplicity, I'll use only the latter. Copyvendor/bundles/Sonata/AdminBundle/Resources/views/CRUD/base_edit.html.twig
into the views folder corresponding to the MerchantAdminController -YourBundle/Resources/views/Merchant/base_edit.html.twig
2> We need to tell our MerchantAdmin class to use this template. So we override SonataAdmin's
getEditTemplate
method like this:3> Next we need to code the Ajax functionality in our
base_edit.html.twig
. Standard Ajax comprises of the following:3.1> -- Create an Action in the controller for the Ajax request We primarily want to get a list of category IDs corresponding to a particular tag. But most likely you are just using Sonata's CRUD Controller.
Define your MerchantAdminController which extends CRUDController
3.2> -- Tell your Admin service to use this newly created controller instead of the default CRUDController by defining it in
YourBundle/Resources/config/services.yml
Notice that the 3rd argument is the name of your controller. By default it would have been null.
3.3> -- Create an Action named
getCategoryOptionsFromTagAction
in your controller. Your Ajax call will be to this Action.3.4> -- Create the corresponding route in
app/config/routing.yml
. Remember to expose your route if you are using the FOSJsRoutingBundle (else you'll have to hardcode which is not a good idea).3.5> -- Make the Ajax Request and use the response
Gotcha 1: How to get the Unique ID that is appended to all Sonata elements
Solution: Use the admin variable which will give you access to all the Admin Class's properties including uniqId. See code on how to use it.
Gotcha 2: How to get the Router in your JS.
Solution: By default Symfony2 Routing doesn't work in JS. You need to use a bundle called FOSJSRouting (explained above) and expose the route. This will give you access to the Router object within your JS too.
I have modified my solution slightly to make this example clearer. If you notice anything wrong, please feel free to comment.