cancel
Showing results for 
Search instead for 
Did you mean: 

empty/"all" entry in DropdownBox with OData model - cleanest solution

Former Member
0 Kudos

Hi all,

I'm looking for a way to add an empty option at the top of a dropdown box which is bound to an OData model.

Here's what my basic setup looks like:


var model = new sap.ui.model.odata.ODataModel('/odata/service/sources.xsodata');

var dropdown = new sap.ui.commons.DropdownBox('dropdownBox');

dropdown.setModel(model);

var itemTemplate = new sap.ui.core.ListItem();

itemTemplate.bindProperty('key', 'SOURCE_SHORTFORM');

itemTemplate.bindProperty('text', 'SOURCE_SHORTFORM');

dropdown.bindItems('/sources', itemTemplate);

dropdown.placeAt('content');

This gives me a dropdown box, populated with my "sources" data - so far, so good.

Now, since the dropdown is supposed to be a filter, it needs to have an entry at the top that is empty, or "<all sources>", or something similar. I am working with HANA views, so I could add an actual record to my table or insert it in a calculation view, but I would prefer doing it in the frontend. My opinion is that this is a job that the dropdown's SAPUI5 model should do, not a HANA view.

The following works for my simple example:


model.attachRequestCompleted(null, function() {

     dropdown.insertItem(new sap.ui.core.ListItem({text: '<all>', key: undefined}), 0);

});

So I'm inserting an unbound ListItem directly at the top of the dropdown control's items once the odata request has returned and completed.

The problem here is that this method seems unclean to me, because I am circumventing the model and manipulating the view directly. I imagine there could be errors because the model and the view are not synchronized. Is there a better / cleaner way to do this?

I appreciate any comments that you could give.

Cheers

Christoph

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Christoph,

I thought about your apprach using the insertItem method.

I could imagine that it doesn't make many problems. I think the biggest problem could arise if u are using the TwoWay binding mode, since your are sending data to the server which doesn't belong to the model itself. But I guess you could overcome this problem with using customer exits (stored procedures)  which handles the CRUD-Operations for the model (and in this SP you could hande the "select all / null value item which you added manually)...

In my opinion the "insertItem"-approach is cleaner then the other proposed solutions, at least you are using pure ui5 functionality and no jquery /direct-DOM fiddeling...

What errors/drawback are you actually afraid for?

Greets,

ben

Former Member
0 Kudos

Ben,

thanks again for your thoughts!

I've also given this some more consideration, and I arrived at the same question: What are the actual potential undesirable consequences of what I'm currently doing? For my current case, the answer is "none", as I'm not looking to write back any data, so I really don't need two-way binding.

Still, it just feels a little messy, so I wondered what the "clean" solution looked like (in theory). My understanding of the MVC pattern (and SAPUI5s interpretation thereof) is that the model should be responsible for managing the "all" option. Say you have two different view elements attached to the same model, both should automatically show that option without any further implementation on the view side.

Following this logic, the model should offer functionality to add an "all" option and then manage it internally. When interfacing with the backend, the model would know about the added option and could

a) (re-)add it to its internal data representation after refreshing from the backend

b) leave it out when writing back data to the backend

I'll try to write an extension to the ODataModel that provides this functionality. If I manage to do that, I'll share my results.

Thanks for the discussion!

Christoph

Former Member
0 Kudos

Hi Chris,

thank you too for your input. Since this is a very commonly used (or desired) feature, it's interesting to talk about it.

You say you would the this option to be handled by the model - I'm not sure if this is the correct place to put this in.

In think the model is responsible to handle the "real" data, and maybe not such "pseudo-data" like an "select all" option.

Just a fast thougt about it:

- If you are adding such an option to the model

     a. what would happen to the controls (expcet combo/dropwdown-boxes, where such an entry makes perfect sense) if they are bound to such a model? Just ignore it?

     b. What if you would like to have on combobox which offers the option, and other's shouldn't?

I think to solve those issues, the controls has to be adapted to support the behaviour of the model.

