Override Edit button action

Hi,

I have below method which auto increment one field (order). Its working fine as expected. But I dont want to use another button (update in this case) for this action. Is it possible to perform same below functionality by using edit button?

a

 public void onUpdateBtnClick() {

	 CorpRTSUndIns grsIndusIns = corpRTSUndInsesTable.getSingleSelected();
    	
        if (grsIndusIns != null) {	
        	CorpRTSUndIns newGrsIndusIns = metadata.create(CorpRTSUndIns.class);
        	newGrsIndusIns.setOrder((int) unService.getNextNumber(grsIndusIns.getType()));
 
        	openEditor(newGrsIndusIns, WindowManager.OpenType.THIS_TAB).addCloseWithCommitListener(() -> corpRTSUndInsesDs.refresh());
        	} else {
        			showNotification("Please select a row to update", NotificationType.HUMANIZED);
        	}
 
        	}

Thanks,
Saurabh

Saurabh,
You can do this two ways. First, you can just remove the normal Edit action and rename your currently working button to Edit with the same icon. That would be the easiest. Second, if you want to use the Edit button instead of an additional button, then you can add a BeforePerformActionHandler

@Named("corpRTSUndInsesTable.edit")
private EditAction corpRTSUndInsesEdit;

@Override
public void init(Map<String, Object> params) {
        this.corpRTSUndInsesEdit.setBeforeActionPerformedHandler(() -> {
            CorpRTSUndIns grsIndusIns = corpRTSUndInsesTable.getSingleSelected();

            if (grsIndusIns != null) {
                CorpRTSUndIns newGrsIndusIns = metadata.create(CorpRTSUndIns.class);
                newGrsIndusIns.setOrder((int) unService.getNextNumber(grsIndusIns.getType()));

                openEditor(newGrsIndusIns, WindowManager.OpenType.THIS_TAB).addCloseWithCommitListener(() -> corpRTSUndInsesDs.refresh());
            } else {
                showNotification("Please select a row to update", NotificationType.HUMANIZED);
                return false; // This makes the action not continue
            }
        });

}

This should work for modifying the EditAction with a before handler. You need to make sure the bad path returns false so that the EditAction doesn’t continue. Hope this helps!

Vincent

1 Like

Perfect. It worked. But the only thing is every time its incrementing the number irrespect of saving the record or not.

Did this problem occur with the additional button?

With the both button (additional & Edit). Actually its about this line :

newGrsIndusIns.setOrder((int) unService.getNextNumber(grsIndusIns.getType()));

I have used Unique Number service to auto increment one field (order) but the problem is if i just edit the record and do not save but cancel edit screen , in this case also the order number is incremented for next time.

So, what you can do is in the Edit Controller that is being used you can override the preClose method and do a check to see if the window is being closed rather than committed. If it is being closed, then you can reset the number. Something like:

    @Override
    protected boolean preClose(String actionId)
    {
        if ("windowClose".equalsIgnoreCase(actionId))
        {
            unService.setCurrentNumber = unService.getCurrentNumber - 1;
        }

        return Boolean.TRUE;
    }

I believe this will work given my reading of Sequence Generation - CUBA Platform. Developer’s Manual but you may have to play with it to get it to work correctly.

Hi @vsposato5370,

Above logic is working great for Edit Action but can I implement same on Create Button Action?
In this case I want to make “Type” field as dropdown and while selecting any record from “Type” field, “Order” field should automatic Increase in numbers(Unique Service).

Capture

@saurabh60292,
I don’t think I understand what you are trying to accomplish. The screen you show looks like an EditScreen which means the CreateButton wouldn’t exist in that context.

 To answer your question, yes you can modify the CreateAction the same way you did with the EditAction with either BeforeActionPerformHandler or AfterActionPerformHandler. It just depends on where the logic you want to happen needs to occur in the Lifecycle.

Vincent

@vsposato5370,

sorry If I did not make it clear understanding.

Actually this (below) is my browse screen:

