/* *+------------------------------------------------------------------------+ *| Licensed Materials - Property of IBM *| BI and PM: prmt *| (C) Copyright IBM Corp. 2002, 2021 *| *| US Government Users Restricted Rights - Use, duplication or *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *| *+------------------------------------------------------------------------+ */ /** @file This script is used to provide interactivity for the SelectValue single and multiple select prompt components. */ /** @private @class */ cognos.Prompt.Control.SelectValue = cognos.Prompt.Control.f_extend({ f_initialize: function( v_oProps ) { this._type_ = "cognos.Prompt.Control.SelectValue"; this.f_parent( v_oProps ); // call parent's f_initialize this.m_aOptions = null; this.m_aSuperLiterals = []; this.m_currentlySelected = null; // set selectValueUI to selectUI if ( !this.selectUI ) { this.selectUI = this["@selectValueUI"]; } if ( this.m_oRangeControl ) { this.selectUI = "dropdown"; } if ( this.selectUI == "checkboxGroup" && !this.isMulti() ) { this.selectUI = "radioGroup"; } else if ( this.selectUI == "radioGroup" && this.isMulti() ) { this.selectUI = "checkboxGroup"; } else if ( this.selectUI == "dropdown" ) { this["@multiSelect"] = false; } this.f_initCompleted(); }, checkData: function() { this.m_bValid = true; var v_bPass = this.f_parent(); // call parent's checkData if ( !v_bPass || (this.isRequired() && !this.hasValue() )) { this.m_bValid = false; this.checkFail(); } else { this.m_bValid = true; this.checkPass(); } return this.m_bValid; }, clearValues: function() { this.f_parent(); this.f_deselectAll(); }, singleValueSelect: function(event) { var selectedIndex = event.target.selectedIndex; var options = this.f_getOptions(); var selected = options[selectedIndex]; //only set aria-selected = true for valid options if (selected.hasAttribute("role") && selected.getAttribute("role") === "option") { if (this.m_currentlySelected !== null) { this.m_currentlySelected.setAttribute("aria-selected","false"); } this.m_currentlySelected = selected; selected.setAttribute("aria-selected","true"); } else { //if invalid option selected - clear the previously selected if (this.m_currentlySelected !== null) { this.m_currentlySelected.setAttribute("aria-selected","false"); this.m_currentlySelected = null; } } }, multiValueSelect: function (event) { var options = this.f_getOptions(); for (let i = 0 ; i < options.length ; i++ ) { options[i].setAttribute("aria-selected",options[i].selected); } }, f_drawCompleted: function() { var v_elPrompt = $( this.f_getId(K_PRMT_sSV_PREFIX) ); var v_elContainer = $( this.f_getId("PRMT_SV_CONTAINER_") ); if ( v_elPrompt ) { var v_CPE = new C_PromptElement(); var v_sStyle = this["@style"]; // @listStyle is used by the search control. if ( this["@listStyle"] ) { v_sStyle = (v_sStyle ? v_sStyle : K_PRMT_sEMPTY) + this["@listStyle"]; } v_CPE.f_setStyle( v_elPrompt, cssParser(this["@style"], "color,font,text") + (this["@listStyle"] ? this["@listStyle"] : K_PRMT_sEMPTY) ); // put it back at the right place. this.f_moveInContainer( v_elContainer, v_elPrompt ); v_elPrompt.m_oPrompt = this; var v_sWidth = cssParser( v_sStyle, "width", true ); if ( v_sWidth ) { if ( this.m_oRangeControl && this.m_oRangeControl.isMulti() ) { var p = v_elPrompt; p.style.width = "100%"; var v_reTable = new RegExp("div", "i"); while (p && !p.nodeName.match(v_reTable)) { p.setAttribute("width", "100%"); p = p.parentNode; } } else { v_elPrompt.style.width = v_sWidth; } } var v_sHeight = cssParser( v_sStyle, "height", true ); if ( v_sHeight && this.selectUI != "dropdown" ) { v_elPrompt.style.height = v_sHeight; v_elPrompt.style.maxHeight = "none"; } if ( this.selectUI == "checkboxGroup" || this.selectUI == "radioGroup" ) { // link a11y label if it exists var v_a11yLabel = $( this.f_getId("PRMT_LBL_") ); if ( v_a11yLabel ) { var v_container = $( this.f_getId("PRMT_SV_CONTAINER_") ); v_container.setAttribute("aria-labelledby", this.f_getId("PRMT_LBL_")); } var v_sChildStyle = cssParser( v_sStyle, "color,font,text" ); if ( v_sChildStyle ) { var v_oChild = v_elPrompt.firstChild; while ( v_oChild ) { v_CPE.f_setStyle( v_oChild, v_sChildStyle ); v_oChild = v_oChild.nextSibling; } } } else { // link a11y label if it exists using FOR var v_a11yLabel = $( this.f_getId("PRMT_LBL_") ); if ( v_a11yLabel && !v_a11yLabel.getAttribute("for")) { v_a11yLabel.setAttribute("for", this.f_getId("PRMT_SV_")); } // @listSize is used by the cognos.Prompt.Control.Search. if ( this["@listSize"] ) { v_elPrompt.setAttribute( "size", this["@listSize"] ); v_elPrompt.selectedIndex=-1; } else if ( this.selectUI == "listBox" ) { v_elPrompt.setAttribute( "size", "11" ); v_elPrompt.selectedIndex=-1; } else if ( this.selectUI == "dropdown" && !this.isMulti() && typeof this["@columnName"] == K_PRMT_sUNDEFINED) { v_elPrompt.selectedIndex=(window.isAllowEmptyStringHeaderText && !window.isAllowEmptyStringHeaderText()) ? 0 : -1; } if ( !this.isMulti() ) { v_elPrompt.removeAttribute( "multiple" ); v_elPrompt.setAttribute("aria-multiselectable", 'false'); //REPORT-13599 PRMTUtils.f_addEvent( v_elPrompt, "change", this.singleValueSelect.bind(this) ); } else { v_elPrompt.setAttribute("aria-multiselectable", 'true'); //REPORT-13599 PRMTUtils.f_addEvent( v_elPrompt, "change", this.multiValueSelect.bind(this) ); } if ( this.isRequired() ) { v_elPrompt.setAttribute("aria-required", true); } } if ( typeof SYSTEMPROPERTY_CHANGE_DROPDOWN_BACKGROUNDCOLOR_ALL !== K_PRMT_sUNDEFINED && SYSTEMPROPERTY_CHANGE_DROPDOWN_BACKGROUNDCOLOR_ALL === true ) { if ( this.selectUI == "listBox" || this.selectUI == "dropdown" ) { var v_sBackgroundColor = cssParser( v_sStyle, "background-color", true ); if ( v_sBackgroundColor ) { v_elPrompt.style.backgroundColor = v_sBackgroundColor; } } } if ( this[K_PRMT_sATTR_DISABLED] ) { v_elPrompt.setAttribute( "disabled", "disabled" ); } PRMTUtils.f_addEvent( v_elPrompt, "change", this.f_onChange.bind(this) ); // ipad quirk, Select with one option does not fire onChange, but it fires onBlur if (this.selectUI == "listBox" && PRMTUtils.f_isMobileDevice()) { PRMTUtils.f_addEvent( v_elPrompt, "blur", this.f_onBlur.bind(this) ); } this.m_elPrompt = v_elPrompt; } var v_link = $( this.f_getId(K_PRMT_sSV_LINK_SELECT_PREFIX) ); if ( v_link ) { PRMTUtils.f_addEvent( v_link, "click", this.f_selectAll.bind(this) ); } v_link = $( this.f_getId(K_PRMT_sSV_LINK_DESELECT_PREFIX) ); if ( v_link ) { PRMTUtils.f_addEvent( v_link, "click", this.f_deselectAll.bind(this) ); } this.f_parent(); // call parent's f_drawCompleted // set the classnames if (this.selectUI == "checkboxGroup" || this.selectUI == "radioGroup") { //set the css class to the option parent DIV var v_aOptions = this.f_getOptions(); var v_iLength = v_aOptions.length; var isFirstTabIndexSet = false; for (var i = 0; i < v_iLength; i++) { var v_cb = v_aOptions[i]; var v_div = v_cb.parentNode; if (v_cb.type == "checkbox") { v_div.className = (v_cb.checked ? K_PRMT_CSS_CHECKBOX_CHECKED : K_PRMT_CSS_CHECKBOX); PRMTUtils.f_addEvent( v_div, "keydown", this.f_checkboxKeyNav.bind(this) ); if (!isFirstTabIndexSet) { v_cb.tabIndex = 0; isFirstTabIndexSet = true; } else { v_cb.tabIndex = -1; } } else { v_div.className = (v_cb.checked ? K_PRMT_CSS_RADIOBUTTON_CHECKED : K_PRMT_CSS_RADIOBUTTON); } PRMTUtils.f_updateElementAriaChecked(v_cb, v_cb.checked); var v_label = v_div.nextSibling; if ( G_IsBidiEnabled && v_label && this["@contentTextDirection"] ) { v_label.innerHTML = PRMT_BidiUtils.enforceBidiDirection(v_label.innerHTML, PRMT_BidiUtils.getTextDirection(v_label.firstChild.nodeValue, this["@contentTextDirection"])); } if ( this.isRequired() ) { v_cb.setAttribute("aria-required", true); } } } else { var v_aOptions = this.f_getOptions(); for (var i = 0; i < v_aOptions.length; i++) { var v_elOption = v_aOptions[i]; if ( G_IsBidiEnabled && v_elOption && this["@contentTextDirection"] ) { v_elOption.innerHTML = PRMT_BidiUtils.enforceBidiDirection(v_elOption.innerHTML, PRMT_BidiUtils.getTextDirection(v_elOption.firstChild.nodeValue, this["@contentTextDirection"])); } } } // FIXME: remove the hardcoded minimal width and use CSS if (!this.f_isBUX()) { setTimeout( this.f_updateSize.bind(this), 20 ); } // focus Select control var oCV = this.f_getCV(); if (oCV && typeof oCV.getCurrentPromptControlFocus == K_PRMT_sFUNCTION){ if (this["@name"] == oCV.getCurrentPromptControlFocus()) { var v_elPrompt = $( this.f_getId(K_PRMT_sSV_PREFIX) ); v_elPrompt.focus(); oCV.setCurrentPromptControlFocus(null); } } } }); /** * Getter for range inputId * rangeInputId used by range label to associate the label (From/To) to the input when there are not radio buttons * */ cognos.Prompt.Control.SelectValue.prototype.f_getRangeInputId = function() { return (this.m_oRangeControl ? this.f_getId(K_PRMT_sSV_PREFIX) : null ); } /** * Adds an option element to the list of candidates for a choice. @private @param {HTMLelement} v_option @param {cognos.Value[]} v_aSC @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_addCandidateForSelection = function(v_option, v_aSC) { for (var i = 0; i < v_aSC.length; i++) { v_aSC[i].m_aCandidates.push( { "option": v_option, "score": this.f_getScore(v_aSC[i], v_option) } ); } }; /** Adds an option element to the list of candidates for a choice. @private @param {object} v_oMap @param {String} v_sKey @param {object} v_oValue @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_addOptionInValueMap = function( v_oMap, v_sKey, v_oValue ) { if (typeof(v_oValue.m_aCandidates) === K_PRMT_sUNDEFINED ) { // A choice will need an array for candidates. v_oValue.m_aCandidates = []; } v_sKey = sDecodeU003( v_sKey ); if ( v_oMap[v_sKey] ) { v_oMap[v_sKey].push( v_oValue ); } else { v_oMap[v_sKey] = [v_oValue]; } }; /** Select the elements which have the best match for each choice. @private @param v_oChoices The 'selectChoices' node from RSVP. @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_applySelection = function(v_oChoices) { var i; var v_oCandidate = null; var v_aCandidates = null; var v_aToSelect = null; var v_iHighScore = 0; for ( var v_idx = 0; v_idx < v_oChoices.c.length; v_idx++ ) { v_aCandidates = v_oChoices.c[v_idx].m_aCandidates; if (v_aCandidates && v_aCandidates.length) { v_aToSelect = []; v_iHighScore = 0; // Find candidates with highest score for (i = 0; i < v_aCandidates.length; i++) { v_oCandidate = v_aCandidates[i]; if (v_oCandidate.score > v_iHighScore) { v_aToSelect = []; v_iHighScore = v_oCandidate.score; } if (v_oCandidate.score === v_iHighScore) { v_aToSelect.push(v_oCandidate.option); } } // apply selection for (i=0; i < v_aToSelect.length; i++) { v_aToSelect[i].checked = true; v_aToSelect[i].selected = true; } } } }; /** Compare values. See {@link cognos.Prompt.Control#f_compare} for details. @see cognos.Prompt.Control#f_compare @private @return {Integer} */ cognos.Prompt.Control.SelectValue.prototype.f_compare = function( v_oValue ) { var v_iRetval = 1; if ( SYSTEMPROPERTY_REORDER_DROPDOWN_VALUES_IN_RANGES === true && v_oValue ) { // f_compare is used by Ranges. We supposed we are using DROPDOWN controls. var v_iThis = this.m_elPrompt.selectedIndex; var v_iCompareTo = v_oValue.m_elPrompt.selectedIndex; if ( v_iCompareTo > v_iThis ) { v_iRetval = -1; } else if ( v_iCompareTo == v_iThis ) { v_iRetval = 0; } } return v_iRetval; }; /** Sets the JavaScript references used by custom scripts based on generated code from Blaring and before. (Custom Scripts Workaround) @private @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_CSW_init = function() { var v_sPrefix = "listBox"; switch( this.selectUI ) { case "checkboxGroup": v_sPrefix = "checkBoxList"; break; case "radioGroup": v_sPrefix = "radioList"; break; } var v_oPC = this.f_CSW_createJSObject( v_sPrefix ); if ( v_oPC ) { if (typeof v_oPC.selectAll == K_PRMT_sUNDEFINED ) { v_oPC.selectAll = this.f_selectAll.bind(this); } if (typeof v_oPC.checkData == K_PRMT_sUNDEFINED ) { v_oPC.checkData = this.checkData.bind(this); } } if ( this.selectUI == "checkboxGroup" || this.selectUI == "radioGroup" ) { var aChoices = document.getElementsByName( this.f_getId("pOpt_") ); if (aChoices.length > 0) { if (aChoices.length == 1) { aChoices = aChoices[0]; } this.f_CSW_SetFormElement("_oLstChoices", aChoices); } } else { this.f_CSW_SetFormElement("_oLstChoices"); } }; /** @private @param {boolean} v_bSelected @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_deselectAll = function( v_bSelected ) { this.f_selectAll( false ); }; /** Draws a deselect link inside of the container passes as a param @private @param {C_PromptElement} v_div Container @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_drawDeselectLink = function( v_div ) { var v_a1 = $CE("a", { "id": this.f_getId(K_PRMT_sSV_LINK_DESELECT_PREFIX), "href": "javascript:;", "onclick": "document.location.hash='';", "class": "clsLink pl"}, v_div ); v_a1.f_appendText( this[K_PRMT_LABEL_DESELECT] ); }; /** @private @param {C_PromptElement} v_el Container. @return {C_PromptElement} */ cognos.Prompt.Control.SelectValue.prototype.f_drawInput = function( v_el ) { var v_oInput = $( this.f_getId(K_PRMT_sSV_PREFIX) ); if ( v_oInput && this.f_isHidingGroupingBox() ) { PRMTUtils.f_removeClass( v_oInput, "clsCheckBoxList" ); PRMTUtils.f_removeClass( v_oInput, "pv" ); PRMTUtils.f_addClass( v_oInput, "clsCheckBoxHidingGroupingList" ); } var v_oContainer = $CE("div", {"id": this.f_getId("PRMT_SV_CONTAINER_")}, v_el); var v_sCustomDir = cssParser( this["@style"], "direction", true ); var v_FinalDir = ((v_sCustomDir == "ltr" || v_sCustomDir == "rtl") ? v_sCustomDir : PRMT_BidiUtils.lookupDirection($( this.f_getId(this.m_sDivPrefix) ))); var v_sAlignStyle = "text-align:" + ( ( v_FinalDir == "rtl" ) ? "left" : "right"); v_oContainer.f_appendText(K_PRMT_sEMPTY); switch( this.selectUI ) { case "checkboxGroup": this.f_drawSelectLinks( v_el, v_sAlignStyle ); break; case "radioGroup": if ( !this.isRequired() ) { var v_div = $CE( "div", {style:v_sAlignStyle}, v_el ); if ( this[K_PRMT_sATTR_DISABLED] ) { var v_span = $CE( "span", { "class": "clsLink", "style": "text-decoration:underline;color: #CCCCCC" }, v_div ); v_span.f_appendText( this[K_PRMT_LABEL_DESELECT] ); } else { this.f_drawDeselectLink( v_div ); } } break; case "listBox": if ( this.isMulti() ) { this.f_drawSelectLinks( v_el, v_sAlignStyle ); } else if ( !this.isRequired() && typeof this["@columnName"] == K_PRMT_sUNDEFINED ) { var v_div = $CE( "div", {style:v_sAlignStyle}, v_el ); this.f_drawDeselectLink( v_div ); } break; } return v_oInput; }; /** Renders the layout of the control: position lists, adornments and control inputs. @private @param {C_PromptElement} v_trLayout Container for this control. @return {C_PromptElement} */ cognos.Prompt.Control.SelectValue.prototype.f_drawLayout = function( v_trLayout ) { if ( !(this["@hideAdornments"] || this.m_bSkipAdornments) ) { this.f_drawAdornments( v_trLayout ); } var v_sWidth = cssParser(this["@style"], "width", true); // set to 100% only if already set to relative size v_sWidth = ( (/\d%/).test( v_sWidth ) ? "100%" : K_PRMT_sEMPTY ); this.m_elPrompt = this.f_drawInput( $CE( "td", {"width":v_sWidth}, v_trLayout ) ); this.setAriaRequired(); }; /** @private @param {C_PromptElement} v_el Container @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_drawSelectLinks = function( v_el, v_sAlignStyle ) { var v_sStyle = v_sAlignStyle; if ( typeof SYSTEMPROPERTY_SELECTVALUE_LINKS_NOWRAP !== K_PRMT_sUNDEFINED && SYSTEMPROPERTY_SELECTVALUE_LINKS_NOWRAP === true ) { v_sStyle = v_sAlignStyle + ";white-space:nowrap;padding:5px 0px 0px 0px"; } var v_aSO = this.getSelectOptions(); // bug 538852.1,587743,592296,593802 var v_iLimitWhenToHideLinks = ( this.f_isHidingGroupingBox() ? 1 : 0); if ( (!v_aSO || v_aSO.length <= v_iLimitWhenToHideLinks) && !this.m_bIsAComponent ) { v_sStyle += ";display:none"; } var v_div = $CE( "div", {"style":v_sStyle}, v_el ); if ( this[K_PRMT_sATTR_DISABLED] ) { var v_spanProps = { "class": "clsLink", "style": "text-decoration:underline;color: #CCCCCC" }; var v_span = $CE( "span", v_spanProps, v_div ); v_span.f_appendText( (v_sAlignStyle == "text-align:right") ? this[K_PRMT_LABEL_RESULTS_SELECT_ALL] : this[K_PRMT_LABEL_RESULTS_DESELECT_ALL]); v_div.f_appendText( K_PRMT_sSP ); v_span = $CE( "span", v_spanProps, v_div ); v_span.f_appendText( (v_sAlignStyle == "text-align:right") ? this[K_PRMT_LABEL_RESULTS_DESELECT_ALL] : this[K_PRMT_LABEL_RESULTS_SELECT_ALL]); } else { var v_a1 = $CE( "a", { "id": (v_sAlignStyle == "text-align:right") ? this.f_getId(K_PRMT_sSV_LINK_SELECT_PREFIX) : this.f_getId(K_PRMT_sSV_LINK_DESELECT_PREFIX), "href": "javascript:;", "onclick": "document.location.hash='';", "class": "clsLink pl"}, v_div ); v_a1.m_oPrompt = this; v_a1.f_appendText( (v_sAlignStyle == "text-align:right") ? this[K_PRMT_LABEL_RESULTS_SELECT_ALL] : this[K_PRMT_LABEL_RESULTS_DESELECT_ALL] ); v_div.f_appendText( K_PRMT_sSP ); var v_a2 = $CE( "a", { "id": (v_sAlignStyle == "text-align:right") ? this.f_getId(K_PRMT_sSV_LINK_DESELECT_PREFIX) : this.f_getId(K_PRMT_sSV_LINK_SELECT_PREFIX), "href": "javascript:;", "onclick": "document.location.hash='';", "class": "clsLink pl"}, v_div ); v_a2.f_appendText( (v_sAlignStyle == "text-align:right") ? this[K_PRMT_LABEL_RESULTS_DESELECT_ALL] : this[K_PRMT_LABEL_RESULTS_SELECT_ALL]); } }; /** Return an attribute for an object. @private @param {object} v_obj Object acting as dictionary. @param {String} v_sAttr Key for the value. @return (String) null if attribute don't exists, return attribute value as a string otherwise. */ cognos.Prompt.Control.SelectValue.prototype.f_getAttribute = function( v_obj, v_sAttr ) { var v_sValue = null; if ( typeof(v_obj[v_sAttr]) !== K_PRMT_sUNDEFINED ) { v_sValue = v_obj[v_sAttr]; if ( typeof(v_sValue) !== K_PRMT_sSTRING ) { v_sValue = v_sValue.toString(); } v_sValue = sDecodeU003( v_sValue ); } return (v_sValue); }; /** @private @return {array} */ cognos.Prompt.Control.SelectValue.prototype.f_getOptions = function( ) { var result = []; var v_elPrompt = this.m_elPrompt; if ( v_elPrompt ) { switch( this.selectUI ) { case "checkboxGroup": case "radioGroup": // find first checked radio or checkbox // v_elPrompt should be a div with a DIV/input for each value and a label as a second child var v_div = v_elPrompt.firstChild; var v_cbDiv = v_div == null ? null : v_div.firstChild; var v_cb = (v_cbDiv != null && v_cbDiv.firstChild && v_cbDiv.firstChild.tagName == "INPUT" ? v_cbDiv.firstChild : null); var v_lbl = v_cbDiv == null? null : v_cbDiv.nextSibling; while ( v_div && (v_cbDiv = v_div.firstChild) && (v_cb) && (v_lbl = v_cbDiv.nextSibling) ) { v_cb = v_cbDiv.firstChild; result.push( v_cb ); v_div = v_div.nextSibling; } break; default: // v_elPrompt should be a select control result = v_elPrompt.options; }; } return result; }; cognos.Prompt.Control.SelectValue.prototype.f_getOptionPV = function(v_elOption) { var v_oPV = null; var v_sUse = v_elOption.getAttribute(K_PRMT_sATTR_USE_VALUE); if (v_sUse === null) { v_sUse = v_elOption.value; } // for embedded IE 9 "feature" if (!v_sUse && v_elOption.attributes && v_elOption.attributes['value']) { v_sUse = v_elOption.attributes['value'].value; } var v_sDisplay = v_elOption.getAttribute(K_PRMT_sATTR_DISPLAY_VALUE); if (v_sDisplay === null) { v_sDisplay = v_elOption.getAttribute(K_PRMT_sDV); } var v_oPV = {"use": v_sUse, "display": v_sDisplay}; if ( v_elOption.getAttribute(K_PRMT_sATTR_NULL) || v_elOption.getAttribute(K_PRMT_sNULLUSE) ) { v_oPV['nil'] = true; } return v_oPV; }; /** @private @return {cognos.Value[]} */ cognos.Prompt.Control.SelectValue.prototype.f_getPV = function(bSkipType, v_allOptions) { var v_elPrompt = this.m_elPrompt; var v_aPV = []; var v_oPV = null; if ( v_elPrompt && ((this.selectUI == "checkboxGroup" || this.selectUI == "radioGroup") || ( v_elPrompt.selectedIndex >= (v_elPrompt.getAttribute('hasLabel') ? 2 : 0)) || v_allOptions)) { var v_startScanOption = 0; var v_sOptionSelectAttr;; switch( this.selectUI ) { case "checkboxGroup": case "radioGroup": v_sOptionSelectAttr = "checked"; break; default: // v_elPrompt should be a select control v_sOptionSelectAttr = "selected"; v_startScanOption = v_elPrompt.selectedIndex; };// switch var v_bBreakAfterOne = !this.isMulti(); var v_aOptions = this.f_getOptions(); var v_iLength = v_aOptions.length; if (v_allOptions) { for (var i = 0; i < v_iLength; i++) { v_aPV.push( this.f_getOptionPV(v_aOptions[i]) ); } } else { for (var i = v_startScanOption; i < v_iLength; i++) { if ( v_aOptions[i][v_sOptionSelectAttr] ) { v_aPV.push( this.f_getOptionPV(v_aOptions[i]) ); if ( v_bBreakAfterOne ) { break; } } } } } return v_aPV; }; /** Calculate a score for a option element matching a selectOption node. Scores: @private @param v_nSelectOption The selectOption node. @param v_elOption The option (UI) element. @return {Integer} */ cognos.Prompt.Control.SelectValue.prototype.f_getScore = function( v_nSelectOption, v_elOption ) { var v_iScore = 0; if ( this.f_getAttribute(v_nSelectOption, K_PRMT_sATTR_USE_VALUE) === v_elOption.value ) { v_iScore += 2; } if ( this.f_getAttribute(v_nSelectOption, K_PRMT_sATTR_DISPLAY_VALUE) === v_elOption.getAttribute(K_PRMT_sDV) ) { v_iScore += 1; } return v_iScore; }; /** Create internal hash maps for selection. One based on 'use' value and one based on 'display' value. @private @param v_oChoices The selectChoices node passed in by RSVP. @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_initSelectionDictionaries = function(v_oChoices) { var v_sUse, v_sDisplay, v_nSelectOption; this.m_oMapForUseValuesAndOptions = {}; this.m_oMapForDisplayValuesAndOptions = {}; this.m_bSelectNulls = false; for ( var v_idx = 0; v_idx < v_oChoices.c.length; v_idx++ ) { v_nSelectOption = v_oChoices.c[v_idx]; v_sUse = this.f_getAttribute(v_nSelectOption, K_PRMT_sATTR_USE_VALUE); if ( v_sUse !== null ) { this.f_addOptionInValueMap( this.m_oMapForUseValuesAndOptions, v_sUse, v_nSelectOption ); } v_sDisplay = this.f_getAttribute(v_nSelectOption, K_PRMT_sATTR_DISPLAY_VALUE); if ( v_sDisplay !== null ) { this.f_addOptionInValueMap( this.m_oMapForDisplayValuesAndOptions, v_sDisplay, v_nSelectOption ); } if ( typeof( v_nSelectOption[K_PRMT_sATTR_NULL] ) !== K_PRMT_sUNDEFINED ) { this.m_bSelectNulls = true; } } }; /** Checks if the box around the options should be hidden or not. @private @return true if checkBox groups has only one option (and the property alwaysShowGroupingBox isn't set). Returns false otherwise. */ cognos.Prompt.Control.SelectValue.prototype.f_isHidingGroupingBox = function() { var bRetVal = false; var v_aSO = this.getSelectOptions(); if ( v_aSO && v_aSO.length == 1 && this.selectUI == "checkboxGroup" && !this["@alwaysShowGroupingBox"] ) { bRetVal = true; } return bRetVal; }; /** @private @param {HTMLelement} v_oContainer @param {HTMLelement} v_elPrompt @return {HTMLelement} */ cognos.Prompt.Control.SelectValue.prototype.f_moveInContainer = function( v_oContainer, v_elPrompt ) { if ( v_oContainer && v_elPrompt ) { while (v_oContainer.hasChildNodes()) { v_oContainer.removeChild(v_oContainer.firstChild); } if ( v_elPrompt.parentNode ) { v_oContainer.appendChild( v_elPrompt.parentNode.removeChild(v_elPrompt)); } else { v_oContainer.appendChild( v_elPrompt ); } } return v_oContainer; }; /** Event handler to handle keyboard navigation for checkboxes, using up and down arrows instead of TAB/Shift-TAB @private @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_checkboxKeyNav = function(evt) { evt = ( arguments && arguments.length ? arguments[arguments.length-1] : null ); var v_oEvt = (evt || event || null); var result = false; if ( v_oEvt ) { //cancel any text selection //clearSelection(); var v_optionNode = this.f_getChkBoxRow(evt); var focusDelta = 0; if ( v_oEvt.type == "keydown" ) { var keyCode = (v_oEvt.keyCode? v_oEvt.keyCode : v_oEvt.which); if (v_oEvt.altKey || keyCode == 9 || keyCode == 13 || keyCode == K_KEY_SPACE) { return true; // Browser should use this, the control does not need alt-modified keys or the TAB key } switch (keyCode) { case K_KEY_UP: focusDelta = K_PRMT_FOCUS_MOVE_UP; break; case K_KEY_DOWN: focusDelta = K_PRMT_FOCUS_MOVE_DOWN; break; default: result = true; //select ? } } if ( focusDelta != 0 ) { var nextNode = this.f_getRelativeChkbox(focusDelta, v_optionNode); if (nextNode != null && nextNode != v_optionNode) { this.f_moveFocus( v_optionNode, nextNode ); } } PRMTUtils.F_StopEvent(v_oEvt); } return result; }; /** * Navigate the DOM to find the DIV node that represents the checkbox row */ cognos.Prompt.Control.SelectValue.prototype.f_getChkBoxRow = function(evt) { var uiNode = (evt.target || evt.srcElement || null); while ( uiNode && !(uiNode.tagName == "DIV" && uiNode.className == "clsCheckBoxRow" ) ){ uiNode = uiNode.parentNode; } return uiNode; }; /** * Return the next/prev checkbox row depending on the delta. If will loop when it reaches the last * element in each direction */ cognos.Prompt.Control.SelectValue.prototype.f_getRelativeChkbox = function(focusDelta, node) { var result = null; var parentNode = node.parentNode; if ( focusDelta == K_PRMT_FOCUS_MOVE_DOWN ) { // Next if (parentNode.lastChild == node){ result = parentNode.firstChild; } else if (node.nextSibling && node.nextSibling.className == "clsCheckBoxRow") { result = node.nextSibling; } } else if ( focusDelta == K_PRMT_FOCUS_MOVE_UP ) { //Prev if (parentNode.firstChild == node){ result = parentNode.lastChild; } else if (node.previousSibling && node.previousSibling.className == "clsCheckBoxRow") { result = node.previousSibling; } } return result; }; /** * Move focus for checkbox keyboard navigation */ cognos.Prompt.Control.SelectValue.prototype.f_moveFocus = function(prevNode, nextNode) { if (prevNode) { prevNode.tabIndex = -1; } var v_checkbox = (nextNode && nextNode.firstChild ? nextNode.firstChild.firstChild : null) ; window.setTimeout(function () { if (v_checkbox) { v_checkbox.focus();} },0); }; /** Event handler only used for the listbox in the ipad to address an ipad safari bug with a SELECT tag in a list box format @private @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_onBlur = function() { var v_aOptions = this.f_getOptions(); if (v_aOptions.length == 1) { v_aOptions.selectedIndex = 0; this.f_onChange(); } }; /** @private @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_onChange = function() { this.checkData(); if ( this["@autoSubmit"] && (!this.isRequired() || this.getValid())) { var oCV = this.f_getCV(); var v_sAutoSubmitType = ( this["@autoCascade"] || !canSubmitPrompt(this["@parameter"], oCV) ? K_ACTION_REPROMPT : K_ACTION_PROMPT ); if (oCV && typeof oCV.submitPromptValues == K_PRMT_sFUNCTION && typeof ViewerDispatcherEntry == K_PRMT_sFUNCTION){ var oReq = new ViewerDispatcherEntry(oCV); oReq.addFormField("ui.action", K_ACTION_FORWARD); oReq.addFormField("_autosubmitParameter", this["@parameter"]); oReq.addFormField("_promptControl", v_sAutoSubmitType); // set Select control name for focus oCV.setCurrentPromptControlFocus(this["@name"]); oCV.submitPromptValues(oReq); } else { SetPromptMethod(K_ACTION_FORWARD); if (document.forms[0]._autosubmitParameter) { document.forms[0]._autosubmitParameter.value = this["@parameter"]; } else if (document.forms[0]) { var frm = document.forms[0]; genHiddenInputHTML( frm.name, "_autosubmitParameter", this["@parameter"] ); } SetPromptControl( v_sAutoSubmitType ); } } }; /** Checks if an option node is a valid candidate to be selected. @private @param v_elOption 'option' element in the 'select' (UI node) @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_processOption = function( v_elOption ) { var v_aSC; if ( v_aSC = this.m_oMapForUseValuesAndOptions[ v_elOption.value ] ) { this.f_addCandidateForSelection(v_elOption, v_aSC); } if ( v_aSC = this.m_oMapForDisplayValuesAndOptions[v_elOption.getAttribute(K_PRMT_sDV)] ) { this.f_addCandidateForSelection(v_elOption, v_aSC); } if ( this.m_bSelectNulls && v_elOption.getAttribute(K_PRMT_sNULLUSE) ) { v_elOption.checked = true; v_elOption.selected = true; } }; /** @private @param {boolean} v_bSelected @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_selectAll = function( v_bSelected ) { v_bSelected = ( v_bSelected !== false ); var v_elPrompt = this.m_elPrompt; if ( v_elPrompt ) { var v_sOptionSelectAttr = (this.selectUI == "checkboxGroup" || this.selectUI == "radioGroup" ? "checked" : "selected"); var v_aOptions = this.f_getOptions(); var v_iLength = v_aOptions.length; var v_cb = null; var v_div = null; for (var i = 0; i < v_iLength; i++) { v_cb = v_aOptions[i]; v_aOptions[i][v_sOptionSelectAttr] = v_bSelected; if (v_sOptionSelectAttr == "checked") { v_div = v_cb.parentNode; if (v_cb.checked) { v_div.className = (v_cb.type == "checkbox" ? K_PRMT_CSS_CHECKBOX_CHECKED : K_PRMT_CSS_RADIOBUTTON_CHECKED); } else { v_div.className = (v_cb.type == "checkbox" ? K_PRMT_CSS_CHECKBOX : K_PRMT_CSS_RADIOBUTTON); } PRMTUtils.f_updateElementAriaChecked(v_cb, v_cb.checked); } else if (v_sOptionSelectAttr == "selected") { //REPORT-13599 v_aOptions[i].setAttribute("aria-selected",v_bSelected.toString()); } } // fix IE SELECT single mode for DeselectAll(it does not affect FF) if ( !v_bSelected ) { v_aOptions.selectedIndex = -1; } this.checkData(); } }; /** @private @param {cognos.Value} v_oPV @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_setPV = function( v_oPV ) { var v_elPrompt = this.m_elPrompt; if ( v_elPrompt ) { var v_sOptionSelectAttr = (this.selectUI == "checkboxGroup" || this.selectUI == "radioGroup" ? "checked" : "selected"); var v_aOptions = this.f_getOptions(); var v_iLength = v_aOptions.length; for (var i = 0; i < v_aOptions.length; i++) { var v_option = v_aOptions[i]; if ( v_option.value == v_oPV[K_PRMT_sUSE] ) { v_option[v_sOptionSelectAttr] = true; if (v_sOptionSelectAttr == "checked") { v_div = v_option.parentNode; v_div.className = (v_option.type == "checkbox" ? K_PRMT_CSS_CHECKBOX_CHECKED : K_PRMT_CSS_RADIOBUTTON_CHECKED); } break; } } } }; /** @private @param {cognos.Value[]} v_oChoices @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_setSelectChoices = function( v_oChoices ) { if ( !v_oChoices ) { v_oChoices = this.getSelectChoices(); } var v_oPV = null; if ( v_oChoices && v_oChoices.c && v_oChoices.c.length > 0) { this.f_initSelectionDictionaries(v_oChoices); var v_elPrompt = this.m_elPrompt; if ( v_elPrompt ) { var v_aOptions= this.f_getOptions(); if ( v_aOptions ) { var v_iLength = v_aOptions.length; for (var i = 0; i < v_iLength; i++) { this.f_processOption(v_aOptions[i]); } } } this.f_applySelection(v_oChoices); this.checkData(); // FIXME: remove the hardcoded minimal width and use CSS if (!this.f_isBUX()) { setTimeout( this.f_updateSize.bind(this), 20 ); } } }; /** @private @return {void} */ cognos.Prompt.Control.SelectValue.prototype.f_updateSize = function() { if (document.readyState == "complete") { var v_elPrompt = this.m_elPrompt; var v_sWidth = cssParser( this["@style"], "width", true ); if ( !v_sWidth ) { // Setting the width to "auto" will resize the box if ( v_elPrompt && v_elPrompt.style ) { v_elPrompt.style.width = "auto"; if (v_elPrompt.offsetWidth < 200) { // the box is too small, reset the width to its previous value. v_elPrompt.style.width = "200px"; } } } // COGCQ00833069 - If it is IE and we have a horizontal scrollbar, we adjust the height to accomodate the scrollbar so that we don't end up with a vertical scrollbar. // The original fix for COGCQ00833069 was changed to address the performance RTC defect #72240 PI46959 PROMPTS IN 10.2.2 TAKES A LONGER TIME TO LOAD // The performance degradation was observed in 10.2.2 when compared with 10.2.1 // FireFox profiler indicates that the function f_updateSize is taking a longer time to execute in 10.2.2 and the fix for COGCQ00833069 was the only code change done between 10.2.1 and 10.2.2 // Hence, the following code is trying to avoid the multiple dereferencing and the 2nd condition (v_clientHeight < v_scrollHeight && v_scrollHeight < v_offsetHeight )is split in 2 new conditions var v_clientHeight = v_elPrompt.clientHeight; if ( v_clientHeight ){ var v_scrollHeight = v_elPrompt.scrollHeight; if ( v_clientHeight < v_scrollHeight ) { var v_offsetHeight = v_elPrompt.offsetHeight; if ( v_scrollHeight < v_offsetHeight ){ v_elPrompt.style.height = v_offsetHeight + v_scrollHeight - v_clientHeight + "px"; } } } } else if ( document.readyState ) { // IE is still loading the page. // FIXME: remove the hardcoded minimal width and use CSS if (!this.f_isBUX()) { setTimeout(this.f_updateSize.bind(this), 100); } } else { // Firefox, Mozilla: remove min-width if width is explicitly set in the style. var v_sWidth = cssParser( this["@style"], "width", true ); if ( !v_sWidth ) { var v_elPrompt = this.m_elPrompt; if ( v_elPrompt && v_elPrompt.style ) { v_elPrompt.style.minWidth = "200px"; v_elPrompt.style.width = "auto"; } } } }; var C_SelectValue = cognos.Prompt.Control.SelectValue; // Keep old reference for backward compatibility with custom scripts.