i have a problem when i insert date from calender using jquery !there is a problem of conversion i think .
II try to use
{{ form_widget(form.dateArrivage|date("m/d/Y") , {'attr': {'class': 'from'}}) }}<br>
but :
An exception has been thrown during the rendering of a template
Catchable Fatal Error: Object of class Symfony\Component\Form\FormView could not be converted to string
in GestionHotelBundle:Default:index.html.twig at line 147.
this is ReservationType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('dateArrivage',DateTimeType::class, array(
'widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'attr' => array('class' => 'date')
))
->add('dateSortie',DateTimeType::class, array(
'widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'attr' => array('class' => 'date')
))
->add('nbjour')
->add('dateReser',DateType::class)
->add('chambres', CollectionType::class, array(
'entry_type' => ChambreType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
->add('save',SubmitType::class)
;
;
}
and this is the vue :
<script>
$( function() {
var dateFormat = "mm/dd/yy",
from = $( ".from" )
.datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 2
})
.on( "change", function() {
to.datepicker( "option", "minDate", getDate( this ) );
}),
to = $( ".to" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 2
})
.on( "change", function() {
from.datepicker( "option", "maxDate", getDate( this ) );
});
function getDate( element ) {
var date;
try {
date = $.datepicker.parseDate( dateFormat, element.value );
} catch( error ) {
date = null;
}
return date;
}
} );
{{ form_start(form) }}
{{ form_label(form.dateArrivage) }}
{{ form_errors(form.dateArrivage) }}
{{ form_widget(form.dateArrivage , {'attr': {'class': 'from'}}) }}<br>
<br><br>
{{ form_label(form.dateSortie) }}
{{ form_errors(form.dateSortie) }}
{{ form_widget(form.dateSortie, {'attr': {'class': 'to'}}) }}<br><br>
<br><br>
{{ form_row(form.nbjour) }}
{{ form_row(form.dateReser) }}
Doc says :
If you want your field to be rendered as an HTML5 "date" field, you
have to use a single_text widget with the yyyy-MM-dd format (the RFC
3339 format) which is the default value if you use the single_text
widget.
So you have to change date format into your form builder:
$builder
->add('dateArrivage',DateTimeType::class, array(
'date_widget' => 'single_text',
'date_format' => 'yyyy-MM-dd', //here
))
->add('dateSortie',DateTimeType::class, array(
'date_widget' => 'single_text',
'date_format' => 'yyyy-MM-dd', //and here
))
Set the dateformat option in the jQuery-UI datepicker :
$(".from").datepicker({ dateFormat:'mm/dd/yy'})
Nothing else. You don't need to parse the date yourself.
Other mistake you have :
DateTimeType must not use format and widget options but date_format, date_widget, time_format and time_widget options ...
Because the jQuery plugin doesn't care about time. It can only be applied on the date part.
http://symfony.com/doc/current/reference/forms/types/datetime.html#date-format
Related
In a Symfony 3.4 project, I just created a new form type ProductSearchType. The form fields are not shown in twig template. There are only the <form> tags, but nothing between them.
FormType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, [
'required' => false,
'label' => 'Name',
])
->add('sizes', EntityType::class, [
'required' => false,
'label' => 'Bauform',
'class' => ProductSize::class,
])
->add('description', TextType::class, [
'required' => false,
'label' => 'Beschreibung',
])
->add('price', EntityType::class, [
'required' => false,
'label' => 'Preiskategorie',
'class' => ProductPrice::class,
])
->add('booster', EntityType::class, [
'required' => false,
'label' => 'Hörverlust',
'class' => ProductBooster::class,
])
->add('brand', EntityType::class, [
'required' => false,
'label' => 'Marke',
'class' => ProductBrand::class,
]);
}
Action:
public function index(Request $request): Response
{
$products = $this->getDoctrine()->getRepository(Produkt::class)
->findBy([
'showOnEmptySearch' => true,
], [
'sortOnEmptySearch' => 'asc',
]);
$searchForm = $this->createForm(ProductSearchType::class);
$searchForm->handleRequest($request);
$params = [
'products' => $products,
'search_form' => $searchForm->createView(),
];
return $this->render('Products/index.html.twig', $params);
}
Twig part:
{% block template_filter %}
<h1>
Suche
</h1>
<div class="filter_box">
{{ form(search_form) }}
</div>
{% endblock %}
I recommend to follow the documentation. On your example:
$searchForm = $this->createForm(ProductSearchType::class); should be:
$searchForm = $this->createForm(ProductSearchType::class)->getForm();.
Also on twig;
{{ form_start(search_form) }}
{{ form_widget(search_form) }}
{{ form_end(search_form) }}
Here is the documentation link. Welcome to Stackoverflow.
If you get answer to your question, don't forget to mark this answer as Accepted Answer.
I need to create a form adding faculty to the database. First, the user selects a region from the list ( / ChoiceType), then the city of this region from the following list, the university, and finally enters the name of the faculty. The default values are the first region from the database, its first city and first university.
Sending the page with default data works, the choice of the region works, but the the choice of the city return to 500 status
Form:
Twig and ajax:
{% extends 'admin/insert/insert.html.twig' %}
{% block title %}Add Faculty{% endblock %}
{% block body %}
<div class="insert">
<h1 class="insert__title">Add Faculty</h1>
{{ form_start(insert_faculty, { 'attr' : {'class' : 'insert__form'} }) }}
{% for message in app.flashes('success') %}
<div class="insert__success">
{{ message }}
</div>
{% endfor %}
<div class="insert__errors">
{{ form_errors(insert_faculty) }}
</div>
{{ form_label(insert_faculty.region, 'Region:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.region, { 'attr' : {'class' : 'insert__input'} }) }}
{{ form_label(insert_faculty.city, 'City:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.city, { 'attr' : {'class' : 'insert__input'} }) }}
{{ form_label(insert_faculty.university, 'University:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.university, { 'attr' : {'class' : 'insert__input'} }) }}
{{ form_label(insert_faculty.name, 'Name:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.name, { 'attr' : {'class' : 'insert__input insert__input_name'} }) }}
<button type="submit" class="insert__button">Save</button>
{{ form_end(insert_faculty) }}
<div class="insert__buttons">
Back
</div>
</div>
{% block javascripts_footer %}
{{ parent() }}
<script>
let $region = $('#insert_faculty_region');
$region.change(function() {
let $form = $(this).closest('form');
let data = {};
data[$region.attr('name')] = $region.val();
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(get) {
$('#insert_faculty_city').html(
$(get).find('#insert_faculty_city').html()
);
$('#insert_faculty_university').html(
$(get).find('#insert_faculty_university').html()
);
}
});
});
let $city = $('#insert_faculty_city');
$city.change(function() {
let $form = $(this).closest('form');
let data = {};
data[$city.attr('name')] = $city.val();
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(get) {
$('#insert_faculty_university').html(
$(get).find('#insert_faculty_university').html()
);
}
});
});
</script>
{% endblock %}
{% endblock %}
Form class:
class InsertFacultyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('region', ChoiceType::class, [
'choices' => $options['regions_array'],
'mapped' => false,
])
->add('city', ChoiceType::class, [
'choices' => null,
'mapped' => false,
])
->add('university', ChoiceType::class, [
'choices' => null,
])
->add('name')
;
$formModifier = function (FormInterface $form, $entity_parent) {
if (get_class($entity_parent) === 'App\Entity\Region') {
if (!$entity_parent->getCities()->count()) {
$form->add('city', ChoiceType::class, [
'choices' => null,
'mapped' => false,
]);
}
else {
$cities_in_database = $entity_parent->getCities();
foreach ($cities_in_database as $city) {
$cities[$city->getName()] = $city;
}
$form->add('city', ChoiceType::class, [
'choices' => $cities,
'mapped' => false,
]);
}
}
else if (get_class($entity_parent) === 'App\Entity\City') {
if (!$entity_parent->getUniversities()->count()) {
$form->add('university', ChoiceType::class, [
'choices' => null,
]);
}
else {
$university_in_database = $entity_parent->getUniversities();
foreach ($university_in_database as $university) {
$universities[$university->getName()] = $university;
}
$form->add('university', ChoiceType::class, [
'choices' => $universities,
]);
}
}
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($options, $formModifier, $builder) {
$region = $options['regions_array'][array_key_first($options['regions_array'])];
$city = $region->getCities()[0];
$formModifier($event->getForm(), $region);
$formModifier($event->getForm(), $city);
}
);
$builder->get('region')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$region = $event->getForm()->getData();
$city = $region->getCities()[0];
$formModifier($event->getForm()->getParent(), $region);
$formModifier($event->getForm()->getParent(), $city);
}
);
$builder->get('city')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$city = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $city);
}
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Faculty::class,
'regions_array' => null,
]);
$resolver->setAllowedTypes('regions_array', 'array');
}
}
Controller:
/**
* #Route("/admin/insert/faculty", name="faculty")
*/
public function faculty(Request $request)
{
$regions_in_database = $this->getDoctrine()->getRepository(Region::class)->findAll();
$regions = [];
foreach ($regions_in_database as $region) {
$regions[(string)$region->getName()] = $region;
}
$faculty = new Faculty();
$insert_faculty = $this->createForm(InsertFacultyType::class, $faculty, [
'regions_array' => $regions,
]);
if (!$regions_in_database) {
$insert_faculty->addError(new FormError("There are no regions!"));
}
$insert_faculty->handleRequest($request);
if ($insert_faculty->isSubmitted() && $insert_faculty->isValid()) {
$repository = $this->getDoctrine()->getRepository(University::class);
$faculty_in_database = $repository->findOneBy(
[
'name' => $faculty->getName(),
'university' => $faculty->getUniversity(),
]
);
if ($faculty_in_database) {
$insert_faculty->addError(new FormError('Such a faculty is already in the database!'));
}
else {
$faculty->setRating(0);
if(!$faculty->getUniversity()) {
$insert_faculty->addError(new FormError("Select the university!"));
}
else {
$entity_manager = $this->getDoctrine()->getManager();
$entity_manager->persist($faculty);
$entity_manager->flush();
$this->addFlash(
'success',
'Faculty "' . $faculty->getName() . '" successfully saved!'
);
}
}
}
return $this->render('admin/insert/faculty/faculty.html.twig', [
'insert_faculty' => $insert_faculty->createView(),
]);
}
I invite you to use the Symfony debug toolbar. It will allow you to see the different problems associated with your code and give much more information about the problems that appear.
Profiler Symfony
About your problem, I think it is necessary to debug at the level of what your form sends to your application. But if you want more help, you must provide the error message that come with your 500 error.
I want to "Dynamically populate project drop down data based on client drop down choice data" in symfony 5. New page work properly, but when change client drop down value from edit page then ajax called and show this exception/error: "Expected argument of type "string", "null" given at property path "buildingPosition"."
Form Code:
class EnquiryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client', EntityType::class, [
// looks for choices from this entity
'class' => Client::class,
// uses the User.username property as the visible option string
'choice_label' => 'name',
'placeholder' => 'Select a Client...',
// 'label' => 'Contact Person Designation',
// used to render a select box, check boxes or radios
// 'multiple' => true,
// 'expanded' => true,
])
->add('buildingPosition', TextType::class, [
'attr' => ['class' => 'form-control'],
])
->add('offerSubmissionDate', DateType::class, [
'attr' => ['class' => 'form-control'],
'widget' => 'single_text',
'empty_data' => null,
])
->add('probability', ChoiceType::class, [
'choices' => [
'P1' => 'P1',
'P2' => 'P2',
'P3' => 'P3',
],
'placeholder' => 'Select a Probability...',
])
->add('notes', TextType::class, [
'attr' => ['class' => 'form-control'],
])
;
// Start Project data populate dynamically based on the value in the "client" field
$formModifier = function (FormInterface $form, Client $client = null) {
$projects = null === $client ? [] : $client->getProjects();
$form->add('project', EntityType::class, [
'class' => 'App\Entity\Project',
'placeholder' => '',
'choices' => $projects,
]);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
// this would be your entity, i.e. Enquiry
$data = $event->getData();
$formModifier($event->getForm(), $data->getClient());
}
);
$builder->get('client')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
// It's important here to fetch $event->getForm()->getData(), as
// $event->getData() will get you the client data (that is, the ID)
$client = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifier($event->getForm()->getParent(), $client);
}
);
// End Project data populate dynamically based on the value in the "client" field
}
Controller Code:
public function edit(Request $request, $id): Response
{
$enquiry = new Enquiry();
$entityManager = $this->getDoctrine()->getManager();
$enquiry = $entityManager->getRepository(Enquiry::class)->find($id);
$form = $this->createForm(EnquiryType::class, $enquiry);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
$this->addFlash('notice', 'Enquiry updated successfully!');
return $this->redirectToRoute('enquiry_index');
}
return $this->render('enquiry/edit.html.twig', [
'enquiry' => $enquiry,
'form' => $form->createView(),
]);
}
Twig/View Code:
{{ form_start(form) }}
{{ form_row(form.client, {'attr': {'class': 'form-control'}}) }}
{{ form_row(form.project, {'attr': {'class': 'form-control'}}) }}
{{ form_row(form.buildingPosition) }}
{{ form_row(form.offerSubmissionDate) }}
{{ form_row(form.probability, {'attr': {'class': 'form-control'}}) }}
{{ form_row(form.notes) }}
{{form_row(row)}}
JavaScript Code:
var $client = $('#enquiry_client');
// When sport gets selected ...
$client.change(function() {
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected sport value.
var data = {};
data[$client.attr('name')] = $client.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: "POST",
data : data,
success: function(html) {
// Replace current position field ...
$('#enquiry_project').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#enquiry_project')
);
// Position field now displays the appropriate positions.
}
});
});
Please help me.....
I tried some things and I am unable to add a multiple checkbox. When I submit the form I get this error message:
Expected argument of type "string or null", "array" given at property path "caractere_emotion".
My PersonnageType.php
->add('caractere_emotion', ChoiceType::class, [
'required' => false,
'label' => 'Émotions',
'choices' => [
'Actif' => 'Actif',
'Créatif' => 'Créatif',
'Génie' => 'Génie',
'Créatif' => 'Créatif',
'Joyeux' => 'Joyeux',
'Morose' => 'Morose',
'Pitre' => 'Pitre',
'Romantique' => 'Romantique',
'Sang Chaud' => 'Sang Chaud',
'Sûr de lui' => 'Sûr de lui',
],
'expanded' => true,
'multiple' => true,
])
My Personnage.php entity :
/**
* #ORM\Column(type="array", nullable=true)
*/
private $caractere_emotion;
CharacterController.php
class CharacterController extends AbstractController
{
public function index(Request $request)
{
$em = $this->getDoctrine()->getManager();
$personnage = new Personnage();
$form = $this->createForm(PersonnageType::class, $personnage);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($personnage);
$em->flush();
}
return $this->render('character/index.html.twig', [
'form' => $form,
'form' => $form->createView()
]);
}
}
Template :
{{ form_start(form) }}
{{ form_row(form.competences) }}
{{ form_row(form.principes) }}
{{ form_row(form.autres_personnalite) }}
{{ form_row(form.caractere_emotion) }}
{{ form_row(form.caractere_loisir) }}
<button type="submit" class="btn btn-success">Terminer</button>
{{ form_end(form) }}
Issue
For those with this issue, I'll save you some headache.
In summary: It is critical that the Pjax linkSelector must point to an < a > anchor element or you will receive an uncaught jquery error.
The issue I was having was updating content outside of the Gridview Widget using Pjax. I added a custom button using Html::button, but the pjax was failing for unknown reason.
When testing pjax on the gridview widget using the native buttons using 'class'=>'yii\grid\ActionColumn', the pjax would refresh just fine which caused me some confusion. What I didn't realize is that the pjax linkSelector only works on < a > elements, the linkSelector will not work on < button > element generated when using Html::button(...); .
Recieved this error: Uncaught $.fn.pjax or $.pjax.click requires an anchor element.
View
File Location: app/views/default/pjax-example.php
[Code for Pjax]
<?php Pjax::begin([
'id'=>'p0',
'timeout' => false,
//Selector must target the <a> anchor.
'linkSelector'=>'.action-select',
]); ?>
<?php Pjax::end(); ?>
[Code for Gridview Widget]
$data = [
['step_id' => 1, 'step_name' => 'Step A'],
['step_id' => 2, 'step_name' => 'Step B'],
['step_id' => 3, 'step_name' => 'Step C'],
];
$dataProvider = new ArrayDataProvider([
'allModels' => $data,
'sort' => [
'attributes' => ['id', 'name'],
],
]);
echo GridView::widget([
'dataProvider' => $dataProvider,
'tableOptions' => [
'class' => 'table',
],
'columns' => [
'step_id',
'step_name',
[
'class' => 'yii\grid\DataColumn',
'label' => 'Button-1',
'format'=> 'raw',
'value' => function ($url, $data) {
return Html::a(
'<span class="glyphicon glyphicon-flash"></span>',
Url::to(['default/select', 'id'=>$data['step_id']]),
[
'class' => 'btn btn-danger btn-xs action-select',
'data-pjax'=> 'p0', // We must specify the pjax ID.
]
);
},
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{select}',
'header' => 'Button-2',
'buttons' => [
'select' => function ($url, $data) {
return Html::Button(
'<span class="glyphicon glyphicon-pencil"></span>',
['value' => Url::to(['default/select', $data['step_id']]),
'class' => 'btn btn-danger btn-xs action-select',
'data-pjax'=> 'p0',
]);
},
],
],
],
]);
Controller
File Location: app/controllers/defaultController.php
public function actionSelect()
{
$random_val = 'Rand_01: ' . rand(10,100);
return $random_val;
}
public function actionPjaxExample()
{
$random_val = 'Rand_02: ' . rand(10,100);
return $this->render('pjax-example', [
'random_val' => $random_val
]);
}
I am using this code without a link selector. And also without data-pjax=0
views/tranlate/index.php
<?php Pjax::begin(['id' => 'translate-grid', 'timeout' => false, 'enablePushState' => true]) ?>
# here you form
<?php $form = ActiveForm::begin(['action'=> Url::current(),'id'=>'edit-form']) ?>
<?= $form->field($model, 'word')->textInput() ?>
<?php ActiveForm::end() ?>
<?= GridView::widget([
'id' => 'data-grid',
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'title',
'format' => 'raw',
'value' => function ($model) {
return Html::a($name, [
'id' => $model->id
]);
},
],
]
]) ?>
<?php Pjax::end() ?>
controllers/TranalteController.php
public function actionIndex($id = false)
{
$searchModel = new TranslateSearch();
$model = $id ? $this->findModel($id) : new Translate();
if ($model->load(Yii::$app->request->post())) {
if ($model->save()) {
return $this->redirect(Yii::$app->request->getReferrer());
}
}
return $this->render('index', [
'model' => $model,
'searchModel' => $searchModel,
'dataProvider' => $searchModel->search(Yii::$app->request->get()),
]);
}