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.