Using template: Products list with filters

Introduction:

When we have the need to show products with images, names and prices, in WorkWithPlus we have a template called 'Products list with filters'.

In which we can show a list of products with filters, price ranges, order them from highest to lowest, least to highest and by category.

But the filters are not pre-established to use due to the multiple scenarios that can arise when creating a screen with these characteristics.

That is why in this How To, you will learn how to use the filters of the template 'Products list with filters' when it is based on a transaction.

We will use a transaction called Product, since it is a typical scenario to display with this screen.

ProductsListWithFilters13

 

Setting filters:

 

Preparing transaction

First you must have at least two attributes, price and type of the product, depending on what you want to show, but in this case we will work with a Product transaction.

For the ProductType data type, we need to create an enumerated domain with the following values (you can use whatever you need, this is just an example):

The Values Editor dialog in GeneXus, listing enumerated Name/Description/Value rows All=0, Shoes=1, Bags=2, Sweater=3, with Add, Remove, Edit, Move Up, Move Down, OK, and Cancel buttons, next to the attribute property grid showing the resulting Values string and Combo Box control type.

 

The transaction will look something like this:

Product transaction structure with the ProductType attribute selected. The Properties panel shows it is based on the TypeProduct domain with Value range '0 1 2 3', Control Type Combo Box, and Values All:0,Shoes:1,Bags:2,Sweater:3, annotated with the callout 'Enum Value with value like:'.

 

Orders and Filters

In the template that creates WorkWithPlus by choosing 'Product list with filters', inside TableMain we add the Orders node and within it, two Orders, which we will use to sort the records in ascending and descending order, sorting them by price.

WorkWithPlus Patterns tab showing two Order nodes under Orders, 'Order (Price: Low to High)' and 'Order (Price: Hight to Low)', each containing a ProductPrice Order Attribute with Ascending set to True or False respectively, next to a 'SHOES & BAGS' filter preview with Price and Type controls.

 

To the variable &RangeFilter we change the property Data type: Based On and Domain / Attribute / SDT: TypeProduct.

WorkWithPlus Patterns tab with the RangeFilter variable node selected, its properties showing Data Type 'Based on' the TypeProduct domain, Control Type Radio Button, and Values All:0,Shoes:1,Bags:2,Sweater:3, next to an Extra Small preview of a 'SHOES & BAGS' page with All/Shoes/Bags/Sweater filter buttons.

 

Then you will need to add two filters. One by range and one for attribute only.

We filter the ProductPrice attribute by range and ProductType a filter by attribute as in the following image:

WorkWithPlus Patterns tree with a right-click 'Add' context menu open on the TableMain node, listing options including Attribute, Variable, Table, Grid, FreeStyleGrid, Orders, FilterAttributeRange (highlighted), FilterAttribute, FilterAttributeMultiple, UserAction, StandardAction, and ActionGroup, over a build Output log referencing ProductPrice and ProductType attributes.

 

This will cause WorkWithPlus to automatically generate conditions and create variables based on these attributes that we will use later:

Conditions tab code editor showing WorkWithPlus auto-generated filter conditions: ProductPrice >= &ProductPriceFilter when not IsEmpty(), ProductPrice <= &ProductPriceFilter_To when not IsEmpty(), and ProductType = &ProductType when not IsEmpty(), with a callout reading 'Will generated automatically by WorkWithPlus'.

 

When creating these orders and filters, they will be added on screen, which we do not want, therefore we will hide them.

You look in the WebForm for the name of the table that contains the filters and you can see that the variable &ProductType is also present, we will also hide it.

The GeneXus Web Form designer shows the TestProductFilter web panel with a Shoes_Bags section containing an &RangeFilter combo box, a Price range table with &ProductPriceFilter and &ProductPriceFilter_To fields, and a Type combo box bound to &ProductType. The Properties panel on the right displays the selected TableSplittedFilterTextProductPriceFilter responsive table, with red callouts pointing to the Control Name field and the Type combo box, labeled "Hide this table in Start event" and "Hide this varibale in Start event".

 

Creating Sub's and Events

To hide them, we do it in the Start event with the name of the table of the filter by range and the ProductType variable.

We will also initialize the value of &PriceRange as empty, so that it takes the value of the enumerated 0, therefore it shows all the products and &SortBy with 1, so that it starts in an Ascending way.

