Turn off setReadOnly action for one component inside binder - vaadin8

I have some components inside binder:
binder.bind(cbClientRating, Client::getRating, Client::setRating);
binder.bind(tfFirstName, Client::getFirstName, Client::setFirstName);
binder.bind(tfLastName, Client::getLastName, Client::setLastName);
binder.bind(dfBirthDate, Client::getBirthDate, Client::setBirthDate);
According my business logic i do not need to change readonly status for one component inside binder, for example Combobox - cbClientRating when i call binder.setReadOnly(false). It should be stay in readonly mode equal true.
Now i call
cbClientRating.setReadOnly(true) after calling binder.setReadOnly(false)
binder.setReadOnly(false);
cbClientRating.setReadoOnly(true);
Is there any other solution?

Source code of Binder#setReadOnly(boolean):
/**
* Sets the read only state to the given value for all currently bound
* fields.
* <p>
* This is just a shorthand for calling setReadOnly for all currently bound
* fields. It means that fields bound after this method call won't be set
* read-only.
*
* #param fieldsReadOnly
* true to set the fields to read only, false to set them to read
* write
*/
public void setReadOnly(boolean fieldsReadOnly) {
getBindings().stream().map(BindingImpl::getField)
.forEach(field -> field.setReadOnly(fieldsReadOnly));
}
So this is only a convenience method. I recommend that you handle the field read only states completly by yourself according to your business logic.

Related

Logging from the Spring Integration DSL to the database

