Show null for switch items

An application I maintain needed a checklist feature added. I wanted to show a “Yes / No” switch for a list of checklist items. Initially, when the record is created, the checklist is populated with the questions along with a NULL for the response.

I generated the switches in an ordinary Classic report using code like this:

select r.name as risk_category
      ,apex_item.switch
         (p_idx        => 10
         ,p_value      => i.response
         ,p_on_value   => 'Yes'
         ,p_on_label   => 'Yes'
         ,p_off_value  => 'No'
         ,p_off_label  => 'No'
         ,p_item_id    => 'RESPONSE_' || rownum
         ,p_item_label => i.risk_category_code || '-' || i.rci_fk
         ,p_attributes => 'data-risk="' || i.risk_category_code || '"'
         )
       ||apex_item.hidden(p_idx => 11, p_value => i.rci_fk)
       as response
      ,i.question_text
from supplier_risk_checklist_items i
join risk_categories r on r.code = i.risk_category_code
where i.sri_fk = :P10_ID
order by r.sort_order nulls last, i.sort_order nulls last, i.rci_fk

I’ve used p_idx values of 10 and 11 in order to avoid conflicting with another tabular report on this particular page. The “response” column in the report has CSS Classes set to responseSwitch (this becomes useful later when we want to write javascript targeting just these items and nothing else on the page) and its Escape special characters attribute is set to No. The report when run looks like this:

Some of the responses are “Yes”, some “No”, and some are NULL (unanswered).

The problem is that all the NULL responses are indistinguishable from the “No” responses. If the user clicks “Yes” or “No”, the response is saved correctly – but the user cannot tell which ones haven’t explicitly been answered yet.

To find a solution for this issue I started by examining the HTML being generated for each question. I noticed that the input option for the “No” value was marked as “checked”, while the hidden input item had no “value” on it. These were the ones that needed fixing.

Example 1. Notice that the displayed radio button RESPONSE_10_N is “checked”, but the associated hidden input RESPONSE_10 has no value attribute.
Example 2. In this example, the displayed radio button RESPONSE_5_N is “checked”, but that’s ok because the hidden input RESPONSE_5 has the value “No” – so we don’t want to change this one.

In the page’s Execute When Page Loads, I search for all instances of responseSwitch where the hidden input item does not have a value attribute; in each case, I find the associated input item that shows “No” and unset the “checked” property:

// workaround for generated switch items showing "No" when value is null
// search for the hidden input items without a value (i.e. null on the database)
$(".responseSwitch input[name='f10']:not([value])").each(function(i){
    var id = $(this).attr("id");
    // these will have "checked" on the "No" option; remove it
    $(".responseSwitch input#"+id+"_N").prop("checked",null);
});

This makes it clear to the user which checklist items have been answered so far, and which ones haven’t.

Note: the user is given no way to unset an answer once it has been saved; if this were a problem I would change this to use an ordinary Select list item instead of a Switch item.

“No Primary Key item has been defined for form region”
User-editable Application Setting

Comments

  1. Great, very useful, thanks!

  2. Hi Jeffrey,

    really good article,
    can you please let me know how you performed column break on the “risk_category” column?

    thanks

    • Hi Ankit, I used Break Formatting. This is under the region Attributes node -> Break Formatting -> Break Columns (set to First Column).

  3. Gustavo Ariel Vallejos
    4 November 2020 - 2:29 pm

    hi,
    I have a report with a query similar to the one you posted.
    I would like to make the switch disable ( or readonly ) . Ive tried different stuff but couldn’t make it work. how can I make that ?
    cheers
    gus

    select r.name as risk_category
    ,apex_item.switch
    (p_idx => 10
    ,p_value => i.response
    ,p_on_value => ‘Yes’
    ,p_on_label => ‘Yes’
    ,p_off_value => ‘No’
    ,p_off_label => ‘No’
    ,p_item_id => ‘RESPONSE_’ || rownum
    ,p_item_label => i.risk_category_code || ‘-‘ || i.rci_fk
    ,p_attributes => ‘data-risk=”‘ || i.risk_category_code || ‘”‘
    )
    ||apex_item.hidden(p_idx => 11, p_value => i.rci_fk)
    as response
    ,i.question_text
    from supplier_risk_checklist_items i
    join risk_categories r on r.code = i.risk_category_code
    where i.sri_fk = :P10_ID
    order by r.sort_order nulls last, i.sort_order nulls last, i.rci_fk

    • Hi Gustavo,

      Good question. If you add “disabled” to the attributes for the switch, it doesn’t work because that is the attributes on the containing div, not the input items themselves.

      To implement this, I would add “disabled” to p_attributes, like this:

      ,p_attributes => 'disabled data-risk="' ...

      Then add the following to the page’s Execute When Page Loads:

      $("div[disabled] input[type='radio']").each(function(){
          $(this).prop("disabled",true);
      });
      

      This finds all the divs which you have marked as “disabled”, and adds that attribute to its radio items.

Leave a Reply

Your email address will not be published / Required fields are marked *