0

Given two CheckboxCell's checkboxA and checkboxB, how can I programmatically uncheck checkboxB if checkboxA is unchecked? From what I've tried, I'm able to set the value of checkboxB = false when checkboxA = false, but this change is not being reflected in the UI.

My table with the checkboxes -

public void buildTable() {
    myDataProvider.addDataDisplay(myTable);

    // other columns

    Column<Note, Boolean> checkboxA = new Column<Note, Boolean>(new CheckboxCell()){

        @Override
        public Boolean getValue(Note object) {
            return object.isAChecked();
        }

    };

    checkboxA.setFieldUpdater(new FieldUpdater<Note, Boolean>() {

        @Override
        public void update(int index, Note object, Boolean value) {
            performCheckboxAOperation(object, value);
        }
    });

    Column<Note, Boolean> checkboxB = new Column<Note, Boolean>(new CheckboxCell()){

        @Override
        public Boolean getValue(Note object) {
            return object.isBChecked();
        }

    };

    checkboxB.setFieldUpdater(new FieldUpdater<Note, Boolean>() {

        @Override
        public void update(int index, Note object, Boolean value) {
            performCheckboxBOperation(object, value);
        }
    });

    myTable.addColumn(checkboxA, "BOX A");
    myTable.addColumn(checkboxB, "BOX B");
}

Method to store checkbox A's value in the DB, and if checkboxA == false, also set checkboxB = false in the DB -

public void performCheckboxAOperation(Note note, Boolean bool) {
    this.presenter.performBoxOperation(note, bool, new AsyncCallback<CNote>() {

        @Override
        public void onFailure(Throwable caught) {
            // error logic
        }

        @Override
        public void onSuccess(CompanyNote result) {
            cleanupDataProvider.flush();

            if (result.isAChecked() == false) {
                if (result.isBChecked() == true) {
                    unsetB(result);
                }
            }
        }
    });
}

This is my method to unset checkboxB which is changing the value in the DB but not in the UI -

private void unsetB(Note note) {
    this.presenter.performBoxOperation(note, false, new AsyncCallback<Note>() {

        @Override
        public void onFailure(Throwable caught) {
            // error logic
        }

        @Override
        public void onSuccess(Note result) {
            myDataProvider.flush();
            myTable.redraw();
        }
    });
}

From what I understand, ListDataProvider needs to be flushed for the changes to be reflected in the UI. This has worked very well for all the other fields in the table, but it is not working with CheckboxCells.

I've already tried to redraw() the table as can be seen above but without any luck.

So what should I be doing to trigger a UI change in another CheckboxCell when one CheckboxCell is clicked?

Anish Sana
  • 518
  • 1
  • 12
  • 30

1 Answers1

1

I think that you forgot to actually change the object's value.

private void unsetB(final Note note) {
    this.presenter.performBoxOperation(note, false, new AsyncCallback<Note>() {
        // ...
        @Override
        public void onSuccess(Note result) {
            note.setB(false);  // set B value or copy `result` to `note`
                               // (`note` must be final)
            myDataProvider.flush();
            myTable.redraw();
        }
    });
}

Also, in performCheckboxAOperation you call unsetB(result); - it should be unsetB(note);

You need to understand that in onSuccess you get a copy of Note. The result object is not in the DataProvider, note is. And you should change note's value.

Adam
  • 5,403
  • 6
  • 31
  • 38
  • I am changing the object's value. As stated above, `this.presenter.performBoxOperation(note, false, new AsyncCallback()`, sets the object's value to `false` on the server, stores it in the DB, and then returns `Note` with the change. When I step-through `myDataProvider` inside `onSuccess()`, I can see that `checkboxB = false`. So the value is being changed but not being reflected in the UI by unchecking the checkbox, even after flushing the data provider and redrawing the table. I tried making `note` final and calling `unsetB(note)`, which weirdly worked once and then never again. – Anish Sana May 30 '18 at 15:53
  • 1
    Whenever you send an object to/from the server it is serialized and deserialized, which simply means that you make a _copy_ of that object. So you take an object, make a copy and update a copy, – Adam May 30 '18 at 16:13
  • Thanks for this. Your answer and the comment helped me debug the issue. I had to replace the `'note` in `myDataProvider` with `result` and then `flush()` for the changed to get reflected. So, `myDataProvider.getList().set(myDataProvider.getList().indexOf(note), result); myDataProvider.flush();`. – Anish Sana May 30 '18 at 16:46