I'm doing the application with the Spring Integration Java DSL.
What is the best way to log to the database using the Spring Data JPA from the application?
I have a quite long integration flow with the multiple HTTP gets and posts. I want at least log the sent and responded messages and which URLs were used and possible some other custom values.
I have tried the logging with the method IntegrationFlowBuilder.log. With that my plan would be create some custom logger, which logs to the database.
I have tried the method IntegrationFlowBuilder.enrichHeaders with the method IntegrationFlowBuilder.log to log the URLSs and the other custom values. How to change some header entry inside the IntegrationFlowBuilder? I have added the entry with same key and different value, but the value in the logging doesn't change.
The HeaderEnricherSpec for the enrichHeaders() provides an option like:
/**
* Determine the default action to take when setting individual header specifications
* without an explicit 'overwrite' argument.
* #param defaultOverwrite the defaultOverwrite.
* #return the header enricher spec.
* #see HeaderEnricher#setDefaultOverwrite(boolean)
*/
public HeaderEnricherSpec defaultOverwrite(boolean defaultOverwrite) {
Also each added entry into the headers can be specified with their own override flag:
/**
* Add a single header specification where the value is a String representation of a
* SpEL {#link Expression}.
* #param name the header name.
* #param expression the expression.
* #param overwrite true to overwrite an existing header.
* #return the header enricher spec.
*/
public HeaderEnricherSpec headerExpression(String name, String expression, Boolean overwrite) {

How to set possible date input formats for Typo3 6.2 Extbase Extension?

I made an extension with the Extension Builder in Typo3 6.2 using Fluid 6.2 and Extbase 6.2.
I made Appointment-Objects with a date property.
I want to enter the date in the format "dd.mm.yyyy".
So I tried this:
And it gives this error:
I'm clueless as I'm not familiar with this and I want to solve this in a nice way.
My createAction code is simply generated by the extension builder and therefore looks like this:
/**
* action create
*
* #param \JH\Appmgmt\Domain\Model\Appointment $newAppointment
* #return void
*/
public function createAction(\JH\Appmgmt\Domain\Model\Appointment $newAppointment) {
$this->addFlashMessage('The object was created. Please be aware that this action is publicly accessible unless you implement an access check. See Wiki', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR);
$this->appointmentRepository->add($newAppointment);
$this->redirect('list');
}
Now I realize that if I change something here in order for the format to work I would have to do the same thing in the updateAction and maybe others that I don't know about yet.
I also desperately tried to format it to the desired format somehow in the partial but that was bound to fail - same result:
<f:form.textfield property="appointmentDate" value="{appointment.appointmentDate->f:format.date(format:'Y-m-d\TH:i:sP')}" /><br />
So that's where I need your help - I don't know where and how to globally allow this date format since I will be needing it for other fields as well.
The only other thing I can think of is changing something in the domain model:
/**
* appointmentDate
*
* #var \DateTime
*/
protected $appointmentDate = NULL;
but I don't know how I should approach this. :(
Anyone an idea?
You send a date that is not formatted correctly as a date Object.
that's exactly what the error says.
What you can do is re-format the date you send so that it arrives at your controller action as a valid argument for your object. this is done with an initialize action that invokes a property mapping.
a clear example can be found here:
http://www.kalpatech.in/blog/detail/article/typo3-extbase-datetime-property-converter.html
the part that you need is:
// Here we convert the property mapping using the property mapper
public function initializeAction() {
if ($this->arguments->hasArgument('newCalendar')) {
$this->arguments->getArgument('newCalendar')->getPropertyMappingConfiguration()->forProperty('startdate')->setTypeConverterOption('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT,'d-m-Y');
}
}
You could also disable the validation of the date arguments to your controller and create a valid date Object from your 'date' and then use setAppointmentDate($yourNewDateObject).
You then go round the extbase validation, what is not a good practise.

Typo3 extbase validating custom or manual objects

I have created extbase extension, there for some reason I need to create object manually in create action.
My create action looks like this,
/**
* action create
*
* #return void
*/
public function createAction() {
$newObj = new \TYPO3\Myext\Domain\Model\Modelname();
$newObj->setMyval('value');
$this->myrepository->add($newObj);
}
Here the problem is its not validating for require field, captcha etc even if I mention #validate NotEmpty in model.
So how to make the validation of manually created object ?
It should throw error to form like out-of-the-box features.
Thank you.
Out of the box validation is only triggered on constructing model objects from GET/POST parameters according to your controller actions signature.
It should look something like this:
/**
* action create
* #param \TYPO3\Myext\Domain\Model\Modelname $newObject
* #return void
*/
public function createAction(\TYPO3\Myext\Domain\Model\Modelname $newObject) {
$this->myrepository->add($newObj);
}
Take a look at the extension_builder, create a model and let the new/create action be generated for you. That will give you a good example on the create action as well as on the new action where the form is being rendered.

typo3 extbase validate for multiple records

I have written one extbase plugin, that creates the FE users from front end form.
The create action is something like this
/**
* action create
*
* #param \TYPO3\Usermanagement\Domain\Model\Users $newUsers
* #return void
*/
public function createAction(\TYPO3\Usermanagement\Domain\Model\Users $newUsers) {
$this->usersRepository->add($newUsers);
}
Here I want to validate for same username or email already exists or not.
How can I do this ?
Any suggestions ?
Thank you.
You don't need to bind a $newUser as an action's param, instead you can just read some fields using $this->request->hasArgument('something') and $this->request->getArgument('something') to validate properties yourself, and create new user object manually like.
public function createAction() {
$newUsers = new \TYPO3\Usermanagement\Domain\Model\Users();
// do something with $newUsers object...
$this->usersRepository->add($newUsers);
}
It will not throw an exception in case when there's no valid user object in the request, so it will allow you to handle form's error as you want/need.
It will also allow you to use some preprocessing before saving ie hashing/salting passwords.

preUpdate and postUpdate events not triggered on Doctrine 2

I have followed the instructions from this tutorial: http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html, and have created a simple listener, that listens for events dispatched by Doctrine on insert or update of an entity. The preInsert and the postInsert events work fine and are dispatched on the creation of a new entity. However, preUpdate and postUpdate are never called on the update of the entity no matter what. The same goes for onFlush. As a side note, I have a console generated controller that supports the basic CRUD operations, and have left it untouched.
Below are some code snippets to demonstrate the way I am doing this.
config.yml
annotation.listener:
class: City\AnnotatorBundle\Listener\AnnotationListener
tags:
- { name: doctrine.event_listener, event: postUpdate}
Listener implementation (I have omitted the other functions and left only the postUpdate for simplicity purposes)
class AnnotationListener
{
public function postUpdate(LifecycleEventArgs $args)
{
$entity=$args->getEntity();
echo $entity->getId();
die;
}
}
The entity id is never displayed, and the script continues its execution until it is complete, despite the die at the end of the function.
Did you forget to add #HasLifecycleCallbacks annotaion? You could use #PreUpdate annotation and skip service definition altogether.
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class YouEntity
{
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function preUpdate(){
// .... your pre-update logic here
}
....
}
In my opinion this way of attaching events is much easier as you don't have to define new services and listeners explicitly. Also you have direct access to data being updated as this method is locations within your entity.
Now, drawback is that you mix logic with your model and that's something that should be avoided if possible...
You can read more about Lifecycle callbacks here:
http://symfony.com/doc/master/cookbook/doctrine/file_uploads.html#using-lifecycle-callbacks

Resources