how i can add constrainte greatherthan or equal today to field dateType when user update data? - constraints

I have formType class that i use for creation and modification of data, i need to use constrainte GreaterThanOrEqual than today if user create a new object or modifie date field and not activate the constrainte if user not modifie field dateType how i can do that .
there is my form type:
$builder
->add('title', TextType::class, [
'label' => "title",
'constraints' => [
new NotBlank(),
]
])
->add('percentage', PercentageType::class, [
'required' => false,
'label' => "percentage",
'constraints' => [
new Range(min: 0, max: 100),
new NotBlank()
],
])
->add('startAt', DateType::class, [
'label' => 'startAt',
'widget' => 'single_text',
'input' => 'datetime_immutable',
'constraints' => [
new NotBlank(),
new GreaterThanOrEqual(['value' => 'today'])
],
])

Related

Symfony 5 - display an required input field after a specify dropdown select

I would like to build a form with Symfony 5 that should display a required input field for a certain dropdown selection.
After selecting "sonstiges" I need a required input field.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('salutation', ChoiceType::class, [
'label' => 'salutation',
'required' => true,
'constraints' => [
new NotBlank()
],
'placeholder' => 'Bitte wählen',
'label_attr' => [
'class' => 'visually-hidden'
],
'choices' => [
'Herr' => 'herr',
'Frau' => 'frau',
'Diverse' => 'diverse',
],
])
->add('firstname', TextType::class, [
'label' => false,
'required' => true,
'constraints' => [
new NotBlank()
],
'attr' => [
'placeholder' => "firstname",
],
])
->add('afterWork', ChoiceType::class, [
'label' => 'afterWork',
'required' => true,
'constraints' => [
new NotBlank()
],
'placeholder' => 'Bitte wählen',
'label_attr' => [
'class' => 'visually-hidden'
],
'choices' => [
'Studium' => 'studium',
'weitere Schule' => 'weiterSchule',
'Ausbildung' => 'ausbildung',
'Sonstiges' => 'sonstiges',
],
])
}
I added a $builder->addEventListener, unfortunately it didn't give me the result I need, I also added the input field as not required, hidden it and displayed it with a javascript. Unfortunately, it will not be validated because it is not required in the $builder.
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$form = $event->getForm();
// this would be your entity, i.e. SportMeetup
$data = $event->getData();
if (!is_null($data) && $data['afterWork'] == "sonstiges") {
$form->add('afterWorkText', TextType::class, [
'label' => "afterWorkText",
'required' => false,
'constraints' => array(
new NotBlank(),
),
'attr' => [
'placeholder' => "afterWorkText"
],
'label_attr' => [
'class' => 'visually-hidden'
],
]);
}
}
Is there a way to insert this field with "display:none" attribute and activate it with a javascript? In addition, the field should then be set to required.
Or can someone help me to find the right solution here?

Symfony - How i can get all selected files from request with bellow the name

enter image description here
<input type="file" id="admin_novelty_NoveltyGrants_0_file" name="admin_novelty[NoveltyGrants][0][file]" required="required" multiple="multiple" class="form-control-file">
I have a table grantProduct with 2 mainly properties are title and URL
this is my formType.php. but this is just sub-form. it is included in another form.
$builder
->add('title', InputType\TextType::class, [
'label' => 'novelty.common.title',
'required' => true,
'trim' => true,
'attr' => array(
'placeholder' => 'タイトルを入力ください'
),
'constraints' => [
new Assert\NotBlank(),
]
])
->add('url', InputType\TextType::class, [
'label' => 'novelty.common.url',
'required' => true,
'trim' => true,
'constraints' => [
new Assert\NotBlank(),
]
])
->add('file', FileType::class, [
'multiple' => false,
'mapped' => false,
'attr' => [
'multiple' => 'multiple'
],
])
;
How i can get file input value after selecting some local files?
You can get your file(s) as such $files = $form['file']->getData();
You can loop over each and do what you want
$files = $form['file']->getData();
foreach($files as $file) {
//do what you want with file
}

Symfony manually $form->submit(); with multidimensional array

