TokenField - new component

I guess there are a few other fiddly things, too. Can’t wait for the Vaadin 7 version–literally… A custom TokenField is at the center of one of the features we’re prototyping!

Current Version compatible with Vaadin 7 beta10?

Hi,

I Try to use this Addon on Vaadin 7 Beta10 and i get a compile Error on the Widgetset.
Is this Version 7.0.0 from Maven Repository Compatible?

I Get:


[INFO]
          [ERROR]
 Line 7: The import com.vaadin.terminal.gwt.client cannot be resolved
[INFO]
          [ERROR]
 Line 8: The import com.vaadin.terminal.gwt.client cannot be resolved
[INFO]
          [ERROR]
 Line 9: The import com.vaadin.terminal.gwt.client cannot be resolved
[INFO]
          [ERROR]
 Line 11: Connect cannot be resolved to a type
[INFO]
          [ERROR]
 Line 11: The attribute value is undefined for the annotation type Connect
[INFO]
          [ERROR]
 Line 12: ComboBoxConnector cannot be resolved to a type
[INFO]
          [ERROR]
 Line 14: RpcProxy cannot be resolved
[INFO]
          [ERROR]
 Line 20: The method init() of type TokenFieldConnector must override or implement a supertype method
[INFO]
          [ERROR]
 Line 30: The method getWidget() of type TokenFieldConnector must override or implement a supertype method
[INFO]
          [ERROR]
 Line 31: ComboBoxConnector cannot be resolved to a type
[INFO]
          [ERROR]
 Line 35: The method createWidget() of type TokenFieldConnector must override or implement a supertype method

Since this is the first and only Addon i use, i do not know if i made something else wrong.
I have my dependency to (version here not present):


<dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin-server</artifactId>
    </dependency>
    <dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin-client-compiled</artifactId>
    </dependency>
    <dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin-client</artifactId>
    </dependency>
    <dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin-themes</artifactId>
    </dependency>      
    <dependency>
      <groupId>org.vaadin.addons</groupId>
      <artifactId>tokenfield</artifactId>
    </dependency>

I can not find the import “com.vaadin.terminal.gwt.client” in the upper dependencies. Did i miss something?

thanks

Hi Author,

It’s a great addon.
My problem is the read-only state looks not correct.
Even I set it read-only, the “x” close button is still there. My expectation is if it is set to read-only, the “x” close button should be hidden.

Hi Marc,

nice Add-On, just what I was looking for.

I was wondering if it is possible to set a different Background to the Tokens that did not validate correctly so the User can easly see which token is wrong.
Really usefull if he enters several tokens at once

On Inpection with the Browser I only see that all of them are buttons, but with the same StyleName

Marc

Hi, I’m new to Vaadin, so this probably is a newbie problem.

When I have the tokenfield on screen and I add a value, the new value is listed on the UI, but it is not written to my database. I get the following error:

java.lang.UnsupportedOperationException
at com.vaadin.data.util.sqlcontainer.SQLContainer.addItem(SQLContainer.java:1469)

Does anyone know what I’m doing wrong??

Hi, I have a problem with the method TokenField.getValue () . It returns a String and Long values, but Id of my custom Container is Long.
If I enter “abc” twice,

TokenField.getValue ()

returns [abc, 12345]

and

tokenField.getContainerDataSource().getItemIds()

returns [12345]
.
The result is duplicating values in TokenField.
Source code of my Container:

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.ObjectProperty;

@SuppressWarnings("serial")
public class ProfileContainer implements Container {

	private Map<Long, Item> items = new HashMap<Long, Item>();
	
	@SuppressWarnings("unchecked")
	private List<String> containerPropertyIds = Arrays.asList(new String[]{"id", "name"});
	
	@Override
	public Item getItem(Object itemId) {
		return items.get(convertId(itemId));
	}

	@Override
	public Collection<String> getContainerPropertyIds() {
		return containerPropertyIds;
	}

	@Override
	public Collection<Long> getItemIds() {
		return items.keySet();
	}
	
	@Override
	public Property getContainerProperty(Object itemId, Object propertyId) {
		return getItem(convertId(itemId)).getItemProperty(propertyId);
	}