The Events tab of the TestProductFilter web panel shows the &RangeFilter.ControlValueChanged event's Start sub-event in GeneXus source code, setting TableSplittedFilterTextProductPriceFilter.Visible and &ProductType.Visible to False, followed by &PriceRange.SetEmpty(), &SortBy = 1, and calls to 'FilterSortBy' and 'FilterPriceRange'. Red callouts label the visibility lines "Table and variable hidden" and the filter initialization lines "Initialize filters".

Here the code:

    TableSplittedFilterTextProductPriceFilter.Visible = False
    &ProductType.Visible = False
    &PriceRange.SetEmpty()
    &SortBy = 1
    Do 'FilterSortBy'
    Do 'FilterPriceRange'

 

You will also notice that he is calling two Sub's,

Do 'FilterSortBy' and Do 'FilterPriceRange'.

We call them so that when initializing the values, it already filters when entering the screen.

We proceed to create the subroutines:

The Events tab shows the 'FilterPriceRange' sub in GeneXus source code, containing a Do Case block that sets &ProductPriceFilter and &ProductPriceFilter_To ranges based on the value of &PriceRange (cases 1 through 5 map to ranges like 0-10, 10-20, 20-30, 30-40, 40-9999), with a default case for &PriceRange.IsEmpty() setting the full range 0-9999, followed by calls to 'SaveGridState' and 'LoadGridState'.

 

Code:

Sub 'FilterPriceRange'

    Do Case
        Case &PriceRange = 1
            &ProductPriceFilter = 0
            &ProductPriceFilter_To = 10

        Case &PriceRange = 2
            &ProductPriceFilter = 10
            &ProductPriceFilter_To = 20

        Case &PriceRange = 3
            &ProductPriceFilter = 20
            &ProductPriceFilter_To = 30

        Case &PriceRange = 4
            &ProductPriceFilter = 30
            &ProductPriceFilter_To = 40

        Case &PriceRange = 5
            &ProductPriceFilter = 40
            &ProductPriceFilter_To = 9999

        Case &PriceRange.IsEmpty()
            &ProductPriceFilter = 0
            &ProductPriceFilter_To = 9999
    EndCase

        Do 'SaveGridState'
        Do 'LoadGridState'

EndSub

 

&RangeFilter.ControlValueChange event, since the template creates it as a RadioButton:

The Events tab shows the &RangeFilter.ControlValueChanged event in GeneXus source code, with a Do Case block assigning &ProductType based on &RangeFilter value: case 1 sets TypeProduct.Shoes, case 2 TypeProduct.Bags, case 3 TypeProduct.Sweater, and the IsEmpty case sets TypeProduct.All, followed by calls to 'SaveGridState' and 'LoadGridState'.

Code:

Event &RangeFilter.ControlValueChanged

    Do Case
        Case &RangeFilter = 1
            &ProductType = TypeProduct.Shoes
        Case &RangeFilter = 2
            &ProductType = TypeProduct.Bags
        Case &RangeFilter = 3
            &ProductType = TypeProduct.Sweater
        Case &RangeFilter.IsEmpty()
            &ProductType = TypeProduct.All
    EndCase
        Do 'SaveGridState'
        Do 'LoadGridState'

EndEvent

 

And the subroutine to filter by the variable &SortBy:

Events code editor showing the Sub 'FilterSortBy' procedure: if &SortBy equals 1 it sets &OrderedBy to 1 (callout 'Ascending'), if it equals 2 it sets &OrderedBy to 2 (callout 'Descending'), followed by defaulting &SortBy to 1 and calling SaveGridState and LoadGridState.

Code:

Sub 'FilterSortBy'

    If &SortBy = 1
        &OrderedBy = 1
    EndIf
    If &SortBy = 2
        &OrderedBy = 2
    EndIf

    If &SortBy < 1
        &SortBy = 1
    EndIF

    Do 'SaveGridState'
    Do 'LoadGridState'

EndSub

Finally, we call the PriceRange and SortBy subroutines in their respective OnOptionClicked event, so that when a value is chosen, it effectively filters it.

Events code editor showing Combo_PriceRange.OnOptionClicked and Combo_SortBy.OnOptionClicked handlers, each converting the selected combo value with FromString and then calling 'Do FilterPriceRange' or 'Do FilterSortBy' respectively, both highlighted in red boxes between WorkWithPlus generated-code comment markers.

The subroutines created by WorkWithPlus:

         Do 'SaveGridState'
         Do 'LoadGridState'

They must be present for you to assign the values of our variables to those created by WorkWithPlus, in this way it uses the conditions created automatically.