I noticed the SelectField for material-ui is composed of divs and spans and as a result when serializing the form, which includes a SelectField, the SelectField isn't serialized. Is there a way to serialize the SelectField?
Related
I need some help designing a React app singe page app.
I want to show and let the user edit (via form inputs) a complex JSON structure (with known shape), but I'm having trouble picturing how to bind the values in my generated form to the data structure. The JSON structure is static, I just want to let the user edit values, not the structure itself.
Some of the values depend on other values in the structure (e.g. the max value of a field is specified in other field). The data has nested structures but they do not map 1:1 to my components (I don't control the input) which makes handling more complex (deep components can change surface values).
For example purposes:
data.json
{
"age": 12,
"maxAge": 100,
"name": {
"first": "John",
"last": "Doe"
},
"dogName": "Foo"
}
main.jsx
ReactDOM.render(<Editor data={data} />, mount);
Editor.jsx
<form>
<Person data={props.data} />
<Text defaultValue={props.data.dogName} />
<h2>Settings:</h2>
<Number defaultValue={props.data.maxAge} />
</form>
Person.jsx
<fieldset>
<Text defaultValue={props.data.name.first} />
<Text defaultValue={props.data.name.last} />
<Number max={props.data.maxAge} defaultValue={props.data.age} />
</fieldset>
Handling each and every field manually with change events seems too complex, tiresome (I have tens of fields per component), and error-prone... and I'm not even sure how to propagate the changes to the top-level component from the inner ones.
What are the alternatives?
For an official guide: Thinking in React
I believe the above guide can help walk you through some of the challenges that you are facing.
For your first point: I would use state to hold the information. You can do "two way" data binding to have the form represent your data and the data represent your form. You can also use some form of onChange function calls to update the data that relies on other inputs.
Section 5 of the linked guide goes over propagating data up the chain (ie person -> editor) using callbacks.
If this is going to potentially evolve into a larger project, I would suggest looking into Flux for a MVC type front end with React as the View.
Is it considered correct to have a composite component (compA) that holds a form, when compA can itself be contained in another form (in the using page)?
<!-- composite -->
<cc:implementation>
<h:form id="innerForm">
... composite stuff
</h:form>
</cc:implementation>
<!-- using page/component -->
<h:form id="outerForm">
<util:compA ... />
</h:form>
When trying to remove nested forms, any ajax call in the composite will submit the whole form, and as has some values may not yet be filled, validation fails.
Is there any best-practice approach to this?
Nested forms are always a bad idea and will result in invalid HTML output.
A Composite Component itself is a Naming Container so it should not be a problem to process only the CC or even some parts of it.
To prevent the whole form from being even submitted I would suggest PrimeFaces AJAX calls with partialSubmit="true". See here for reference.
If there are still problems with your AJAX calls you habe to provide the related code of your CC.
I am printing an arbitrary number of identical forms on a page using Spring's <form:form tag, and I need a way to distinguish between them, because form errors of one form are now printed on all forms.
Currently all the identical forms are bound to the same, single backing object. That works fine, because a user can only submit one form at a time.
I am using Spring validation to validate form fields. When one of the fields has an error (let's say 'name' is empty) than the error message is printed under the 'name' field of all forms.
Obviously, I need some way to allow Spring to distinguish between the forms, but how?
Some example code:
This Spring webflow definition creates a ClientFormBacking object to back the client forms. And it submits a form POST to the bindAndValidate method, which calls the validator.
<webflow:var name="clientFormBacking" class="com.example.ClientFormBacking"/>
<webflow:view-state id="list" view="clients" model="clientFormBacking">
<webflow:on-entry>
<webflow:evaluate expression="contextParameterManager.findAll()" result="flowScope.clients"/>
</webflow:on-entry>
<webflow:transition on="update-client" to="list">
<webflow:evaluate expression="clientBinder.bindAndValidate(flowRequestContext)"/>
<webflow:evaluate expression="clientService.saveOrUpdate(flowScope.clientsPageBacking)"/>
</webflow:transition>
</webflow:view-state>
Print an arbitrary number of identical forms with a name field and name error field in JSP:
<c:forEach items="${clients} var="client">
<form:form commandName="clientFormbacking">
<form:input path='name' value='${client.name}'/>
<form:errors path="name" cssClass="input-error" />
</form:form>
</c:forEach>
The validator that rejects the 'name' field:
ClientValidator implements Validator {
public void validate(Object target, Errors errors) {
// Problem here! There are multiple <form:errors path='name'/> tags....
errors.rejectValue("name", "validation.error.name.empty");
}
}
My ServiceStack API is returning the following XML:
<UserResult>
<Email>dan-dare#the-eagle.com</Email>
<Forenames>Daniel</Forenames>
<Href>/users/00000001-0000-0000-0000-00000000000d</Href>
<Memberships>
<Href>/users/00000001-0000-0000-0000-00000000000d/memberships</Href>
</Memberships>
<Surname>Dare</Surname>
<UserGuid>00000001-0000-0000-0000-00000000000d</UserGuid>
<Username>test_dan</Username>
</UserResult>
I'm curious as to whether I can modify the XML serialization so it returns the HREF properties as attributes rather than elements:
<UserResult href="/users/00000001-0000-0000-0000-00000000000d">
...
<Memberships href="/users/00000001-0000-0000-0000-00000000000d/memberships" />
...
</UserResult>
or even override the default serialization entirely so that particular properties are exposed as <link /> elements:
<UserResult href="/users/00000001-0000-0000-0000-00000000000d">
...
<link rel="memberships" href="/users/00000001-0000-0000-0000-00000000000d/memberships" />
...
</UserResult>
I'm undecided as to whether I should do this, but very curious to know whether it's possible - either by decorating the properties or by replacing the default XML serializer (DataContractSerializer?) used by ServiceStack.
A have problem with accessing my custom components (which are used as parts of the form).
Here is the story:
I have dynamic form which have few modes of work. Each mode can be selected and loaded into form body with AJAX. It looks like that (template):
<t:form t:id = "form">
<p class= "calcModeTitle">
${message:modeLabel}: <select t:id="modeSelect"
t:type="select"
t:model="modesModel"
t:value="selectedMode"
t:blankOption="NEVER"
t:encoder="modeEncoder"
t:zone = "modeZone"
/>
</p>
<div class="horizontal_tab">
<t:errors/>
</div>
<t:zone t:id="modeZone" id="modeZone" t:update="show">
<t:if test="showCompany">
<t:delegate to="block:companyBlock" />
</t:if>
<t:if test="showPersonal">
<t:delegate to="block:personalBlock" />
</t:if>
<t:if test="showMulti">
<t:delegate to="block:multiBlock" />
</t:if>
</t:zone>
<t:block id="companyBlock">
<t:modes.CompanyMode t:id="company"/>
</t:block>
<t:block id="personalBlock">
<t:modes.PersonalMode t:id="personal" />
</t:block>
<t:block id="multiBlock">
<t:modes.MultiMode t:id="multi" />
</t:block>
<div class="horizontal_tab">
<input type="submit" value="${message:submit_label}" class="submitButton thickBtn"/>
</div>
</t:form>
AJAX works pretty well and form changes accordingly the "modeSelect" state. But i run into problem when submitting the form. I have in class definition hooks for components placed as:
//----form elements
#Component(id = "form")
private Form form;
#InjectComponent
private CompanyMode company;
#InjectComponent
private PersonalMode personal;
#InjectComponent
private MultiMode multi;
where *Mode classes are my own components, containing form elements and input components. I planned to get access to them during validation, and check values supplied by user with form, but when I am trying to reach anything from them I've got nullPointerException - it seems that component are not initialized in my class definition of form. On the other hand form component is injected properly (I am able to write some error for example). I am a bit lost now. How to properly inject my components to class page containing the form?
Dynamic forms in tapestry are a bit complicated. Tapestry passes a t:formdata request parameter which contains the serialized form entities. This is then used serverside in the POST to re-hydrate initial form state. This must be kept up-to-date with what the client sees.
If you want to add dynamic content to a form via ajax, you will need to use the FormInjector. You might want to take a look at the source code for the AjaxFormLoop to see an example.
If you want to render hidden form fragments and make them visible based on clientside logic, you can use the FormFragment
From tapestry guide:
A block does not normally render; any component or contents you put
inside a block will not ordinarily be rendered. However, by injecting
the block you have precise control over when and if the content
renders.
Try to use here either "t:if" or "t:delegate".
Something like this:
<t:zone t:id="modeZone" id="modeZone" t:update="show">
<t:delegate to="myBlock" />
</t:zone>
<t:block t:id="companyBlock">
<t:modes.CompanyMode t:id="company"/>
</t:block>
<t:block t:id="personalBlock">
<t:modes.PersonalMode t:id="personal" />
</t:block>
<t:block t:id="multiBlock">
<t:modes.MultiMode t:id="multi" />
</t:block>
java:
#Inject
private Block companyBlock, personalBlock, multiBlock;
public Block getMyBlock(){
if (getShowCompany()) return companyBlock;
if (getShowPersonal()) return personalBlock;
return multiBlock;
}