	@Override
	public Class<?> getType(Object propertyId) {
		if(propertyId.equals("id")) return Long.class;
		if(propertyId.equals("name")) return String.class;
		return null;
	}

	@Override
	public int size() {
		return items.size();
	}

	@Override
	public boolean containsId(Object itemId) {
		return items.keySet().contains(convertId(itemId));
	}

	@Override
	public Item addItem(Object itemId) throws UnsupportedOperationException {
		Long newItemId = convertId(itemId);
		if(containsId(newItemId)) return null;
		ProfileItem profileItem = new ProfileItem(newItemId, (String)itemId);
		items.put(newItemId, profileItem);
		return profileItem;
	}

	@Override
	public Object addItem() throws UnsupportedOperationException {
		Long itemId = System.currentTimeMillis();
		while(containsId(itemId)) itemId = System.currentTimeMillis();
		ProfileItem profileItem = new ProfileItem(itemId, "");
		items.put(itemId, profileItem);
		return profileItem;
	}

	@Override
	public boolean removeItem(Object itemId)
			throws UnsupportedOperationException {
		items.remove(convertId(itemId));
		return true;
	}

	@Override
	public boolean addContainerProperty(Object propertyId, Class<?> type,
			Object defaultValue) throws UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean removeContainerProperty(Object propertyId)
			throws UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean removeAllItems() throws UnsupportedOperationException {
		items.clear();
		return true;
	}
	
	private Long convertId(Object itemId) {
		if(itemId instanceof Long)
			return (Long) itemId;
		else 
			return (long) itemId.hashCode();
	}

	private class ProfileItem implements Item {

		private Property<Long> id = new ObjectProperty<Long>(-1L);
		private Property<String> name = new ObjectProperty<String>("");
		
		public ProfileItem() {
		}
		
		public ProfileItem(Long id, String name) {
			this.id.setValue(id);
			this.name.setValue(name);			
		}
		
		@Override
		public Property<?> getItemProperty(Object id) {
			if(id.equals("id")) return (Property<Long>) this.id;
			if(id.equals("name")) return (Property<String>) this.name;
			return null;
		}

		@Override
		public Collection<?> getItemPropertyIds() {
			return containerPropertyIds;
		}

		@Override
		public boolean addItemProperty(Object id, Property property)
				throws UnsupportedOperationException {
			throw new UnsupportedOperationException();
		}

		@Override
		public boolean removeItemProperty(Object id)
				throws UnsupportedOperationException {
			throw new UnsupportedOperationException();
		}

	}
	
}

So I’ve been battling to get tokenfield to work with a JPA container (eclipse link) and have just about got it working.
One problem which I’ve not been able to resolve is inclusion of the tokenfield style sheet. It is my understanding that when using maven I should run:


mvn vaadin:update-widgetset 
[INFO]
 Scanning for projects...
[INFO]
 ------------------------------------------------------------------------
[INFO]
 Building Vaadin Web Application
[INFO]
    task-segment: [vaadin:update-widgetset]

[INFO]
 ------------------------------------------------------------------------
[INFO]
 [vaadin:update-widgetset {execution: default-cli}]

[INFO]
 auto discovered modules [au.org.scoutmaster.AppWidgetSet]

[INFO]
 Updating widgetset au.org.scoutmaster.AppWidgetSet
[INFO]
 Adding resource directory to command classpath: /home/bsutton/git/scoutmaster/scoutmaster/src/main/resources
[ERROR]
 Jul 28, 2013 9:21:32 PM com.vaadin.server.widgetsetutils.ClassPathExplorer getAvailableWidgetSetsAndStylesheets
[ERROR]
 INFO: Widgetsets found from classpath:
[ERROR]
 	com.vaadin.DefaultWidgetSet in jar:file:/home/bsutton/.m2/repository/com/vaadin/vaadin-client/7.1.0/vaadin-client-7.1.0.jar!/
[ERROR]
 	au.org.scoutmaster.AppWidgetSet in file:/home/bsutton/git/scoutmaster/scoutmaster/src/main/java
