Generate subform in ajax call - forms

I have a form with collection of subforms - student with different studies - relation manyToOne. I have corrent database schema and entities and form builder works well. I don't know how to append new "study" object. I need to get html tags from somewhere in either cases - when there is at least one "study: object (clone him) or there is no such a one.
Let's assume that study object has 2 fields: name and year. If for a student there is such a record (object) it's first input in generated form has name "student[study][0][name]". And is surrounded by . When I click "Add new study" button I want to duplicate this surrounding div and change id's and name's of html form elements respectively. Is there ready library or method to use?
But there may happen there is no study records so far. So I need to get form from server through ajax call. Unfortunately returned form has inputs with names like "study[name]". Is it possible to render this form similar to first case - I mean "student[study][0][name]". But i'd like to avoid manually generate twig template for form - I prefer
{{ form_widget(form) }}

You should be dealing with data-prototype rather than issuing separate AJAX request. The whole concept of adding/removing subform items is described here:
http://symfony.com/doc/current/reference/forms/types/collection.html#adding-and-removing-items
Obviously, you will need to some JS (jQuery is highly recommended) in order to replicate subform fields.
You should note, however, that data-prototype behaves differently when you initially have empty or non-empty collection. At least I have encountered this weird behavior. As far as I remember, in first your when you say {{ form_rest(form) }} additional DIV is appended with data-prototype attribute consisting of form's HTML. In second case actual HTML (not as an attribute) is appended with ID attribute "form_name_$$name$$" where you need to replace $$name$$ with proper index.
Now, you really should take a look - maybe all this has been fixed in some recent versions but I can't be sure...
Hope this helps a bit...

Related

Data in array collection shows empty when retrieving info

I'm creating a web app with symfony. I'm currently building the forms and as I've never used the ManyToMany relation I'm having some problem with retrieving the information.
The form I'm working with is this one:
The point is that when I'm retrieving the information of the array in the twig template, the data property inside the array shows empty, when there is Alumne's entities created. Let me show you.
Twig template (create page):
As you can see, what I pretend is to retrieve the info of every Alumne entity inside the array.
What I get doing this is:
The alumnes field is completly empty. But if I change the form Builder to this:
(I have also changed a little bit the twig template to make it more readable)
It works!
And as you can see there is an Alumne created.
The point is, as you can see, the select and option tag it creates is kinda ugly, I want to custom so it can fit the rest of the forms. So that's why I need a CollectionType in the builder and I don't know what I'm doing wrong. Also if I check the dump(form.alumnes.vars.data) it shows empty.
The issue here is, that you use the CollectionType instead of the EntityType. To load data from the Database into a form, you should use the EntityType https://symfony.com/doc/current/reference/forms/types/entity.html
If you leave the type out, Symfony will try to guess what form element to use and will (correctly) guess the EntityType

redux-form Wizard form with linked fields

