|
| 1 | +--- |
| 2 | +outline: [2, 4] |
| 3 | +--- |
| 4 | +# Filter, Search and Table |
| 5 | + |
| 6 | +The closest UI5 cousin of an ALV report: a table with a search field and one or two filter dropdowns above it. The user types, picks filters, the list narrows. |
| 7 | + |
| 8 | +The split of work is simple — UI5 takes the input, ABAP does the filtering. Each filter change fires a backend event, the handler re-runs the `SELECT` (or filters the in-memory table), and the table re-renders. |
| 9 | + |
| 10 | +#### Step 1 — The bare table |
| 11 | + |
| 12 | +Start with the result table. No filters yet — just bind the data and show columns. This is the [tables](../model/tables.md) pattern unchanged: |
| 13 | + |
| 14 | +```abap |
| 15 | +DATA(view) = z2ui5_cl_xml_view=>factory( )->page( `Sales Orders` ). |
| 16 | +DATA(tab) = view->table( client->_bind( mt_orders ) growing = abap_true ). |
| 17 | +tab->columns( )->column( )->text( `Order` )->get_parent( |
| 18 | + )->column( )->text( `Customer` )->get_parent( |
| 19 | + )->column( )->text( `Value` ). |
| 20 | +tab->items( )->column_list_item( )->cells( |
| 21 | + )->text( `{VBELN}` )->text( `{KUNNR}` )->text( `{NETWR}` ). |
| 22 | +``` |
| 23 | + |
| 24 | +#### Step 2 — A search field in the toolbar |
| 25 | + |
| 26 | +Add a header toolbar to the table with a `search_field`. Bind its `value` two-way to a filter string and fire `SEARCH` on enter or button click. The `liveChange` event would fire on every keystroke — usually too chatty for a backend roundtrip: |
| 27 | + |
| 28 | +```abap |
| 29 | +DATA(tab) = view->table( client->_bind( mt_orders ) growing = abap_true ). |
| 30 | +tab->header_toolbar( )->overflow_toolbar( |
| 31 | + )->title( `Sales Orders` |
| 32 | + )->toolbar_spacer( ) |
| 33 | + )->search_field( |
| 34 | + value = client->_bind_edit( mv_search ) |
| 35 | + width = `20rem` |
| 36 | + search = client->_event( `SEARCH` ) ). |
| 37 | +``` |
| 38 | + |
| 39 | +#### Step 3 — A filter dropdown |
| 40 | + |
| 41 | +Add a `select` next to the search field for typed filtering — sales organisation, status, type — anything with a small fixed set of values. A `change` event makes it re-filter immediately, without a separate apply button: |
| 42 | + |
| 43 | +```abap |
| 44 | +tab->header_toolbar( )->overflow_toolbar( |
| 45 | + )->title( `Sales Orders` |
| 46 | + )->toolbar_spacer( ) |
| 47 | + )->label( `Org:` ) |
| 48 | + )->select( |
| 49 | + selectedkey = client->_bind_edit( mv_org ) |
| 50 | + change = client->_event( `APPLY_FILTER` ) |
| 51 | + )->items( )->core_item( key = `` text = `All` |
| 52 | + )->core_item( key = `1000` text = `Germany` |
| 53 | + )->core_item( key = `2000` text = `France` )->get_parent( |
| 54 | + )->search_field( |
| 55 | + value = client->_bind_edit( mv_search ) |
| 56 | + width = `20rem` |
| 57 | + search = client->_event( `APPLY_FILTER` ) ). |
| 58 | +``` |
| 59 | + |
| 60 | +#### Step 4 — Apply the filter in ABAP |
| 61 | + |
| 62 | +One event handler covers both filter sources. Use a clean re-`SELECT` for small datasets, or — when the source is already in memory — filter with `FILTER` / `DELETE … WHERE`: |
| 63 | + |
| 64 | +```abap |
| 65 | +WHEN client->check_on_event( `APPLY_FILTER` ). |
| 66 | + SELECT FROM vbak |
| 67 | + FIELDS vbeln, kunnr, netwr, vkorg |
| 68 | + WHERE ( @mv_org = '' OR vkorg = @mv_org ) |
| 69 | + AND ( @mv_search = '' OR vbeln LIKE @( `%` && mv_search && `%` ) |
| 70 | + OR kunnr LIKE @( `%` && mv_search && `%` ) ) |
| 71 | + INTO TABLE @mt_orders |
| 72 | + UP TO 100 ROWS. |
| 73 | + client->view_model_update( ). |
| 74 | +``` |
| 75 | + |
| 76 | +#### Full Example |
| 77 | + |
| 78 | +A complete order list with search and a sales-org filter, both wired to the same event: |
| 79 | + |
| 80 | +```abap |
| 81 | +CLASS z2ui5_cl_sample_filter_table DEFINITION PUBLIC. |
| 82 | +
|
| 83 | + PUBLIC SECTION. |
| 84 | + INTERFACES z2ui5_if_app. |
| 85 | + TYPES: |
| 86 | + BEGIN OF ty_order, |
| 87 | + vbeln TYPE vbak-vbeln, |
| 88 | + kunnr TYPE vbak-kunnr, |
| 89 | + netwr TYPE vbak-netwr, |
| 90 | + vkorg TYPE vbak-vkorg, |
| 91 | + END OF ty_order. |
| 92 | + DATA mt_orders TYPE STANDARD TABLE OF ty_order WITH EMPTY KEY. |
| 93 | + DATA mv_search TYPE string. |
| 94 | + DATA mv_org TYPE vbak-vkorg. |
| 95 | +
|
| 96 | +ENDCLASS. |
| 97 | +
|
| 98 | +CLASS z2ui5_cl_sample_filter_table IMPLEMENTATION. |
| 99 | + METHOD z2ui5_if_app~main. |
| 100 | +
|
| 101 | + CASE abap_true. |
| 102 | +
|
| 103 | + WHEN client->check_on_init( ). |
| 104 | + load_data( ). |
| 105 | + render( ). |
| 106 | +
|
| 107 | + WHEN client->check_on_event( `APPLY_FILTER` ). |
| 108 | + load_data( ). |
| 109 | + client->view_model_update( ). |
| 110 | +
|
| 111 | + ENDCASE. |
| 112 | +
|
| 113 | + ENDMETHOD. |
| 114 | +
|
| 115 | + METHOD load_data. |
| 116 | +
|
| 117 | + SELECT FROM vbak |
| 118 | + FIELDS vbeln, kunnr, netwr, vkorg |
| 119 | + WHERE ( @mv_org = '' OR vkorg = @mv_org ) |
| 120 | + AND ( @mv_search = '' OR vbeln LIKE @( `%` && mv_search && `%` ) |
| 121 | + OR kunnr LIKE @( `%` && mv_search && `%` ) ) |
| 122 | + INTO TABLE @mt_orders |
| 123 | + UP TO 100 ROWS. |
| 124 | +
|
| 125 | + ENDMETHOD. |
| 126 | +
|
| 127 | + METHOD render. |
| 128 | +
|
| 129 | + DATA(view) = z2ui5_cl_xml_view=>factory( )->shell( )->page( `Sales Orders` ). |
| 130 | + DATA(tab) = view->table( client->_bind( mt_orders ) growing = abap_true ). |
| 131 | +
|
| 132 | + tab->header_toolbar( )->overflow_toolbar( |
| 133 | + )->title( `Sales Orders` |
| 134 | + )->toolbar_spacer( ) |
| 135 | + )->label( `Org:` ) |
| 136 | + )->select( |
| 137 | + selectedkey = client->_bind_edit( mv_org ) |
| 138 | + change = client->_event( `APPLY_FILTER` ) |
| 139 | + )->items( )->core_item( key = `` text = `All` |
| 140 | + )->core_item( key = `1000` text = `Germany` |
| 141 | + )->core_item( key = `2000` text = `France` )->get_parent( |
| 142 | + )->search_field( |
| 143 | + value = client->_bind_edit( mv_search ) |
| 144 | + width = `20rem` |
| 145 | + search = client->_event( `APPLY_FILTER` ) ). |
| 146 | +
|
| 147 | + tab->columns( )->column( )->text( `Order` )->get_parent( |
| 148 | + )->column( )->text( `Customer` )->get_parent( |
| 149 | + )->column( )->text( `Value` )->get_parent( |
| 150 | + )->column( )->text( `Org` ). |
| 151 | + tab->items( )->column_list_item( )->cells( |
| 152 | + )->text( `{VBELN}` )->text( `{KUNNR}` )->text( `{NETWR}` )->text( `{VKORG}` ). |
| 153 | +
|
| 154 | + client->view_display( view->stringify( ) ). |
| 155 | +
|
| 156 | + ENDMETHOD. |
| 157 | +
|
| 158 | +ENDCLASS. |
| 159 | +``` |
| 160 | + |
| 161 | +::: tip |
| 162 | +For more advanced patterns — saved filter variants, multi-range selection, fuzzy search — the [layout-variant add-on](https://github.com/abap2UI5-addons) and `Z2UI5_CL_POP_GET_RANGE` (see [Built-In Popups](../popups/built_in.md)) are worth a look. |
| 163 | +::: |
0 commit comments