Im struggling since 10 hours with Symfony 5.1.7 and $form->submit();
My target is a JSON API that converts data to a similiar array. I already debugged and found following part.
Can someone please help me what I am doing wrong here?
To test it, i have created a manually PHP array to submit it.
My Code in Controller
$form = $this->createForm(AddCommentFormType::class);
$test = [
'content' => 'Test',
'media' => [
[
'path' => '1.png',
],
[
'path' => '2.png',
],
],
'_token' => '3bF4qkiUPjKNuGnbY-ySdO6B2sCLzKcS4ar7auX3Dek',
];
$form->submit($test);
AddCommentFormType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('content', TextareaType::class, [
'constraints' => [
new NotBlank(),
new Length([
'max' => 10000,
]),
],
])
->add('media', CollectionType::class, [
'entry_type' => MediaFormType::class,
'constraints' => [
new Count([
'min' => 1,
'max' => 5,
]),
],
])
->add('_token', HiddenType::class, [
'mapped' => false,
'constraints' => [
new NotBlank(),
],
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => false,
]);
}
MediaFormType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('path', TextType::class, [
'constraints' => [
new NotBlank(),
],
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Media::class,
]);
}
Validator Result
children[media].data
This collection should contain 1 element or more.
[]
children[media]
This form should not contain extra fields.
[▼
[▼
"path" => "1.png"
]
[▼
"path" => "2.png"
]
]
your form has no default data, since you create it with
$form = $this->createForm(AddCommentFormType::class);
createForm can take an additional parameter for default data. This alone is not necessarily a problem, the default is an array of the form (or something very similar, maybe empty strings instead of null)
[
'content' => null,
'media' => [],
'_token' => null,
]
However, the CollectionType will not allow adding or removing elements by default. Setting it's options allow_add (and optionally allow_remove, if you ever set default values) will change that.
So the minimal change would be:
->add('media', CollectionType::class, [
'allow_add' => true, // <-- this is new
'entry_type' => MediaFormType::class,
'constraints' => [
new Count([
'min' => 1,
'max' => 5,
]),
],
])
If your type is AddCommentFormType the form expects by default the data to be in add_comment_form keys like:
$test = [
‘add_comment_form’ => [
'content' => 'Test',
'media' => [
[
'path' => '1.png',
],
[
'path' => '2.png',
],
],
'_token' => '3bF4qkiUPjKNuGnbY-ySdO6B2sCLzKcS4ar7auX3Dek',
]
];

Use Expression constrainst on non object

I have a form like it:
class FeatureDynamicSequenceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('upstream', IntegerType::class, [
'data' => 0,
'constraints' => [
new LessThan([
'value' => 1000,
]),
],
])
->add('downstream', IntegerType::class, [
'data' => 0,
'constraints' => [
new LessThan([
'value' => 1000,
]),
],
])
->add('showUtr', CheckboxType::class,[
'data' => true,
'label' => 'Show UTR',
'required' => false,
])
->add('showIntron', CheckboxType::class,[
'data' => true,
'required' => false,
])
;
}
}
In this form, I would like add a Constrainst that check:
If showUtr or ShowIntron are not checked, then upstream and downstreal can't be > to 0.
Then I want something like it:
->add('upstream', IntegerType::class, [
'data' => 0,
'constraints' => [
new LessThan([
'value' => 1000,
]),
new Expression([
'expression' => 'value > 0 && (this.showUtr || this.showIntron)',
'message' => 'You cannot set upstream if you do not display UTRs and introns.',
]),
],
])
But I can't use it, because it's not an object, value give me the value of the upstream field (it's ok), but I can't access to the showUtr or showIntron value...
EDIT: try with Callback closure
->add('upstream', IntegerType::class, [
'data' => 0,
'constraints' => [
new LessThan([
'value' => 1000,
]),
new Callback([
'callback' => function($data, ExecutionContextInterface $executionContectInterface) {
dump($data);
$executionContectInterface->addViolation('You cannot set upstream if you do not display UTRs and introns.');
},
])
],
])
I have the same problem, $data just contain the field value.
I don't really want to create an Entity, because I don't persist it... And I can't believe there is not a solution to check it whithout creating an Entity.
I answered in a previous question here
I solved it by using:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'constraints' => [
new Callback([
'callback' => function($data, ExecutionContextInterface $executionContectInterface) {
if ($data['upstream'] > 0 && (!$data['showUtr'] || !$data['showIntron'])) {
$executionContectInterface->buildViolation('You cannot set upstream if you do not display UTRs and introns.')
->atPath('[upstream]')
->addViolation()
;
}
},
]),
],
]);
}
The full code is:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('upstream', IntegerType::class, [
'data' => 0,
'constraints' => [
new LessThan([
'value' => 1000,
]),
],
])
->add('downstream', IntegerType::class, [
'data' => 0,
'constraints' => [
new LessThan([
'value' => 1000,
]),
],
])
->add('showUtr', CheckboxType::class, [
'data' => true,
'label' => 'Show UTR',
'required' => false,
])
->add('showIntron', CheckboxType::class, [
'data' => true,
'required' => false,
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'constraints' => [
new Callback([
'callback' => function($data, ExecutionContextInterface $executionContectInterface) {
if ($data['upstream'] > 0 && (!$data['showUtr'] || !$data['showIntron'])) {
$executionContectInterface->buildViolation('You cannot set upstream if you do not display UTRs and introns.')
->atPath('[upstream]')
->addViolation()
;
}
},
]),
],
]);
}

How to create a Drupal 8 view programmatically