[ERROR]
 	org.vaadin.tokenfield.TokenfieldWidgetset in jar:file:/home/bsutton/.m2/repository/org/vaadin/addons/tokenfield/7.0.1/tokenfield-7.0.1.jar!/
[ERROR]
 	fi.jasoft.dragdroplayouts.DragDropLayoutsWidgetSet in jar:file:/home/bsutton/.m2/repository/org/vaadin/addons/dragdroplayouts/1.0.0.alpha4/dragdroplayouts-1.0.0.alpha4.jar!/
[ERROR]
 	com.vaadin.addon.calendar.gwt.CalendarWidgetset in jar:file:/home/bsutton/.m2/repository/com/vaadin/addon/vaadin-calendar/2.0.0/vaadin-calendar-2.0.0.jar!/
[ERROR]
 Addon styles found from classpath:
[ERROR]
 
[ERROR]
 Jul 28, 2013 9:21:32 PM com.vaadin.server.widgetsetutils.ClassPathExplorer getAvailableWidgetSetsAndStylesheets
[ERROR]
 INFO: Search took 14ms

You will note in the above output that it didn’t detect the tokenfield style sheet.

Any clues?

I’m using Eclipse, Vaadin 7.1 and maven 2.2.1, tokenfield 7.0.1

The pom entries are:



	<dependency>
			<groupId>org.vaadin.addons</groupId>
			<artifactId>tokenfield</artifactId>
			<version>7.0.1</version>
</dependency>

<plugin>
				<groupId>com.vaadin</groupId>
				<artifactId>vaadin-maven-plugin</artifactId>
				<version>${vaadin.plugin.version}</version>
				<configuration>
					<extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
					<!-- <runTarget>mobilemail</runTarget> -->
					<!-- We are doing "inplace" but into subdir VAADIN/widgetsets. This 
						way compatible with Vaadin eclipse plugin. -->
					<webappDirectory>${basedir}/src/main/webapp/VAADIN/widgetsets
					</webappDirectory>
					<hostedWebapp>${basedir}/src/main/webapp/VAADIN/widgetsets
					</hostedWebapp>
					<noServer>true</noServer>
					<!-- Remove draftCompile when project is ready -->
					<draftCompile>false</draftCompile>
					<compileReport>true</compileReport>
					<style>OBF</style>
					<strict>true</strict>
					<runTarget>http://localhost:8080/</runTarget>
				</configuration>
				<executions>
					<execution>
						<configuration>
							<!-- if you don't specify any modules, the plugin will find them -->
							<!-- <modules> <module>com.vaadin.demo.mobilemail.gwt.ColorPickerWidgetSet</module> 
								</modules> -->
						</configuration>
						<goals>
							<goal>resources</goal>
							<goal>update-widgetset</goal>
							<goal>compile</goal>
						</goals>
					</execution>
				</executions>
			</plugin>

The target update-widgetset just scans the classpath for JARs that have a special manifest field indicating that they are Vaadin client side add-ons (as well as other GWT related JARs) and updates your .gwt.xml widgetset file. It has nothing to do with themes (except maybe indirectly for alternative 2 below by updating your main widgetset to point to its widgetset).

I don’t know how the theme is included in TokenField, so the below is just going over various possibilities.

If TokenField uses the Vaadin 7.1 mechanism of including themes in add-ons (which I don’t believe - I’m not sure if any published add-on uses it yet), you would need to run mvn vaadin:update-theme (using a recent Maven plug-in) and ensure the file addons.xml is imported and included correctly. Then, mvn vaadin:compile-theme would be required as for any SCSS theme.

If TokenField includes its theme rules from its widgetset (which I guess might be the case), you just need to compile the widgetset (mvn vaadin:update-widgetset vaadin:compile), which might or might not log anything about the theme, but it should get compiled into the widgetset JavaScript files.

Finally, TokenField might require the user to explicitly import its theme. If so, check the Directory page and documentation of TokenField.

With Vaadin 7.1.1 when I add a new token token combo box is not cleared. Tried to recompile widgetset, didn’t help.

