Overview
Widget Lookup
Widget colonna per relazioni (lookupByID, multiple_check) con tab dedicato Lookup nel metadata-editor colonne.
Esempi
- Pattern 3c — lookup puro-OData (State/Province da `/odata/Stateprovinces`) — dimostra
mc_props_bag.lookup.endpointcon providerodatae rendering inline via$expand.
Quando usarlo
- selezione record correlati da tabella metadata esterna.
- scenari con ricerca lato server e paging lookup.
- supporto singola selezione (
lookupByID) e multi selezione (multiple_check).
Proprieta metadata colonna (tab Lookup)
mc_ui_lookup_entity_name: route metadata sorgente lookup.mc_ui_lookup_dataValueField: campo ID restituito.mc_ui_lookup_dataTextField: campo descrizione mostrata.mc_ui_lookup_computed_dataTextField: espressione SQL per il testo mostrato (override dimc_ui_lookup_dataTextField). Referenzia i campi della tabella correlata con l'alias di join<colonna>_<entity>, es.UPPER([StateProvinceID_stateprovinces].[StateProvinceName]). Via chatbot l'alias si ottiene conrequest_metadata_detail{detail:'lookup_columns'}.mc_ui_lookup_filter: filtro base lookup.mc_serverside_operations: ricerca/paging server-side.mc_ui_pagesize: dimensione pagina risultati lookup.mc_ui_lookup_edit_allow: abilita edit record lookup da popup.mc_ui_lookup_insert_allow: abilita inserimento record lookup da popup.mc_ui_lookup_search_grid: abilita griglia di ricerca nel popup.mc_logic_allow_navigation: navigazione su route collegata.
mc_props_bag utile
{
"lookup": {
"filter": {
"logic": "AND",
"filters": [
{ "field": "is_active", "operatore": "eq", "value": true }
]lookup.filter: vincolo aggiuntivo lato client/server nella query lookup.lookup.virtualize: abilita virtual scroll sup-autocompletedel widget lookup.lookup.virtualize.enabled: parser tollerante (true/false,1/0, stringhe equivalenti); defaultfalsequando assente.lookup.virtualize.itemSize: altezza riga virtuale in px; default44.lookup.endpoint: override provider dati del dropdown. Quando settato, il nested datasource del lookup-editor non passa piu' dal combo endpoint metadata (MetaService.getFlatRecordComboData) ma direttamente dal provider dichiarato intypecon la URL inuri.lookup.endpoint.type:'odata'(dispatcher instrada aDataProviderOdataService.selectComboche emette GET con$top,$count=true,$select=valueField,textFielde$filter=contains(textField,'<query>')per la server-side search). Altri valori seguono la stessa logica del table-levelextraProps.endpoint.type.lookup.endpoint.uri: URL base dell'entity set (es./odata/<EntitySet>), con o senza origine esplicita. Query params esistenti vengono ignorati — il provider ricostruisce i params ad ogni fetch.form.columns: larghezza campo nel form edit.style.editCss: stile custom editor.
Combo slim — campi extra via mc_props_bag.slimCombo
Il dropdown lookup di default fa un SELECT minimale sulla tabella correlata: PK + mc_ui_lookup_dataValueField + mc_ui_lookup_dataTextField. Riduce il payload del combo. Se il client ha bisogno di altri campi della tabella correlata — tipicamente per pre-popolare colonne dipendenti via mc_selection_changed_custom_function__fn — si usa mc_props_bag.slimCombo come array di nomi colonna extra da includere nel SELECT del combo:
{
"slimCombo": ["unita_misura_id","codice_iva_id","prezzo_vendita","sconto_default"]
}- Array: i nomi vengono aggiunti al
columnRestrictionListdel combo response (logica inDataProviderMetaService.buildSlimComboRestriction). slimCombo: false: disabilita la restrizione → il combo ritorna tutte le colonne. Utile in debug, payload piu' grande.- Se la colonna ha
mc_ui_lookup_combo_text_edit_computed_dataTextFieldvalorizzato (formula display computata),slimComboviene ignorato e il combo ritorna tutte le colonne (la formula puo' referenziare campi arbitrari).
I campi extra finiscono in record['<col>__lookup_obj'].value (record pieno della tabella correlata, gia' completo dei campi dichiarati in slimCombo) e sono accessibili dal callback mc_selection_changed_custom_function__fn:
prodCol.mc_selection_changed_custom_function__fn = (record, _f, _m, newValue) => {
const prod = record['prodotto_id__lookup_obj']?.value;
if (!prod) return;
record['descrizione']?.next(prod.descrizione);
record['prezzo_unitario']?.next(prod.prezzo_vendita);
record['unita_misura_id']?.next(prod.unita_misura_id);
record['codice_iva_id']?.next(prod.codice_iva_id);Tradeoff: payload combo leggermente piu' grande ma niente HTTP roundtrip aggiuntivo (getFlatRecordData per recuperare il record pieno per id) ad ogni selezione.
Workflow Assistito: Clone Lookup + Filtro Default + Lookup Hierarchy
- Flusso operativo inline:
suggestLookup2 -> suggestLookupDefaultFilter -> getLookupListByRoute -> getSeletClauseByLookupHierarchy. - Snippet inline campi principali:
mc_ui_lookup_entity_name,mc_ui_lookup_dataValueField,mc_ui_lookup_dataTextField,mc_ui_lookup_filter. - Snippet inline filtro rapido:
lookup.filter: {"logic":"AND","filters":[{"field":"is_active","operatore":"eq","value":true}]}. - Effetto client: setup lookup accelerato nel metadata-editor e filtro coerente gia pronto nel widget.
- Effetto server: query lookup e select clause restano allineate agli endpoint
MetaService.*senza mapping manuale.
Checklist operativa rapida:
1. clonare configurazione base con suggestLookup2;
2. generare filtro default con suggestLookupDefaultFilter;
3. rifinire gerarchia/select clause dal tree lookup;
4. validare in runtime che ricerca e value/text mapping siano coerenti.
Effetti Client/Server
- Client: rendering widget lookup, search, etichetta/value binding.
- Client: con
lookup.virtualizeattivo, l'autocomplete renderizza solo il subset visuale delle opzioni. - Server: query lookup paginata/filtrata tramite
MetaService.getFlatRecordData.
Note operative
- in
multiple_checkla parte lookup resta la stessa, cambia il renderer multi valore. - se manca
mc_ui_lookup_entity_name, il widget non puo risolvere la sorgente.
Auto-fetch su FK programmatici
Il wuic-lookup-editor sottoscrive automaticamente al BehaviorSubject di record[mc_nome_colonna] e gestisce i cambi di FK programmatici (es. import documento sorgente, callback custom che setta record.cliente_id.next(99)):
- Se il nuovo valore e' gia' presente in `items` (la pagina caricata della lookup): popola solo
__lookup_objper coerenza, niente HTTP. - Se il nuovo valore non e' negli items (es. valore fuori dalla pagina corrente del combo, o non ancora fetchato): scatta una second-stage fetch filtrata
WHERE <valueField> eqor <newValue>per recuperare il record correlato e popolare automaticamente il dropdown.
Skip cases (no-op):
- Lookup multi-value (
isFilterconeqor,multiple_check) - Prima emit del BS (gia' coperto dal flow init)
- Valore null/undefined (utente ha clearato)
hasActiveLookupQuery=true(utente sta typing una query manuale)
Implicazione per i custom form: settare solo il FK basta — non servono piu' workaround manuali per popolare __lookup_obj o l'alias joined. Il display del dropdown si aggiorna da solo.
// PRIMA (workaround manuale richiesto)
record.cliente_id.next(99);
record.cliente_id__lookup_obj.next({ id: 99, ragione_sociale: 'Acme S.r.l.' });
record['clienti___ragione_sociale__cliente_id'].next('Acme S.r.l.');
// ORA (auto-fetch del lookup-editor)
record.cliente_id.next(99);> Nota: l'auto-fetch fired solo quando il <wuic-lookup-editor> e' montato (cella in edit mode). Per il display in lista (cella read-only), formatGridViewValue legge l'alias joined <route>___<textField>__<col> direttamente dal record — quello va comunque popolato manualmente se non viene dal backend.
Screenshot