I am trying to create a view programmatically in Drupal 8. Something similar to the crud log module in Drupal 7. I couldn't find any references on the internet either.
I was successful in creating a view programatically----I did the following--
1. Create a folder--C:\xampp\htdocs\Drupal Instance\modules
2. Create a YML info file --first_view.info and add the following code to it----
name: First View
type: module
description: My First Drupal 8 View
package: Custom
core: 8.x
3. Create an install file---first_view.install
And add the following code to it
<?php
/**
* #file
* Install, schema, and uninstall functions for the First View module.
*/
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\taxonomy\Entity\Term;
/**
* Implements hook_install().
*/
function first_view_install() {
}
/**
* Implements hook_uninstall().
*/
function first_view_uninstall() {
}
/**
* Implements hook_schema().
*/
function first_view_schema() {
$schema['first_view_table'] = [
// Example (partial) specification for table "node".
'description' => 'The base table for first_view.',
'fields' => [
'id' => [
'description' => 'The primary identifier for a node.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'name' => [
'description' => 'The name of Employee.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '',
],
'age' => [
'description' => 'The age of employee.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'is_active' => [
'description' => 'The activity of employee.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
],
'timestamp' => [
'description' => 'The timestamp of employee.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'project_code' => [
'description' => 'The project code of employee.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => 0,
],
],
'unique keys' => [
'id' => ['id'],
],
// For documentation purposes only; foreign keys are not created in the
// database.
'primary key' => ['id'],
];
return $schema;
}
4. Create a file---first_view.views.inc
And add the following code to it--
<?php
/**
* Implements hook_views_data().
*/
function first_view_views_data() {
$data = [];
$data['first_view_table'] = [];
$data['first_view_table']['table'] = [];
$data['first_view_table']['table']['group'] = t('First View table');
$data['first_view_table']['table']['provider'] = 'first_view_module';
$data['first_view_table']['table']['base'] = [
'field' => 'id',
'title' => t('First View table'),
'help' => t('First View table contains example content and can be related to nodes.'),
'weight' => -10,
];
$data['first_view']['table']['join'] = [
'node_field_data' => [
'left_field' => 'id',
'field' => 'id',
'extra' => [
0 => [
'field' => 'published',
'value' => TRUE,
],
1 => [
'left_field' => 'age',
'value' => 1,
'numeric' => TRUE,
],
2 => [
'field' => 'published',
'left_field' => 'is_active',
'operator' => '!=',
],
],
],
];
$data['first_view_table']['table']['join']['node_field_data'] = [
'left_table' => 'foo',
'left_field' => 'id',
'field' => 'id',
'extra' => [
['left_field' => 'project_code', 'field' => 'project_code'],
['field' => 'age', 'value' => 0, 'numeric' => TRUE, 'operator' => '>'],
],
];
$data['first_view_table']['id'] = [
'title' => t('Example content'),
'help' => t('Relate example content to the node content'),
'relationship' => [
'base' => 'node_field_data',
'base field' => 'id',
'id' => 'standard',
'label' => t('Example node'),
],
];
$data['first_view_table']['name'] = [
'title' => t('Name'),
'help' => t('Just a Name field.'),
'field' => [
'id' => 'standard',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'string',
],
'argument' => [
'id' => 'string',
],
];
$data['first_view_table']['project_code'] = [
'title' => t('Project Code'),
'help' => t('Just a Project code field.'),
'field' => [
'id' => 'standard',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'string',
],
'argument' => [
'id' => 'string',
],
];
$data['first_view_table']['age'] = [
'title' => t('Age'),
'help' => t('Just a numeric field.'),
'field' => [
'id' => 'numeric',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'numeric',
],
'argument' => [
'id' => 'numeric',
],
];
$data['first_view_table']['is_active'] = [
'title' => t('Is Active'),
'help' => t('Just an on/off field.'),
'field' => [
'id' => 'boolean',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'boolean',
'label' => t('Published'),
'type' => 'yes-no',
'use_equal' => TRUE,
],
];
$data['first_view_table']['timestamp'] = [
'title' => t('Timestamp'),
'help' => t('Just a timestamp field.'),
'field' => [
'id' => 'date',
],
'sort' => [
'id' => 'date',
],
'filter' => [
'id' => 'date',
],
];
$data['views']['area'] = [
'title' => t('Text area'),
'help' => t('Provide markup text for the area.'),
'area' => [
'id' => 'text',
],
];
return $data;
}
By following the above steps....when we install and enable the module a table gets created in the database...You will have to populate it in order to see some data in the view...don't forget to add dummy data in the table.....After that go to Structure/views--- And click on "Add View"----Give a name to your View---and then you will be able to see the table name in "Show" Drop Down box---In this case the table name is "First View Table"...I hope this article would be helpful....
Although it is not created from scratch programatically, here is a simple method:
create a view using the back office
export that single view using the configuration manager module
copy that yml file and place it in a basic custom module /config/install folder
remove the first line containing the uuid
(optional )modify the file manually if needed and if understood how it work
activating your custom module will import the view
You can create a new View through the ConfigEntityStorage.
Create the View in the UI. Export the View's YAML config file to a path in your module, removing the UUID.
// view config is in `my_module/config/install/views.view.my_view.yml`
// (uuid removed!)
$dir = drupal_get_path('module', 'my_module');
$fileStorage = new FileStorage($dir);
$config = $fileStorage->read('views.view.my_view');
/** #var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
$storage = \Drupal::entityTypeManager()
->getStorage('view');
/** #var \Drupal\views\Entity\View $view */
$view = $storage->create($config);
$view->save();

Resources