I am building a multi-step application form with React. Having first built it with pure internal state I am now in the process of refactoring to Redux using redux-form.
Having used the example here as a basis: http://redux-form.com/5.2.5/#/examples/wizard?_k=oftw7a we have come a good way.
However the problem appears when i have two forms which are supposed to have the same value. During one of the pages i have a name field, that is supposed to be duplicated on the name field of the next page. The opposite should happen if you go back from the last page. Any tips to how this could be achieved?
Using the wizard, you are basically working with the exact same form that's split into multiple pieces. Ultimately it's the same form, because redux-form tracks them by name. It is how the library identifies the pieces of the same form - using the name.
form: 'wizard',
Here you can see that the exact same instance of the form will be shared throughout the pieces. fields work in a similar manner. Each field is defined as part of a form.
As long as you use the same field constants inside the fields object that you pass into the reduxForm function and as long as the value for form is the same, so that they use the same underlying form object, it should work for you just fine.
On one page you should pass in
export default reduxForm({
form: 'wizard',
fields : {
'fieldIWantOnBothPartsOfTheForm',
'someOtherFieldThatShouldOnlyBeHere',
},
...
And then on the other page:
export default reduxForm({
form: 'wizard',
fields : {
'fieldIWantOnBothPartsOfTheForm',
'thirdFieldHere',
},
...
Also, make sure you keep destroyOnUnmount equal to false if you want to navigate back-and-forth.
Hope that helps.

Laravel 4 - get data from multiselect form

I'm using Laravel 4, and I have two tables related 'Many to many': 'Actividad' and 'Material'. Every Actividad can have one or more Materials, and every Material can belong to one or more Actividad.
So, I have made a form to create a new Actividad where you can save one or more Materials. I've done that with a multiselect input. Like that:
{{ Form::label('material_id', 'Material necesario:') }}
<p>{{ Form::select('material_id', $material_id, Input::old('material_id'), array('multiple')) }}</p>
I don't know if I'm doing correctly but, before saving anything, my first problem is that I'm only obtaining one result. I suppose I should get every option 'checked' in the form... The relevant part of my Controller is:
$material = Input::get('material_id');
return var_dump($material);
I should obtain a list of options selected, but the result of that in my browser is:
string(1) "1"
This is the first time I'm working with tables related in this way, and probably I'm doing something wrong (in the form, in my controller, in my Models,...)
Thank you very much for your help!!
Just change your code to this
{{ Form::select('material_id[]', $material_id, Input::old('material_id'), array('multiple')) }}
I hope this helps.
if you are using custom response handlers on the client side such in the case of submitting info with AJAX, all you need to do is to simple add "[]" to the name of the select control.
e.g.
<select name="material_id[]" multiple>
This is the same case as with regular PHP. The other methods are required if you want Laravel to handle the form elements for you when rendering a new response/view. ( page reload ). This reload doesn't happen with REST requests.

How can I get the Zend_Form object via the Zend_Form_Element child

I've built a Zend_Form_Decorator_Input class which extends Zend_Form_Decorator_Abstract, so that I could customize my form inputs -- works great. I ran into a problem in the decorate class, in trying to get the form name of the element, so as to built a unique id for each field (in case there are multiple forms with identical field names).
There is no method like this: Zend_Form_Element::getForm(); It seems Zend_Form_Decorator_Abstract doesn't have this ability either. Any ideas?
I don't think changing the id from the decorator is the right approach. At the time the decorator is called the element already has been rendered. Thus changing the id would have no effect to the source code. Additionally, as you already have pointed out, the relation between a form and its elements is unidirectional, i.e. (to my best knowledge) there is no direct way to access the form from the element.
So far the bad news.
The good news is, that there actually is a pretty easy solution to your problem: The Zend_Form option elementsBelongTo. It prevents that the same ID is assigned to two form elements that have the same name but belong to different forms:
$form1 = new Zend_Form(array('elementsBelongTo' => 'form1'));
$form1->addElement('Text', 'text1');
$form2 = new Zend_Form(array('elementsBelongTo' => 'form2'));
$form2->addElement('Text', 'text1');
Although both forms have a text field named 'text1', they have different ids: 'form1-text1' and 'form2-text1'. However, there is a major drawback to this: This also changes the name elements in such a way that they are in the format formname[elementname]. Therefore $this->getRequest()->getParam('formname') will return an associative array containing the form elements.

Zend Form dynamic row number with javascript

I have a form here in which there is a textfield which contains a number. In another part of the form there are rows, which coresponds with the number entered. For example 2 = 2 rows etc.
So my idea is to create one row which is duplicated by a javascript. So i must create a input element which name is in a array like name="input[]" how can i do this in Zend Framework?
The only approach i found for this kind of problem is to use subforms. But every Subform has a explicite name which is not in a array.
To make a rendered Zend_Form respond to client-side changes - as in your example, to allow the user to enter the number of rows he wants - you need both client-side and server-handling.
The best example demonstrating the general idea is from Jeremy Kendall:
jeremykendall.net » Blog Archive » Dynamically Adding Elements to Zend_Form
The upshot is that you have client-side code that adds tracks the number of fields and then a preValidation() method that injects the right number of fields into the $form instance before isValid() gets called.
[As noted in the comments there, this preValidation() processing could just be bundled into isValid() so that the controller remains unchanged.]