Tabsheet switching to second tab on loading record

Hello Cuba team,

I’ve got a Tabsheet created for which the tabs need to show conditionally. When loading existing records, it defaults to the second tab. The only place I’m calling setSelectedTab is in onValueChange Events.

This is the screen controller:

package com.company.hermes.web.screens.applicant;

import com.company.hermes.entity.StatesEnum;
import com.company.hermes.entity.WJOfficeLocationEnum;
import com.haulmont.cuba.gui.components.*;
import com.haulmont.cuba.gui.screen.*;
import com.company.hermes.entity.Applicant;

import javax.inject.Inject;
import javax.inject.Named;
import java.util.Collection;
import java.util.Date;

@UiController("hermes_Applicant.edit")
@UiDescriptor("applicant-edit.xml")
@EditedEntityContainer("applicantDc")
@LoadDataBeforeShow
public class ApplicantEdit extends StandardEditor<Applicant> {
    @Inject
    private TextField<String> firstNameField;
    @Inject
    private TextField<String> middleNameField;
    @Inject
    private TextField<String> lastNameField;
    @Inject
    private TextField<String> nameField;
    @Inject
    private TextField<String> interviewProcessNameField;
    @Inject
    private TextField<String> hiringProcessNameField;
    @Inject
    private TextField<String> adminEmployeeNameField;
    @Inject
    private TextField<String> winEmployeeNameField;
    @Inject
    private TextField<String> hrEmployeeNameField;
    @Inject
    private TextField<String> addressField;
    @Inject
    private TextField<String> cityField;
    @Inject
    private LookupField<StatesEnum> stateField;
    @Inject
    private TextField<String> zipField;
    @Inject
    private TextField<String> adminEmployeeAddressField;
    @Inject
    private TextField<String> adminEmployeeCityField;
    @Inject
    private LookupField<StatesEnum> adminEmployeeStateField;
    @Inject
    private TextField<String> adminEmployeeZipField;
    @Inject
    private DateField<Date> dateOfHireField;
    @Inject
    private LookupField<WJOfficeLocationEnum> officeLocationField;
    @Inject
    private TextField<String> officeField;
    @Inject
    private DateField<Date> adminDateOfHireField;
    @Inject
    private LookupField<WJOfficeLocationEnum> adminOfficeLocationField;
    @Inject
    private TextField<String> adminOfficeField;
    @Inject
    private DateField<Date> winDateOfHireField;
    @Inject
    private LookupField<WJOfficeLocationEnum> winOfficeLocationField;
    @Inject
    private TextField<String> winOfficeField;
    @Inject
    private DateField<Date> hrDateOfHireField;
    @Inject
    private LookupField<WJOfficeLocationEnum> hrOfficeLocationField;
    @Inject
    private TextField<String> hrOfficeField;
    @Inject
    private TabSheet applicantTabSheet;
    @Named("applicantTabSheet.newApplicantTab")
    private VBoxLayout newApplicantTab;
    @Named("applicantTabSheet.interviewProcessTab")
    private VBoxLayout interviewProcessTab;
    @Named("applicantTabSheet.hiringProcessTab")
    private VBoxLayout hiringProcessTab;
    @Named("applicantTabSheet.adminChecklistTab")
    private VBoxLayout adminChecklistTab;
    @Named("applicantTabSheet.winChecklistTab")
    private VBoxLayout winChecklistTab;
    @Named("applicantTabSheet.hrChecklistTab")
    private VBoxLayout hrChecklistTab;
    @Inject
    private CheckBox scheduleInterviewNewApplicantField;
    @Inject
    private DateField<Date> dateScheduledNewApplicantField;
    @Inject
    private CheckBox moveToHiringProcessInterviewProcessField;
    @Inject
    private DateField<Date> dateProcessedInterviewProcessField;


    @Subscribe
    public void onInit(InitEvent event) {
        buildTabs();
    }

