I work with symfony 2.7 , and I use SonataAdminBundle.
I have 2 entities called (Produit) and (Correspondant) with OneToMany relation, One Produit can have Many Correspondant. in the create form for the (Produit) I have correspondants to add Many (Correspondant), and I like by default add all the Correspondants, for that I tried to do this :
ProduitAdmin
$query = $this->modelManager->getEntityManager(new User())->createQuery("SELECT s FROM UserBundle\Entity\User s WHERE s.type LIKE 'Correspondant'" );
$formMapper
->add('correspondants','sonata_type_model', array(
'class'=>'Devagnos\UserBundle\Entity\User',
'multiple'=> true,
'by_reference' => false,
'label'=>'Correspondants associés',
'data' => function() {
$data = new ArrayCollection();
$r= $query->getResult();
foreach($r as $result) {
$data->add($result->getId());
}
return $data;
},
'query' => $query ),
)
But this does not work,
Someone can help me please ? thanks
You need to set data attribute and put the entities you want to be selected as default.
$selected = ... //fetch entities, e.g. from repository
$formMapper
->add('field', 'sonata_type_model', array(
'your_settings' => '...',
'query' => '...',
'data' => $selected
)
);
Related
I'm working on a view with lots of invoices.
Users can filter them by 'Customer', 'Date' and also by 'Referent'.
An invoice is linked to a customer, and a customer can have a 'referent' or not.
So in my 'referent' select list, the default value is 'All' to not filter by 'referent', and the rest is the list of all referents got by QueryBuilder.
Now, I need help to know how can I insert an option 'No Referent' in the select list to get all invoices for which the customer has no referent.
Here is my referent field in my 'InvoiceSearchType':
->add('referent', 'genemu_jqueryselect2_entity', array(
'label' => 'Referent',
'class' => 'GeocalUserBundle:User',
'query_builder' => function (UserRepository $ur) {
return $ur->getEmployesQueryBuilder();
},
'empty_value' => '',
'configs' => array(
'placeholder' => 'All',
'width' => '100%',
'allowClear' => true,
),
'required' => false,
))
Here, my QueryBuilder:
public function getEmployesQueryBuilder()
{
$queryBuilder = $this->createQueryBuilder('u')
->leftJoin('u.groups', 'g')
->where('u.enabled = 1')
->andWhere('g.id NOT IN(1)')
->orderBy('u.nom', 'ASC')
;
return $queryBuilder;
}
And I just display the field like that:
<td class="label">Chargé d'affaire</td>
<td colspan="2">{{ form_widget(form.referent) }}</td>
Thanks in advance ! :)
[SOLVED]
First I added a method which get the result (array) of the query, add another referent and return it:
public function getReferentWithNull()
{
// Get the list of referents
$referents = $this->doctrine->getRepository('GeocalUserBundle:User')->getEmployesQueryBuilder()->getQuery()->getResult();
// Create a new instance
$nobody = new User();
$nobody->setName("No Referent");
// Put it in the array result with the key -1
$referents[-1] = $nobody;
return $referents;
}
Then, I modified my form field type to 'choice' type and call my previous function:
->add('referent', 'genemu_jqueryselect2_choice', array(
'label' => 'Referent',
'choices' => $this->getReferentWithNull(),
'empty_value' => '',
'configs' => array(
'placeholder' => 'All',
'width' => '100%',
'allowClear' => true,
),
'required' => false,
))
Finally, I have my last option 'No Referent' with a key of -1.
Hope that it helps someone :)
I am using Symfony 2.7 I have built a form with an entity, which when submitted returns an array of objects. I need to be able to compare this array of objects with what I have in the that table?
So this is how I have the form setup
$builder
.......
->add('my_options', 'entity', [
'label' => 'Options:',
'class' => 'xxxxBundle:Details',
'choice_label' => 'Title',
'multiple' => true,
'expanded' => true,
'required' => false,
'mapped' => false,
'data' => $data,
'attr' => ['class' => 'AdminList'],
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('de')
->where('de.active = ?1')
->setParameter(1, 1); }
]);
I then do a basic lookup of what my options table has already got,
$EditPanels = $this->getDoctrine()
->getRepository('xxxBundle:Options')
->findBy(['AccountID' => $AcID]);
This gives me two arrays, one of which the user has just selected (the options they now need on this account) and one with what is already in the database table.
How do I compare these tables to update the rows with the new options, by removing whats not needed and adding in the new options?
Thanks.
$newIds = array_map($formData, function (Details $d) {
return $d->id;
});
$oldIds = array_map($EditPanels, function (Details $d) {
return $d->id;
});
$shouldBeRemoved = array_diff($oldIds, $newIds);
$shouldBeAdded = array_diff($newIds, $oldIds);
Now you have all the IDs for the Options that need to change. Hope this helps.
I think you should not even query for existing records. Instead you can:
Persist all new records and update existing:
foreach ($new as $object) {
if ($object->getId() === null) {
$em->persist($object);
}
}
$em->flush();
Delete all other records from database:
$qb = $em->getRepository('xxxxBundle:Details')->createQueryBuilder();
$qb->delete()->where($qb->expr()->notIn('id', array_column('id', $new)));
P.S. Not sure regarding the syntax, but you got the idea.
i'm passing my symfony2 application to PHPUnit and i have some problems with the form test. In my form i have a choice list and i filled this list by passing from controller array of choices with $options like this :
//Controller
$form = $this->createForm(new AdddocType(), array(
'docdata' => $myarray,
));
//Form
->add('myfield', 'choice', array(
'choices' => $options['data']['docdata'],
'multiple' => false,
'required' => true,
'expanded' => false,
))
And here my PHPUnit test :
public function testaddContact()
{
$formData = array(
'myfield' => 10,
...
...
);
$type = new AdddocType();
$form = $this->factory->create($type);
$form->submit($formData);
$this->assertTrue($form->isSynchronized());
}
When i pass PHPUnit, the code stop at this line in my formType :
'choices' => $options['data']['docdata'],
My question is : How can i pass the $options in my PHPUnit test ?
Thanks
Options can be passed in the third argument of create(). It isn't very hard to find that out...
I created a symfony entity form-type and used a QueryBuilder to get the entities.
My Querybuilder looks like this:
$qb = $this
->em
->getRepository('Namespace\Entity\Domain\Nic')
->createQueryBuilder('domainNic')
->join('domainNic.article', 'article')
->andWhere('article.category = :domainCategory')
->setParameter('domainCategory', Article::CATEGORY_DOMAINS)
->orderBy('article.title');
My form type definition below looks like this:
$builder->add(
'withTld',
'bootstrap_collection',
array(
'allow_add' => true,
'allow_delete' => true,
'add_button_text' => 'addtext',
'delete_button_text' => 'deletetext',
'type' => 'entity',
'sub_widget_col' => 5,
'label' => '***',
'options' => array(
'class' => 'Namespace\Entity\Domain\NIC',
'query_builder' => $qb,
'property' => 'title'
)
)
);
The result looks exactly as expected, but for every found record, Symfony doesn't use the data from the QueryBuilder. Instead, Symfony fetches the title for each record again.
Anybody knows a solution? I want Symfony to use the data from the QueryBuilder.
You will need an extra select line in you query builder:
$qb = $this
->em
->getRepository('Namespace\Entity\Domain\Nic')
->createQueryBuilder('domainNic')
->addSelect('article') // <---------------- THIS
->join('domainNic.article', 'article')
->andWhere('article.category = :domainCategory')
->setParameter('domainCategory', Article::CATEGORY_DOMAINS)
->orderBy('article.title');
Good morning,
In Symfony 1.4,
I tried to do what is explained here : Customizing layout to sfWidgetFormDoctrineChoice
But it doesn't work. Instead of adding a thumbnail, I just want to hide the <li> before the input, and in some condition disable/hide the checkbox input but show the label anyway.
When I add the renderer without argument, I get this error :
sfWidgetFormMySelectCheckbox requires the following options: 'choices'.
Here is my formatter code :
class sfWidgetFormMySelectCheckbox extends sfWidgetFormSelectCheckbox
{
public function configure($options = array(), $arguments = array())
{
parent::configure($options, $arguments);
}
protected function formatChoices($name, $value, $choices, $attributes)
{
.....
// new
$inputs[$id] = array(
'input' => sprintf('| test | %s',
$this->renderTag('input', array_merge($baseAttributes, $attributes))
),
'label' => $this->renderContentTag('label', self::escapeOnce($option), array('for' => $id)),
);
}
return call_user_func($this->getOption('formatter'), $this, $inputs);
}
}
And now the form where I call it :
$this->setWidget('aaa', new sfWidgetFormDoctrineChoice(array(
'model' => 'Aaa',
'expanded' => true,
'multiple' => true,
'add_empty' => false,
'query' => $query,
'renderer' => new sfWidgetFormMySelectCheckbox()
)));
Thanks for your help !
According to the docs you have to pass the choices option to the renderer object. Try something like this:
$this->setWidget('aaa', new sfWidgetFormDoctrineChoice(array(
'model' => 'Aaa',
'expanded' => true,
'multiple' => true,
'add_empty' => false,
'query' => $query,
)));
$this->widgetSchema['aaa']->setOption('renderer', new sfWidgetFormMySelectCheckbox(array(
'choices' => new sfCallable(array($this->widgetSchema['aaa'], 'getChoices'))
)));
So basically you want the renderer object get the choices from the parent widget. To do that you have to pass a sfCallable object which takes an array as the first argument in which you pass the instance of your parent widget and the name of the function getChoices.
Remember also that the expanded option is not used when you override the renderer.