Hi all first of all I´m noob using SmartGWT, I have a SelectItem component with setVisible(false) and added into a DynamicForm. This DynamicForm is added into a Layout. I need to set the SelectItem with visible to true when another component is changed.
I do this:
SelectItem -> setVisible(true);
DynamicForm -> .redraw();
Layout -> .redraw();
Following piece of code works, and toggles the visibility of SelectItem on button click.
However note that this could lead to a jumpy UI, as other form controls flow in and out to fill the gap.
A better approach would be to enable/disable the component as indicated in the comment, which does not require a redraw.
final DynamicForm form = new DynamicForm();
form.setWidth100();
form.setHeight100();
final SelectItem selectItem = new SelectItem("sel", "Select");
selectItem.setValueMap("First", "Second", "Third");
ButtonItem buttonItem = new ButtonItem("btn", "Set");
buttonItem.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
selectItem.setVisible(!selectItem.getVisible());
form.redraw();
// uncomment following two lines and comment above two lines to enable/disable
// boolean isDisabled = Boolean.TRUE.equals(selectItem.getDisabled());
// selectItem.setDisabled(!isDisabled);
}
});
form.setFields(selectItem, buttonItem);
Other ways to handle form layouts:
http://www.smartclient.com/smartgwt/showcase/#layout_form_sections
http://www.smartclient.com/smartgwt/showcase/#layout_form_splitting
Related
DatePicker behavior in view: In a Vaadin 23 application there is a view with two DatePickers and a button:
When a user steps between the fields with TAB, then the DatePicker marks the whole content as selected (which is fine and the intended behavior):
DatePicker behavior in Dialog is different: When I put two DatePicker instances into a Dialog then the TAB behavior is different: it does not mark the whole content, but sets the focus after the content:
Code:
#Route("sandbox")
public class SandboxView extends VerticalLayout {
public SandboxView() {
this.add(createDatePicker(), createDatePicker());
this.add(new Button("Open dialog", event -> {
openDialog();
}));
}
private void openDialog() {
VerticalLayout layout = new VerticalLayout(createDatePicker(), createDatePicker());
Dialog dialog = new Dialog(layout);
dialog.open();
}
private DatePicker createDatePicker() {
DatePicker datePicker = new DatePicker();
datePicker.setValue(LocalDate.now());
datePicker.setAutoOpen(false);
return datePicker;
}
}
Intended behavior: I'd like the DatePicker to show the same behavior in a Dialog as it is in a view.
Question: How can I do this?
What I tried: When a focus listener calls select() at the INPUT child node in JavaScript (see code below), the whole content is marked/selected (which is as intended). But this also marks/selects the whole content when the user clicks with the mouse into the field (which is not intended).
field.getElement().addEventListener("focus", new DomEventListener() {
#Override
public void handleEvent(DomEvent event) {
event.getSource().executeJs("for (var i=0;i<$0.childNodes.length;i++){if($0.childNodes[i].nodeName=='INPUT'){$0.childNodes[i].select();}}");
}
});
Update for TextField: When using TextFields instead of DatePickers, it's the same behavior: in a view a TAB marks/selects the whole content. In a Dialog a TAB sets the focus before the content, but does not mark/select it:
This behavior is fixed in Vaadin 23.1.6.
I use the menuBar component in my application and I would like to add a "mini" form in the menu.
In the "contact" menu, the user can fill a TextField with a phone number and click on a submit button to be called.
My issue is when I select the TextField, the menu closes automatically.
Do you know if it's possible to do that and how I can do ?
Thank you.
This an example of my menu
public class HeaderView extends MenuBar implements RouterLayout {
private final MenuItem tools;
private final MenuItem contacts;
public HeaderView() {
// logo
final Image img = new Image("img/logo.png", "image");
img.setHeight("44px");
this.addItem(img);
// TOOLS
tools = this.addItem("Tools");
tools.addComponentAsFirst(new Icon(VaadinIcon.TOOLS));
// CONTACTS
contacts = this.addItem("Contacts");
contacts.addComponentAsFirst(new Icon(VaadinIcon.PHONE));
// layout for the form contact
final FormLayout nameLayout = new FormLayout();
final TextField phoneField = new TextField();
phoneField.setLabel("Phone");
phoneField.setPlaceholder("Phone");
final Button sendButton = new Button("send");
// add textfield and button to the layout
nameLayout.add(phoneField, sendButton);
// add the form to the menubar
contacts.getSubMenu().addItem(nameLayout);
}
You can try changing contacts.getSubMenu().addItem(nameLayout) to contacts.getSubMenu().add(nameLayout) I'm not sure if you can self trigger closure of the submenu after submission. If that is required.
this.grid = new Grid<>(Person.class);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.removeAllColumns();
this.grid.setColumns("firstname");
this.editButton = new Button(null, ImageIcons.EDIT.create());
this.editButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.editButton);
this.deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create());
this.deleteButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.deleteButton);
this.addComponentAsFirst(this.grid);
I have a personList with several entries. The grid shows all these entries with their first name. But it only shows the buttons in the last row. What is the problem?
You use the very same Button instance for each row. You should create a new Button within the componentRenderer, so each row will have its own Button.
Try it like this:
this.grid = new Grid<>(Person.class, false);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.setColumns("firstname");
this.grid.addComponentColumn(person -> {
// edit: added click listener for inline-editing of the person. Editor must be configured for this to work. See https://vaadin.com/components/vaadin-grid/java-examples/grid-editor
// You don't have to use inline-editing if you don't want. you can also edit the item in a separate Layout with Input fields and a Binder.
Button editButton = new Button(ImageIcons.EDIT.create(), click -> {
this.grid.getEditor().editItem(person);
});
editButton.getStyle().set("color", "#000000");
return editButton;
});
this.grid.addComponentColumn(person -> {
// edit: added click listener for person removal
Button deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create(), click -> {
this.personDao.remove(person);
// TODO: when using an in-memory dataprovider, fetch all items again from service/dao and set them with grid.setItems(this.personDao.findAll());
// but that is not necessary when using a callback dataprovider, which I belive OP is using
this.grid.getDataProvider().refresh();
});
deleteButton.getStyle().set("color", "#000000");
return deleteButton;
}
this.addComponentAsFirst(this.grid);
Edit: a minor thing but I still wanted to mention it - You do some unnecessary creation of columns, only to remove them all again later. Instead of this you could tell the grid not to create these columns in the first place, by passing false as second parameter of the Grid constructor.
this.grid = new Grid(Person.class, false);
// instead of
this.grid = new Grid(Person.class);
this.grid.removeAllColumns();
I would like to add a tooltip to a disabled text field.
Do you have any ideas how can I do it?
I'm using Vaadin 6.8.13.
When I select a specific item in combo box, disabled text field will be enabled. Otherwise, text field will be disabled
TextField readonly = new TextField("Read-Only");
readonly.setValue("I am sitting here read only");
readonly.setReadOnly(true);
readonly.setDescription("Not this time Mojojojo");
Is this what you want?
Sure, why should it not work -- unless you have not even tried it first.
Disable the TextField via setEnabled(false) and add a description via setDescription('...'):
#Grapes([
#Grab('org.vaadin.spring:spring-boot-vaadin:0.0.5.RELEASE'),
#Grab('com.vaadin:vaadin-server:7.4.4'),
#Grab('com.vaadin:vaadin-client-compiled:7.4.4'),
#Grab('com.vaadin:vaadin-themes:7.4.4'),
])
import org.vaadin.spring.annotation.VaadinUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.*
#VaadinUI
class MyUI extends UI {
protected void init(VaadinRequest request) {
setContent( new TextField().with{
caption = "I have a Caption"
value = "And a Value"
enabled = false
description = "And have a Description"
it
})
}
}
// spring run vaadin.groovy
Try disabling the label and then putting it inside a layout. Then set that layout's description. The user won't know the difference.
VerticalLayout layout = new VerticalLayout();
TextArea textArea = new TextArea("Hello World");
textArea.setEnabled(false);
VerticalLayout textAreaWrapper = new VerticalLayout();
textAreaWrapper.addComponent(textArea);
textAreaWrapper.setDescription("Some description");
layout.addComponent(textAreaWrapper);
this.setContent(layout);
this.setSizeFull();
You could create your own class which extends VerticalLayout and creates a TextArea inside it. That way you don't have to create a layout wrapper each time you just create your "MyTextArea" or whatever you want to call it.
Screenshot
N.B.
From your question I had originally thought the following code wouldn't work but it works fine? I haven't tried it in Vaadin 6.8.13 though. I am using Vaadin 7.1.2.
VerticalLayout layout = new VerticalLayout();
TextArea textArea = new TextArea("Hello World");
textArea.setEnabled(false);
textArea.setDescription("Some description");
layout.addComponent(textArea);
this.setContent(layout);
this.setSizeFull();
I am newbie to vaadin. I have to develop PoC on vaadin. Service layer is already written using spring. As a part of Poc I have to develop a screen below.
When request comes to my UI class, it will call my View using navigator. This view consists of one tabsheet and each tab have its own functionality and depends on other tab values too. First tab is search tab. It displays all the records came from db in the tab content area(Table/Grid addon. I dont know what to use). Each record have access to other two tabs. The other two tabs has fields to map each record's property. As of now, i have taken dummy data to display.
I wrote the view like this . But I am confused weather this approach is correct or not.
#VaadinView(UserView.NAME)
public class UserView extends VerticalLayout implements View {
public static final String NAME = "user";
public UserView(){
// For Tabs
TabSheet tabs = new TabSheet();
// first tab component
VerticalLayout layout = new VerticalLayout();
// for search fields
HorizontalLayout searchArea = new HorizontalLayout();
FormLayout searchAreaName = new FormLayout();
TextField name = new TextField("name");
FormLayout searchAreaEmail = new FormLayout();
TextField email = new TextField("email");
searchAreaName.addComponent(name);
searchAreaEmail.addComponent(email);
searchArea.addComponent(searchAreaName);
searchArea.addComponent(searchAreaEmail);
// for search table
BeanContainer<String, test.User> users = new BeanContainer<String, User>(
User.class);
users.setBeanIdProperty("userId");
users.addBean(new User("sudheer", "sudheer#kewil.com", "1"));
users.addBean(new User("sridhar", "sridhar#kewil.com", "2"));
users.addBean(new User("ranga", "ranga#kewil.com", "3"));
Table table = new Table("", users);
table.setSizeFull();
table.setPageLength(6);
layout.addComponent(searchArea);
layout.addComponent(table);
Tab tabOne = tabs.addTab(layout, "User Search", null);
// second tab component
VerticalLayout userLayout = new VerticalLayout();
userLayout.addComponent(new TextField("user name"));
userLayout.addComponent(new TextField("email"));
tabs.addTab(userLayout, "main details", null);
// tab change event
addComponent(tabs);
tabs.setHeight("50%");
tabs.setWidth("50%");
setComponentAlignment(tabs, Alignment.MIDDLE_CENTER);
}
#Override
public void enter(ViewChangeEvent event) {
}
}
I haven't implemented pagination also. Before going forward, I would like to know any other best approaches to go ahead.
Any suggestions would help me very much. Thanks in advance.
Anybody.. please help me out. I am going blindly with my appproach
Here is what I do in such cases:
Use the Blackboard event bus to fire events. These events carry a payload that essentially is the id of the record clicked/selected.
The other tabs or views are registered as a listener of this event. When the event is fired, the listeners extract the record/entity id from the payload, fetch the entity object from the back-end, and display it accordingly.
This approach ensures loosely-coupled components.
I hope it helps.