Text.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| BI and PM: prmt
  5. *| (C) Copyright IBM Corp. 2002, 2022
  6. *|
  7. *| US Government Users Restricted Rights - Use, duplication or
  8. *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *|
  10. *+------------------------------------------------------------------------+
  11. */
  12. /**
  13. This script is used to provide interactivity for the textBox prompt control
  14. @private
  15. @class
  16. */
  17. cognos.Prompt.Control.Text = cognos.Prompt.Control.f_extend({
  18. f_initialize: function( v_oProps ) {
  19. this._type_ = "cognos.Prompt.Control.Text";
  20. this.f_parent( v_oProps ); // call parent's initialize()
  21. this.m_reMultiLineDelimiters = new RegExp("[\\n\\f\\r\\t]");
  22. this.m_bIsCurrency = false;
  23. // by default we allow zeros in the text areas
  24. if ( this["@allowZero"] !== false )
  25. {
  26. this["@allowZero"] = true;
  27. }
  28. if ( !this["@dataType"] && this["@numbersOnly"] )
  29. {
  30. this["@dataType"] = "number";
  31. }
  32. if ( this["@showThousandSeparator"] && this["@showThousandSeparator"] !== false )
  33. {
  34. this["@showThousandSeparator"] = true;
  35. }
  36. this.m_sCurrentValue = ( this["@defaultValue"] ? sDecodeU003( this["@defaultValue"] ) : K_PRMT_sEMPTY );
  37. //create regular expressions for parsing with current locale
  38. initParsingRegularExpressions();
  39. this.f_initCompleted();
  40. },
  41. //validate the input into the control
  42. checkData: function()
  43. {
  44. // We keep a reference to the parent function
  45. // Calling this.m_oFrom functions seems to have a side effect on this.f_parent().
  46. var v_fnParent = this.f_parent;
  47. this.checkRequired();
  48. if ( this.isRequired() && !this.isMulti() && !(this.getValue()) )
  49. {
  50. this.m_bValid = false;
  51. }
  52. else
  53. {
  54. //determine whether this is a single value or multiple values
  55. var v_aInsertText = this.m_oForm.value.split( this.m_reMultiLineDelimiters );
  56. if (v_aInsertText.length > 1)
  57. {
  58. var bParseValid = true;
  59. for (var i=0; i < v_aInsertText.length; i++)
  60. {
  61. var bTest = sParseByDataType( v_aInsertText[i], this["@dataType"] );
  62. if (bTest === false)
  63. {
  64. bParseValid = false;
  65. }
  66. }
  67. if (bParseValid == false)
  68. {
  69. this.m_bValid = false;
  70. }
  71. else
  72. {
  73. this.m_bValid = true;
  74. this.m_sCurrentValue = this.m_oForm.value;
  75. //set the form value for non-xml prompts
  76. if (this["@submitType"] != K_PRMT_sXML && this.m_oSubmit)
  77. {
  78. this.m_oSubmit.value = this.m_sCurrentValue;
  79. }
  80. }
  81. }
  82. else
  83. {
  84. var sValue = this.bParse(this.m_oForm.value, this["@dataType"]);
  85. if ( sValue === false && this.m_oForm.value != K_PRMT_sEMPTY )
  86. {
  87. this.m_bValid = false;
  88. }
  89. else
  90. {
  91. this.m_bValid = true;
  92. //set the form value for non-xml prompts
  93. if (this["@submitType"] != K_PRMT_sXML && this.m_oSubmit)
  94. {
  95. this.m_oSubmit.value = this.m_sCurrentValue;
  96. }
  97. }
  98. }
  99. }
  100. this.f_parent = v_fnParent; // call parent's checkData using saved reference.
  101. this.f_parent(); // call parent's checkData using saved reference.
  102. return this.m_bValid;
  103. },
  104. clearValues: function() {
  105. this.f_parent();
  106. this.f_clear();
  107. },
  108. f_drawCompleted: function()
  109. {
  110. v_InputId = this.f_getId(K_PRMT_sTB_PREFIX);
  111. var v_oInput = $( v_InputId );
  112. v_oInput.m_oPrompt = this;
  113. // link a11y label if it exists using FOR
  114. var v_a11yLabel = $( this.f_getId("PRMT_LBL_") );
  115. if ( v_a11yLabel && !v_a11yLabel.getAttribute("for")) {
  116. v_a11yLabel.setAttribute("for", v_InputId);
  117. }
  118. PRMTUtils.f_addEvent( v_oInput, "keyup", this.f_keyUp.bind(this) );
  119. PRMTUtils.f_addEvent( v_oInput, "keypress", this.f_keyPress.bind(this) );
  120. PRMTUtils.f_addEvent( v_oInput, "blur", this.f_endCheckDataInterval.bind(this) );
  121. PRMTUtils.f_addEvent( v_oInput, "contextmenu", this.f_startCheckDataInterval.bind(this) );
  122. this.m_elPrompt = this.m_oForm = v_oInput;
  123. this.f_parent(); // call parent's f_drawCompleted
  124. this.f_lostFocus();
  125. // Bidi text style
  126. if ( G_IsBidiEnabled && this["@contentTextDirection"] && !this["@hideText"]) {
  127. this.m_oForm.style.direction = PRMT_BidiUtils.getTextDirection(this.m_oForm.value, this["@contentTextDirection"]);
  128. }
  129. }
  130. });
  131. /**
  132. Parse the current input and validate the data.
  133. @private
  134. @param {String} sValue
  135. @param {String} sDataType
  136. @return {boolean}
  137. */
  138. cognos.Prompt.Control.Text.prototype.bParse = function(sValue, sDataType)
  139. {
  140. var sTestString = sParseByDataType(sValue, sDataType, this["@allowZero"]);
  141. var v_bRetVal = true;
  142. if (sTestString === false)
  143. {
  144. this.m_bIsCurrency = false;
  145. v_bRetVal = false;
  146. }
  147. else
  148. {
  149. sTestString = sTestString.toString();
  150. //persist currency character?
  151. var z = sTestString.search(rCurrencySymbol);
  152. this.m_bIsCurrency = (z != -1);
  153. this.m_sCurrentValue = sTestString;
  154. }
  155. return v_bRetVal;
  156. };
  157. /**
  158. Check if value has changed.
  159. @private
  160. @return {void}
  161. */
  162. cognos.Prompt.Control.Text.prototype.checkValueChange = function()
  163. {
  164. if (this.m_oForm.value != this.m_sCurrentValue)
  165. {
  166. this.f_endCheckDataInterval();
  167. }
  168. };
  169. /**
  170. Remove all values from the prompt control.
  171. @private
  172. @return {void}
  173. */
  174. cognos.Prompt.Control.Text.prototype.f_clear = function()
  175. {
  176. this.f_clearMemberValue("m_oSubmit");
  177. this.m_oForm.value = K_PRMT_sEMPTY;
  178. this.m_sCurrentValue = K_PRMT_sEMPTY;
  179. };
  180. cognos.Prompt.Control.Text.prototype.f_clearMemberValue = function(v_member)
  181. {
  182. if (!this[v_member]) {
  183. this[v_member] = {};
  184. }
  185. this[v_member]["value"] = K_PRMT_sEMPTY;
  186. };
  187. /**
  188. Compare values. See {@link cognos.Prompt.Control#f_compare} for details.
  189. @see cognos.Prompt.Control#f_compare
  190. @private
  191. @return {Integer}
  192. */
  193. cognos.Prompt.Control.Text.prototype.f_compare = function( v_oValue )
  194. {
  195. var v_iRetval = 1;
  196. if ( SYSTEMPROPERTY_REORDER_TEXT_VALUES_IN_RANGES === true && v_oValue )
  197. {
  198. var v_thisValue = null;
  199. var v_compareTo = null;
  200. if (this["@dataType"] == "number")
  201. {
  202. v_thisValue = parseFloat(this.m_sCurrentValue);
  203. v_compareTo = parseFloat(v_oValue.m_sCurrentValue);
  204. }
  205. else
  206. {
  207. v_thisValue = this.m_sCurrentValue;
  208. v_compareTo = v_oValue.m_sCurrentValue;
  209. }
  210. if ( v_compareTo > v_thisValue )
  211. {
  212. v_iRetval = -1;
  213. }
  214. else if (v_compareTo == v_thisValue)
  215. {
  216. v_iRetval = 0;
  217. }
  218. }
  219. return v_iRetval;
  220. };
  221. /**
  222. Sets the JavaScript references used by custom scripts based on generated code from Blaring and before.
  223. (Custom Scripts Workaround)
  224. @private
  225. @return {void}
  226. */
  227. cognos.Prompt.Control.Text.prototype.f_CSW_init = function()
  228. {
  229. this.f_CSW_SetFormElement("_textEditBox");
  230. };
  231. /**
  232. @private
  233. @param {C_PromptElement} v_el Container.
  234. @return {void}
  235. */
  236. cognos.Prompt.Control.Text.prototype.f_drawInput = function( v_el )
  237. {
  238. var v_oInput = null;
  239. var v_oP = {
  240. "style": cssParser(this["@style"], 'color,font,text'),
  241. "class": "clsTextWidget pt"
  242. };
  243. if ( this["@maxLength"] !== K_PRMT_sEMPTY && !isNaN(this["@maxLength"]) )
  244. {
  245. v_oP.maxLength = this["@maxLength"];
  246. }
  247. if ( this["@readOnly"] )
  248. {
  249. v_oP.readOnly = true;
  250. }
  251. // With display:inline-table, width:100% work in IE too
  252. if ( cssParser( this["@style"], "width" ) )
  253. {
  254. v_oP.style += ";width:100%";
  255. }
  256. if ( this["@size"] )
  257. {
  258. v_oP.size = this["@size"];
  259. }
  260. if ( this[K_PRMT_sATTR_DISABLED] )
  261. {
  262. v_oP.disabled = true;
  263. }
  264. // title for WCAG 2.0
  265. if ( this["@title"] )
  266. {
  267. v_oP.title = this["@title"];
  268. }
  269. if ( this.isRequired() )
  270. {
  271. v_oP["aria-required"] = "true";
  272. }
  273. // Password field
  274. if (this["@hideText"])
  275. {
  276. v_oP.type = "password";
  277. v_oP.autocomplete = "off";
  278. v_oP.value = this.m_sCurrentValue;
  279. v_oInput = $CE( "input", v_oP );
  280. }
  281. // Single line edit box
  282. else if (!this["@multiLine"])
  283. {
  284. var v_customHeight = cssParser( this["@style"], "height", true );
  285. if ( !(/\d%/).test(v_customHeight) )
  286. {
  287. v_oP.style += ";height:" + v_customHeight;
  288. }
  289. v_oP.type = "text";
  290. v_oP.value = this.m_sCurrentValue;
  291. v_oInput = $CE( "input", v_oP );
  292. }
  293. // Multi line edit box
  294. else
  295. {
  296. var v_customHeight = cssParser( this["@style"], "height", true );
  297. if ( !(/\d%/).test(v_customHeight) )
  298. {
  299. v_oP.style += ";height:" + v_customHeight;
  300. }
  301. v_oP.rows = 7;
  302. v_oP.cols = 20;
  303. v_oInput = $CE( "textarea", v_oP );
  304. v_oInput.f_appendText( this.m_sCurrentValue );
  305. }
  306. var sId = this.f_getId(K_PRMT_sTB_PREFIX);
  307. v_oInput.f_setProperty( "id", this.f_getId(K_PRMT_sTB_PREFIX) );
  308. v_el.f_appendChild( v_oInput );
  309. //set the default parameter values
  310. if (this.m_sCurrentValue)
  311. {
  312. //convert the default value to the locale
  313. var sLocaleDefaultValue = convertSQLToLocale(this.m_sCurrentValue, this["@dataType"]);
  314. var sText = sLocaleDefaultValue;
  315. if (this.bParse(sLocaleDefaultValue, this["@dataType"]) == true)
  316. {
  317. sText = this.m_sCurrentValue;
  318. }
  319. v_oInput.value = getFormatByDataType( sText, this["@dataType"], this.m_bIsCurrency, this.f_getShowThousandSeparator() );
  320. }
  321. else
  322. {
  323. this.m_sCurrentValue = K_PRMT_sEMPTY;
  324. }
  325. return v_oInput;
  326. };
  327. /**
  328. * Getter for range inputId
  329. * rangeInputId used by range label to associate the label (From/To) to the input when there are not radio buttons
  330. *
  331. */
  332. cognos.Prompt.Control.Text.prototype.f_getRangeInputId = function() {
  333. return (this.f_getId(K_PRMT_sTB_PREFIX));
  334. }
  335. /**
  336. Stop the control from checking for changed/valid data.
  337. @private
  338. @return {void}
  339. */
  340. cognos.Prompt.Control.Text.prototype.f_endCheckDataInterval = function()
  341. {
  342. if (typeof this.m_intervalId != K_PRMT_sUNDEFINED)
  343. {
  344. clearInterval(this.m_intervalId);
  345. }
  346. this.f_lostFocus();
  347. this.checkData();
  348. };
  349. /**
  350. @private
  351. @return {cognos.Value[]}
  352. */
  353. cognos.Prompt.Control.Text.prototype.f_getPV = function()
  354. {
  355. var v_oPV = null;
  356. if ( this.hasValue() )
  357. {
  358. if ( this["@multiLine"] && this.m_oChoices )
  359. {
  360. var v_sText = this.sGetValue();
  361. var v_bAllowEmptyStrings = window.isAllowEmptyStrings ? window.isAllowEmptyStrings() : true;
  362. var v_aInsertText = v_sText.split( this.m_reMultiLineDelimiters );
  363. v_oPV = [];
  364. for (var i=0; i < v_aInsertText.length; i++)
  365. {
  366. if (v_aInsertText[i].length == 0 && v_bAllowEmptyStrings == false)
  367. {
  368. continue;
  369. }
  370. var v_sFormatValue = getFormatByDataType( v_aInsertText[i], this["@dataType"], this.m_bIsCurrency );
  371. v_oPV.push( {"use": v_aInsertText[i], "display": v_sFormatValue } );
  372. }
  373. }
  374. else
  375. {
  376. v_oPV = {"use": this.sGetValue(), "display": this.sGetFormatValue()};
  377. }
  378. }
  379. return v_oPV;
  380. };
  381. /**
  382. @private
  383. @return {boolean}
  384. */
  385. cognos.Prompt.Control.Text.prototype.f_getShowThousandSeparator = function()
  386. {
  387. return ( this["@showThousandSeparator"] ? true : false );
  388. };
  389. /**
  390. Catch the backspace key. Some browsers (IE5.5) don't capture this event.
  391. @private
  392. @return {boolean}
  393. */
  394. cognos.Prompt.Control.Text.prototype.f_keyPress = function (evt)
  395. {
  396. var evt = ( arguments && arguments.length ? arguments[arguments.length-1] : null );
  397. var v_oEvt = (evt ? evt : (typeof event != K_PRMT_sUNDEFINED ? event : null ));
  398. if ( v_oEvt )
  399. {
  400. var keyCode = (v_oEvt.keyCode) ? v_oEvt.keyCode : v_oEvt.which;
  401. if (keyCode == '8')
  402. {
  403. //check the data that has been typed in
  404. this.checkData();
  405. }
  406. else if (keyCode=='13' && !this["@multiLine"])
  407. {
  408. var oCV = this.f_getCV();
  409. if ( this.m_oChoices )
  410. {
  411. if ( this.m_bValid )
  412. {
  413. this.m_oChoices.F_Insert();
  414. }
  415. }
  416. else if ( oCV && (typeof oCV.canSubmitPrompt == K_PRMT_sFUNCTION) && oCV.canSubmitPrompt() && (typeof oCV.promptAction == K_PRMT_sFUNCTION))
  417. {
  418. // submits the form
  419. oCV.promptAction(K_ACTION_NEXT);
  420. }
  421. return PRMTUtils.F_StopEvent( v_oEvt );
  422. }
  423. }
  424. return true;
  425. };
  426. /**
  427. @private
  428. @return {void}
  429. */
  430. cognos.Prompt.Control.Text.prototype.f_keyUp = function(evt)
  431. {
  432. var evt = ( arguments && arguments.length ? arguments[arguments.length-1] : null );
  433. this.checkData();
  434. if ( !this["@multiLine"] )
  435. {
  436. PRMTUtils.F_PreventSubmit(evt);
  437. }
  438. if ( G_IsBidiEnabled && this["@contentTextDirection"] && !this["@hideText"] )
  439. {
  440. PRMT_BidiUtils.fixInputDirection(evt.target ? evt.target : evt.srcElement, this["@contentTextDirection"], 'true');
  441. }
  442. };
  443. /**
  444. Update UI when control is losing the focus.
  445. @private
  446. @return {void}
  447. */
  448. cognos.Prompt.Control.Text.prototype.f_lostFocus = function()
  449. {
  450. //dynamically format values in the text box
  451. if ( this.bParse(this.m_oForm.value, this["@dataType"]) !== false)
  452. {
  453. var v_sFormatValue = this.sGetFormatValue();
  454. if ( v_sFormatValue !== false)
  455. {
  456. this.m_oForm.value = v_sFormatValue;
  457. }
  458. }
  459. if ( this["@multiLine"] )
  460. {
  461. this.checkData();
  462. }
  463. };
  464. /**
  465. @private
  466. @param {cognos.Value} v_oPV
  467. @return {void}
  468. */
  469. cognos.Prompt.Control.Text.prototype.f_setPV = function( v_oPV )
  470. {
  471. var v_sValue = v_oPV[K_PRMT_sUSE];
  472. if ( this["@dataType"] == "percentage" )
  473. {
  474. v_sValue = sParseOutCommon(v_sValue);
  475. v_sValue = sMultiplyBy100(v_sValue);
  476. }
  477. v_sValue = convertSQLToLocale(v_sValue, this["@dataType"]);
  478. this.m_oForm.value = v_sValue;
  479. this.f_lostFocus();
  480. };
  481. /**
  482. Set an interval in which the control will check for changed/valid data.
  483. @private
  484. @return {void}
  485. */
  486. cognos.Prompt.Control.Text.prototype.f_startCheckDataInterval = function( v_iInterval )
  487. {
  488. if ( typeof v_iInterval != "number" )
  489. {
  490. v_iInterval = 100;
  491. }
  492. this.m_sCurrentValue = this.m_oForm.value;
  493. this.m_intervalId = setInterval( this.checkValueChange.bind(this), v_iInterval );
  494. };
  495. /**
  496. @private
  497. @return {Integer}
  498. */
  499. cognos.Prompt.Control.Text.prototype.getDecimalSize = function()
  500. {
  501. var sTest = this.sGetValue();
  502. // we are testing against the use value which will always have a value of "." no matter which locale we're in
  503. var iDecimalPos = -1;
  504. if (sTest !== false)
  505. {
  506. iDecimalPos = sTest.lastIndexOf(K_PRMT_sDOT);
  507. }
  508. //test for a decimal place
  509. if (iDecimalPos != -1)
  510. {
  511. //strip the leading characters
  512. sTest= sTest.substring (iDecimalPos +1);
  513. //strip any non numerics
  514. var iLastNumber = sTest.search(/\D/);
  515. if (iLastNumber != -1)
  516. {
  517. sTest = sTest.substring (0, iLastNumber);
  518. }
  519. return sTest.length;
  520. }
  521. return 0;
  522. };
  523. /**
  524. Return the value from the textbox.
  525. @private
  526. @return {String}
  527. */
  528. cognos.Prompt.Control.Text.prototype.getValue = function()
  529. {
  530. return this.m_oForm.value;
  531. };
  532. /**
  533. @private
  534. @return {boolean}
  535. */
  536. cognos.Prompt.Control.Text.prototype.hasValue = function()
  537. {
  538. return ( this.m_bValid && !this.isEmpty() ? true: false );
  539. };
  540. /**
  541. * By default, returns true if the control does not return any value.
  542. *
  543. * @private
  544. * @return {boolean}
  545. */
  546. cognos.Prompt.Control.Text.prototype.isEmpty = function()
  547. {
  548. return (this.m_oForm && this.m_oForm.value && this.m_oForm.value.length > 0? false : true);
  549. };
  550. /**
  551. Check if this control is valid, i.e. ready to submit.
  552. @private
  553. @return {boolean} <i>true</i> if this control has a valid selection.
  554. */
  555. cognos.Prompt.Control.Text.prototype.isValid = function()
  556. {
  557. result = false;
  558. if ( this.isRequired() && this.isMulti() && this.m_oChoices ) {
  559. result = this.m_oChoices.f_getValid();
  560. } else {
  561. this.checkData();
  562. result = (this.m_bValid===true);
  563. }
  564. return result;
  565. };
  566. /**
  567. Hndle focus given to the control.
  568. @private
  569. @param {HTMLelement} obj Element to give the focus to.
  570. @return {void}
  571. */
  572. cognos.Prompt.Control.Text.prototype.setCurrentFocus = function(obj)
  573. {
  574. this.m_oCurrentFocus = obj;
  575. this.m_oCurrentFocus.select();
  576. };
  577. /**
  578. @private
  579. @return {void}
  580. */
  581. cognos.Prompt.Control.Text.prototype.setCurrentValue = function()
  582. {
  583. this.m_oForm.value = this.m_sCurrentValue;
  584. };
  585. /**
  586. Return a formatted value.
  587. @private
  588. @return {String} Returns false (boolean) if invalid.
  589. */
  590. cognos.Prompt.Control.Text.prototype.sGetFormatValue = function()
  591. {
  592. if (!this.m_bisGetValuesCall) {
  593. this.checkData();
  594. }
  595. if (this.m_bValid == true)
  596. {
  597. return getFormatByDataType(this.sGetValue(), this["@dataType"], this.m_bIsCurrency, this.f_getShowThousandSeparator());
  598. }
  599. else
  600. {
  601. return false;
  602. }
  603. };
  604. /**
  605. Return a valid value.
  606. @private
  607. @return {String} The value or false if invalid.
  608. */
  609. cognos.Prompt.Control.Text.prototype.sGetValue = function()
  610. {
  611. if (!this.m_bisGetValuesCall) {
  612. this.checkData();
  613. }
  614. if (this.m_bValid == true)
  615. {
  616. return (K_PRMT_sEMPTY + this.m_sCurrentValue);
  617. }
  618. return false;
  619. };
  620. var C_Text = cognos.Prompt.Control.Text; // Keep old reference for backward compatibility with custom scripts.