Checking more than one checkbox in a check field

Hi All

I couldn’t figure out the various possibilities (if they exist) on a check field, if one wishes to check (select) more than one chechbox. I did it on a field with an attached value list (as in the developer docu) but the check(box) field behaves as a radio button (one out of all, it accepts just one selection (but checkbox should accept zero to many out of all).
How to do that? And where does it store the content? )If it’s stored in one field, it’s also a violation of even the 1st normal form, how you takle with that?)

Thanks in advance, Robert

Hi Robert,

If the destination field is a text one, servoy will store there the checked values, separated by new line (\n).

When you can not unselect all checkboxes (if I understand correct then that’s your issue) you should allow empty values when you define your value list.

Hello Enrico

automazione:
Hi Robert,

If the destination field is a text one, servoy will store there the checked values, separated by new line (\n).

Thanks a lot for that, it’s just what I wanted to find out. The field is a text one, the displayType (of course) CHECK. A minor display problem for me to solve is eliminating the spaces between the characters (H M A should be AHM)) if displayed in a text field (see Attributes text field on the right on the picture) and how to sort order that field alphabetically, as on the left side field (checkbox field). Have you got any idea how to do that?

Best regards and thanks, Robert

Hi Marcel

IT2BE:
When you can not unselect all checkboxes (if I understand correct then that’s your issue) you should allow empty values when you define your value list.

Thanks for your reply. No, it’s not about unchecking all checkboxes, but how the checkbox data is stored internally, because obviously, if I select more than one checkbox, and the data is stored in one field, the 1st normal form is not met. See also my reply to Enricos answer.

Thanks and best regards, Robert

Robert Huber:
A minor display problem for me to solve is eliminating the spaces between the characters

Maybe a calculated field will be enough

Robert Huber:
(H M A should be AHM)) if displayed in a text field (see Attributes text field on the right on the picture) and how to sort order that field alphabetically, as on the left side field (checkbox field). Have you got any idea how to do that?

I’ve already reported to the Dev Team the “strange - umpredictable” order in which the checked voices are recorded in the field, and I think they are already working on the problem.

Robert Huber:
if I select more than one checkbox, and the data is stored in one field, the 1st normal form is not met.

So true (and, for those who care, checkbox data in FMP is stored very much the same way). Checkbox fields can be really useful but careful thought must be put into the ramifications of using them. Breaking the normal forms with checkbox fields presents at least two potential, serious, problems:

– It becomes very difficult to count/summarize/otherwise analyze or manipulate the checkbox data, vis-a-vis if each entry were stored in its own row in a related table

– There is no such thing as cascading delete between values defined in a value list and data in a checkbox field. So, for example, if Robert removes the “S Start” choice from his value list, this will not have the effect of deleting instances of the “S Start” string from the data field. Usually the desired effect of removing the choice would be to also remove the string, rather than leave “orphaned” data in the field.

kazar

kazar:

Robert Huber:
if I select more than one checkbox, and the data is stored in one field, the 1st normal form is not met.

So true (and, for those who care, checkbox data in FMP is stored very much the same way). Checkbox fields can be really useful but careful thought must be put into the ramifications of using them. Breaking the normal forms with checkbox fields presents at least two potential, serious, problems:

I would say it is absolutely up to you to stay in “normal form” or to go in “chaos mode”… I’ve found smart uses of multiple checkboxes more than once. The good news :wink: is that you can always use radio buttons instead of checkboxes, or you can build your related check-table.

kazar:
– There is no such thing as cascading delete between values defined in a value list and data in a checkbox field. So, for example, if Robert removes the “S Start” choice from his value list, this will not have the effect of deleting instances of the “S Start” string from the data field. Usually the desired effect of removing the choice would be to also remove the string, rather than leave “orphaned” data in the field.

kazar

sorry Ilyse… I don’t understand your point here…

automazione:

kazar:
– There is no such thing as cascading delete between values defined in a value list and data in a checkbox field. So, for example, if Robert removes the “S Start” choice from his value list, this will not have the effect of deleting instances of the “S Start” string from the data field. Usually the desired effect of removing the choice would be to also remove the string, rather than leave “orphaned” data in the field.

kazar

sorry Ilyse… I don’t understand your point here…

Apologies if I did not express it well, the caffeine hasn’t hit yet this morning. I’ll use a different value-list example that I hope will make my point better:

Let’s say you have a travel company and in your database’s Customers table you wish to track “destinations_of_interest” for each customer. And let’s say the vacation packages you offer include:

Hawaii
Bora Bora
Zanglia

For the first year you use this database, you enter for each customer one or more of these three destinations of interest. Then suddenly there is big trouble - political unrest - in (the fictional) Zanglia, so you terminate the availability of that vacation package and instead begin offering Alaska as a travel destination.

So let’s look at the effect of this change in choices (i.e., value-list items) with two different approaches:

NORMALIZED APPROACH: Create a destination table containing a row for each destination, and a customer_interest join table (between the customer table and the destination table) containing a row for each choice a customer makes. Now, establish a relationship with cascading delete between destination and customer_interest (and another relationship with cascading delete, of course, between customer and customer_interest).

Effect of deleting the row for the “Zanglia” vacation package: All customer_interest rows that had contained “Zanglia” would also be deleted. This is probably what you would want to happen.

CHECKBOX APPROACH: Create a “destination_list” value list and use a checkbox UI for marking customer interests.

Effect of deleteing the “Zanglia” item from the value list: All customer records that have “Zanglia” as an entry in the checkbox field would keep that value in the field even though it would no longer be displayed as a choice in the checkbox list. This presents some problems! There is now data in the field that resulted from an obsolete choice that no longer exists.

Does that help explain what meant?

kazar

I wrote: <<This presents some problems! There is now data in the field that resulted from an obsolete choice that no longer exists. >>

And I should add: And now you cannot see the “Zanglia” choice in the records that contain that string in the checkbox field. In other words, if a customer had expressed interest in Bora Bora and in Zanglia, when you change the Zanglia choice to Alaska, that customer’s checkboxes would show:

X Bora Bora
Hawaii
Alaska

… when in reality the field contains:

Bora Bora
Zanglia

kazar

I hope I’m not boring anyone, sitting here talking to myself about checkboxes. ;^}

But Robert’s question started me off on a chain of investigation/thinking/learning about checkboxes in a Servoy/SQL environment. Here are two more tidbits

Robert had asked:

A minor display problem for me to solve is eliminating the spaces between the characters (H M A should be AHM)

You must have the field on the right formatted with text display. Choices made in a checkbox field are entered into the data field (in what seems like arbitrary order) separated by line-return characters … i.e., a return-delimited list is what results. If you change the field on the right to Text Area display you’ll see what I mean.

if displayed in a text field (see Attributes text field on the right on the picture) and how to sort order that field alphabetically

You could probably handle the return-delimited list as an array and use a method attached to the checkbox field that uses a string function to sort the values… (I don’t know, just guessing) … HOWEVER, your desire to see the values sorted only points us back to your original observation that checkbox fields break the first normal form. If you want to work with, manipulate, report on or do much more than just look at the selections, use a fully relational approach instead.

For example, if you normalized the structure and stored each checkbox choice in its own row in a table you could then …
… create a list form in this valueChoices table and attach an onShow method that loads all records & then sorts them
… make the choiceDescription field on this form non-editable and attach a method that creates a related record if none exists for that choice, and that deletes a related record if it does exist (i.e., your method would act as a “toggle” to “turn the selection on and off”)
… define some kind of unstored calc to apply highlighting or even a checked box graphic to the rows on the list form, depending on each row’s “selected” or “non-selected” status
… put the valueChoices list form into an unrelated tab panel on the form the user will be working in

[[now I bet David W is about to post something that makes this approach look way overdone! (in fact, I hope he does)]]

No matter how much extra work this might look like up front compared to simply formatting a checkox field to display a value list, by sticking with normalized data you will make your life (and your users’ lives) SOOOO much easier down the road.

For example, check a couple of boxes in your checkbox field, go into Find mode, and try finding all records that have one of the choices checked. Only records that have ONLY that choice will show up, when the user would expect that ANY record that has that choice checked (plus perhaps others checked as well) would be returned. Using your screenshot as an example, if you entered Find mode and checked the “A Airport” box, you would expect that record to turn up, but it won’t. (See Finds on Checkboxes - How get Servoy to act like FMP? - Classic Servoy - Servoy Community) So to allow users to perform finds on checkbox fields, you will be writing & maintaining a rather complex onSearch method…

Or try generating a report that summarizes a count of each value-list choice. A snap with a related table that stores each selected value in a row; and significantly more complex to build the same report with return-delimited checkbox choices.

I’ve made a little start on a suggested UI for providing a checkbox-like UI within a normalized structure. If I get anywhere with it, I’ll post it as my first Servoy demo!

kazar

Ok Ilyse I agree with you: better do not use multiple-checkbox for selecting changing listvalues.

I think using multi-checkbox in a situation like the one you expose is NOT an option, unless you want to go for trouble…

automazione:
Ok Ilyse I agree with you: better do not use multiple-checkbox for selecting changing listvalues.

I think using multi-checkbox in a situation like the one you expose is NOT an option, unless you want to go for trouble…

Oh, I’ve been known to “go for trouble” but only if it’s more fun than correcting inaccurate data. And the more I am able to avoid trouble with my database designs, the more time I have left in life for those other kinds of trouble! So design sturdy solutions, then go out and “paint the town”!

kazar

Robert Huber:
A minor display problem for me to solve is eliminating the spaces between the characters (H M A should be AHM))

You can use:
dataprovider = Utils.stringReplace(dataprovider,‘\n’,‘’) to remove the newlines

Robert Huber:
…not sorted…

In Servoy 3.0 we do sort the values, to overcome a search problem Enrico pointed out.

Jan Blok:

Robert Huber:
A minor display problem for me to solve is eliminating the spaces between the characters (H M A should be AHM))

You can use:
dataprovider = Utils.stringReplace(dataprovider,‘\n’,‘’) to remove the newlines

Hi Jan – I think the problem Robert was referring to is not blank lines… but rather he was expecting to see a string because he was using a text-formatted field instead of textarea.

Robert Huber:
…not sorted…

In Servoy 3.0 we do sort the values, to overcome a search problem Enrico pointed out.

Yay! Does the query automatically add the necessary %'s so that users can do a simple form-based query on a form that includes checkboxes, or will we be writing methods for searching checkboxes?

kazar

kazar:
Yay! Does the query automatically add the necessary %'s so that users can do a simple form-based query on a form that includes checkboxes, or will we be writing methods for searching checkboxes?

yes, it does in 3.0

Hello Ilyse and all others

Hope you found a good way getting home after Servoy world :-)

kazar:

automazione:

kazar:
– There is no such thing as cascading delete between values defined in a value list and data in a checkbox field. So, for example, if Robert removes the “S Start” choice from his value list, this will not have the effect of deleting instances of the “S Start” string from the data field. Usually the desired effect of removing the choice would be to also remove the string, rather than leave “orphaned” data in the field.

kazar

sorry Ilyse… I don’t understand your point here…

Apologies if I did not express it well, the caffeine hasn’t hit yet this morning. I’ll use a different value-list example that I hope will make my point better:

Let’s say you have a travel company and in your database’s Customers table you wish to track “destinations_of_interest” for each customer. And let’s say the vacation packages you offer include:

Hawaii
Bora Bora
Zanglia

For the first year you use this database, you enter for each customer one or more of these three destinations of interest. Then suddenly there is big trouble - political unrest - in (the fictional) Zanglia, so you terminate the availability of that vacation package and instead begin offering Alaska as a travel destination.

So let’s look at the effect of this change in choices (i.e., value-list items) with two different approaches:

NORMALIZED APPROACH: Create a destination table containing a row for each destination, and a customer_interest join table (between the customer table and the destination table) containing a row for each choice a customer makes. Now, establish a relationship with cascading delete between destination and customer_interest (and another relationship with cascading delete, of course, between customer and customer_interest).

Effect of deleting the row for the “Zanglia” vacation package: All customer_interest rows that had contained “Zanglia” would also be deleted. This is probably what you would want to happen.

CHECKBOX APPROACH: Create a “destination_list” value list and use a checkbox UI for marking customer interests.

Effect of deleteing the “Zanglia” item from the value list: All customer records that have “Zanglia” as an entry in the checkbox field would keep that value in the field even though it would no longer be displayed as a choice in the checkbox list. This presents some problems! There is now data in the field that resulted from an obsolete choice that no longer exists.

Does that help explain what meant?

kazar

Thanks for describing that. Thats exactly what’s all about - normalized approach vs checkbox approach, as you name it.

Can I do the the normalized approach with checkbox selection of the entries in the join table? (I assume this is not possible, but would be very nice). The checkbox approach really works only if you never ever change the value list after initiation of it. This is well true for some cases, but there are other cases as you describe.

Best regards, Robert

Hi Ilyse

This is exactly the problem! (for the checkbox case). So for such a case one can never change the value list after the first use!

Best regards, Robert

kazar:
I wrote: <<This presents some problems! There is now data in the field that resulted from an obsolete choice that no longer exists. >>

And I should add: And now you cannot see the “Zanglia” choice in the records that contain that string in the checkbox field. In other words, if a customer had expressed interest in Bora Bora and in Zanglia, when you change the Zanglia choice to Alaska, that customer’s checkboxes would show:

X Bora Bora
Hawaii
Alaska

… when in reality the field contains:

Bora Bora
Zanglia

kazar

We did think about making the normalized approach possible via something like an N-M relation, but so far no one reqested this.

Hello Jan

Ok, sorting comes in Version 3, that’s ok (for me).
A stupid question: What is dataprovider = Utils.stringReplace(dataprovider,‘\n’,‘’)? Is it a calculation field or a method (on this form) or ??? My attribute with that “H M A” content (for example) is named attributes (quite confusing, I know, but that’s how the originator of that instrument called it so I don’t change it).

I see what you mean but I don’t know how to do that.

Best regards, Robert

kazar:

Jan Blok:

Robert Huber:
A minor display problem for me to solve is eliminating the spaces between the characters (H M A should be AHM))

You can use:
dataprovider = Utils.stringReplace(dataprovider,‘\n’,‘’) to remove the newlines

Hi Jan – I think the problem Robert was referring to is not blank lines… but rather he was expecting to see a string because he was using a text-formatted field instead of textarea.

Robert Huber:
…not sorted…

In Servoy 3.0 we do sort the values, to overcome a search problem Enrico pointed out.

Yay! Does the query automatically add the necessary %'s so that users can do a simple form-based query on a form that includes checkboxes, or will we be writing methods for searching checkboxes?

kazar