Technical solutions and general life savers

Managing buttons within a control interface

It sounds trivial, but have you ever found yourself clicking on a button at the bottom of an administrative panel to delete an item while nothing was selected inside a grid or list, presenting you with a ‘nice’ exception.

Why does this happen? The answer is probably: that the most forward way to make button states work, is to manually disable buttons for different actions.

Note: All code are orginall written in Javascript for ExtJs 3.4, but if you can read it are easily transferable to other programming languages.

1

2

3

4

5

6

DeleteItem:function(){

varselectedRec=this.grid.getSelectionModel().getSelected();

this.stores.items.remove(selectedRec);

this.deleteButton.disable();

this.editbutton.disabled();

}

Consider the following case.

You have a grid with items that can be deleted and edited.

You can always add something.

When you delete something, nothing is selected afterward. So edit and delete should be disabled.

Now there are multiple cases this will break when you manage button states with every action.

You add another button, move for example.You have to add the disable to the end of edit and delete function.

Items get states where they can’t be either deleted or edited.The logic of this will be scattered.

An item can be deselected by a refresh called from numerous functions.Again scattering logic and leaving room for errors.

You get the idea.

Interfaces like this have lot’s of states ending in an even larger list of actions that a possible. So what IS a good way to do this? In my personal opinion it’s best to fit all state information into ONE function.

Why?

Because you want the logic to be in one place.

You can call this function as often you want, so if you are unsure about states. Call it.

When it is done, it is guaranteed to be valid because it doesn’t care which function just got executed.

When you add a new state or button you only have to add a little logic to this function and don’t have to bother to check all the other places the state could change in a way unintended.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

DeleteItem:function(){

varselectedRec=this.grid.getSelectionModel().getSelected();

this.stores.items.remove(selectedRec);

this.ManageButtons();

},

ManageButtons:function(){

varhasSelection=this.grid.getSelectionModel().hasSelection();

if(hasSelection){

this.deleteButton.disable();

this.editbutton.disabled();

}else{

this.deleteButton.enabled();

this.editbutton.enabled();

}

}

Last consideration

Yes, it creates some overhead. It will run checks that ‘could’ be unnecessary because part of the buttons only change ‘sometimes’.

That are a lot of ifs. Furthermore checking for states is not that expensive. That is unless you need to loop a whole lot of items to find out if something is true. Which would be a good thing to cache or split off so you only check it when necessary.

You could consider making logical groups that you pass as parameters for things to check during the manageButtons call. But I have not experimented with that yet.