How to refresh "browse" datasource after closing "edit" screen

I created custom method for accepting changes in editor.
Now when I accept changes return to “browse” tab which shows data as it was before editing.
Is there a way to get access datasource that belongs to “browse” tab or some other way to force refreshing data on “browse” tab?

public class TodoEdit extends AbstractEditor<Todo>{
   public void onAccept(Component source) {
        getItem().setTrusted(newSecurityDs.getItem());
        commit();
        close("",true);
  }
...

p.s. In my example “trusted” property is not shown on “browse” and I fiter out entities that have that property not null

select e from sdata$Todo e where e.trusted is null


2 Likes

The right place of refreshing the browser datasource is the action in the browser that invokes the editor screen.
Assuming that you open the editor via “edit” action, you should add the following code to the browser:


public class TodoBrowse extends AbstractLookup {

    @Named("todosTable.edit")
    private EditAction todosTableEdit;

    @Inject
    private CollectionDatasource<Todo, UUID> todosDs;

    @Override
    public void init(Map<String, Object> params) {
        todosTableEdit.setAfterCommitHandler(entity -> todosDs.refresh());
    }
}

This “after commit” handler will be invoked if the editor returns Window.COMMIT_ACTION_ID when closed. So you should use this string identifier when calling close() in the editor, or use the special commitAndClose() method:


public class TodoEdit extends AbstractEditor<Todo> {

    @Inject
    private Datasource<Todo> todoDs;

    public void onClosebtnClick(Component source) {
        todoDs.getItem().setStatus(1);
        commitAndClose();
    }
}
3 Likes

Thank you for quick replay.
Now when I click “browse” on Todo I get error:

IllegalArgumentException: Can't find component '[todosTable]'

I even tried with ID “staticdata$Todo.edit” in name of EditAction and got same error.
Probably “edit” screen is not loaded before “browse” is.

My code injecting the components in the browser’s controller


    @Named("todosTable.edit") 
    private EditAction todosTableEdit; 
    @Inject 
    private CollectionDatasource<Todo, UUID> todosDs; 

assumes that your table has “todosTable” name, the datasource is “todosDs” and you open the editor by clicking on the button connected to “edit” action defined for the table.
Probably you have to adjust the code to use your components.
BTW if you are using IntelliJ, you can easily inject components into controller by pressing Alt+Insert (Generate) and select “Inject”.

1 Like

Thank you very much, it worked.

Required name was “todoesTable.edit” :slight_smile:
I used IntelliJ to inject datasource, but I wasn’t aware that I can use it for EditAction also.
Great platform

Hi

I would like to do the same thing but with a different acction like “quickEdit” … because this is not an EditAction it does not know setAfterCommitHandler method… how can I make it inherit EditAction?

Thank you

If it’s your custom action, why not just refresh the datasource at the end of the handler method?

I am trying but I think I am missing something

I have


@Inject
private GroupDatasource<PA, UUID> pAsDs;

and then


@Override
public void init(Map<String, Object> params) {
  super.init(params);

  printButton.setAction(new BaseAction("a01") {
      @Override
      public void actionPerform(Component component) {

          dsContext.commit();
          pAsDs.refresh();
          runReport();
         close("arhidoc$PA.a01.edit");
      }
  });

and I get NullPointerException


java.lang.NullPointerException
	at ro.gsdata.arhidoc.web.pa.PaA01aEdit$1.actionPerform(PaA01aEdit.java:84)
	at com.haulmont.cuba.web.gui.components.WebButton.performAction(WebButton.java:45)
	at com.haulmont.cuba.web.gui.components.WebButton.lambda$new$61446b05$1(WebButton.java:37)
	at sun.reflect.GeneratedMethodAccessor181.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:510)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:200)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:163)
	at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1037)
	at com.vaadin.ui.Button.fireClick(Button.java:377)
	at com.haulmont.cuba.web.toolkit.ui.CubaButton.fireClick(CubaButton.java:54)
	at com.vaadin.ui.Button$1.click(Button.java:54)

