Installation
composer require drjele/symfony-json-form
Ensure your project uses Symfony 5.4+ or Laravel with Symfony components (e.g., via symfony/http-foundation).
Basic Form Creation
Define a form class extending JsonFormType:
use DrJele\JsonForm\JsonFormType;
class UserForm extends JsonFormType
{
public function buildForm(BuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class)
->add('email', EmailType::class);
}
}
First Use Case: API Response Use the form in a controller to return JSON-serialized form data:
use DrJele\JsonForm\JsonFormFactory;
public function getForm(JsonFormFactory $factory)
{
$form = $factory->create(UserForm::class);
return response()->json($form->toJson());
}
Frontend Integration Consume the JSON output in a frontend framework (e.g., React/Vue) to render dynamic forms.
Client-Side Send JSON payload from frontend:
{
"data": {
"name": "John Doe",
"email": "john@example.com"
}
}
Server-Side Handling
public function submitForm(Request $request, JsonFormFactory $factory)
{
$form = $factory->create(UserForm::class);
$form->submit(json_decode($request->json()->getContent(), true));
if ($form->isValid()) {
$data = $form->getData();
// Save to DB or process
}
return response()->json($form->toJson());
}
Service Provider
Bind the factory in AppServiceProvider:
public function register()
{
$this->app->bind(JsonFormFactory::class, function ($app) {
return new JsonFormFactory();
});
}
Validation Leverage Symfony’s validation constraints:
$builder->add('email', EmailType::class, [
'constraints' => [new NotBlank(), new Email()]
]);
Use JsonFormType to build dynamic forms based on runtime data:
$builder->add('dynamic_field', TextType::class, [
'required' => $someCondition,
'label' => 'Dynamic Label'
]);
JSON Schema Mismatch
$form->toJson() to debug schema.Validation Errors
{
"errors": {
"email": ["This value should not be blank."]
}
}
CSRF Protection
VerifyCsrfToken middleware may interfere):
Route::middleware('api')->group(function () {
// JSON form routes
});
dd($form->getData()) or dd($form->toJson()) to inspect form state.$builder->add('field', TextType::class, [
'validation_groups' => ['group1', 'group2']
]);
Custom JSON Serialization
Override toJson() in a custom form class:
public function toJson()
{
$data = parent::toJson();
$data['custom_field'] = $this->getCustomValue();
return $data;
}
Frontend-Specific Logic Add frontend-specific metadata:
$builder->add('field', TextType::class, [
'attr' => ['frontend_type' => 'autocomplete']
]);
Event Listeners
Use Symfony events (e.g., PRE_SUBMIT) to modify form data:
$dispatcher->addFormTypeSubscriber(new class implements FormEventSubscriberInterface {
public function getSubscribedEvents()
{
return [FormEvents::PRE_SUBMIT];
}
public function onFormPreSubmit(FormEvent $event)
{
$data = $event->getData();
$data['processed'] = true;
$event->setData($data);
}
});
public function __construct()
{
$this->addModelTransformer(new JsonModelTransformer());
}
$builder->add('name', TextType::class, [
'translation_domain' => 'forms'
]);
How can I help you explore Laravel packages today?