Custom Link in ElementCollectionField (Custom Editor Instantiator?)

Hi All,

Fairly new to Vaadin (+ Viritin) but I’m already loving the framework! I’ve never much enjoyed UI work so it’s really refreshing to find something that gives me the power to create good looking modern web UIs without all the fuss.

My current project uses Viritin ElementCollectionField to show a (non-editable) list, and in each row I need to have a Vaadin Link to an ExternalResource, with an image that also comes from an ExternalResource (another servlet in the same webapp). The List is “documents” that are attached to another entity (via a JPA ManyToMany).

My Row class for the ElementCollectionField looks like this:

[code]
public static class DocumentRow {
public MTextField id = new MTextField();
public MTextField name = new MTextField();
public MTextField description = new MTextField();

public Link iconLink;

MButton download = new MButton(FontAwesome.DOWNLOAD, e -> {
  Page.getCurrent().open(new ExternalResource(Document.getDownloadURL(id.getValue())), "_blank", false);      
});    

}
[/code]I wasn’t sure how I should set the properties on the iconLink object, which need to be set according to properties of the entity the row is displaying. My current approach has been to modify AbstractElementCollection, so that I can use an editor instantiator that receives the entity the row is being created for. With this modification, I create the ElementCollectionField like so:

[code]
private final ElementCollectionField attachedDocuments = new ElementCollectionField(
Document.class,
DocumentRow.class
)
.withFullWidth()
.withVisibleHeaders(false)
.withNewEditorInstantiator((doc) → {
DocumentRow row = new DocumentRow();

    row.iconLink = new Link("", new ExternalResource(doc.getDownloadURL()));
    row.iconLink.setIcon(new ExternalResource(doc.getIconURL()));
   
    return row;      
  }
);

[/code](withNewEditorInstantiator is just a method I added to ElementCollectionField to expose the functionality I added to AbstractElementCollection, and the Document class is a simple JPA entity).

This seems to work fine - my links are set up properly and the images display without problem. But I’m wondering if there’s something I’ve missed? Is there a better way to achieve what I want with the existing Viritin code?

Thanks in advance,
Ross

Hi Ross, I’m clad you have finally found the right way to build your web UIs :slight_smile:

Seems like a decent workaround for me. So far I have just used Field instances in forms and then you could do the the actual link configurations in databinding, but, as you have seen, Link is not a Field (or even Property.Viewer).

For some cases I have used LabelField to create read only presentations for certain properties. One workaround would be to create similar LinkField, ImageField etc.

It would be bit backwards incompatible, but I’d be tempted to add your feature to the Viritin. Want to create a pull request for such a feature?

cheers,
matti

Hi Matti,

Thanks for your reply, and apologies for the delay in getting back to you - I have been enjoying some rare sunshine here in UK while on annual leave from work :slight_smile:

I did wrestle a little with attempting to data bind to Link, but found that I couldn’t get it to work because, as you say, it’s not a Field. I had not thought of introducing custom LinkField classes, I will look into that today.

I’d be pleased to have this included in Viritin :slight_smile: I’ll create a pull request now. When I added the code I added it as additional functionality so as to not break backward compatibility, because I was still using the standard editor instantiators elsewhere in my code. Of course feel free to change that as you see fit.

Kind regards,
Ross