Capture1

and this is my edit screen:

Capture

And I want the “Type” field in Edit screen to look like dropdown which should contain “Type” record from the browse screen.

And after selecting any record from “Type” field in Edit screen, The “Order” field should auto increment.

@saurabh60292,
So is the Type field an Entity? Normally, if this is an association or composition then the field would automatically become the dropdown. I don’t know if your project is proprietary or not, but it might help if I can see the bigger picture with an example project or the real project - either one. I just don’t seem to be grasping what you are attempting to do.

Vincent

no its not an Entity, as you can see in the below image from the Data Model, “Type” field is of string type.
Capture

Even I tried it to change into Association but I got an error , see below:

error2

But I got this error.

error1

I dont Know how can I make this “type” field as dropdown in a proper manner.

Below are Datasource from browse and Edit screen:

BROWSE DATASOURCE:
browseDs

EDIT DATASOURCE:
EditDs

What I would suggest, is make an Entity named something like UndInsType and have it just have an ID and a String name. You then associate it to that spot in the CorpRTSUndIns entity and allow it to lookup and open in the field definition in the parent. You can pre-populate this entity with the majority of the options you expect, but if someone needs to add one then they do the magnifying glass and Create on the lookup screen. This ensures that similar things are identified as such, and it will prevent typos and the like from messing anything up.

The other option you have, and I don’t know that I would recommend it, would be to build a method that pulls a listing of distinct Types that have been used before and make that the optionsDatasource for the Type field and manually configure that field as a SuggestionField (or whichever of those fields makes the most sense) with the result saved to the underlying entity type. There are definitely some pitfalls here, and I have not done this so I would have to let the larger CUBA folks help with this path.

I think those are the 2 options for that. As far as incrementing the Order when they select a Type, that should happen on save - so you could use a PreCommit handler in the Controller of your edit screen to increment the value if necessary but only on Commit of a new entity.

Hope this helps!

Thank You for your suggestion. Lookup field issue is ok now.But how can I make listener so that it can change the “Order” field auto increment? Below previous code I used in edit screen if you remember. I think this code need to be change in order to make listener.

@Named("corpRTSUndInsesTable.edit")
private EditAction corpRTSUndInsesEdit;

@Override
public void init(Map<String, Object> params) {
        this.corpRTSUndInsesEdit.setBeforeActionPerformedHandler(() -> {
            CorpRTSUndIns grsIndusIns = corpRTSUndInsesTable.getSingleSelected();

            if (grsIndusIns != null) {
                CorpRTSUndIns newGrsIndusIns = metadata.create(CorpRTSUndIns.class);
                newGrsIndusIns.setOrder((int) unService.getNextNumber(grsIndusIns.getType()));

                openEditor(newGrsIndusIns, WindowManager.OpenType.THIS_TAB).addCloseWithCommitListener(() -> corpRTSUndInsesDs.refresh());
            } else {
                showNotification("Please select a row to update", NotificationType.HUMANIZED);
                
            }
             return false; // This makes the action not continue
        });
}

When should the Order number be incremented? Do you want it to increment at the start or at the end of the process? If you do it at the start, then you have decrement the value if you don’t end up saving. Where would it make sense for your application?

Whenever the user pick any value from the lookupfield (“Type Field”), the Order number should automatically generate. Also in case if user dont save the record it should remain constant and do not increment.

So, I think the easiest way to do this - and again I am not 100% sure I understand the full use case - would be to add a value change listener to the LookupField. You can increment the order on that listener event. Here is a stab at it…

@Named("fieldGroup.type") // This is the name of the FieldGroup that holds your fields and the id of the underlying field.
protected LookupField typeLookupField;

@Override
public void init(Map<String, Object> params) {
      this.typeLookupField..addValueChangeListener(e -> {
           CorpRTSUndIns grsIndusIns = getItem();
           grsIndusIns.setOrder((int) unService.getNextNumber(grsIndusIns.getType()));
      });
}

