With Symfony 2.7, you could customize a form's name in your EntityType class with the method getName()
This is now deprecated. Is there another way to do that with Symfony 3.0 ?
I have custom prototype entry_rows for collections that I would need to use in different forms.
Since the name of the rows is based on the form's name, I would need to change the later in order to use them with a different form.
You should implements the getBlockPrefix method instead of getName as described in the migration guide here.
As example:
/**
* Returns the prefix of the template block name for this type.
*
* The block prefix defaults to the underscored short class name with
* the "Type" suffix removed (e.g. "UserProfileType" => "user_profile").
*
* #return string The prefix of the template block name
*/
public function getBlockPrefix()
{
return "form_name";
}
Hope this help
Depending on how your form is built, there is different ways to set the name of your form.
If you are creating the form through $this->createForm(CustomType::class):
$formFactory = $this->get('form.factory');
$form = $formFactory->createNamed('custom_form_name', CustomType::class);
If you are building the form from the controller directly through $this->createFormBuilder():
$formFactory = $this->get('form.factory');
$form = $formFactory->createNamedBuilder('custom_form_name', CustomType::class);
Look at the FormFactory and FormBuilder APIs for more information.
You can try it, remove prefix on field name
public function getBlockPrefix()
{
return null;
}
Related
I currently have a custom form field with a bunch of optional parameters in the constructor. I want to change this and have the field use setter functions but I can't find any way to include my templated JavaScript except during construction
class CustomField extends FormField {
protected $myField;
public function __construct($name, $title = null, $myField = null)
{
parent::__construct($name, $title);
$this->setMyField($myField);
Requirements::javascriptTemplate('path/to/script.js', ['Field' => $this->myField]);
}
/**
* I can update the value of myField but the value is already baked into the JavaScript and wont be updated
*/
public function setMyField($value) {
$this->myField = $value;
return $this;
}
I found a solution but it does feel a little hacky. I added a RequireJs() function to the form field as such:
<?php
function RequireJs() {
Requirements::javascriptTemplate('path/to/script.js', ['Field' => $this->myField]);
}
The added $RequireJs to the top of my template file so it would be called when the template is being rendered.
I'm trying to use a virtual domain model property in TYPO3 9.5.x that doesn't have a database field representation but I can't get it to work.
My model looks like this
class Project extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
/**
* participants
*
* #var string
*/
protected $participants;
...
/**
* Returns the participants
*
* #return string $participants
*/
public function getParticipants()
{
$this->participants = "foo";
return $this->participants;
}
}
I do see the property when I debug the model but it's always null as if it doesn't even recognise the getter method getParticipants().
Any idea what I might be doing wrong?
Already added a database field to ext_tables.sql and the TCA, but it didn't seem to make a difference.
The property is null because that's the state when the Extbase debugger inspects it. Notice that the Extbase debugger knows nothing about getters and also does not call them.
So if you want to initialize your property you must do this at the declaration time:
protected $participants = 'foo';
You can debug this property by simpy accessing it.
In Fluid, if you use <f:debug>{myModel}</f:debug>, you will see NULL for your property.
But if you directly use <f:debug>{myModel.participants}</f:debug>, you will see 'foo'.
When using Extbase's "show" action:
<f:link.action action="show" arguments="{event : event}">
I would like to look up said event by a special column ('customID').
The actual TYPO3-uid should NOT appear in the URL (with or without RealURL).
The reason is that the data has been imported, and the "real" uid is 'customId'.
There's always #biesior's approach using f:link.page https://stackoverflow.com/a/26145125/160968 – but I thought I'd try it with the official way.
(how) is it possible to do that in extbase/fluid?
This is possible. Let's assume your model Event has a property customId. So you generate your link like this:
<f:link.action action="show" arguments="{event : event.customId}">
The link generated will have a queryString like this:
?tx_myext[event]=9999
The showAction generated by the Extension Builder expects that the UID of the event is passed. The PropertyMapper then fetches the object automatically and assigns it to the view:
/**
* action show
*
* #param \Your\Extension\Domain\Model\Event $event
* #return void
*/
public function showAction(\Your\Extension\Domain\Model\Event $event) {
$this->view->assign('event', $event);
}
But in your case you cannot fetch the object by UID because you passed the customId. So you need to fetch the object yourself:
/**
* action show
*
* #param integer $event
* #return void
*/
public function showAction($event) {
$event = $this->eventRepository->findOneByCustomId($event);
$this->view->assign('event', $event);
}
The annotation #param integer $event tells TYPO3 that the parameter is "just" an integer. You then call the magic method findOneByCustomId from your eventRepository. findOne indicates that you want exactly one Event object back (and not a QueryResult), while the ByCustomId that queries an existing property of your Event model.
Why not use realUrl with lookUpTable? See here: https://wiki.typo3.org/Realurl/manual#-.3ElookUpTable
In Spring 3, I have seen two different attribute in form tag in jsp
<form:form method="post" modelAttribute="login">
in this the attribute modelAttribute is the name of the form object whose properties are used to populate the form. And I used it in posting a form and in controller I have used #ModelAttribute to capture value, calling validator, applying business logic. Everything is fine here. Now
<form:form method="post" commandName="login">
What is expected by this attribute, is it also a form object whose properties we are going to populate?
If you look at the source code of FormTag (4.3.x) which backs your <form> element, you'll notice this
/**
* Set the name of the form attribute in the model.
* <p>May be a runtime expression.
*/
public void setModelAttribute(String modelAttribute) {
this.modelAttribute = modelAttribute;
}
/**
* Get the name of the form attribute in the model.
*/
protected String getModelAttribute() {
return this.modelAttribute;
}
/**
* Set the name of the form attribute in the model.
* <p>May be a runtime expression.
* #see #setModelAttribute
*/
public void setCommandName(String commandName) {
this.modelAttribute = commandName;
}
/**
* Get the name of the form attribute in the model.
* #see #getModelAttribute
*/
protected String getCommandName() {
return this.modelAttribute;
}
They are both referring to the same field, thus having same effect.
But, as the field name indicates, modelAttribute should be preferred, as others have also pointed out.
OLD WAY = commandName
...
<spring:url value="/manage/add.do" var="action" />
<form:form action="${action}" commandName="employee">
<div>
<table>
....
NEW WAY = modelAttribute
..
<spring:url value="/manage/add.do" var="action" />
<form:form action="${action}" modelAttribute="employee">
<div>
<table>
..
I had the same question a while ago, I can't remember the exact differences but from research I ascertained that commandName was the old way of doing it and in new applications you should be using modelAttribute
commandName = name of a variable in the request scope or session scope that contains the information about this form,or this is model for this view. Tt should be a been.
In xml based config, we will use command class to pass an object between controller and views. Now in annotation we are using modelattribute.
I need to validate some fields based on values other fields have, within the same model. Since a custom validator only has access to the value it is validating, I can't check other validations there. From inspecting AbstractValidator, I couldn't find a possibility to reach that object the current value is validated.
Is there a solution to validate/add errors in a controller, set errors and render the actual view by keeping the original routine instead of introducing and assigning new objects to the view? Basically I could create a custom $errors var, fill it with errors after having done custom validations and the display it along with the original form errors. But I don't like that workaround approach.
When you add a new model validator, you have access to the other fields of that model
File: test_extension/Classes/Domain/Validator/TestModelValidator.php:
class Tx_TestExtension_Domain_Validator_TestModelValidator extends Tx_Extbase_Validation_Validator_AbstractValidator {
/**
* #param Tx_TestExtension_Domain_Model_TestModel $testModel
* #return boolean
*/
public function isValid($testModel) {
/** #var $testModel Tx_TestExtension_Domain_Model_TestModel */
//Access all properties from $testModel
$field1 = $testModel->getMyField1();
$field2 = $testModel->getMyField2();
}
}
You can also add errors to speific fields, but this code is from TYPO3 4.5, don't know if its still valid:
$error = t3lib_div::makeInstance('Tx_Extbase_Validation_Error', 'The entered value is allready in use.', 1329936079);
$this->errors['field2'] = t3lib_div::makeInstance('Tx_Extbase_Validation_PropertyError', 'field2');
$this->errors['field2']->addErrors(array($error));