I can add some information to this. I’m seeing the same problem however its worth noting that if you exit the field using ‘tab’ then the value is cleared, it is only when you exit the field with the ‘enter’ key that the field isn’t cleared.

So the structure of the tokenfield jar is:


META-INF/MANIFEST.MF
org/vaadin/tokenfield/TokenComboBox$1.class
org/vaadin/tokenfield/TokenComboBox.class
org/vaadin/tokenfield/TokenComboBox.java
org/vaadin/tokenfield/TokenField$1.class
org/vaadin/tokenfield/TokenField$2.class
org/vaadin/tokenfield/TokenField$3.class
org/vaadin/tokenfield/TokenField$4.class
org/vaadin/tokenfield/TokenField$InsertPosition.class
org/vaadin/tokenfield/TokenField.class
org/vaadin/tokenfield/TokenField.java
org/vaadin/tokenfield/TokenfieldWidgetset.gwt.xml
org/vaadin/tokenfield/public/tokenfield/black-input-right.png
org/vaadin/tokenfield/public/tokenfield/input-right.png
org/vaadin/tokenfield/public/tokenfield/tokenfield.css
org/vaadin/tokenfield/client/ui/TokenFieldServerRpc.class
org/vaadin/tokenfield/client/ui/TokenFieldServerRpc.java
org/vaadin/tokenfield/client/ui/VTokenField$DeleteListener.class
org/vaadin/tokenfield/client/ui/VTokenField.class
org/vaadin/tokenfield/client/ui/VTokenField.java
org/vaadin/tokenfield/client/ui/TokenFieldConnector$1.class
org/vaadin/tokenfield/client/ui/TokenFieldConnector.class
org/vaadin/tokenfield/client/ui/TokenFieldConnector.java

When I run mvn vaadin:update-theme


[vaadin:update-theme {execution: default-cli}]

Updating theme VAADIN/themes/scoutmaster
com.vaadin.server.widgetsetutils.ClassPathExplorer getAvailableWidgetSetsAndStylesheets
Widgetsets found from classpath:
com.vaadin.DefaultWidgetSet in jar:file:/home/bsutton/.m2/repository/com/vaadin/vaadin-client/7.1.0/vaadin-client-7.1.0.jar!/
au.org.scoutmaster.AppWidgetSet in file:/home/bsutton/git/scoutmaster/scoutmaster/target/classes
org.vaadin.tokenfield.TokenfieldWidgetset in jar:file:/home/bsutton/.m2/repository/org/vaadin/addons/tokenfield/7.0.1/tokenfield-7.0.1.jar!/
	fi.jasoft.dragdroplayouts.DragDropLayoutsWidgetSet in jar:file:/home/bsutton/.m2/repository/org/vaadin/addons/dragdroplayouts/1.0.0.alpha4/dragdroplayouts-1.0.0.alpha4.jar!/
	com.vaadin.addon.calendar.gwt.CalendarWidgetset in jar:file:/home/bsutton/.m2/repository/com/vaadin/addon/vaadin-calendar/2.0.0/vaadin-calendar-2.0.0.jar!/
Addon styles found from classpath:

com.vaadin.server.widgetsetutils.ClassPathExplorer getAvailableWidgetSetsAndStylesheets
Search took 15ms
Theme "VAADIN/themes/scoutmaster" updated

The scoutmaster themes then looks thus:

addons.scss


@mixin addons {
}

styles.css - this file is large but has no tokenfield related content that i can see:


.v-assistive-device-only {
        position: absolute;
        top: -2000px;
        left: -2000px;
        width: 10px;
        overflow: hidden;
}

.v-vaadin-version:after {
        content: "7.1.0";
}

.v-generated-body {
        width: 100%;
        height: 100%;
        border: 0;
        margin: 0;
        overflow: hidden;
}

... trimmed below here

The file styles.scss mostly contains font statements I’ve added to increase the default font size:


@import "../reindeer/reindeer.scss";

@mixin scoutmaster
{
  @include reindeer;


        /* Global font styles */
        .v-app,

... trimmed
         .v-table-header-drag
        {
                font-family: Arial, Helvetica, Tahoma, Verdana, sans-serif;
                font-size: 14px;
                line-height: normal;
                color: #222;
        }
}