Well, I cannot see what is in your PaA01aEdit.java:84 line which throws the exception. Try to debug your code step-by-step in IDE, you’ll see what variable is not initialized.

I thought that in the controller I can inject any datasource from the application. In fact my datasource was not defined in this particular screen so I had to pass it as a window parameter and it works.

Hi Konstantin,
Do we need to call the commitAndClose() when we’re using the standard windowActions buttons, If so, how can we call it?


  public void onClosebtnClick(Component source) {
        commitAndClose();
    }

As I have not called it from the standard window actions and it’s not refreshing in browser after create/edit in Editor. Here is my browser code:


public class PurchaseRequisitionBrowse extends AbstractLookup {

    @Named("purchaseRequisitionsTable.edit")
    private EditAction purchaseRequisitionsTableEdit;
    @Named("purchaseRequisitionsTable.create")
    private CreateAction purchaseRequisitionsTableCreate;
    
    @Inject
    private CollectionDatasource<PurchaseRequisition, UUID> purchaseRequisitionsDs;

    @Override
    public void init(Map<String, Object> params) {

        purchaseRequisitionsTableEdit.setAfterCommitHandler(entity -> purchaseRequisitionsDs.refresh());
        purchaseRequisitionsTableCreate.setAfterCommitHandler(entity -> purchaseRequisitionsDs.refresh());
        

2nd question-
I have called the preCommit method to do some updates (auto-number, status etc) before commit and create a new. It works, is that a right approach?


  public void createNew() {
        if(preCommit()==true) {
            getDsContext().commit();
            showNotification("Saved: " + getItem().getInstanceName(), NotificationType.TRAY);
            setItem(metadata.create(PurchaseRequisition.class));
            fieldGroup.requestFocus();
        }
    }

Hi Mortoza,

  1. Sorry, I don’t understand your question.

  2. You don’t need to invoke preCommit() if you don’t override it in your controller. Its standard implementation just returns true.

Hi Konstantin

  1. I understand we have to call commitAndClose in the Editor controller. When I am using a button I can invoke it from that button. My question is, how can I invoke this method when I am using standard window action buttons?

  2. I’m overriding preCommit to set the auto number. If I don’t call it the auto number is not updated. Is there any suggested alternative?

Hi Mortoza,

  1. The standard window actions invoke commitAndClose().

  2. It’s fine if it works for you.

The browser screen is refreshed with new entity after the editor screen is calling commitAndClose.

in browser screen

@Named("retailInvoicesTable.create")
private CreateAction retailInvoicesTableCreate;
@Named("retailInvoicesTable.edit")
private EditAction retailInvoicesTableEdit;
@Inject
private GroupDatasource<RetailInvoice, UUID> retailInvoicesDs;

@Override
public void init(Map<String, Object> params) {
    retailInvoicesTableCreate.setAfterCommitHandler(entity -> retailInvoicesDs.refresh());
    retailInvoicesTableEdit.setAfterCommitHandler(entity -> retailInvoicesDs.refresh());
}

in Editor screen

public void save() {
    if(preCommit()==true) {
        commitAndClose();
  }
}

However, I don’t want to close the editor screen after create, rather want the to continue creating more transactions. To achieve that I am using following codes but when I close the screen by clicking close button, the browser it is not refreshed with newly added entries.

Editor screen

public void saveAndCreateNew() {
    if(preCommit()==true) {
        getDsContext().commit();

        setItem(metadata.create(RetailInvoice.class));
        retailCustomerField.requestFocus();
    }
}

calling close_Action in close button action to enable the commitHandler in browser.

  public void closeWindow(){
    close(CLOSE_ACTION_ID, true);
}

Here I am not using commitAndClose in saveAndCreateNew but using CLOSE_ACTION_ID in close button, isn’t not enough? It’s not refreshed when I go back to browser screen. Thanks for the help.