ParameterController.js 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. /* Copyright (c) Business Objects 2006. All rights reserved. */
  2. /* TODO Dave
  3. * - Use delete button to set value to empty string if it can't be removed
  4. */
  5. /**
  6. * ParameterController creates and controls the widgets that show and edit
  7. * parameter values in the interactive parameter panel.
  8. *
  9. * @param panel [ParameterPanel] Panel that will contain the parameter widgets
  10. * @param viewerCtrl [ViewerListener] Controller for the entire viewer
  11. * @param paramOpts [Object] Parameter options, such as dateTimeFormat
  12. */
  13. bobj.crv.params.ParameterController = function(panel, viewerCtrl, paramOpts) {
  14. this._panel = panel;
  15. this._viewerCtrl = viewerCtrl;
  16. this._paramOpts = paramOpts;
  17. this._paramList = null;
  18. this._selected = null; // Selected parameter widget
  19. this._selectedValueIdx = null; // Index of selected value
  20. this._disablePanel = false; // in drilldown views, the panel needs to be disabled
  21. var delClickCB = MochiKit.Base.bind(this._onClickTbDeleteButton,this);
  22. var applyClickCB = MochiKit.Base.bind(this._onClickTbApplyButton,this);
  23. this._panel.setToolbarCallBacks(delClickCB,applyClickCB);
  24. };
  25. bobj.crv.params.ParameterController.prototype = {
  26. /**
  27. * Set the list of parameters to display in the parameter panel.
  28. *
  29. * @param paramList [Array] List of bobj.crv.params.Parameter instances
  30. */
  31. setParameters: function(paramList) {
  32. var Type = bobj.crv.params.DataTypes;
  33. var map = MochiKit.Base.map;
  34. var bind = MochiKit.Base.bind;
  35. this._deleteWidgets();
  36. this._paramList = paramList;
  37. this._selected = null;
  38. this._selectedValueIdx = null;
  39. for (var i = 0; i < paramList.length; ++i) {
  40. var param = paramList[i];
  41. // Adding callbacks for when a duplicate value is detected
  42. var hasDuplicateValueCB = bind(this._onParamHasDupValue,this, param);
  43. var hasNoDuplicateValueCB = bind(this._onParamHasNoDupValue, this, param);
  44. param.addDuplicateValuesCB(hasDuplicateValueCB, hasNoDuplicateValueCB);
  45. var getDisplayText = bind(this._getDisplayText, this, param);
  46. var getDefaultValue = bind(this._getDefaultValue, this, param.valueDataType,param.defaultDisplayType);
  47. var panelCanChangeValues = this._canPanelChangeValues(param);
  48. var minMaxText = this._getMinMaxText(param.valueDataType, param.minValue, param.maxValue);
  49. var openAdvDialogCB = MochiKit.Base.bind(this._onClickTbAdvButton, this);
  50. var isReadOnly = !param.isEditable;
  51. var paramValue = param.getValue();
  52. // we need to treat the parameter as readOnly if the current view is not the MainReport
  53. var currentView = this._viewerCtrl.getCurrentView ();
  54. if(currentView && !currentView.isMainReport ()) {
  55. this._disablePanel = true;
  56. isReadOnly = true;
  57. panelCanChangeValues = false;
  58. }
  59. // Removing Null value from value list when parameter is nullable and has only null value.
  60. if(param.allowNullValue == true && paramValue != null && paramValue.length == 1 && paramValue[0] == null) {
  61. paramValue = [];
  62. }
  63. // TODO: Post Titan, We should be delgating some of the logic to the consumer regarding parameter attributes.
  64. // It will be much cleaner to pass around the entire param object rather than specific details.
  65. var paramWidget = bobj.crv.params.newParameterUI({
  66. values: map(getDisplayText, paramValue),
  67. canChangeOnPanel: panelCanChangeValues,
  68. allowCustom: param.allowCustomValue,
  69. canAddValues: param.allowMultiValue && panelCanChangeValues,
  70. isReadOnlyParam: isReadOnly,
  71. isPassword: param.isPassword(),
  72. valueRequired: (!param.isOptionalPrompt && !param.allowNullValue),
  73. defaultValues: map(getDefaultValue, param.defaultValues || []),
  74. hasRowButtons: param.allowCustomValue && panelCanChangeValues &&
  75. (param.valueDataType === Type.DATE || param.valueDataType === Type.DATE_TIME),
  76. rowButtonsUrl: bobj.crvUri('images/calendar.gif'),
  77. openAdvDialogCB: openAdvDialogCB,
  78. maxNumParameterDefaultValues: this._paramOpts.maxNumParameterDefaultValues,
  79. tooltip : param.getTitle()
  80. });
  81. this._observeParamWidget(paramWidget);
  82. this._panel.addParameter({paramUI: paramWidget,
  83. label : param.getTitle(),
  84. isDataFetching: param.isDataFetching,
  85. isReadOnly: !param.isEditable, // this controls the strictly the readOnly.
  86. // This should only show if the report designer marked the parameter as readOnly.
  87. isDirty: false,
  88. selectCB: bind(this._onSelectValue, this, paramWidget, 0),
  89. openAdvCB: isReadOnly? null : openAdvDialogCB,
  90. minMaxTooltip: minMaxText
  91. });
  92. }
  93. this._panel.resize();
  94. },
  95. /**
  96. * Get the list of params that are displayed in the panel
  97. *
  98. * @return [Array] List of bobj.crv.params.Parameter instances or null
  99. */
  100. getParameters: function() {
  101. return this._paramList;
  102. },
  103. /**
  104. * Sets the current values of the param with the same name as the one passed
  105. * in and updates the UI.
  106. *
  107. * @param [Parameter]
  108. */
  109. updateParameter: function(paramName, paramValue) {
  110. if (paramName) {
  111. var index = -1;
  112. for (var i = 0; i < this._paramList.length; ++i) {
  113. if (this._paramList[i].paramName === paramName) {
  114. this._paramList[i].setValue(paramValue);
  115. index = i;
  116. break;
  117. }
  118. }
  119. if (index != -1) {
  120. var paramUI = this._panel.getParameter(index);
  121. var getDisplayText = MochiKit.Base.bind(this._getDisplayText, this, this._paramList[index]);
  122. if(this._paramList[i].allowNullValue && paramValue.length == 1 && paramValue[0] == null) {
  123. paramValue = [];
  124. }
  125. paramUI.setValues( MochiKit.Base.map(getDisplayText, paramValue) );
  126. if(!paramUI.valueRequired && !paramUI.canAddValues) {
  127. if(paramValue.length > 0) {
  128. paramUI.showRowCreater(false);
  129. }
  130. else {
  131. paramUI.showRowCreater(true);
  132. }
  133. }
  134. this._panel.setDirty(index, paramUI.isDirty());
  135. }
  136. }
  137. },
  138. /**
  139. * Checks whether a parameter can be edited directly in the panel. Params
  140. * that can't be edited in the panel are either read-only or must be
  141. * edited in the Advanced Dialog.
  142. *
  143. * @param param [Parameter]
  144. *
  145. * @return [bool] True if ParameterPanel is capable of changing the
  146. * parameter's values. False otherwise.
  147. */
  148. _canPanelChangeValues: function(param) {
  149. return param && param.isEditable && !param.allowRangeValue && !param.editMask && !param.isDCP();
  150. },
  151. /**
  152. * Private. Deletes the parameter widgets in the panel.
  153. */
  154. _deleteWidgets: function() {
  155. var paramUI = this._panel.getParameter(0);
  156. while (paramUI) {
  157. delete _widgets[paramUI.widx];
  158. this._panel.removeParameter(0);
  159. paramUI = this._panel.getParameter(0);
  160. }
  161. },
  162. /**
  163. * Private. Compares 2 objects that have date like members (y, m, d, h, min, s, ms)
  164. * returns true if all members match, false otherwise.
  165. */
  166. _compareCustomDateObject: function(valA, valB) {
  167. if (valA.y != valB.y) {
  168. return false;
  169. }
  170. if (valA.m != valB.m) {
  171. return false;
  172. }
  173. if (valA.d != valB.d) {
  174. return false;
  175. }
  176. if (valA.h != valB.h) {
  177. return false;
  178. }
  179. if (valA.min != valB.min) {
  180. return false;
  181. }
  182. if (valA.s != valB.s) {
  183. return false;
  184. }
  185. if (valA.ms != valB.ms) {
  186. return false;
  187. }
  188. return true;
  189. },
  190. /**
  191. * Private. Erom doesn't give us NULL in all cases so we need to compare against the boundary values for each type.
  192. * type - the value type
  193. * minValue - the value to check
  194. * returns true if the minValue is NOT equal NULL or the MIN value for the given datatype.
  195. */
  196. _hasMinBound: function(type,minValue) {
  197. if (minValue == null) {
  198. return false;
  199. }
  200. var Type = bobj.crv.params.DataTypes;
  201. switch(type) {
  202. case Type.STRING:
  203. if (minValue == 0) {
  204. return false;
  205. }
  206. return true;
  207. case Type.DATE:
  208. case Type.DATE_TIME:
  209. absoluteMin = {y:1753, m:0, d:1, h:0, min:0, s:0, ms:0};
  210. return !this._compareCustomDateObject (absoluteMin, minValue);
  211. case Type.TIME:
  212. absoluteMin = {y:1899, m:11, d:30, h:0, min:0, s:0, ms:0};
  213. return !this._compareCustomDateObject (absoluteMin, minValue);
  214. case Type.NUMBER:
  215. case Type.CURRENCY:
  216. if (minValue == -3.40282346638529e+38) {
  217. return false;
  218. }
  219. return true;
  220. }
  221. // should not get here!
  222. return false;
  223. },
  224. /**
  225. * Private. Erom doesn't give us NULL in all cases so we need to compare against the boundary values for each type.
  226. * type - the value type
  227. * minValue - the value to check
  228. * returns true if the maxValue is NOT equal NULL or the MAX value for the given datatype.
  229. */
  230. _hasMaxBound: function(type,maxValue) {
  231. if (maxValue == null) {
  232. return false;
  233. }
  234. var Type = bobj.crv.params.DataTypes;
  235. switch(type) {
  236. case Type.STRING:
  237. if (maxValue == 65534) {
  238. return false;
  239. }
  240. return true;
  241. case Type.DATE:
  242. absoluteMax = {y:9999, m:11, d:12, h:0, min:0, s:0, ms:0};
  243. return !this._compareCustomDateObject (absoluteMax, maxValue);
  244. case Type.TIME:
  245. absoluteMax = {y:1899, m:11, d:30, h:23, min:59, s:59, ms:0};
  246. return !this._compareCustomDateObject (absoluteMax, maxValue);
  247. case Type.DATE_TIME:
  248. absoluteMax = {y:9999, m:11, d:12, h:23, min:59, s:59, ms:0};
  249. return !this._compareCustomDateObject (absoluteMax, maxValue);
  250. case Type.NUMBER:
  251. case Type.CURRENCY:
  252. if (maxValue == 3.40282346638529e+38) {
  253. return false;
  254. }
  255. return true;
  256. }
  257. // should not get here!
  258. return false;
  259. },
  260. _getMinMaxText: function(type,minValue,maxValue) {
  261. var Type = bobj.crv.params.DataTypes;
  262. var maxValueDisplay,minValueDisplay;
  263. if(type == Type.STRING) {
  264. /* because min/max of string are in number format */
  265. minValueDisplay = this._getValueText(Type.NUMBER , minValue);
  266. maxValueDisplay = this._getValueText(Type.NUMBER, maxValue);
  267. }
  268. else {
  269. minValueDisplay = this._getValueText(type, minValue);
  270. maxValueDisplay = this._getValueText(type, maxValue);
  271. }
  272. if(type == Type.BOOLEAN || (minValue == null && maxValue == null)) {
  273. return null;
  274. }
  275. var displayType,returnString;
  276. switch(type) {
  277. case Type.DATE:
  278. displayType = L_bobj_crv_Date;
  279. break;
  280. case Type.TIME:
  281. displayType = L_bobj_crv_Time;
  282. break;
  283. case Type.DATE_TIME:
  284. displayType = L_bobj_crv_DateTime;
  285. break;
  286. case Type.NUMBER:
  287. displayType = L_bobj_crv_Number;
  288. break;
  289. case Type.CURRENCY:
  290. displayType = L_bobj_crv_Number;
  291. break;
  292. }
  293. var hasMinBound = this._hasMinBound (type, minValue);
  294. var hasMaxBound = this._hasMaxBound (type, maxValue);
  295. switch(type) {
  296. case Type.STRING:
  297. if(hasMinBound && hasMaxBound) {
  298. returnString = L_bobj_crv_ParamsStringMinAndMaxTooltip.replace("%1", minValueDisplay);
  299. returnString = returnString.replace("%2",maxValueDisplay);
  300. }
  301. else if(hasMinBound) {
  302. returnString = L_bobj_crv_ParamsStringMinOrMaxTooltip.replace("%1", L_bobj_crv_Minimum);
  303. returnString = returnString.replace("%2", minValueDisplay);
  304. }
  305. else if(hasMaxBound) {
  306. returnString = L_bobj_crv_ParamsStringMinOrMaxTooltip.replace("%1", L_bobj_crv_Maximum);
  307. returnString = returnString.replace("%2", maxValueDisplay);
  308. }
  309. break;
  310. default:
  311. if(hasMinBound && hasMaxBound) {
  312. returnString = L_bobj_crv_ParamsMinAndMaxTooltip.replace("%1", displayType);
  313. returnString = returnString.replace("%2",minValueDisplay);
  314. returnString = returnString.replace("%3",maxValueDisplay);
  315. }
  316. else if(hasMinBound) {
  317. returnString = L_bobj_crv_ParamsMinTooltip.replace("%1", displayType);
  318. returnString = returnString.replace("%2", minValueDisplay);
  319. }
  320. else if(hasMaxBound) {
  321. returnString = L_bobj_crv_ParamsMaxTooltip.replace("%1", displayType);
  322. returnString = returnString.replace("%2", maxValueDisplay);
  323. }
  324. }
  325. return returnString;
  326. },
  327. /**
  328. * Constructs description and display value for default values
  329. * @param type [bobj.crv.params.DataTypes]
  330. * @param displayType [bobj.crv.params.DefaultValueDisplayTypes]
  331. * @param value [Object] Parameter value to convert to text
  332. *
  333. * @return {value: convertedValue, desc: description}
  334. */
  335. _getDefaultValue: function(type, displayType, valueObj) {
  336. var displayTypes = bobj.crv.params.DefaultDisplayTypes;
  337. var valueText = this._getValueText(type, valueObj.value);
  338. var valueDesc;
  339. switch(displayType) {
  340. case displayTypes.Description:
  341. if(valueObj.desc != null && valueObj.desc.length > 0) {
  342. valueDesc = valueObj.desc;
  343. }
  344. else {
  345. valueDesc = valueText;
  346. }
  347. break;
  348. case displayTypes.DescriptionAndValue: // Value And Description
  349. valueDesc = valueText;
  350. if(valueObj.desc != null && valueObj.desc.length > 0) {
  351. valueDesc += ' - ' + valueObj.desc;
  352. }
  353. break;
  354. }
  355. return valueDesc;
  356. },
  357. /*
  358. * Private. Convert value text which could contains description to value text based on default values of param
  359. * @param param [bobj.crv.params.Parameter] Value's data type (bobj.crv.params.DataTypes)
  360. * @param desc [string]
  361. */
  362. _getValueTextFromDefValueDesc: function(param, desc) {
  363. if(param.defaultValues && bobj.isArray(param.defaultValues)) {
  364. for(var i = 0 ; i < param.defaultValues.length;i++) {
  365. var defValueDesc = this._getDefaultValue(param.valueDataType,param.defaultDisplayType, param.defaultValues[i]);
  366. if(defValueDesc == desc) {
  367. // if desc is equal to one of LOV's row desc, then get value text of that row
  368. return this._getValueText(param.valueDataType, param.defaultValues[i].value);
  369. }
  370. }
  371. }
  372. return null;
  373. },
  374. /**
  375. * Private. Converts a parameter value to display text.
  376. *
  377. * @param type [int] Value's data type (bobj.crv.params.DataTypes)
  378. * @param isRange [bool]
  379. * @param value [Object] Parameter value to convert to text
  380. *
  381. * @return [String] Returns display text representing the value
  382. */
  383. _getValueText: function(type, value) {
  384. if (value === undefined) {
  385. return undefined;
  386. }
  387. var Type = bobj.crv.params.DataTypes;
  388. switch(type) {
  389. case Type.DATE:
  390. return this._getDateTimeText(value, this._paramOpts.dateFormat);
  391. case Type.TIME:
  392. return this._getDateTimeText(value, this._paramOpts.timeFormat);
  393. case Type.DATE_TIME:
  394. return this._getDateTimeText(value, this._paramOpts.dateTimeFormat);
  395. case Type.NUMBER:
  396. case Type.CURRENCY:
  397. return this._getNumberText(value,this._paramOpts.numberFormat);
  398. case Type.BOOLEAN:
  399. return this._getBooleanText(value,this._paramOpts.booleanFormat);
  400. case Type.STRING:
  401. default:
  402. return '' + value;
  403. }
  404. },
  405. _getBooleanText: function(value, booleanFormat) {
  406. return booleanFormat[''+value];
  407. },
  408. /**
  409. * Private. Converts a Number value into display text.
  410. *
  411. * @param value [int] Parameter value to convert to text
  412. * @param format [{decimalSeperator,groupSeperator}] Number format
  413. *
  414. * @return [String] Returns display text for the value
  415. */
  416. _getNumberText: function(value,format) {
  417. var dcSeperator = format.decimalSeperator;
  418. var gpSeperator = format.groupSeperator;
  419. var valueSplitted = ('' + value).split(".");
  420. var leftVal,rightVal,formattedValue;
  421. var numberSign = null;
  422. leftVal = valueSplitted[0];
  423. if(leftVal.length > 0 && leftVal.slice(0,1) == '-' || leftVal.slice(0,1) == '+') {
  424. numberSign = leftVal.slice(0,1);
  425. leftVal = leftVal.slice(1,leftVal.length);
  426. }
  427. rightVal = (valueSplitted.length == 2) ? valueSplitted[1] : null;
  428. formattedLeftVal = null;
  429. if(leftVal.length <= 3) {
  430. formattedLeftVal = leftVal;
  431. }
  432. else {
  433. var gp = null;
  434. var sliceIndex = null;
  435. while(leftVal.length > 0) {
  436. sliceIndex = (leftVal.length > 3) ? leftVal.length - 3 : 0;
  437. gp = leftVal.slice(sliceIndex,leftVal.length);
  438. leftVal = leftVal.slice(0, sliceIndex);
  439. formattedLeftVal = (formattedLeftVal == null) ? gp : gp + gpSeperator + formattedLeftVal;
  440. }
  441. }
  442. formattedValue = (rightVal != null) ? formattedLeftVal + dcSeperator + rightVal : formattedLeftVal;
  443. formattedValue = (numberSign != null) ? numberSign + formattedValue : formattedValue;
  444. return formattedValue;
  445. },
  446. /**
  447. * Private. Converts a DateTime value into display text.
  448. *
  449. * @param value [Object] Parameter value to convert to text
  450. * @param format [String] DateTime format
  451. *
  452. * @return [String] Returns display text for the value
  453. */
  454. _getDateTimeText: function(value, format) {
  455. var date = bobj.crv.params.jsonToDate(value);
  456. if (date) {
  457. return bobj.external.date.formatDate(date, format);
  458. }
  459. return '';
  460. },
  461. /*
  462. * Looks up value in the param's defualt values list, and if it's existing, get value/desc based on valueDisplayType
  463. * @param value [Object] Parameter value to convert to text
  464. */
  465. _getValueTextFromDefaultValue: function(param, value) {
  466. if(bobj.isArray(param.defaultValues)) {
  467. var hashValue = bobj.getValueHashCode(param.valueDataType,value);
  468. for(var i = 0 ; i < param.defaultValues.length; i++) {
  469. if(hashValue == bobj.getValueHashCode(param.valueDataType,param.defaultValues[i].value)) {
  470. return this._getDefaultValue(param.valueDataType, param.defaultDisplayType, param.defaultValues[i]);
  471. }
  472. }
  473. }
  474. return null;
  475. },
  476. /*
  477. * Converts value object to value text in order to be displayed on ParameterUI. takes into account valueDisplayType
  478. * IMPORTANT : use _getValueText if you want to convert param value Obj to param value text
  479. */
  480. _getDisplayText: function(param,value) {
  481. if (value === undefined) {
  482. return undefined;
  483. }
  484. if (value.lowerBoundType !== undefined || value.upperBoundType !== undefined) {
  485. return this._getRangeDisplayText(param, value);
  486. }
  487. var valueText = this._getValueTextFromDefaultValue(param,value);
  488. if(valueText == null) {
  489. valueText = this._getValueText(param.valueDataType, value);
  490. }
  491. return valueText;
  492. },
  493. /**
  494. * Private. Converts a range value into display text.
  495. *
  496. * @param value [Object] Parameter value to convert to text
  497. * @param type [int] Value's data type (bobj.crv.params.DataTypes)
  498. *
  499. * @return [String] Returns display text for the value
  500. */
  501. _getRangeDisplayText: function(param, value) {
  502. var valString = '';
  503. if (value.lowerBoundType !== undefined || value.upperBoundType !== undefined) {
  504. var lbType = parseInt(value.lowerBoundType, 10);
  505. var ubType = parseInt(value.upperBoundType, 10);
  506. var lowerBound = '(';
  507. var upperBound = ')';
  508. if (lbType == bobj.crv.params.RangeBoundTypes.INCLUSIVE) {
  509. lowerBound = '[';
  510. }
  511. if (ubType == bobj.crv.params.RangeBoundTypes.INCLUSIVE) {
  512. upperBound = ']';
  513. }
  514. var beginValue = '';
  515. var endValue = '';
  516. if (lbType != bobj.crv.params.RangeBoundTypes.UNBOUNDED) {
  517. beginValue = this._getDisplayText(param, value.beginValue);
  518. }
  519. if (ubType != bobj.crv.params.RangeBoundTypes.UNBOUNDED) {
  520. endValue = this._getDisplayText(param, value.endValue);
  521. }
  522. valString = lowerBound + ' ' + beginValue;
  523. valString += ' .. ';
  524. valString += endValue + ' ' + upperBound;
  525. }
  526. else {
  527. //this is a discrete value
  528. valString = this._getDisplayText(param, value);
  529. }
  530. return valString;
  531. },
  532. /**
  533. * Private. Converts text into a parameter value.
  534. *
  535. * @param type [int] Value's data type (bobj.crv.params.DataTypes)
  536. * @param text [String] Value's display text
  537. *
  538. * @return [Object] Parameter value
  539. */
  540. _getParamValue: function(type, text) {
  541. if (type === undefined) {
  542. return undefined;
  543. }
  544. var Type = bobj.crv.params.DataTypes;
  545. switch(type) {
  546. case Type.DATE:
  547. return this._getDateTimeParamValue(text, this._paramOpts.dateFormat);
  548. case Type.TIME:
  549. return this._getDateTimeParamValue(text, this._paramOpts.timeFormat);
  550. case Type.DATE_TIME:
  551. return this._getDateTimeParamValue(text, this._paramOpts.dateTimeFormat);
  552. case Type.NUMBER:
  553. case Type.CURRENCY:
  554. return this._getNumberParamValue(text,this._paramOpts.numberFormat);
  555. case Type.BOOLEAN:
  556. return this._getBooleanParamValue(text,this._paramOpts.booleanFormat);
  557. case Type.STRING:
  558. default:
  559. return text;
  560. }
  561. },
  562. /**
  563. * Private. Converts boolean text to a paramter value
  564. * @param text [String] Value's display text
  565. * @param booleanFormat [boolean format] {true: text : false : text}
  566. * @return [String]
  567. */
  568. _getBooleanParamValue: function(text,booleanFormat) {
  569. if(text != null && text.length != 0) {
  570. return booleanFormat["true"] == text;
  571. }
  572. else {
  573. return null;
  574. }
  575. },
  576. /**
  577. * Private. Converts Number text to a paramter value
  578. * @param text [String] Value's display text
  579. * @param format [{decimalSeperator,groupSeperator}] number format
  580. *
  581. * @return [String]
  582. */
  583. _getNumberParamValue: function(text,format) {
  584. if(text == null) {
  585. return null;
  586. }
  587. var value = '';
  588. if (/[ \f\n\r\t\v\u00A0\u2028\u2029]/.test(format.groupSeperator)) {
  589. value = text.replace(/[ \f\n\r\t\v\u00A0\u2028\u2029]/g, '');
  590. }
  591. else {
  592. var gpRE = new RegExp( "\\" + format.groupSeperator, "g" );
  593. value = text.replace(gpRE,"")
  594. }
  595. return value.replace(format.decimalSeperator, ".");
  596. },
  597. /**
  598. * Private. Converts DateTime text into a parameter value.
  599. *
  600. * @param text [String] Value's display text
  601. * @param format [String] DateTime format
  602. *
  603. * @return [Object] DateTime parameter value or the original value if getDateFromFormat fails
  604. */
  605. _getDateTimeParamValue: function(text, format) {
  606. var date = bobj.external.date.getDateFromFormat(text, format);
  607. if (date) {
  608. return bobj.crv.params.dateToJson(date);
  609. }
  610. return text;
  611. },
  612. /**
  613. * Private. Attach callbacks to a parameter widget
  614. *
  615. * @param widget [ParameterUI]
  616. */
  617. _observeParamWidget: function(widget) {
  618. if (widget) {
  619. var bind = MochiKit.Base.bind;
  620. widget.changeValueCB = bind(this._onChangeValue, this, widget);
  621. widget.addValueCB = bind(this._onAddValue, this, widget);
  622. widget.selectValueCB = bind(this._onSelectValue, this, widget);
  623. widget.enterPressCB = bind(this._onEnterPress, this, widget);
  624. widget.clickRowButtonCB = bind(this._onClickRowButton, this, widget);
  625. }
  626. },
  627. _onParamHasDupValue: function(param, value) {
  628. var widget = this._findWidget(param);
  629. var displayText = this._getDisplayText(param, value); // Making sure we put up warning when either value or display value is in the panel ie) 1 or '1 - one'
  630. if(widget) {
  631. for(var i = 0 ; i < widget.getNumValues(); i++) {
  632. var widgetValue = widget.getValueAt(i);
  633. if(displayText == widgetValue) {
  634. widget.setWarning(i, {code : bobj.crv.params.Validator.ValueStatus.VALUE_DUPLICATE, message : L_bobj_crv_ParamsDuplicateValue });
  635. }
  636. }
  637. }
  638. },
  639. /*
  640. * Removes warning signs associated with Duplicate-value error
  641. * if no value is provided, this function will clear all 'VALUE_DUPLICATE' errors
  642. */
  643. _onParamHasNoDupValue: function(param, value) {
  644. var widget = this._findWidget(param);
  645. var displayText = this._getDisplayText(param, value); // Making sure we put up warning when either value or display value is in the panel ie) 1 or '1 - one'
  646. var duplicateCode = bobj.crv.params.Validator.ValueStatus.VALUE_DUPLICATE;
  647. if(widget) {
  648. for(var i = 0 ; i < widget.getNumValues(); i++) {
  649. var widgetValue = widget.getValueAt(i);
  650. if((arguments.length == 1 || displayText == widgetValue) && widget.getWarning(i) != null && widget.getWarning(i).code == duplicateCode) {
  651. widget.setWarning(i, null);
  652. }
  653. }
  654. }
  655. },
  656. /**
  657. * Private ParameterUI callback. Updates the UI when a param value is edited.
  658. *
  659. * @param widget [ParameterUI] The source of the event
  660. * @param valueIdx [int] The index of the value that changed
  661. * @param new Value [String] The new value (display text) at valueIdx
  662. */
  663. _onChangeValue: function(widget, valueIdx, newValue) {
  664. if (this._disablePanel) {
  665. return;
  666. }
  667. widget.setWarning(valueIdx, null);
  668. var isDirty = widget.isDirty();
  669. this._panel.setDirty(this._panel.getIndex(widget), isDirty);
  670. this._updateToolbar();
  671. },
  672. /**
  673. * Private ParameterUI callback. Updates the UI when a new param value is
  674. * added.
  675. *
  676. * @param widget [ParameterUI] The source of the event
  677. * @param new Value [String] The new value (display text)
  678. */
  679. _onAddValue: function(widget, newValue) {
  680. if (this._disablePanel) {
  681. return;
  682. }
  683. this._updateToolbar();
  684. this._panel.setDirty(this._panel.getIndex(widget), widget.isDirty());
  685. },
  686. /**
  687. * Private ParameterUI callback. Updates the UI when a param value is
  688. * selected.
  689. *
  690. * @param widget [ParameterUI] The source of the event
  691. * @param valueIdx [int] The index of the value that received focus
  692. */
  693. _onSelectValue: function(widget, valueIdx) {
  694. var lastWidget = this._selected;
  695. var lastValueIdx = this._selectedValueIdx;
  696. this._select(widget, valueIdx);
  697. if (lastWidget && bobj.isNumber(lastValueIdx)) {
  698. this._checkAndSetValue(lastWidget, lastValueIdx);
  699. }
  700. },
  701. /**
  702. * Private ParameterUI callback. Attempts to apply change param values to
  703. * the report when the Enter key is pressed while editing a value.
  704. *
  705. * @param widget [ParameterUI] The source of the event
  706. * @param valueIdx [int] The index of the value that has focus
  707. */
  708. _onEnterPress: function(widget, valueIdx) {
  709. this._applyValues();
  710. },
  711. /**
  712. * Private ParameterUI callback. Shows a calendar picker when the button
  713. * next to a parameter value is clicked.
  714. *
  715. * @param widget [ParameterUI] The source of the event
  716. * @param valueIdx [int] The index of the value
  717. * @param x [int] The absolute horizontal position of the event
  718. * @param y [int] The absolute vertical position of the event
  719. */
  720. _onClickRowButton: function(widget, valueIdx, x, y) {
  721. this._setConnectedToCalendar(true);
  722. var calendar = bobj.crv.Calendar.getInstance();
  723. var param = this._findParam(widget);
  724. var format = this._getDateTimeFormat(param.valueDataType);
  725. var date = bobj.external.date.getDateFromFormat(widget.getValueAt(widget.getSelectedIndex()), format);
  726. if (date) {
  727. calendar.setDate(date);
  728. }
  729. calendar.setShowTime(param.valueDataType === bobj.crv.params.DataTypes.DATE_TIME);
  730. calendar.show(true, x, y);
  731. },
  732. /**
  733. * Private Calendar callback. Updates display text after a date is picked
  734. * from the calendar picker.
  735. *
  736. * @param date [Date] The date that should be displayed
  737. */
  738. _onClickCalendarOKButton: function(date) {
  739. this._setConnectedToCalendar(false);
  740. if (date && this._selected) {
  741. var param = this._findParam(this._selected);
  742. var valueIdx = this._selected.getSelectedIndex();
  743. var format = this._getDateTimeFormat(param.valueDataType);
  744. var strValue = bobj.external.date.formatDate(date, format);
  745. this._selected.setValueAt(valueIdx, strValue);
  746. var isDirty = this._selected.isDirty();
  747. this._selected.setWarning(valueIdx, null);
  748. this._panel.setDirty(this._panel.getIndex(this._selected), isDirty);
  749. this._updateToolbar();
  750. }
  751. },
  752. /**
  753. * Private Calendar callback. Stops listening to calendar widget events when the
  754. * calendar is dismissed with the cancel button.
  755. */
  756. _onClickCalendarCancelButton: function() {
  757. this._setConnectedToCalendar(false);
  758. },
  759. _onHideCalendar : function() {
  760. this._setConnectedToCalendar(false);
  761. },
  762. /**
  763. * Private ParameterPanel callback. Applies changed parameter values to the
  764. * report when the run button is clicked on the panel's toolbar.
  765. */
  766. _onClickTbApplyButton: function() {
  767. this._applyValues();
  768. },
  769. /**
  770. * Private ParameterPanel callback. Shows the advanced dialog for the
  771. * selected parameter when the advanced dialog button is clicked on the
  772. * panel's toolbar.
  773. */
  774. _onClickTbAdvButton: function() {
  775. if (this._selected) {
  776. this._viewerCtrl.showAdvancedParamDialog(this);
  777. }
  778. },
  779. /**
  780. * Private ParameterPanel callback. Deletes the selected parameter value
  781. * when the delete button is clicked on the panel's toolbar.
  782. */
  783. _onClickTbDeleteButton: function() {
  784. if (this._selected) {
  785. var index = this._selected.getSelectedIndex();
  786. this._selected.deleteValue(index);
  787. this._panel.setDirty(this._panel.getIndex(this._selected), this._selected.isDirty());
  788. this._updateToolbar();
  789. var param = this._findParam(this._selected);
  790. param.removeValueAt(index);
  791. index = Math.min(index, this._selected.getNumValues() - 1);
  792. this._selected.setSelected(index);
  793. if((param.isOptionalPrompt || param.allowNullValue) && param.getValue().length == 0) {
  794. this._selected.showRowCreater(true);
  795. }
  796. }
  797. },
  798. /**
  799. * Private. Selects a parameter value.
  800. *
  801. * @param widget [Widget] The ParameterUI to select
  802. * @param valueIdx [int] The index of the value to select
  803. */
  804. _select: function(widget, valueIdx) {
  805. this._selectedValueIdx = valueIdx;
  806. if (this._selected !== widget) {
  807. if (this._selected) {
  808. this._selected.deselect();
  809. }
  810. this._selected = widget;
  811. this._panel.setSelected(this._panel.getIndex(widget), true);
  812. this._updateToolbar();
  813. }
  814. if (bobj.isNumber(valueIdx)) {
  815. this._selected.setSelected(valueIdx);
  816. }
  817. },
  818. /**
  819. * Private. Attempts to apply changed parameter values to the report.
  820. * Changed display text will be converted to parameter values and validated.
  821. * Validation failure will cause a warning to appear instead of updating the
  822. * report.
  823. */
  824. _applyValues: function() {
  825. this._checkAndSetValue(this._selected, this._selectedValueIdx);
  826. var numParams = this._paramList.length;
  827. var badParamIdx = -1;
  828. var badValueIdx = -1;
  829. var warning = null;
  830. var paramUI = null;
  831. for (var i = 0; (i < numParams) && !warning; ++i) {
  832. paramUI = this._panel.getParameter(i);
  833. var numValues = paramUI.getNumValues();
  834. for (var j = 0; (j < numValues) && !warning; ++j) {
  835. warning = paramUI.getWarning(j);
  836. if (warning) {
  837. badParamIdx = i;
  838. badValueIdx = j;
  839. }
  840. }
  841. }
  842. if (warning) {
  843. paramUI = this._panel.getParameter(badParamIdx);
  844. this._onSelectValue(paramUI, badValueIdx);
  845. var dlg = bobj.crv.ErrorDialog.getInstance();
  846. dlg.setText(warning.message, null);
  847. dlg.setTitle(L_bobj_crv_ParamsInvalidTitle);
  848. dlg.setPromptType(_promptDlgWarning);
  849. dlg.show(true, function(){paramUI.setSelected(badValueIdx);});
  850. }
  851. else {
  852. // make all value changes permanent
  853. for (var i = 0, c = this._paramList.length; i < c; i++) {
  854. this._paramList[i].commitValue();
  855. }
  856. this._viewerCtrl.applyParams(this._paramList);
  857. }
  858. },
  859. /**
  860. * Private. Finds the Parameter associated with a given ParameterUI.
  861. *
  862. * @param widget [ParameterUI]
  863. *
  864. * @return [Parameter]
  865. */
  866. _findParam: function(widget) {
  867. return this._paramList[this._panel.getIndex(widget)];
  868. },
  869. _findWidget: function(param) {
  870. for(var i = 0 ; i < this._paramList.length; i++) {
  871. if(this._paramList[i].paramName == param.paramName) {
  872. return this._panel.getParameter(i)
  873. }
  874. }
  875. return null;
  876. },
  877. /**
  878. * Private. Updates the state of the parameter panel's toolbar buttons.
  879. */
  880. _updateToolbar: function() {
  881. if (this._disablePanel) {
  882. return;
  883. }
  884. if (this._selected) {
  885. var param = this._findParam(this._selected);
  886. this._panel.setDeleteButtonEnabled( this._canPanelChangeValues(param) &&
  887. (((param.isOptionalPrompt || param.allowNullValue) && this._selected.getValues().length > 0) ||
  888. (param.allowMultiValue && this._selected.getValues().length > 1)));
  889. }
  890. else {
  891. this._panel.setDeleteButtonEnabled(false);
  892. }
  893. var isPanelDirty = false;
  894. for(var i = 0, len = this._paramList.length; i < len; i++) {
  895. if(this._panel.isDirty(i)) {
  896. isPanelDirty = true;
  897. break;
  898. }
  899. }
  900. this._panel.setApplyButtonEnabled(isPanelDirty);
  901. },
  902. /**
  903. * Private. Selects a Date/Time format string from paramOpts based on the
  904. * give parameter value type.
  905. *
  906. * @param dataType [bobj.crv.params.DataTypes]
  907. *
  908. * @return [String] Returns a DateTime format string.
  909. */
  910. _getDateTimeFormat: function(dataType) {
  911. var Type = bobj.crv.params.DataTypes;
  912. switch(dataType) {
  913. case Type.DATE:
  914. return this._paramOpts.dateFormat;
  915. case Type.TIME:
  916. return this._paramOpts.timeFormat;
  917. case Type.DATE_TIME:
  918. return this._paramOpts.dateTimeFormat;
  919. default: return null;
  920. }
  921. },
  922. /**
  923. * Private. Connects or disconnects to/from Calendar widget events. A shared
  924. * Calendar widget instance is used, so events should only be monitored
  925. * when this controller has caused the Calendar to display.
  926. *
  927. * @param isConnected [bool] True causes Calendar events to be handled.
  928. * False causes them to be ignored.
  929. */
  930. _setConnectedToCalendar: function(isConnected) {
  931. var op = isConnected ? MochiKit.Signal.connect : MochiKit.Signal.disconnect;
  932. var calendar = bobj.crv.Calendar.getInstance();
  933. op(calendar, calendar.Signals.OK_CLICK, this, '_onClickCalendarOKButton');
  934. op(calendar, calendar.Signals.CANCEL_CLICK, this, '_onClickCalendarCancelButton');
  935. op(calendar, calendar.Signals.ON_HIDE, this, '_onHideCalendar');
  936. },
  937. /**
  938. * Private. Convert display text to a param value, validate it, and update
  939. * the value of the associated Parameter instance when validation succeeds.
  940. * Sets the warning text of the value when validation fails.
  941. *
  942. * @param widget [ParameterUI]
  943. * @param valueIdx [int] Index of value to validate and update
  944. */
  945. _checkAndSetValue: function(widget, valueIdx) {
  946. /*
  947. * Return if parameter value is modified in advanced dialog as the parameter value is already set by updateParameter
  948. */
  949. if(!widget.canChangeOnPanel) {
  950. return;
  951. }
  952. var parameter = this._findParam(widget);
  953. var valueText = widget.getValueAt(valueIdx);
  954. // Checking if value exists in defaultValues and if it does, get the value from defaultValue
  955. var defValue = this._getValueTextFromDefValueDesc(parameter,valueText);
  956. if(defValue != null) {
  957. valueText = defValue;
  958. }
  959. var paramValue = this._getParamValue(parameter.valueDataType, valueText);
  960. // if the following condition is true, the user is providing 'no value' to an optional parameter
  961. if (valueIdx == 0 && paramValue == null && parameter.getValue().length == 0) {
  962. if(parameter.allowNullValue) {
  963. parameter.setValue(0, null);
  964. }
  965. if(parameter.isOptionalPrompt || parameter.allowNullValue) {
  966. return;
  967. }
  968. }
  969. var Status = bobj.crv.params.Validator.ValueStatus;
  970. var code = Status.OK;
  971. var warningMsg = null;
  972. code = bobj.crv.params.Validator.getInstance().validateValue(parameter, paramValue);
  973. if (Status.OK === code) {
  974. var cText = this._getValueTextFromDefaultValue(parameter,paramValue);
  975. if(cText != null) {
  976. widget.setValueAt(valueIdx,cText);
  977. }
  978. widget.setWarning(valueIdx,null); // Removes warning
  979. parameter.setValue(valueIdx, paramValue); //checks for duplicates when setting a value
  980. }
  981. else {
  982. warningMsg = this._getWarningText(parameter, code);
  983. widget.setWarning(valueIdx, {code : code, message : warningMsg });
  984. }
  985. },
  986. /**
  987. * Private. Convert a validation error code into a readable warning message.
  988. *
  989. * @param param [Parameter] Parameter that has the erroroneous value
  990. * @param code [ValueStatus] Validation error code
  991. *
  992. * @return [String] Returns a warning message suitable for display in the UI
  993. */
  994. _getWarningText: function(param, code) {
  995. var Type = bobj.crv.params.DataTypes;
  996. switch(param.valueDataType) {
  997. case Type.DATE:
  998. case Type.TIME:
  999. case Type.DATE_TIME:
  1000. return this._getDateTimeWarning(param,code);
  1001. case Type.STRING:
  1002. return this._getStringWarning(param, code);
  1003. case Type.NUMBER:
  1004. case Type.CURRENCY:
  1005. return this._getNumberWarning(param,code);
  1006. default:
  1007. return null;
  1008. }
  1009. },
  1010. /**
  1011. * Private. Create warning message for invalid datetime value
  1012. * @param param [Parameter] Parameter that has the erroroneous value
  1013. * @param code [ValueStatus] Validation error code
  1014. *
  1015. * @return [String] Returns a warning message suitable for display in the UI
  1016. */
  1017. _getDateTimeWarning: function(param,code) {
  1018. var dataTypes = bobj.crv.params.DataTypes;
  1019. var ValueStatus = bobj.crv.params.Validator.ValueStatus;
  1020. var dateFormat = this._paramOpts.dateFormat;
  1021. dateFormat = dateFormat.replace('yyyy', '%1');
  1022. dateFormat = dateFormat.replace('M', '%2');
  1023. dateFormat = dateFormat.replace('d', '%3');
  1024. dateFormat = dateFormat.replace('%1', L_bobj_crv_ParamsYearToken);
  1025. dateFormat = dateFormat.replace('%2', L_bobj_crv_ParamsMonthToken);
  1026. dateFormat = dateFormat.replace('%3', L_bobj_crv_ParamsDayToken);
  1027. if(code == ValueStatus.ERROR || code == ValueStatus.VALUE_INVALID_TYPE) {
  1028. switch(param.valueDataType) {
  1029. case dataTypes.DATE:
  1030. return L_bobj_crv_ParamsBadDate.replace("%1",dateFormat);
  1031. case dataTypes.DATE_TIME:
  1032. return L_bobj_crv_ParamsBadDateTime.replace("%1",dateFormat);
  1033. break;
  1034. case dataTypes.TIME:
  1035. return L_bobj_crv_ParamsBadTime
  1036. break;
  1037. }
  1038. }
  1039. else if(code == ValueStatus.VALUE_TOO_BIG || code == ValueStatus.VALUE_TOO_SMALL){
  1040. return this._getMinMaxText(param.valueDataType,param.minValue,param.maxValue);
  1041. }
  1042. return null;
  1043. },
  1044. /**
  1045. * Private. Create a warning message for String parameter
  1046. *
  1047. * @param param [Parameter] Parameter that has the erroroneous value
  1048. * @param code [ValueStatus] Validation error code
  1049. *
  1050. * @return [String] Returns a warning message suitable for display in the UI
  1051. */
  1052. _getStringWarning: function(param, code) {
  1053. var Status = bobj.crv.params.Validator.ValueStatus;
  1054. if (Status.VALUE_TOO_LONG === code) {
  1055. return L_bobj_crv_ParamsTooLong.replace('%1', param.maxValue);
  1056. }
  1057. else if(Status.VALUE_TOO_SHORT === code){
  1058. return L_bobj_crv_ParamsTooShort.replace('%1', param.minValue);
  1059. }
  1060. return null;
  1061. },
  1062. /**
  1063. * Private. Create warning message for invalid datetime value
  1064. * @param param [Parameter] Parameter that has the erroroneous value
  1065. * @param code [ValueStatus] Validation error code
  1066. *
  1067. * @return [String] Returns a warning message suitable for display in the UI
  1068. */
  1069. _getNumberWarning : function(param,code) {
  1070. var ValueStatus = bobj.crv.params.Validator.ValueStatus;
  1071. var dataTypes = bobj.crv.params.DataTypes;
  1072. switch(code) {
  1073. case ValueStatus.ERROR:
  1074. case ValueStatus.VALUE_INVALID_TYPE:
  1075. if(param.valueDataType == dataTypes.NUMBER) {
  1076. return L_bobj_crv_ParamsBadNumber;
  1077. }
  1078. else if(param.valueDataType == dataTypes.CURRENCY) {
  1079. return L_bobj_crv_ParamsBadCurrency;
  1080. }
  1081. case ValueStatus.VALUE_TOO_BIG:
  1082. case ValueStatus.VALUE_TOO_SMALL:
  1083. return this._getMinMaxText(param.valueDataType,param.minValue,param.maxValue);
  1084. default:
  1085. return null;
  1086. }
  1087. }
  1088. };