Removing Blank Line in Multi-select Cascading Parameters

georgeh12
edited February 11, 2022 in Analytics #1
I realize the title appears to be extremely specific, but this is a common request by my clients. I strongly recommend patching this on your BIRT server, as it will take less than 10 minutes. (I promise!) I have not started using BIRT 3.7.2, but I assume most of this code remains unchanged.<br />
<br />
The issue is that the combo box parameter displays a blank option.<br />
<br />
birt_combo_box_1.png<br />
<br />
The error message resulting from selecting such an ominous blank space seems to freak out customers more than not. More frequently this message appears when a user attempts to select all parameter values from the list, resulting in even more confusion.<br />
<br />
birt_combo_box_2.png<br />
But do not fear! These parameter pages may not be manipulated by the .rptdesign file, but there are webpages that render the parameter window. A solution is afoot. First off, we want to locate the JSP that renders the cascading parameter object. If no default value is found, the cascading parameter box should not be populated with a blank line. Find your relative path from here: [C:/BIRT-2.6.1]/plugins/org.eclipse.birt.report.viewer_2.6.1.v20100913/birt/webcontent/birt/pages/parameter/ComboBoxParameterFragment.jsp
if( !parameterBean.isRequired( ) || ( parameterBean.isCascade( ) &amp;&amp; DataUtil.trimString( defaultValue ).length( )&lt;=0 ) )
{
if( allowMultiValue &amp;&amp; DataUtil.contain( values, "", true ) )
{
%&gt;
&lt;OPTION SELECTED&gt;&lt;/OPTION&gt;
&lt;%
}
else
{
%&gt;
&lt;OPTION&gt;&lt;/OPTION&gt;
&lt;%
}
}
<br />
Aha! I see the problem right here:
if( !parameterBean.isRequired( ) || ( parameterBean.isCascade( ) &amp;&amp; DataUtil.trimString( defaultValue ).length( )&lt;=0 ) )
<br />
This does not check whether the cascading parameter is required. Required parameters will not accept a blank line anyway, so let's tweak this a bit.
if( !parameterBean.isRequired( ) )
<br />
Done!<br />
birt_combo_box_3.png<br />
<br />
Wow, that was easy! I wonder why it took so long to figure out such a simp-- now hold on just a minute. When the first parameter is changed, the solution crashes and we are back to square one. At this point, I was stumped.<br />
<br />
birt_combo_box_4.png<br />
<br />
...and whenever there is an HTML glitch, I always turn to Firebug. The error has to be caused by JavaScript, but using the console we can narrow this problem even further.<br />
<br />
birt_combo_box_5.png<br />
<br />
An AJAX request is being POSTed at the same time our error is occurring. This needs to be investigated. The POST request is handled by the following file: [C:/BIRT-2.6.1]/plugins/org.eclipse.birt.report.viewer_2.6.1.v20100913/birt/webcontent/birt/ajax/ui/dialog/AbstractParameterDialog.js
    /**
     *    Binding data to the dialog UI. Data includes zoom scaling factor.
     *    @data, data DOM tree (schema TBD)
     *    @return, void
     */
    __propogateCascadeParameter : function( data )
    {
        if ( this.__operationCancelled )
        {
            return;
        }

        if( data )
        {
            var cascade_param = data.getElementsByTagName( 'CascadeParameter' )&#91;0];//assume there is only one cascadeparameter
            var selectionLists = data.getElementsByTagName( 'SelectionList' );
            if ( !selectionLists )
            {
                return;
            }

            for ( var k = 0; k &lt; selectionLists.length; k++ )
            {
                var param_name = selectionLists&#91;k].getElementsByTagName( 'Name' )&#91;0].firstChild.data;
                var selections = selectionLists&#91;k].getElementsByTagName( 'Selections' );

                var append_selection = document.getElementById( param_name + "_selection" );
                append_selection.title = "";
                var len = append_selection.options.length;

                // Clear our selection list.
                for( var i = 0, index = 0; i &lt; len; i++ )
                {
                    /*
                    if ( append_selection.options&#91;index].value == "" )
                    {
                        index++;
                        continue;
                    }
                    */
                    append_selection.remove( index );
                }

                // Add new options based on server response.
                for( var i = 0; i &lt; selections.length; i++ )
                {
                    if ( !selections&#91;i].firstChild )
                    {
                        continue;
                    }

                    var oOption = document.createElement( "OPTION" );
                    var oLabel = selections&#91;i].getElementsByTagName( 'Label' )
                    if ( oLabel &amp;&amp; oLabel.length &gt; 0 )
                    {
                        oLabel = oLabel&#91;0].firstChild;
                    }
                    if( oLabel )
                        oOption.text = oLabel.data;
                    else
                        oOption.text = "";

                    var oValue = selections&#91;i].getElementsByTagName( 'Value' );
                    if ( oValue &amp;&amp; oValue.length &gt; 0 )
                    {
                        oValue = oValue&#91;0].firstChild;
                    }
                    if( oValue )
                        oOption.value = oValue.data;
                    else
                        oOption.value = "";

                    append_selection.options&#91;append_selection.options.length] = oOption;
                }
            }
        }
    },
<br />
Here is where the cascading parameter options are added in response to the AJAX request. By manipulating the last line here, we will be able to remove that silly blank option from being returned by the server.
append_selection.options&#91;append_selection.options.length] = oOption;
<br />
And the much awaited solution:
if( !( append_selection.type == 'select-multiple' &amp;&amp; i == 0 ) ) //Removes the first blank in multiple-select cascading parameters
append_selection.options&#91;append_selection.options.length] = oOption;
<br />
Ha! We defeated that bug in just one line, and even commented the code. Here is a look at the fixed parameter dialog:<br />
<br />
birt_combo_box_6.png