2.5. Step 5 - Implement client side customer list

It's time now to get something working visually, so we start to add a first simple interface to our wolfclient.

For this we need the 'Qt designer'. We open the file ~/tutorial/client/init.ui again draw a single button with the text "Customer List":

We add a dynamic property 'form' of type String to this button, which has the value 'customers':

When we save the form and start the wolfclient, we get (after logging in) the first page with the "Customer List" button. Pressing it gives the error message:

This means we have to define a new form ~/tutorial/client/customers.ui, which will show the list of customers, for now we leave it empty. When we start the wolfclient and press the "Customer List" button again, we see that the form gets changed to the "customer" form (empty).

We add now a QTreeWidget item to the customer.ui form and choose a grid layout for the whole form. We change the name of the widget to 'customer':

We also disable the 'rootIsDecorated' tick (we have a list, not a tree of customers). We also set 'selectionMode' to 'SingleSelection' and 'selectionBehaviour' to 'selectRows' to get the default expected behaviour of a list.

Now we change the columns of the list (context menu "Edit items" in the widget data area):

We can now open the wolfclient and press the button and the customer list is loaded. But it's empty, we have first to fill it with data of our customers.

So we add a string property 'action' to the widget 'customer' containing the following value:

CustomerListRequest customer { }

We define the 'action' to be executed, when the form is loaded. In our case we want to execute a 'CustomerListRequest'. The root element of the request should be 'customer'. We currently don't want to pass any additional elements, so we specify '{ }' for the empty content:

When we reexecute the wolfclient still nothing happens. So we enable the 'Developer Mode' in the settings in the tab 'Developer'. Then we see that the XML request has been constructed:

We see that the request was ok but that the answer has errors:

The reason for this is, we have to tell the client how to map the elements of the result structure in the XML back to widgets and properties of the widgets.

We want to map the following XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <name>Dr Who</name>
        <address>Blue Police Box</address>
        <name>John Smith</name>
        <address>The Wheel in Space</address>


We reference the root element and the tag and attribute values into the properties of the list widget 'customer' (in our case the rows called 'name' and 'address'). This addressing schema belongs into the dynamic property 'answer' similar to the 'action' property:

CustomerList list {
    customer[] {

The line breaks and indentation are optional and you can write the mapping in a single line. The '?' is used for elements in the XML we don't need at the moment. 'row' is a property of the QTreeWidget widget named 'customer' and iterates through all rows in the list. Each row has sub-properties 'name' and 'address' which represent the corresponding column:

When we reexecute the wolfclient and click on the customer list we see that the customer list is shown as expected:

But when we look at the contents of the debug window we still see an error reported:

For simplicity we defined the output with the document meta data attribute '{ standalone = "yes" }' that the returned document should not be built with an explicit document type definition. But the client expects a document type declaration. For this we change the definition in the file tutorial.dmap we created in step 4 in the following way:

COMMAND CustomerListRequest
    CALL SelectCustomerList
    RETURN SKIP CustomerList {root="list"};

The directive 'RETURN SKIP CustomerList {root="list"}' states that a document of type 'CustomerList' with the root element 'list' is returned without validation of the output. We omit a validation on purpose for now to get to the next step.