Conclusion is, that I would put this feature to the controls itself, and you can configure the control to behave the way you need. (and this customizing feature could also render either the combobox or the dropdown box superflous, since the offer almost the same functionalty anyways..)

Greets,

ben

Former Member
0 Kudos

Hi Ben,

Good thinking.

I guess this kind of comes down to how to interpret the MVC pattern. Let's take this specific case:

  • The Model represents a collection of things that are used for filtering.
  • The SAPUI5 "Control"  (the UI element which combines View and Controller as far as I can tell), namely the DropdownBox, is then responsible for rendering that collection, and registering user interactions on it.

Now, the philosophical question is if the "all" option is a part of the collection or not. In my eyes, that would make the Model responsible for it. Since the collection is specifically earmarked as being for filtering, and "all" is a valid filter option, I'd say it is. I think it becomes a little clearer if you substitute "all" for "empty" and just tell the Model to allow an empty selection.

On the other hand, if the "all" option is not considered part of the collection, as one could definitely argue, the Model has nothing to do with it. Without the context "this collection is for filtering", an "all" or empty item should not be part of the Model. In that case, the DropdownBox is responsible for adding it whenever necessary.

I guess you can make a case for both variants, and adding functionality to the DropdownBox control is probably easier than adding it to the ODataModel ...

Cheers

Christoph

Answers (2)

Answers (2)

former_member182862
Active Contributor
0 Kudos

HI Christoph

Would AutoComplete control satisfy your requirement?

Example

-D

Former Member
0 Kudos

Hi Dennis,

thanks for your reply, and for the example!

I like the autocomplete functionality, but it isn't exactly what I need. Your example shows a textfield into which the user starts typing her desired option, and is then supported by the autocompletion. It still is a free text input though, which contrasts my requirement of a pre-defined set of options, plus an "all" option.

I know that you could use a combobox instead of the textfield, but the problem remains: The user can type whatever she wants. For instance, what stops me from typing just "ab" in the field? You'd have to specifically make sure that only the proposed options are submitted, which is at least as messy as what I'm doing now.

Cheers,

Christoph

former_member182862
Active Contributor
0 Kudos

Hi Christoph

I am still thinking about this problem because it is a common one 🙂

Having to change the oData service is evidently a big thing because oData service is not meant for UI consumption only. Other services may depend on it. So, I am thinking that changing oData service to include <All> may not be a good thing.

Here is another solution. Example

Thanks

-D

Former Member
0 Kudos

Dennis,

it seems I'm really not the only one thinking about this

Thanks for your example, the placeholder config option is another good find. This could work in cases where you only select once. The thing here is of course that once you've gone from the default "all" to one of the "actual" items, the only way back is to manually delete the text using the keyboard or right click -> delete. Which means that you can only do this with a free text ComboBox, not with a DropdownBox (which has fixed items).

I agree that changing the OData service to include the "all" option is not a clean solution. Just changing the JS model though ... I'll try to make it work

Cheers

Christoph

ChandraMahajan
Active Contributor
0 Kudos

Hi Christoph,

Recently there was discussion on this kind of requirement. you can see various options discussed in thread

Regards,

Chandra

Former Member
0 Kudos

Thanks for your reply Chandra!

I saw that thread while looking for the right solution - but it doesn't really answer my question. The options mentioned there are basically DOM fiddling, which is exactly what I don't want to do.

What I'm looking for is a way to tell the OData model to always prepend an "all" option, and not leave it to the dropdown control to take care of that. Or, alternatively, the information that this is not possible

Cheers,

Christoph

Former Member
0 Kudos

Hi Chris,

I don't think that there's a "clean" way to do this at the moment.

Maybe we should open a feature request for that (an option to show/hide an null-value-entry, and maybe to define an empty-text for that).

I guess for the moment you have to stick to one of those unlovely DOM-twiddle solutions (or just to leave it..).

Alternatively you could extend the DropdownBox, create an extended version and provide us your solution

Greets,

ben