ViewerIWidgetProperties.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| IBM Cognos Products: Viewer
  5. *| (C) Copyright IBM Corp. 2001, 2013
  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. dojo.provide("bux.reportViewer.Properties");
  13. dojo.declare("bux.reportViewer.Properties", null, {
  14. iWidget : null,
  15. masterDialogSpec : null,
  16. masterDialogSpecProperties : null,
  17. flashChartSpec : null,
  18. isFlashChartOptionEnabled: true,
  19. oldProperties: null, // will contain the last set of properties. Used to compare to see what's changed
  20. dialogDisplayValues : null, // will contain the current set of properties
  21. constructor: function( iWidget, properties )
  22. {
  23. this.isInitialized = false;
  24. this.initializeDialogDisplayValues();
  25. this.oldProperties = {};
  26. this.iWidget = iWidget;
  27. if( properties === "<empty>")
  28. {
  29. return;
  30. }
  31. var json = dojo.eval("[" + properties + "]");
  32. if( json && json[0] )
  33. {
  34. this.initializeWithSavedPropertyValues(json[0]);
  35. }
  36. },
  37. initializeDialogDisplayValues: function() {
  38. /**
  39. * canUndo: if set to true, changing this property will cause the action to be put into the undo stack
  40. * runReport: if true, changing this property will cause the report to rerun
  41. * refreshSavedOutput: if true, changing this property will cause the saved output to get redrawn
  42. */
  43. this.dialogDisplayValues = { flashCharts: { value: null, canUndo: true, runReport: true },
  44. rowsPerPage: { value: null, canUndo: true, runReport: true },
  45. promptUserOnLoad: { value: false },
  46. retrieveAll: { value: false, refreshSavedOutput: true },
  47. showExpandCollapseIcon: { value: null }
  48. };
  49. },
  50. clearDialogSpec: function() {
  51. this.masterDialogSpec = null;
  52. this.masterDialogSpecProperties = null;
  53. },
  54. /**
  55. * Initialize the property values with the values that were saved with the dashboard
  56. * @param {Object} properties
  57. */
  58. initializeWithSavedPropertyValues: function(properties)
  59. {
  60. // The structure that we're saving the properties in is a little different then
  61. // what's needed by the dialog
  62. for (var prop in properties) {
  63. if (typeof prop != "undefined" && prop != null) {
  64. if (this.dialogDisplayValues[prop]) {
  65. this.dialogDisplayValues[prop].value = properties[prop];
  66. } else {
  67. this.dialogDisplayValues[prop] = { value: properties[prop], canUndo: false };
  68. }
  69. }
  70. }
  71. },
  72. /**
  73. * Helper function to set a property value without knowing the structure needed by the parent class
  74. * @param {String} property
  75. * @param {String} value
  76. */
  77. setProperty: function(property, value)
  78. {
  79. this.dialogDisplayValues[property].value = value;
  80. },
  81. /**
  82. * Helper function to get a property without having to know the structure of the properties are saved in
  83. * @param {String} property
  84. * @return null if the property isn't found
  85. */
  86. getProperty: function(property)
  87. {
  88. if (this.dialogDisplayValues[property])
  89. {
  90. return this.dialogDisplayValues[property].value;
  91. }
  92. return null;
  93. },
  94. /**
  95. * Helper function to get a an old property without having to know the structure the properties are saved in
  96. * @param {String} property
  97. * @return null if the property isn't found
  98. */
  99. getOldProperty: function(property)
  100. {
  101. if (this.oldProperties && this.oldProperties[property])
  102. {
  103. return this.oldProperties[property].value;
  104. }
  105. return null;
  106. },
  107. /**
  108. * Returns the last set of properties
  109. */
  110. getOldProperties: function()
  111. {
  112. /**
  113. * Need to make a new copy of the oldProperties. If we simply returned this.oldProperties,
  114. * it would return it as a reference. So any time this.oldProperties got updated it would
  115. * also change the values in the undoRedo queue (not good).
  116. */
  117. var oldProps = {};
  118. for (var prop in this.oldProperties) {
  119. if (this.dialogDisplayValues[prop].canUndo === true) {
  120. oldProps[prop] = {};
  121. oldProps[prop].value = this.oldProperties[prop].value;
  122. }
  123. }
  124. return oldProps;
  125. },
  126. /**
  127. * Called right before the properties dialog is opened.
  128. */
  129. onGet: function()
  130. {
  131. // Keep track of the old properties. Will be used if the user hits Ok to know if something has changed
  132. this.copyPropertyValues(this.dialogDisplayValues, this.oldProperties);
  133. if (!this.masterDialogSpec) {
  134. this.initializeDialogSpec();
  135. } else {
  136. this.updateDialogSpec();
  137. }
  138. var _payload = {
  139. tabTitle: this._getReportWidgetTabTitle(),
  140. properties: this.dialogDisplayValues,
  141. propertiesDialogSpec: this.masterDialogSpec
  142. };
  143. return _payload;
  144. },
  145. _getReportWidgetTabTitle: function() {
  146. var reportWidgetTabTitle;
  147. if( this.iWidget && this.iWidget.getViewerObject() )
  148. {
  149. reportWidgetTabTitle = RV_RES.IDS_REPORT_WIDGET_PROPERTY_TAB_TITLE;
  150. }
  151. return reportWidgetTabTitle;
  152. },
  153. /**
  154. * Called the the user hits the Ok button
  155. * @param {Object} payload
  156. */
  157. onSet: function( payload )
  158. {
  159. if( this.isSavedOutput() )
  160. {
  161. this.updateSavedOutput();
  162. }
  163. else
  164. {
  165. if( !this.runReportWithNewOptions() ){
  166. this._updateReport();
  167. }
  168. }
  169. },
  170. /*
  171. * For some properties,like Show expand/collapse icon, there is no need to rerun the report in order for the property to be
  172. * applied. This function updates report without re-running it and should only be called in the case that the report had not ran.
  173. * If the report had ran, there is no need to call it.
  174. */
  175. _updateReport : function(){
  176. //update report without having to run it again
  177. var newShowExpandCollapseIconFlag = this.getProperty('showExpandCollapseIcon');
  178. if( this.getOldProperty('showExpandCollapseIcon') != newShowExpandCollapseIconFlag ){
  179. var oCV = this.iWidget.getViewerObject();
  180. if( newShowExpandCollapseIconFlag === true ){
  181. oCV.insertExpandIconsForAllCrosstabs();
  182. } else {
  183. oCV.removeExpandIconsForAllCrosstabs();
  184. }
  185. }
  186. },
  187. /**
  188. * Copies the properties from an object to another
  189. * @param {Object} from
  190. * @param {Object} to
  191. */
  192. copyPropertyValues: function(from, to) {
  193. for (var prop in from) {
  194. if (!to[prop]) {
  195. to[prop] = {};
  196. }
  197. to[prop].value = from[prop].value;
  198. }
  199. },
  200. /**
  201. * Update the properties with the values from the undo stack. Only the properties that are
  202. * undoable will be updated
  203. * @param {Object} properties
  204. */
  205. doUndo: function( properties )
  206. {
  207. this.copyPropertyValues(properties, this.dialogDisplayValues);
  208. },
  209. /**
  210. * Returns only the properties that can be undone
  211. */
  212. getUndoInfo : function()
  213. {
  214. // we need to make sure initialized was called before adding anything to the undo stack
  215. if (!this.isInitialized) {
  216. var oCV = this.iWidget.getViewerObject();
  217. this.initialize(oCV.envParams);
  218. }
  219. var undoInfo = {};
  220. for (var prop in this.dialogDisplayValues) {
  221. if (this.dialogDisplayValues[prop].canUndo === true) {
  222. undoInfo[prop] = { value: this.getProperty(prop) };
  223. }
  224. }
  225. return undoInfo;
  226. },
  227. /**
  228. * Checked to see if any of the properties that would cause the
  229. * report to get run have changed
  230. * @param {String} propertyToCheck: liveReport or savedOutput
  231. */
  232. shouldUpdateReport: function(propertyToCheck)
  233. {
  234. for (var prop in this.dialogDisplayValues) {
  235. if (this.dialogDisplayValues[prop][propertyToCheck] == true && this.getOldProperty(prop) != this.getProperty(prop)) {
  236. return true;
  237. }
  238. }
  239. return false;
  240. },
  241. runReportWithNewOptions: function()
  242. {
  243. // only rerun the report if needed
  244. if (this.shouldUpdateReport('runReport'))
  245. {
  246. var oCV = this.iWidget.getViewerObject();
  247. var runReport = oCV.getAction("RunReport");
  248. runReport.setReuseQuery(true);
  249. runReport.execute();
  250. this.iWidget.getUndoRedoQueue().initUndoObj({"tooltip" : this.getUndoHint(), "saveSpec" : this.saveSpecForUndo()});
  251. return true;
  252. }
  253. return false;
  254. },
  255. updateSavedOutput: function()
  256. {
  257. if (this.shouldUpdateReport('refreshSavedOutput')) {
  258. var savedOutput = this.iWidget.getSavedOutput();
  259. savedOutput.setPagedOutput( !this.getRetrieveAll() );
  260. savedOutput.render();
  261. }
  262. },
  263. /**
  264. * Builds a string representing the properties to use when we do a save
  265. */
  266. toString: function()
  267. {
  268. var str = "{";
  269. for (var prop in this.dialogDisplayValues) {
  270. var propertyData = this.getProperty(prop);
  271. if (propertyData != null && typeof propertyData !== "undefined") {
  272. if (str != "{") {
  273. str += ", ";
  274. }
  275. str += "\"" + prop + "\": ";
  276. str += (typeof(propertyData)=='string') ? propertyData.toString() : dojo.toJson(propertyData);
  277. }
  278. }
  279. str += "}";
  280. return str;
  281. },
  282. isSavedOutput: function()
  283. {
  284. return this.iWidget.getViewerObject().envParams["ui.action"] === 'view';
  285. },
  286. getUndoHint: function()
  287. {
  288. return RV_RES.IDS_JS_WIDGET_PROPERTIES;
  289. },
  290. saveSpecForUndo: function()
  291. {
  292. return false;
  293. },
  294. getRetrieveAll: function()
  295. {
  296. return this.getProperty("retrieveAll");
  297. },
  298. getPromptUserOnLoad: function()
  299. {
  300. return this.getProperty("promptUserOnLoad");
  301. },
  302. getFlashCharts: function()
  303. {
  304. return this.getProperty("flashCharts");
  305. },
  306. getRowsPerPage: function()
  307. {
  308. return this.getProperty("rowsPerPage");
  309. },
  310. getOriginalReportLocation: function(widget)
  311. {
  312. if(widget.getAttributeValue && !widget.getAttributeValue("originalReport")){
  313. return RV_RES.IDS_JS_PROPERTY_ORIGINAL_REPORT_LOCATION + " " + RV_RES.IDS_JS_PROPERTY_ORIGINAL_REPORT_LOCATION_UNAVAILABLE;
  314. }
  315. var sReportLocation = widget.getViewerObject().envParams["originalReportLocation"];
  316. if(typeof sReportLocation == "undefined" || sReportLocation == null || sReportLocation == "Unavailable")
  317. {
  318. return RV_RES.IDS_JS_PROPERTY_ORIGINAL_REPORT_LOCATION + " " + RV_RES.IDS_JS_PROPERTY_ORIGINAL_REPORT_LOCATION_UNAVAILABLE;
  319. }
  320. return (RV_RES.IDS_JS_PROPERTY_ORIGINAL_REPORT_LOCATION + " " + sReportLocation);
  321. },
  322. getShowExpandCollapseIconFlag : function()
  323. {
  324. return this.getProperty('showExpandCollapseIcon');
  325. },
  326. /**
  327. * This returns the Advanced Server settings in Cognos Admin for the specified property
  328. */
  329. getAdvancedServerProperty : function( property )
  330. {
  331. if( !this.iWidget && !this.iWidget.getViewerObject() ){ return null;}
  332. return this.iWidget.getViewerObject().getAdvancedServerProperty( property );
  333. },
  334. /**
  335. * If server setting is undefined - do not show the option, therefore, do not update the property value.
  336. * If server setting is defined, set the widget property value only there is no saved value.
  337. */
  338. initializeShowExpandCollapseIconFlag : function(){
  339. var sAdvancedServerPropertyValue = this.getAdvancedServerProperty( 'VIEWER_JS_EXPAND_COLLAPSE_CONTROLS_DEFAULT' );
  340. this.bHideExpandCollapseOption = (!sAdvancedServerPropertyValue );
  341. if( this.bHideExpandCollapseOption ){
  342. return;
  343. }
  344. if( this.getShowExpandCollapseIconFlag() === null ){
  345. this.setProperty( 'showExpandCollapseIcon', sAdvancedServerPropertyValue.toLowerCase() === 'on' );
  346. }
  347. },
  348. /**
  349. * The settings are updated based on server configuration.
  350. */
  351. initialize: function( envParams )
  352. {
  353. if( this.isInitialized )
  354. {
  355. return;
  356. }
  357. this.isInitialized = true;
  358. this.initializeFlashChartSettings( envParams.flashChartOption );
  359. this.initializeShowExpandCollapseIconFlag();
  360. if (this.getRowsPerPage() == null)
  361. {
  362. if (envParams["run.verticalElements"] != null)
  363. {
  364. this.setProperty("rowsPerPage", envParams["run.verticalElements"]);
  365. }
  366. else
  367. {
  368. // 20 is the default used in rsvp, so if we didn't find the vertical element in CM,
  369. // set it to the default of 20 so the UI matches the report
  370. this.setProperty("rowsPerPage", 20);
  371. }
  372. }
  373. this.initializeDialogSpec();
  374. },
  375. createViewReportSpecLink: function()
  376. {
  377. var oCV = this.iWidget.getViewerObject();
  378. var reportSpec = oCV.envParams["ui.spec"];
  379. // only show the link to get the report spec if the user is a report author
  380. // and he's not viewing saved output
  381. if (oCV.bCanUseReportStudio && reportSpec && reportSpec.length > 0 && oCV.envParams["ui.action"] != "view") {
  382. return {columns:
  383. [
  384. {
  385. propertyName: 'viewReportSpecification',
  386. uiElementType: 'link',
  387. label: RV_RES.IDS_JS_SHOW_REPORT_SPEC,
  388. eventHandler: this,
  389. onClickAction: dojo.hitch( this, this.onClickViewReportSpecification)
  390. }
  391. ]
  392. };
  393. }
  394. else {
  395. return {};
  396. }
  397. },
  398. isBlackListedOption : function( optionName ){
  399. return this.iWidget.getViewerObject().isBlacklisted( optionName );
  400. },
  401. createFlashChartOption: function()
  402. {
  403. var flashChartOptionSpec =
  404. [
  405. {
  406. columns:
  407. [
  408. {
  409. propertyName: 'flashCharts',
  410. uiElementType: "checkBox",
  411. label: RV_RES.IDS_JS_PROPERTY_FLASHCHARTS
  412. }
  413. ]
  414. },
  415. {
  416. columns:
  417. [
  418. {
  419. uiElementType: "hSpacer"
  420. }
  421. ]
  422. }
  423. ];
  424. return flashChartOptionSpec;
  425. },
  426. getShowExpandCollapseIconOptionSpec : function()
  427. {
  428. var spec = [
  429. {
  430. columns:
  431. [
  432. {
  433. propertyName: 'showExpandCollapseIcon',
  434. uiElementType: 'checkBox',
  435. label: RV_RES.IDS_JS_PROPERTY_SHOW_EXPAND_COLLAPSE_ICON
  436. }
  437. ]
  438. },
  439. {
  440. columns:
  441. [
  442. {
  443. uiElementType: 'hspacer'
  444. }
  445. ]
  446. }
  447. ];
  448. return spec;
  449. },
  450. generateDialogSpec : function(role)
  451. {
  452. var masterDialogSpecArray;
  453. if(role=='consume')
  454. {
  455. masterDialogSpecArray =
  456. [
  457. {
  458. columns:
  459. [
  460. {
  461. propertyName: 'rowsPerPage',
  462. uiElementType: 'textBox',
  463. type: 'number',
  464. label: RV_RES.IDS_JS_PROPERTY_ROWS_PER_PAGE
  465. }
  466. ]
  467. }
  468. ];
  469. this.masterDialogSpec = { rows: masterDialogSpecArray };
  470. }
  471. else
  472. {
  473. var viewReportSpecification = this.createViewReportSpecLink();
  474. masterDialogSpecArray =
  475. [
  476. {
  477. columns:
  478. [
  479. {
  480. propertyName: 'rowsPerPage',
  481. uiElementType: 'textBox',
  482. type: 'number',
  483. label: RV_RES.IDS_JS_PROPERTY_ROWS_PER_PAGE,
  484. constraints:{min:1,max:1000},
  485. required:true,
  486. invalidMessage: RV_RES.IDS_JS_PROPERTY_ROWS_PER_PAGE_ERROR
  487. }
  488. ]
  489. },
  490. {
  491. columns:
  492. [
  493. {
  494. uiElementType: 'hspacer'
  495. }
  496. ]
  497. },
  498. {
  499. columns:
  500. [
  501. {
  502. propertyName: 'promptUserOnLoad',
  503. uiElementType: 'checkBox',
  504. label: RV_RES.IDS_JS_PROPERTY_PROMPT_ON_LOAD
  505. }
  506. ]
  507. },
  508. {
  509. columns:
  510. [
  511. {
  512. propertyName: 'retrieveAll',
  513. uiElementType: 'checkBox',
  514. label: RV_RES.IDS_JS_PROPERTY_RETRIEVE_ENTIRE_REPORT
  515. }
  516. ]
  517. },
  518. viewReportSpecification,
  519. {
  520. columns:
  521. [
  522. {
  523. propertyName: 'originalReportLocation',
  524. uiElementType: 'text',
  525. label: this.getOriginalReportLocation(this.iWidget),
  526. allowWrapping: true
  527. }
  528. ]
  529. }
  530. ];
  531. if( this.isFlashChartOptionEnabled && !this.hasAVSChart() && role!== 'consume' )
  532. {
  533. var flashChartOption = this.createFlashChartOption();
  534. masterDialogSpecArray = flashChartOption.concat( masterDialogSpecArray );
  535. }
  536. if( !this.bHideExpandCollapseOption && !this.isBlackListedOption( 'ExpandMember' ) )
  537. {
  538. masterDialogSpecArray = this.getShowExpandCollapseIconOptionSpec().concat( masterDialogSpecArray );
  539. }
  540. this.masterDialogSpec = { rows: masterDialogSpecArray };
  541. }
  542. if(this.masterDialogSpec && this.masterDialogSpec.rows) {
  543. this.masterDialogSpecProperties = {};
  544. for(var r in this.masterDialogSpec.rows) {
  545. var row = this.masterDialogSpec.rows[r];
  546. if(row.columns) {
  547. for(var c in row.columns) {
  548. var col = row.columns[c];
  549. if(col.propertyName) {
  550. this.masterDialogSpecProperties[col.propertyName] = col;
  551. }
  552. }
  553. }
  554. }
  555. }
  556. },
  557. updateDialogSpec: function()
  558. {
  559. if(this.masterDialogSpecProperties) {
  560. if(this.masterDialogSpecProperties.originalReportLocation) {
  561. this.masterDialogSpecProperties.originalReportLocation.label = this.getOriginalReportLocation(this.iWidget);
  562. }
  563. }
  564. },
  565. initializeDialogSpec: function()
  566. {
  567. var userRole = this.iWidget.getUserRole();
  568. this.generateDialogSpec(userRole);
  569. },
  570. hasAVSChart: function()
  571. {
  572. if (this.iWidget == null || typeof this.iWidget.getViewerObject() == "undefined")
  573. {
  574. return false;
  575. }
  576. var oCV = this.iWidget.getViewerObject();
  577. if (typeof oCV == "undefined")
  578. {
  579. return false;
  580. }
  581. return oCV.hasAVSChart();
  582. },
  583. initializeFlashChartSettings: function( value )
  584. {
  585. if( !value )
  586. {
  587. return;
  588. }
  589. var json = ( typeof value === "string") ? (eval( value) ) : value ;
  590. var flashChartOptions = json[0];
  591. this.setProperty("flashCharts", flashChartOptions.defaultValue);
  592. this.isFlashChartOptionEnabled= !flashChartOptions.isOptionDisabled;
  593. },
  594. onClickViewReportSpecification: function()
  595. {
  596. var sUiSpec = this.iWidget.getViewerObject().envParams["ui.spec"];
  597. this._viewSpecInWindow(sUiSpec);
  598. },
  599. _getWindowOptions: function( w, h )
  600. {
  601. var sOptions = 'resizable=yes,scrollbars=yes,menubar=no,directories=no,location=no,status=no,toolbar=no,titlebar=no';
  602. var left = (screen.width - w)/2;
  603. var top = (screen.height - h)/2;
  604. sOptions += ',top=' + top;
  605. sOptions += ',left=' + left;
  606. sOptions += ',width=' + w;
  607. sOptions += ',height=' + h;
  608. return sOptions;
  609. },
  610. _viewSpecInWindow: function(sUiSpec)
  611. {
  612. var viewport = dijit.getViewport();
  613. var sWindowId = 'debugWindow' + this.iWidget.getViewerObject().getId();
  614. var sOptions = this._getWindowOptions(viewport.w, viewport.h);
  615. var oWindow = window.open("", sWindowId, sOptions);
  616. var head = '<html><body><table width="100%" cellspacing="0" cellpadding="0" border="0">' +
  617. '<tbody><tr><td>' +
  618. '<textarea wrap="off" style="font-family:arial; font-size: 10px; overflow: auto; width:100%; height:';
  619. head += viewport.h*0.95;
  620. head += 'px;">';
  621. var tail = '</textarea></td></tr></tbody></table></body></html>';
  622. oWindow.document.write( head + html_encode(sUiSpec) + tail );
  623. }
  624. });