Editing clients
With an existing client now located and loaded from the database, we need a mechanism to be able to view and edit the data. Let’s prepare by first creating the context commands we will use in the edit view. Repeat the steps we took for the Find Client View and in CommandController, add a new list of commands named editClientViewContextCommands, along with an accessor method and Q_PROPERTY.
Create a new slot to be called when the user saves their changes on the edit view:
void CommandController::onEditClientSaveExecuted() { qDebug() << "You executed the Save command!"; }
Add a new save command to the list that calls the slot when executed:
Command* editClientSaveCommand = new Command( commandController, QChar( 0xf0c7 ), "Save" ); QObject::connect( editClientSaveCommand, &Command::executed, commandController, &CommandController::onEditClientSaveExecuted ); editClientViewContextCommands.append( editClientSaveCommand );
We now have a list of commands we can present to the Edit Client View; however, a challenge that we now need to overcome is that when we execute this command, the CommandController has no idea which client instance it needs to work with. We can’t pass in the selected client as a dependency to the constructor like we do with the new client, because we have no idea which client the user will select. One option would be to move the list of edit commands out of the CommandController and into the client model. Then, each client instance can present its own commands to the UI. However, this means that command functionality is fractured, and we lose the nice encapsulation that the command controller gives us. It also bloats the client model with functionality it shouldn’t care about. Instead, we will add the currently selected client as a member within CommandController and set it whenever the user navigates to the editClientView. In CommandController::Implementation, add the following:
Client* selectedClient{nullptr};
Add a new public slot:
void CommandController::setSelectedClient(cm::models::Client* client) { implementation->selectedClient = client; }
Now that we have the selected client available, we can go ahead and complete the implementation of the save slot. Again, we’ve already done the hard work in the DatabaseController and client classes, so this method is really straightforward:
void CommandController::onEditClientSaveExecuted() { qDebug() << "You executed the Save command!";
implementation->databaseController->updateRow(implementation->selectedClient->key(), implementation->selectedClient->id(), implementation->selectedClient->toJson());
qDebug() << "Updated client saved."; }
From the UI point of view, editing an existing client will essentially be the same as creating a new client. So much so, in fact, that we can even probably use the same view and just pass in a different client object in each case. However, we’ll keep the two functions separate and just copy and tweak the QML we’ve already written for creating a client. Update EditClientView:
import QtQuick 2.9 import QtQuick.Controls 2.2 import CM 1.0 import assets 1.0 import components 1.0
Item { property Client selectedClient Component.onCompleted: masterController.ui_commandController.setSelectedClient(selectedClient)
Rectangle { anchors.fill: parent color: Style.colourBackground }
ScrollView { id: scrollView anchors { left: parent.left right: parent.right top: parent.top bottom: commandBar. top margins: Style.sizeScreenMargin } clip: true
Column { spacing: Style.sizeScreenMargin width: scrollView.width
Panel { headerText: "Client Details" contentComponent: Column { spacing: Style.sizeControlSpacing StringEditorSingleLine { stringDecorator:
selectedClient.ui_reference anchors { left: parent.left right: parent.right } } StringEditorSingleLine { stringDecorator: selectedClient.ui_name anchors { left: parent.left right: parent.right } } } }
AddressEditor { address: selectedClient.ui_supplyAddress headerText: "Supply Address" }
AddressEditor { address: selectedClient.ui_billingAddress headerText: "Billing Address" } } }
CommandBar { id: commandBar commandList: masterController.ui_commandController.ui_editClientViewContextCommands } }
We change the client property to match the selectedClient property MasterView sets in the Connections element. We use the Component.onCompleted slot to call through to CommandController and set the currently selected client. Finally, we update CommandBar to reference the new context command list we just added.
Build and run, and you should now be able to make changes to a selected client and use the Save button to update the database.