    @Subscribe("scheduleInterviewNewApplicantField")
    public void onScheduleInterviewNewApplicantFieldValueChange(HasValue.ValueChangeEvent<Boolean> event) {
        buildTabs();
        applicantTabSheet.setSelectedTab("newApplicantTab");
    }

    @Subscribe("dateScheduledNewApplicantField")
    public void onDateScheduledNewApplicantFieldValueChange(HasValue.ValueChangeEvent<Date> event) {
        buildTabs();
        applicantTabSheet.setSelectedTab("newApplicantTab");
    }

    @Subscribe("moveToHiringProcessInterviewProcessField")
    public void onMoveToHiringProcessInterviewProcessFieldValueChange(HasValue.ValueChangeEvent<Boolean> event) {
        buildTabs();
        applicantTabSheet.setSelectedTab("interviewProcessTab");
    }

    @Subscribe("dateProcessedInterviewProcessField")
    public void onDateProcessedInterviewProcessFieldValueChange(HasValue.ValueChangeEvent<Date> event) {
        buildTabs();
        applicantTabSheet.setSelectedTab("interviewProcessTab");
    }

    private void buildTabs() {
        applicantTabSheet.removeAllTabs();
        // New Applicant tab should always be visible.
        applicantTabSheet.addTab("newApplicantTab", newApplicantTab);
        if (scheduleInterviewNewApplicantField.isChecked() && !dateScheduledNewApplicantField.isEmpty()) {
            applicantTabSheet.addTab("interviewProcessTab", interviewProcessTab);
            if (moveToHiringProcessInterviewProcessField.isChecked() && !dateProcessedInterviewProcessField.isEmpty()) {
                applicantTabSheet.addTab("hiringProcessTab", hiringProcessTab);
                applicantTabSheet.addTab("adminChecklistTab", adminChecklistTab);
                applicantTabSheet.addTab("winChecklistTab", winChecklistTab);
                applicantTabSheet.addTab("hrChecklistTab", hrChecklistTab);
            }
        }
    }

    @Subscribe("firstNameField")
    public void onFirstNameFieldValueChange(HasValue.ValueChangeEvent<String> event) {
        buildName();
    }

    @Subscribe("middleNameField")
    public void onMiddleNameFieldValueChange(HasValue.ValueChangeEvent<String> event) {
        buildName();
    }

    @Subscribe("lastNameField")
    public void onLastNameFieldValueChange(HasValue.ValueChangeEvent<String> event) {
        buildName();
    }

    private void buildName() {
        String name = "";
        if (!firstNameField.isEmpty()) {
            name = name.concat(firstNameField.getValue());
            if (!middleNameField.isEmpty() || !lastNameField.isEmpty()) {
                name = name.concat(" ");
            }
        }
        if (!middleNameField.isEmpty()) {
            name = name.concat(middleNameField.getValue());
            if (!lastNameField.isEmpty()) {
                name = name.concat(" ");
            }
        }
        if (!lastNameField.isEmpty()) {
            name = name.concat(lastNameField.getValue());
        }

        nameField.setValue(name);
        interviewProcessNameField.setValue(name);
        hiringProcessNameField.setValue(name);
        adminEmployeeNameField.setValue(name);
        winEmployeeNameField.setValue(name);
        hrEmployeeNameField.setValue(name);
    }

    @Subscribe("addressField")
    public void onAddressFieldValueChange(HasValue.ValueChangeEvent<String> event) {
        adminEmployeeAddressField.setValue(addressField.getValue());
    }

    @Subscribe("cityField")
    public void onCityFieldValueChange(HasValue.ValueChangeEvent<String> event) {
        adminEmployeeCityField.setValue(cityField.getValue());
    }

    @Subscribe("stateField")
    public void onStateFieldValueChange(HasValue.ValueChangeEvent<StatesEnum> event) {
        adminEmployeeStateField.setValue(stateField.getValue());
    }

