quemb/QMBForm

Library maintenance

Closed this issue · 8 comments

Hi, I checked the sample app and it looks promising.
I'm planning to use this library but I saw that there are no commits recently. Is it still maintained?
Thanks

Hi dneykov. I use it in several apps, so yes I'll maintaining this lib. You are also welcome to contribute if you encounter any issues or missing features.

Thanks for quick reply.
I have one main question is it possible to generate dynamic form? I have a JSON representation of all fields coming form network request and I want to build a form.
Is it possible with this library?

Sure thats what it's made for.
The best practice would be to create a factory class to map your JSON representation to RowDescriptors.

Is there an example for that?
I will give it a try

I do it like this. I map my JSON to Java Objects with GSON and map them to different Attribute classes. There I check the type of my JSON Attribute to map it to an row descriptor. You can also do this without mapping your JSON to Java Objects.

Snippet:

public FormDescriptor generateFormDescriptor(Collection<Attribute> attributes, ValueObject valueObject) {

        FormDescriptor descriptor = FormDescriptor.newInstance();

        SectionDescriptor sectionDescriptor = SectionDescriptor.newInstance("any", "Title");
                descriptor.addSection(sectionDescriptor);

            for (Attribute attribute : attributes) {
               RowDescriptor tmpElement = createRow(attribute);
               sectionDescriptor.addRow(tmpElement);
            }

          

        return descriptor;

    }

protected RowDescriptor createRow(AbstractComponentTypeAttribute attribute) {

        // required options?
        AttributeOptions options = attribute.getOptions();
        Boolean required = false;
        if (options != null) {
            required = options.required;
        }

        // concrete elements
        RowDescriptor tmpElement = null;

        // text inputs

       if (attribute.getClass() == OptionAttribute.class) {

            final OptionAttribute optionAttribute = (OptionAttribute) attribute;
            if (optionAttribute.getValue() != null) {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeSelectorPickerDialog, attribute.getName(), new Value<String>(optionAttribute.getValue()));
            } else {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeSelectorPickerDialog, attribute.getName());
            }

            tmpElement.setDataSource(new DataSource() {

                @Override
                public void loadData(final DataSourceListener listener) {

                    listener.onDataSourceLoaded(optionAttribute.getOptionValues());

                }
            });
        } else if (attribute.getClass() == MultiselectAttribute.class) {

            final MultiselectAttribute multiselectAttribute = (MultiselectAttribute) attribute;
            if (multiselectAttribute.getValue() != null) {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeSelectorMultipleDialog, attribute.getName(), new Value<ArrayList>(multiselectAttribute.getValue()));
            } else {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeSelectorMultipleDialog, attribute.getName());
            }

            tmpElement.setDataSource(new DataSource() {

                @Override
                public void loadData(final DataSourceListener listener) {

                    listener.onDataSourceLoaded(multiselectAttribute.getOptionValues());

                }
            });

        } else if (attribute.getClass() == StringAttribute.class || attribute.getClass() == ExponentAttribute.class) {
            String value = ((StringAttribute) attribute).getValue();
            if (value == null) {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeText, attribute.getName());
            } else {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeText, attribute.getName(), new Value<String>(value));
            }

        } else if (attribute.getClass() == NumberAttribute.class || attribute.getClass() == FloatAttribute.class) {

            // value from attribute
            Number value = ((NumberAttribute) attribute).getValue();
            if (value == null) {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeNumber, attribute.getName());
            } else {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeNumber, attribute.getName(), new Value<Number>(value));
            }


        } else if (attribute.getClass() == BooleanAttribute.class) {

            tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeBooleanSwitch, attribute.getName(), new Value<Boolean>(((BooleanAttribute) attribute).getValue()));

        } else if (attribute.getClass() == DateAttribute.class) {

            Date date = ((DateAttribute) attribute).getValue();
            if (date == null) {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeDate, attribute.getName());
            } else {
                tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeDate, attribute.getName(), new Value<Date>(date));
            }

        } else {
            tmpElement = RowDescriptor.newInstance(attribute.getIndex(), RowDescriptor.FormRowDescriptorTypeName, attribute.getName());
        }

        if (tmpElement != null) {
            tmpElement.setRequired(required);
        }


        return tmpElement;
    }
´´´

Big thanks @tonimoeckel
This will save me lot of time.
(cheers)

Using following function:

public static FormDescriptor generateFormDescriptor(List<FormField> fields) {

        FormDescriptor descriptor = FormDescriptor.newInstance();

        SectionDescriptor sectionDescriptor = SectionDescriptor.newInstance("any", "Title");
        descriptor.addSection(sectionDescriptor);

        for (FormField field : fields) {
            Log.e("Form", field.getType());
            RowDescriptor tmpElement = createRow(field);
            sectionDescriptor.addRow(tmpElement);
        }

        return descriptor;

}

private static RowDescriptor createRow(FormField field) {

        // concrete elements
        RowDescriptor tmpElement = null;

        if (field.getType().equals("input")) {
            tmpElement = RowDescriptor.newInstance(field.getId(), RowDescriptor.FormRowDescriptorTypeText, field.getLabel());
        }

        return tmpElement;
}

I'm getting following error:

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.quemb.qmbform.descriptor.RowDescriptor.setSectionDescriptor(com.quemb.qmbform.descriptor.SectionDescriptor)' on a null object reference

Any idea what is wrong?
Thanks.

Never mind, I made really stupid mistake.