Open editor for specific entity id from main menu

Hello,

i am trying to open edit screen from main menu and selecting a specific entity (table has only one record) in the instance loader query, and it loads the properties to the screen fields but when i save it seems to have created a new entity with no relation to the fields contents. Any advice on how to acomplish this?

<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd" caption="msg://editorCaption" focusComponent="form"
        messagesPack="com.chortitzer.cinweb.web.balanceados.tblfbarecetaactiva">
    <data>
        <instance id="tblFbaRecetaActivaDc" class="com.chortitzer.cinweb.entity.balanceados.TblFbaRecetaActiva"
                  view="tblFbaRecetaActiva-view">
            <loader>
                <query><![CDATA[select e from cinweb_TblFbaRecetaActiva e where e.id = 1]]></query>
            </loader>
        </instance>
        <collection id="idRecetasDc" class="com.chortitzer.cinweb.entity.balanceados.TblFbaRecetas" view="_minimal">
            <loader id="idRecetasLc">
                <query><![CDATA[select e from cinweb_TblFbaRecetas e]]></query>
            </loader>
        </collection>
    </data>
    <dialogMode height="185" width="550"/>
    <layout expand="editActions" spacing="true">
        <form id="form" dataContainer="tblFbaRecetaActivaDc">
            <column width="380px">
                <lookupPickerField id="idRecetaField" caption="Receta" optionsContainer="idRecetasDc" property="idReceta">
                    <actions>
                        <action id="lookup" type="picker_lookup"/>
                        <action id="open" type="picker_open"/>
                    </actions>
                </lookupPickerField>
                <textField id="cantidadCiclosField" property="cantidadCiclos" caption="Cantidad de Ciclos" width="100px"/>
            </column>
        </form>
        <hbox id="editActions" spacing="true">
            <button action="windowCommitAndClose" caption="Guardar"/>
            <button action="windowClose"/>
        </hbox>
    </layout>
</window>
1 Like

HI!

it shouldnā€™t work correctly if you open editor screen from menu. You can find in the documentation that menu item provides invoking methods from beans or using classes.

For instance web-menu.xml

<item bean="editdemo_ProcessCustomerEditor" beanMethod="openCustomerEdit"/>

And in the openCustomerEdit() we can build editor with our settings:

@Inject
private ScreenBuilders screenBuilders;
@Inject
private DataManager dataManager;

public void openCustomerEdit() {
    Customer customer = dataManager.load(Id.of(101, Customer.class)).one();
    AppUI ui = AppUI.getCurrent();
    Window window = ui.getTopLevelWindow();
    if (window != null) {
        screenBuilders.editor(Customer.class, window.getFrameOwner())
                .editEntity(customer)
                .build()
                .show();
    }
}

You can find ScreenBuilders in the documentation.

Hi,

how can I realize this with CUBA Platform 6.10?

Greetings
Andreas

Hi!

You can use the same way. But instead of ScreenBuilders you should use WindowManager in order to open screens.

@Inject
private WindowConfig windowConfig;
@Inject
private DataManager dataManager;

public void showEntityEditor() {
    AppUI ui = AppUI.getCurrent();
    Window window = ui.getTopLevelWindow();
    if (window != null) {
        User user = dataManager.load(LoadContext.create(User.class));
        WindowInfo windowInfo = windowConfig.findWindowInfo("sec$User.edit");

        WindowManager windowManager = window.getWindowManager();
        windowManager.openEditor(windowInfo, user, WindowManager.OpenType.NEW_TAB);
    }
}

Here is a link to 6.10 documentation that describes attributes in menu item.

Works fine. Thanks :slight_smile:

Hi! I donā€™t quite get it. The ScreenBuilders API is only available in the web module, but there I canā€™t set a bean name and the web-menu.xml wonā€™t find it.
Iā€™m missing something here.

I made a custom editor:

@UiController("invoicy_Company.mycompanyEdit")
@UiDescriptor("my-company-edit.xml")
@EditedEntityContainer("companyDc")
@LoadDataBeforeShow
public class MyCompanyEdit extends StandardEditor<Company> {

    @Inject
    private UserSessionSource userSessionSource;

    @Inject
    private ScreenBuilders screenBuilders;

    @Inject
    private DataManager dataManager;

    public void openMyCompanyEdit() {
        ...

web-menu.xml

        <item caption="mycompany" bean="invoicy_Company.mycompanyEdit" beanMethod="openMyCompanyEdit"/>

The stacktrace I get:

com.vaadin.server.ServerRpcManager$RpcInvocationException: Unable to invoke method menuItemTriggered in com.haulmont.cuba.web.widgets.client.verticalmenu.CubaSideMenuServerRpc
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:157) ~[vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:115) ~[vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:431) [vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:396) [vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:260) [vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:82) [vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) [vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1578) [vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:425) [vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:329) [cuba-web-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:215) [cuba-web-7.2.4.jar:7.2.4]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [servlet-api.jar:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [catalina.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.27]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-websocket.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.27]
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) [spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) [spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:93) [cuba-web-7.2.4.jar:7.2.4]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.27]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [catalina.jar:9.0.27]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:9.0.27]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) [catalina.jar:9.0.27]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [catalina.jar:9.0.27]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [catalina.jar:9.0.27]
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) [catalina.jar:9.0.27]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [catalina.jar:9.0.27]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [catalina.jar:9.0.27]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-coyote.jar:9.0.27]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:9.0.27]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) [tomcat-coyote.jar:9.0.27]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579) [tomcat-coyote.jar:9.0.27]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:9.0.27]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.27]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:153) ~[vaadin-server-8.9.2-6-cuba.jar:8.9.2-6-cuba]
	... 38 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'invoicy_Company.mycompanyEdit' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:805) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1278) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:297) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1108) ~[spring-context-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at com.haulmont.cuba.core.sys.BeanLocatorImpl.get(BeanLocatorImpl.java:55) ~[cuba-global-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.gui.config.MenuItemCommands$BeanCommand.run(MenuItemCommands.java:426) ~[cuba-gui-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.web.sys.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:264) ~[cuba-web-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.web.sys.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:249) ~[cuba-web-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.web.gui.components.mainwindow.WebSideMenu$MenuItemImpl.menuSelected(WebSideMenu.java:573) ~[cuba-web-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.web.widgets.CubaSideMenu$1.menuItemTriggered(CubaSideMenu.java:90) ~[cuba-web-widgets-7.2.4.jar:na]
	... 43 common frames omitted

Hello Klaus,

exception tells that invoicy_Company.mycompanyEdit is not a bean.

For your configuration you should create separated spring bean invoicy_Company.mycompanyEdit with openMyCompanyEdit method that will be invoked.
See more information about menu attributes in the documentation.

If you want to open an editor you can define menu item like a browse screen:

<menu id="application-myapp" insertBefore="administration">
    <item screen="myapp_Customer.browse" caption="Customer Browse"/>
    <item screen="myapp_Customer.edit" caption="Editor screen"/>
</menu>

it will open an editor with new entity.

Hello Roman, thanks for your answer. Unfortunately Iā€™m still not sure how to do this.

  1. Where would I place this bean? I need the ScreenBuilders component, as I want to achieve the same as the original poster - an editor screen that will edit a particular entry.
  2. Do you have an example project, where a menu item with a bean is used? (Ideally also with the ScreenBuilders component?)

Thanks!

  1. Bean should be placed under the scanning package that is defined in the web-spring.xml in ā€œwebā€ module. For instance,
    <context:component-scan base-package="com.company.myapp"/>
  1. Here is a demo project demo.zip (170.9 KB)
    See MenuScreenOpener bean and web-menu.xml.
1 Like

Awesome, now I get it. Thanks! :slight_smile: I had troubles, because in the CUBA project view, there is nu such thing as ā€œBeansā€ for the web module (ā€œGeneric UIā€). I thought everything (that is not a hack) had a corresponding category in this view.

One more question. Iā€™m able to open an editor screen in DIALOG mode for a particular entity Iā€™ve loaded before (company) like this:

                screenBuilders.editor(Company.class, window.getFrameOwner())
                        .editEntity(company)
                        .withLaunchMode(OpenMode.DIALOG)
                        .build()
                        .show();

In the background there is a browse screen with all available companies open, but when I edit the company entity in the dialog, the browse screen isnā€™t refreshed automatically. Do I have to fire an event or something like that?

Klaus,
Did you find a solution to your question ?
I am faced with the same challenge

@robert.gilbert Yes, itā€™s quite easy actually, just give the list component to the screen builder, like:

                .withListComponent(companiesTable)

Hello, can you post complete 6.x solution?

I configured menu like this:

<item id="invoiceImport"
                      openType="NEW_TAB"
                      bean="contacts_ProcessImportEditor" beanMethod="openImportEdit"/>

and created a Java Class like this (from example):

package pro.sysonline.contacts.web;

import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.gui.WindowManager;
import com.haulmont.cuba.gui.components.Window;
import com.haulmont.cuba.gui.config.WindowConfig;
import com.haulmont.cuba.gui.config.WindowInfo;
import com.haulmont.cuba.web.AppUI;
import org.springframework.stereotype.Component;

@Component
public class ProcessImportEditor {

    public void openImportEdit() {
        AppUI ui = AppUI.getCurrent();
        Window window = ui.getTopLevelWindow();

        if (window != null) {
            WindowConfig windowConfig = AppBeans.get(WindowConfig.NAME);
            WindowInfo windowInfo = windowConfig.findWindowInfo("sec$User.edit");


            WindowManager windowManager = window.getWindowManager();
            windowManager.openEditor(windowInfo, null, WindowManager.OpenType.NEW_TAB);
        }


    }

}

taken the example and slightly modified.
Platform is 6.10 and in menu item does not find class and method.

When I click on menu item I get this error:
NoSuchBeanDefinitionException: No bean named ā€˜contacts_ProcessImportEditorā€™ available

I tried to put in various locatio even if this should be not so important, according to Spring configuration:

web-spring:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"
       xmlns:context="http://www.springframework.org/schema/context">
    <!-- Annotation-based beans -->
    <context:component-scan base-package="pro.sysonline.contacts"/>
    <bean class="com.haulmont.cuba.web.sys.remoting.WebRemoteProxyBeanCreator">
        <property name="serverSelector"
                  ref="cuba_ServerSelector"/>
        <property name="remoteServices">
            <map>
                <entry key="contacts_AddressService"
                       value="pro.sysonline.contacts.service.AddressService"/>
                <entry key="contacts_EUIDService"
                       value="pro.sysonline.contacts.service.EUIDService"/>
                <entry key="contacts_InvoiceService"
                       value="pro.sysonline.contacts.service.InvoiceService"/>
                <entry key="contacts_MolService"
                       value="pro.sysonline.contacts.service.MolService"/>
                <entry key="contacts_EventService"
                       value="pro.sysonline.contacts.service.EventService"/>
                <entry key="contacts_WageCalculationService"
                       value="pro.sysonline.contacts.service.WageCalculationService"/>
                <entry key="contacts_XMLInvoiceService"
                       value="pro.sysonline.contacts.service.XMLInvoiceService"/>
                <entry key="contacts_XMLEventOPService"
                       value="pro.sysonline.contacts.service.XMLEventOPService"/>
            </map>
        </property>
    </bean>
</beans>

Thanks in advance,
Bye, F. De Massis

Hello!

Try to specify the bean name contacts_ProcessImportEditor because spring creates your bean as processImportEditor.

@Component("contacts_ProcessImportEditor")
public class ProcessImportEditor {

Thank you it worked! Now I have an error that says editor has a null parameter but this is expected.
Thank you very much,
F.