TwinColSelect in GridLayout does not render completely

I’m having trouble getting the add button for the TwinColSelect to be displayed correctly in GridLayout. I’ve tried various sizing and positioning, but nothing seems to work. I was able to see that the button is rendered via Firebug, but it is not visible to the naked eye. Has anyone run into this? Or does anyone have an idea for how to get the button to render correctly?

Thanks.

Did a quick test and it seemed to work correctly at least with the latest Vaadin version. Could you attach some test code where the issue is happening? Which Vaadin version you use and does the issue happen only a specific browser?

I should have mentioned that the GridLayout is the chosen layout for a vaadin Form object. I think the Form maybe manipulating the TwinColselect ‘field’ when inserting it into the layout. I’m using version 6.8.14 and the issue happens in IE and Firefox. As you can see in the following code, I’m just treating the TwinColSelect as a Field.

/**Factory for building fields for the GeneralInfo.*/
@SuppressWarnings("serial")
public class GeneralInfoFieldFactory extends DefaultFieldFactory
{
    final private ComboBox eventList = new ComboBox("Event Name");
    final private TwinColSelect emailList = new TwinColSelect("Client Requestor Email");
    final private TextArea reason = new TextArea("Reason for Event");

    /**Constructor
     * Define how fields are displayed*/
    public GeneralInfoFieldFactory()
    {
        eventList.setWidth(ComponentLayoutEnum.WIDE_FIELD_WIDTH.getValue());
        eventList.setRequired(true);
        eventList.setRequiredError("Please select an event to run");
        for(RequestTaskTypeEnum event : RequestTaskTypeEnum.values())
        {
            eventList.addItem(event.getDisplayName());
        }
        eventList.addListener(new Property.ValueChangeListener()
        {
            @Override
            public void valueChange(ValueChangeEvent event)
            {
                //We need to get the CreateRequestPanel so that we can update the form displayed
                if(eventList.getValue() != null)
                {
                    Component panel = eventList.getParent();
                    while(panel != null && !(panel instanceof CreateRequestPanel))
                    {
                        panel = panel.getParent();
                    }
                    if(panel != null)
                    {
                        ((CreateRequestPanel)panel).updateRequestComponent(
                                RequestTaskTypeEnum.toEnumFromDisplayName((String)eventList.getValue()));
                    }
                }
            }
        });
        eventList.setImmediate(true);
       
        emailList.setWidth(ComponentLayoutEnum.EXTRA_WIDE_FIELD_WIDTH.getValue());
        emailList.setRows(4);
        emailList.setLeftColumnCaption("(Available addresses)");
        emailList.setRightColumnCaption("(Selected addresses)");
        emailList.setNullSelectionAllowed(true);
        emailList.setNewItemsAllowed(true);
       
        reason.setRequired(true);
        reason.setRequiredError("Please enter a reason for this macro");
        reason.setWidth(ComponentLayoutEnum.WIDE_FIELD_WIDTH.getValue());
        reason.setHeight(ComponentLayoutEnum.COMMON_TEXTAREA_HEIGHT.getValue());
    }

   
    @Override
    public Field createField(Item item, Object propertyId, Component uiContext)
    {
        Field field;
        if (GeneralInfo.fieldNames.eventName.toString().equals(propertyId))
        {
            return eventList;
        } else if(GeneralInfo.fieldNames.email.toString().equals(propertyId))
        {
            return emailList;
        } else if (GeneralInfo.fieldNames.reasonForEvent.toString().equals(propertyId))
        {
            return reason;
        } else
        {// Use the super class to create a suitable field base on the property type.
            field = super.createField(item, propertyId, uiContext);
        }

        // define each field's properties
        if (GeneralInfo.fieldNames.comment.toString().equals(propertyId))
        {
            TextField tf = (TextField) field;
            tf.setWidth(ComponentLayoutEnum.FULL.getValue());
            tf.setNullRepresentation("");
        } else if (GeneralInfo.fieldNames.clientRequestNumber.toString().equals(propertyId))
        {
            TextField tf = (TextField) field;
            tf.setWidth(ComponentLayoutEnum.SHORT_FIELD_WIDTH.getValue());
        } else if (GeneralInfo.fieldNames.numberOfThreads.toString().equals(propertyId))
        {
            TextField tf = (TextField) field;
            tf.addValidator(new IntegerValidator("Number of threads must be an integer."));
            tf.setWidth(ComponentLayoutEnum.TINY_FIELD_WIDTH.getValue());
        } else if (GeneralInfo.fieldNames.confirmationDate.toString().equals(propertyId))
        {
            DateField df = (DateField) field;
            df.setDateFormat("yyyy-MM-dd HH:mm");
            df.setResolution(DateField.RESOLUTION_MIN);
            df.setRequired(true);
            df.setRequiredError("Please select the confirmation date");
            df.setWidth(ComponentLayoutEnum.COMMON_FIELD_WIDTH.getValue());
        }

        return field;
    }
    private GridLayout ourLayout;

