Tcomb-form-native: Group fields together without changing the model structure?

Created on 16 Nov 2016  路  7Comments  路  Source: gcanti/tcomb-form-native

I know that you can use a template and basically display the fields however you like (as described here: https://github.com/gcanti/tcomb-form-native/issues/106) (I am doing that currently)

However I was wondering - I need some fields to be grouped together like you would do in html with a fieldset?

This is my model:

var model = t.struct({
    id: t.maybe(t.String),
    name: t.String,
    email: Email,
    street: t.maybe(t.String),
    zip: t.maybe(t.String),
    city: t.maybe(t.String),
    country: t.maybe(t.String),
    tel: t.maybe(t.String),

    manager: t.struct({
        name: t.maybe(t.String),
        lastname: t.maybe(t.String),
        tel: t.maybe(t.String),
        email: t.maybe(Email)
    }),
    notes: t.maybe(t.String),
    position: t.struct({
        latitude: t.Number,
        longitude: t.Number
    }),
});

name and email should be displayed together, steet, zip, city, country, tel as well.

Basic info:

  • name
  • email
    Address info:
  • street
  • ...
  • ...

Am I able to achieve this somehow just with the options?
For the manager fields for example I can have a label for all the fields since it is a new struct. The issue with doing the same for name and email is that I would have to change the object structure. And then the value that comes from tform will be different...

Most helpful comment

function template(locals) {
    // in locals.inputs you find all the rendered fields
    return (
        <View>
            {locals.inputs.company_id}
            {locals.inputs.name}
            {locals.inputs.email}
            {locals.inputs.street}
            {locals.inputs.zip}
            {locals.inputs.city}
            {locals.inputs.country}
            {locals.inputs.tel}

            {locals.inputs.position}

            <View style={{marginTop: 10}}>
                <Text style={[{marginLeft: 20}, constants.styles.strong]}>Betriebsleiter</Text>
                {locals.inputs.manager}
            </View>

            <View style={{marginTop: 10}}>
                {locals.inputs.notes}
            </View>


        </View>
    );
}

and then just pass it to the options

All 7 comments

I also have this same question. @compojoom Did you ever come up with anything? I basically just want a header between groups.

@jesouhaite08 - I went for a template and grouped the fields as I want there.

@jesouhaite08 - important - if your form has hidden fields, make sure to output them as well in the template, otherwise you can run in validation issues. (because they'll lose their values)

@compojoom Cool, thanks, I'll give it a shot. Mind sharing a snippet from your template? I'm just starting with this library, haven't messed with templates yet.

function template(locals) {
    // in locals.inputs you find all the rendered fields
    return (
        <View>
            {locals.inputs.company_id}
            {locals.inputs.name}
            {locals.inputs.email}
            {locals.inputs.street}
            {locals.inputs.zip}
            {locals.inputs.city}
            {locals.inputs.country}
            {locals.inputs.tel}

            {locals.inputs.position}

            <View style={{marginTop: 10}}>
                <Text style={[{marginLeft: 20}, constants.styles.strong]}>Betriebsleiter</Text>
                {locals.inputs.manager}
            </View>

            <View style={{marginTop: 10}}>
                {locals.inputs.notes}
            </View>


        </View>
    );
}

and then just pass it to the options

You're awesome, thank you!

There might be a way to get the result you want this without a template. Here is a simple example of two side by side fields and a full width field without using templates.

const Person = t.struct({
    name: t.struct({
        firstName: t.String,
        lastName: t.String
    }),
    phone: t.Number
});

const parentStyle = _.cloneDeep(t.form.Form.stylesheet);
const childStyle = _.cloneDeep(t.form.Form.stylesheet);

parentStyle.fieldset.flex = 1;
parentStyle.fieldset.flexDirection = 'row';

childStyle.formGroup.normal.flex = 1;

const options = {
    fields: {
        name: {
            stylesheet: parentStyle,
            label: ' ',
            fields: {
                firstName: {
                    stylesheet: childStyle
                },
                lastName: {
                    stylesheet: childStyle
                }
            }
        }
    }
};
Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexicum picture alexicum  路  6Comments

chauthai picture chauthai  路  4Comments

abdelghafourzguindou picture abdelghafourzguindou  路  4Comments

ishigamii picture ishigamii  路  3Comments

casoetan picture casoetan  路  5Comments