When I run:

mvn vaadin:update-widgetset

I get


[vaadin:update-widgetset {execution: default-cli}]

auto discovered modules [au.org.scoutmaster.AppWidgetSet]

Updating widgetset au.org.scoutmaster.AppWidgetSet
Adding resource directory to command classpath: /home/bsutton/git/scoutmaster/scoutmaster/src/main/resources
com.vaadin.server.widgetsetutils.ClassPathExplorer getAvailableWidgetSetsAndStylesheets
Widgetsets found from classpath:
com.vaadin.DefaultWidgetSet in jar:file:/home/bsutton/.m2/repository/com/vaadin/vaadin-client/7.1.0/vaadin-client-7.1.0.jar!/
au.org.scoutmaster.AppWidgetSet in file:/home/bsutton/git/scoutmaster/scoutmaster/src/main/java
org.vaadin.tokenfield.TokenfieldWidgetset in jar:file:/home/bsutton/.m2/repository/org/vaadin/addons/tokenfield/7.0.1/tokenfield-7.0.1.jar!/
fi.jasoft.dragdroplayouts.DragDropLayoutsWidgetSet in jar:file:/home/bsutton/.m2/repository/org/vaadin/addons/dragdroplayouts/1.0.0.alpha4/dragdroplayouts-1.0.0.alpha4.jar!/
com.vaadin.addon.calendar.gwt.CalendarWidgetset in jar:file:/home/bsutton/.m2/repository/com/vaadin/addon/vaadin-calendar/2.0.0/vaadin-calendar-2.0.0.jar!/
Addon styles found from classpath:
com.vaadin.server.widgetsetutils.ClassPathExplorer getAvailableWidgetSetsAndStylesheets
Search took 14ms

So any idea what I’m doing wrong?

tells that the CSS is actually compiled into the widgetset for this add-on. It will not be sent to the client as a separate CSS file but minimized and embedded in the widgetset JS file.

vaadin:update-widgetset would not care about this at all - it just scans add-on JARs for metadata. Only vaadin:compile might or might not produce any output that there are CSS rules included in the widgetset.

Same problem here… any workarounds?

With Vaadin 7.1.5 the remove-on-backspace functionality is not working… Has anyone the same experience?
I checked with Vaadin 7.1.0 with the same result…

Hi,
I had a problem with token orders. The component uses HashSet’s in setInternalValue. If you have order (like using a LinkedHashSet as presentation class) in your tokens, it is lost when displayed. To solve this, I tried extending the TokenField but it was a bust. My solution is to use a wrapper class for tokens which contains the token and an order value that is used as the hash too. Since HashSet uses these hash values to order data, the order is preserved. Hope it helps someone.

After a long time:
Is there a new version and another source repository planned of the TokenField?

Like several others I exported it from the obsolete code.google platform to secure the source code:
https://github.com/jforge/tokenfield

I use this component in several projects and for now I’ve just added 1 further issue due to a known problem with the ComboBox:
https://github.com/jforge/tokenfield/issues/16

Everyone can contribute there and I will apply pull requests ASAP.

But I would appreciate a tokenfield source repository owned by the original author, if he is interested.

Hi, Token field is a nice component but I have a problem after selecting the data from token-field i want to that data remains in the screen when I visited again on that screen.

You should really provide more context to your question. What does “screen” mean? A Vaadin UI instance? A page? What does it mean to “visit again”? Reload the page / re-create the UI?

Having said that, I guess the general / common solution is to actually persist (either in a DB, or even in-memory like in the http / Vaadin session, etc.) the values inserted by the user and upon “re-visiting the screen” to automatically set them accordingly.

If you’re impatient and eager to switch to Vaadin 8 like me, I’ve created a pull request with Vaadin 8 adaptations here: https://github.com/jforge/tokenfield/pull/17

I’ve used the jforge’s github clone of origin google-code repository, the changes were pretty straightforward.
So if you need the Vaadin8 compatible version, you can build your own …