    @Subscribe("zipField")
    public void onZipFieldValueChange(HasValue.ValueChangeEvent<String> event) {
        adminEmployeeZipField.setValue(zipField.getValue());
    }

    @Subscribe("dateOfHireField")
    public void onDateOfHireFieldValueChange(HasValue.ValueChangeEvent<Date> event) {
        adminDateOfHireField.setValue(dateOfHireField.getValue());
        winDateOfHireField.setValue(dateOfHireField.getValue());
        hrDateOfHireField.setValue(dateOfHireField.getValue());
    }

    @Subscribe("officeLocationField")
    public void onOfficeLocationFieldValueChange(HasValue.ValueChangeEvent<WJOfficeLocationEnum> event) {
        adminOfficeLocationField.setValue(officeLocationField.getValue());
        winOfficeLocationField.setValue(officeLocationField.getValue());
        hrOfficeLocationField.setValue(officeLocationField.getValue());
    }

    @Subscribe("officeField")
    public void onOfficeFieldValueChange(HasValue.ValueChangeEvent<String> event) {
        adminOfficeField.setValue(officeField.getValue());
        winOfficeField.setValue(officeField.getValue());
        hrOfficeField.setValue(officeField.getValue());
    }
}

If I remove the setSelectedTab directive from the onDateProcessedInterviewProcessFieldValueChange event, it loads to the first tab correctly. I haven’t found why this is occurring, but I would appreciate any help in figuring this out.

Thanks in advance,
Adam

I’ve got another example of an onValueChange event triggering upon loading a record in the entity editor:

package com.company.eventchange.web.screens.project;

import com.haulmont.cuba.gui.components.CheckBox;
import com.haulmont.cuba.gui.components.DateField;
import com.haulmont.cuba.gui.components.HasValue;
import com.haulmont.cuba.gui.screen.*;
import com.company.eventchange.entity.Project;

import javax.inject.Inject;
import java.util.Calendar;
import java.util.Date;

@UiController("eventchange_Project.edit")
@UiDescriptor("project-edit.xml")
@EditedEntityContainer("projectDc")
@LoadDataBeforeShow
public class ProjectEdit extends StandardEditor<Project> {
    @Inject
    private CheckBox completeField;
    @Inject
    private DateField<Date> completeDateField;
    @Inject
    private CheckBox sentField;
    @Inject
    private DateField<Date> sentDateField;

    @Subscribe("completeField")
    public void onCompleteFieldValueChange(HasValue.ValueChangeEvent<Boolean> event) {
        if (completeField.isChecked() && completeDateField.isEmpty()) {
            completeDateField.setValue(getTodaysDate());
        } else if (!completeField.isChecked()) {
            completeDateField.setValue(null);
        }
    }

    @Subscribe("sentField")
    public void onSentFieldValueChange(HasValue.ValueChangeEvent<Boolean> event) {
        if (sentField.isChecked() && sentDateField.isEmpty()) {
            sentDateField.setValue(getTodaysDate());
        } else if (!sentField.isChecked()) {
            sentDateField.setValue(null);
        }
    }

    private Date getTodaysDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date today = calendar.getTime();
        return today;
    }
}

If the completeField is checked and the completeDateField is set to another date, loading the record automatically changes the completeDateField to today’s date, but the more worrying part about this is that nothing is being changed. Rather, it’s simply loading the editor screen.

Is there something I’m doing incorrectly that is causing these issues of triggering change events upon loading the editor?

Thanks
Adam

Here is the second small project example.

eventchange.zip (84.3 KB)

Hopefully that worked.

Hi,

ValueChangeEvent is fired after any change of the field, including automatic value assignment during loading of screens.

To distinguish value-change events produced by the user from automatic events, use the isUserOriginated() method:
https://doc.cuba-platform.com/manual-7.2/gui_api.html#gui_api_UserOriginated

1 Like

Thank you for this information. I had no idea they fire intentionally when the screen is built.