You will probably still need to do the preClose listener to decrement the service if it is canceled. I hope this helps.

1 Like

Perfect, Your suggestions are really working for me :slight_smile:
Now I am able to auto generate everything perfectly with below code:

@Inject
private UniqueNumbersService unService;

@Named("fieldGroup.typeId") 
protected WebPickerField typeIdLookupField;

@Override
public void init(Map<String, Object> params) {
      this.typeIdLookupField.addValueChangeListener(e -> {
           CorpRTSUndIns corpRTSUndIns = getItem();
           corpRTSUndIns.setType(corpRTSUndIns.getTypeId().getRestictionType());
           corpRTSUndIns.setOrder((int) unService.getNextNumber(corpRTSUndIns.getTypeId().getRestictionType().replaceAll(" ", "").replaceAll("/", "")));
      });
}

As you can see in below screenshot, I am generating two fields based on “TypeId” field which is my WebPickerField.

RestType

Now only challenge is how to preClose listener to decrement the service if it is canceled.
I have seen this topic Entity Listener but couldn’t reach on any conclusion how to do it. Sorry for loose my hand on java.

Thank you again!

Regards,
Saurabh

I actually provided this code in my earlier responses.

@Override
    protected boolean preClose(String actionId)
    {
        if ("windowClose".equalsIgnoreCase(actionId))
        {
            unService.setCurrentNumber = unService.getCurrentNumber - 1;
        }

        return Boolean.TRUE;
    }

This goes into your EditController. It’s not a listener - it’s a lifecycle event that every screen goes through. You want to check that the window is not closing as part of a commit but rather is a straight close - which is what the If statement does. You return true so that the close continues.

so where this code fits in my controller. I tried below one but its saying

setCurrentNumber cannot be resolved or is not a field

code:

	@Inject
	private UniqueNumbersService unService;
	
	@Named("fieldGroup.typeId") 
	protected WebPickerField typeIdLookupField;

	@Override
	public void init(Map<String, Object> params) {
	      this.typeIdLookupField.addValueChangeListener(e -> {
	           CorpRTSUndIns corpRTSUndIns = getItem();
	           corpRTSUndIns.setType(corpRTSUndIns.getTypeId().getRestictionType());
	           corpRTSUndIns.setOrder((int) unService.getNextNumber(corpRTSUndIns.getTypeId().getRestictionType().replaceAll(" ", "").replaceAll("/", "")));
	          
	      });
	
	}
	
	@Override
    protected boolean preClose(String actionId)
    {
        if ("windowClose".equalsIgnoreCase(actionId))
        {
            unService.setCurrentNumber = unService.getCurrentNumber - 1;
        }

        return Boolean.TRUE;
    }

Ok, 2 things are wrong here. First, you probably should use the UniqueNumbersAPI rather than UniqueNumbersService, so that you have access to the method I am referencing. The other thing is, I apparently had a slip up in my code, so here is what it will look like after the change.

@Inject
	private UniqueNumbersAPI unService;
	
	@Named("fieldGroup.typeId") 
	protected WebPickerField typeIdLookupField;

	@Override
	public void init(Map<String, Object> params) {
	      this.typeIdLookupField.addValueChangeListener(e -> {
	           CorpRTSUndIns corpRTSUndIns = getItem();
	           corpRTSUndIns.setType(corpRTSUndIns.getTypeId().getRestictionType());
	           corpRTSUndIns.setOrder((int) unService.getNextNumber(corpRTSUndIns.getTypeId().getRestictionType().replaceAll(" ", "").replaceAll("/", "")));
	          
	      });
	
	}
	
	@Override
    protected boolean preClose(String actionId)
    {
        if ("windowClose".equalsIgnoreCase(actionId))
        {
            unService.setCurrentNumber(unService.getCurrentNumber - 1);
        }

        return Boolean.TRUE;
    }

setCurrentNumber isn’t a property, but a method - so it should have been called as such - my bad! See if that works for you.