    @Override
    public void instantiate(BeanItem<GeneralInfo> item)
    {
        setCaption("General Information");

        ourLayout = new GridLayout(10, 5);

        ourLayout.setSpacing(true);
        ourLayout.setMargin(true);

        setLayout(ourLayout);

        // no invalid values in datamodel
        setInvalidCommitted(false);

        // FieldFactory for customizing the fields and adding validators
        setFormFieldFactory(new GeneralInfoFieldFactory());
        setItemDataSource(item);

        //set all the fields to be visible
        ArrayList<String> fields = new ArrayList<String>();
        for(GeneralInfo.fieldNames field : GeneralInfo.fieldNames.values())
        {
                fields.add(field.toString());
        }
        setVisibleItemProperties(fields);
    }

    /*
     * Override to get control over where fields are placed.
     */
    @Override
    protected void attachField(Object propertyId, Field field)
    {
        if (propertyId.equals(GeneralInfo.fieldNames.eventName.toString()))
        {
            ourLayout.addComponent(field, 0, 0, 1, 0);
        } else if (propertyId.equals(GeneralInfo.fieldNames.confirmationDate.toString()))
        {
            ourLayout.addComponent(field, 3, 0);
        } else if (propertyId.equals(GeneralInfo.fieldNames.clientRequestNumber.toString()))
        {
            ourLayout.addComponent(field, 0, 1);
        } else if (propertyId.equals(GeneralInfo.fieldNames.numberOfThreads.toString()))
        {
            ourLayout.addComponent(field, 0, 2);
        } else if (propertyId.equals(GeneralInfo.fieldNames.reasonForEvent.toString()))
        {
            ourLayout.addComponent(field, 1, 1, 3, 3);
        } else if (propertyId.equals(GeneralInfo.fieldNames.comment.toString()))
        {
            ourLayout.addComponent(field, 0, 4, 9, 4);
        } else if (propertyId.equals(GeneralInfo.fieldNames.email.toString()))
        {
            ourLayout.addComponent(field, 5, 1, 8, 3);//this is the TwinColSelect
        }
    }

Sorry for delay, I had a short vacation. Do you still have the issue? If yes, could you either attach here or push into github a full example application in which the issues is present? I can then try to find a solution.

No worries about the delay, thanks for your attention on this. I am still having the issue. I’ll generate a full example and post it.

An example maven project is available at:
https://github.com/quadrone/quadrones-sandbox

Thanks again.

Ok, thanks for the example. This is quite clearly a bug in the Vaadin. Please, report it in the http://dev.vaadin.com/

The problem seem to be that twincolselect does not reserve any space for the add-new button in the gridlayout.

I found a kind-of workaround for this but it is not very clean solution. Anyway, you can reduce the space taken of twincolselect list by css, which would bring the ‘+’ button visible.

.v-select-twincol-options {
    width:43% !important;
}

.v-select-twincol-selections {
    width:43% !important;
}

Awesome! I’ll give it a shot.

Thanks.

Johannes,

The workaround does the trick, thanks again.

I’ve generated ticket #14209 to track the issue.