PageRenderTime 83ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/scripts/XrmPageTemplate.js

#
JavaScript | 2658 lines | 1634 code | 160 blank | 864 comment | 363 complexity | cd7069f0b78a74c601d0665624d47bdf MD5 | raw file
  1. /// <reference path="PageData.js" />
  2. // DO NOT MODIFY THIS FILE.
  3. // After you have installed the Xrm.Page Script Development Form Snapshot solution in your organization,
  4. // use the Xrm.Page Snapshot button on the Customize tab of a form to generate a pageData object.
  5. // Copy the pageData object definition into the PageData.js file in this Visual Studio project.
  6. // - You should overwrite the existing definition
  7. // In your JScript library you should now get IntelliSense completion support for child objects of the Xrm.Page
  8. // Methods in Xrm.Page will provide IntelliSense guidance.
  9. // Methods that change Xrm.Page data will allow retrieving and setting data values.
  10. // Use the TestPage.htm to include scripts to test functions in your library.
  11. if (typeof (pageData) == "undefined") {
  12. var message = ["You must include the output of the Xrm.Page Snapshot in the\n",
  13. " PageData.js file for this solution. After you have installed the Xrm.Page Script Development Form Snapshot solution\n",
  14. " open an entity form and click the Customize tab in the ribbon. Click\n",
  15. " the Xrm.Page Snapshot button and copy the output into PageData.js."]
  16. alert(message.join(""));
  17. }
  18. var _cntrlDictionary = {};
  19. var _attDictionary = {};
  20. var _formsDictionary = null;
  21. var _navItemDictionary = {};
  22. var Xrm = new _xrm();
  23. function _xrm() {
  24. this.Page = new _page();
  25. if (pageData.xrmUtilityExists)
  26. {
  27. this.Utility = new _utility();
  28. }
  29. this.__namespace = true;
  30. }
  31. _xrm.prototype.toString = function () {
  32. return "[object Xrm namespace]";
  33. }
  34. function _page() {
  35. this.context = new _context();
  36. this.data = new _data();
  37. this.ui = new _ui();
  38. this.getAttribute = function (argument) {
  39. /// <summary>
  40. /// Returns one or more attributes depending on the arguments passed.
  41. /// </summary>
  42. /// <param name="argument" mayBeNull="true" optional="true" >
  43. /// <para>1: None: Returns an array of all the attributes.</para>
  44. /// <para>2: String: Returns the attribute where the argument matches the name.</para>
  45. /// <para>3: Number: Returns the attribute where the argument matches the index.</para>
  46. /// <para>4: Function: Returns any attributes that cause the delegate function to return true.</para>
  47. /// </param>
  48. return Xrm.Page.data.entity.attributes.get(argument);
  49. }
  50. this.getControl = function (argument) {
  51. /// <summary>
  52. /// Returns one or more controls depending on the arguments passed.
  53. /// </summary>
  54. /// <param name="argument" type="Object" mayBeNull="true" optional="true" >
  55. /// <para>1: None: Returns an array of all the controls.</para>
  56. /// <para>2: String: Returns the control where the argument matches the name.</para>
  57. /// <para>3: Number: Returns the control where the argument matches the index.</para>
  58. /// <para>4: Function: Returns any controls that cause the delegate function to return true.</para>
  59. /// </param>
  60. return Xrm.Page.ui.controls.get(argument);
  61. }
  62. }
  63. _page.prototype.toString = function () {
  64. return "[object Xrm.Page]";
  65. }
  66. function _utility() {
  67. this.openEntityForm = function (name, id, parameters) {
  68. /// <summary>
  69. /// Opens an entity form.
  70. /// </summary>
  71. /// <param name="name" type="String" mayBeNull="false" optional="false" >
  72. /// The logical name of an entity.
  73. /// </param>
  74. /// <param name="id" type="String" mayBeNull="true" optional="true" >
  75. /// The string representation of a unique identifier or the record to open in the form. If not set, a form to create a new record is opened.
  76. /// </param>
  77. /// <param name="parameters" type="Object" mayBeNull="true" optional="true" >
  78. /// A dictionary object that passes extra query string parameters to the form. Invalid query string parameters will cause an error.
  79. /// </param>
  80. /// <returns type="window" />
  81. var url;
  82. if (Xrm.Page.context.getClientUrl)
  83. { url = Xrm.Page.context.getClientUrl(); }
  84. else
  85. { url = Xrm.Page.context.getServerUrl(); }
  86. url = url + "/main.aspx?etn="+name+"&pagetype=entityrecord";
  87. if (id != null)
  88. { url = url + "&id=%7B" + id + "%7D"; }
  89. if (parameters != null)
  90. {
  91. var extraqs = "&extraqs=";
  92. var strings = [];
  93. for (var i in parameters) {
  94. strings.push(i + "=" + parameters[i])
  95. }
  96. extraqs += encodeURIComponent(strings.join("&"));
  97. url += extraqs;
  98. }
  99. return window.open(url, "_blank");
  100. };
  101. this.openWebResource = function (webResourceName, webResourceData, width, height) {
  102. /// <summary>
  103. /// Opens an HTML web resource.
  104. /// </summary>
  105. /// <param name="webResourceName" type="String" mayBeNull="false" optional="false" >
  106. /// The name of the HTML web resource to open.
  107. /// </param>
  108. /// <param name="webResourceData" type="String" mayBeNull="true" optional="true" >
  109. /// Data to be passed into the data parameter.
  110. /// </param>
  111. /// <param name="width" type="Number" mayBeNull="true" optional="true" >
  112. /// The width of the window to open in pixels.
  113. /// </param>
  114. /// <param name="height" type="Number" mayBeNull="true" optional="true" >
  115. /// The height of the window to open in pixels.
  116. /// </param>
  117. ///<returns type="window" />
  118. var url;
  119. if (Xrm.Page.context.getClientUrl)
  120. { url = Xrm.Page.context.getClientUrl(); }
  121. else
  122. { url = Xrm.Page.context.getServerUrl(); }
  123. url = url + "/WebResources/" + webResourceName;
  124. if (webResourceData != null)
  125. {
  126. url += "?Data=" + webResourceData;
  127. }
  128. var features = null;
  129. if (width != null)
  130. {
  131. features = "width=" + width;
  132. }
  133. if (height != null)
  134. {
  135. if (features == null)
  136. { features = "height=" + height; }
  137. else
  138. { features += ",height=" + height;; }
  139. }
  140. return window.open(url, "_blank",features);
  141. };
  142. }
  143. _utility.prototype.toString = function () {
  144. return "[object Xrm.Utility]";
  145. }
  146. function _context() {
  147. this.getAuthenticationHeader = function () {
  148. /// <summary>
  149. /// Returns the encoded SOAP header necessary to use Microsoft Dynamics CRM 4.0 web service calls using Jscript.
  150. /// </summary>
  151. /// <returns type="String" />
  152. return pageData.AuthenticationHeader.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
  153. }
  154. this.getCurrentTheme = function () {
  155. /// <summary>
  156. /// Returns the current theme used in the application.
  157. /// </summary>
  158. /// <returns type="String" />
  159. return pageData.CurrentTheme
  160. }
  161. this.getOrgLcid = function () {
  162. /// <summary>
  163. /// Returns the LCID value that represents the Microsoft Dynamics CRM Language Pack that is the base language for the organization.
  164. /// </summary>
  165. /// <returns type="Number" />
  166. return pageData.OrgLcid;
  167. }
  168. this.getOrgUniqueName = function () {
  169. /// <summary>
  170. /// Returns the unique text value of the organization’s name.
  171. /// </summary>
  172. /// <returns type="String" />
  173. return pageData.OrgUniqueName;
  174. }
  175. this.getQueryStringParameters = function () {
  176. /// <summary>
  177. /// Returns a dictionary object of key value pairs representing the query string arguments that were passed to the page.
  178. /// </summary>
  179. /// <returns type="Object" />
  180. return pageData.QueryStringParameters;
  181. }
  182. this.getServerUrl = function () {
  183. /// <summary>
  184. /// Deprecated. Returns the base server URL. When a user is working offline with the Microsoft Dynamics CRM for Microsoft Office Outlook client, the URL is to the local Microsoft Dynamics CRM Web services.
  185. /// </summary>
  186. /// <returns type="String" />
  187. return pageData.ServerUrl;
  188. }
  189. if (pageData.ClientUrl)
  190. {
  191. this.getClientUrl = function () {
  192. /// <summary>
  193. /// Returns the client URL. This URL is the root to the CRM application as it appears in the browser address bar.
  194. /// </summary>
  195. /// <returns type="String" />
  196. return pageData.ClientUrl;
  197. }
  198. }
  199. this.getUserId = function () {
  200. /// <summary>
  201. /// Returns GUID value of the SystemUser.id value for the current user.
  202. /// </summary>
  203. /// <returns type="String" />
  204. return pageData.UserId;
  205. }
  206. this.getUserLcid = function () {
  207. /// <summary>
  208. /// Returns the LCID value that represents the Microsoft Dynamics CRM Language Pack that is the user selected as their preferred language.
  209. /// </summary>
  210. /// <returns type="Number" />
  211. return pageData.UserLcid
  212. }
  213. this.getUserRoles = function () {
  214. /// <summary>
  215. /// Returns an array of strings representing the GUID values of each of the security roles that the user is associated with.
  216. /// </summary>
  217. /// <returns type="Array" />
  218. return pageData.UserRoles
  219. }
  220. this.isOutlookClient = function () {
  221. /// <summary>
  222. /// Returns Whether the client is the Outlook client
  223. /// </summary>
  224. /// <returns type="Boolean" />
  225. return pageData.isOutlookClient
  226. }
  227. this.isOutlookOnline = function () {
  228. /// <summary>
  229. /// Returns whether the use of the Outlook client is connected to the server. Returns false when they are working offline.
  230. /// </summary>
  231. /// <returns type="Boolean" />
  232. return pageData.isOutlookOnline
  233. }
  234. this.prependOrgName = function (url) {
  235. /// <summary>
  236. /// Accepts a string and prepends the organization name to it with a leading forward slash: "/"+OrgUniqueName + url
  237. /// </summary>
  238. /// <returns type="String" />
  239. return "/" + this.getOrgUniqueName() + url;
  240. }
  241. }
  242. _context.prototype.toString = function () {
  243. return "[object Xrm.Page.context]";
  244. }
  245. function _data() {
  246. this.entity = new _entity();
  247. }
  248. _data.prototype.toString = function () {
  249. return "[object Xrm.Page.data]";
  250. }
  251. function _ui() {
  252. this.controls = new _controlsCollection();
  253. this.formSelector = new _formSelector();
  254. this.navigation = new _navigationItems();
  255. this.tabs = new _tabCollection();
  256. this.close = function () {
  257. /// <summary>
  258. /// Closes the form.
  259. /// </summary>
  260. }
  261. this.getCurrentControl = function () {
  262. /// <summary>
  263. /// Returns the control object that currently has focus on the form.
  264. /// </summary>
  265. /// <returns type="Object" />
  266. return _cntrlDictionary[pageData.CurrentControl];
  267. }
  268. this.getFormType = function () {
  269. /// <summary>
  270. /// Indicates the form context for the record.
  271. /// <para> 0 : Undefined</para>
  272. /// <para> 1 : Create</para>
  273. /// <para> 2 : Update</para>
  274. /// <para> 3 : Read Only</para>
  275. /// <para> 4 : Disabled</para>
  276. /// <para> 5 : Quick Create (Deprecated)</para>
  277. /// <para> 6 : Bulk Edit</para>
  278. /// <para> 11: Read Optimized</para>
  279. /// </summary>
  280. /// <returns type="Number" />
  281. return pageData.FormType;
  282. }
  283. this.getViewPortHeight = function () {
  284. /// <summary>
  285. /// Returns the height of the viewport in pixels.
  286. /// </summary>
  287. /// <returns type="Number" />
  288. return pageData.ViewPortHeight;
  289. }
  290. this.getViewPortWidth = function () {
  291. /// <summary>
  292. /// Returns the width of the viewport in pixels.
  293. /// </summary>
  294. /// <returns type="Number" />
  295. return pageData.ViewPortWidth;
  296. }
  297. this.refreshRibbon = function () {
  298. /// <summary>
  299. /// Causes the ribbon to re-evaluate data that controls what is displayed in it.
  300. /// </summary>
  301. }
  302. }
  303. _ui.prototype.toString = function () {
  304. return "[object Xrm.Page.ui]";
  305. }
  306. function _navigationItems() {
  307. this.items = new _navItemCollection();
  308. }
  309. _navigationItems.prototype.toString = function () {
  310. return "[object Xrm.Page.ui.navigation]";
  311. }
  312. function _entity() {
  313. saveEventHandlers = [];
  314. this.addOnSave = function (functionPointer) {
  315. /// <summary>
  316. /// Adds the event handler function to be called when the entity is saved.
  317. /// It will be added to the bottom of the event pipeline and called after the other event handlers.
  318. /// </summary>
  319. if (typeof functionPointer == "function")
  320. { saveEventHandlers.push(functionPointer); }
  321. else
  322. { throw new Error("Xrm.Page.data.entity.addOnSave method requires a function to be passed as a parameter.") }
  323. };
  324. this.removeOnSave = function (functionPointer) {
  325. /// <summary>
  326. /// Removes the the event handler function from the event pipeline.
  327. /// </summary>
  328. var newSaveHandlers = [];
  329. for (var i = 0; i < saveEventHandlers.length; i++) {
  330. if (saveEventHandlers[i] != functionPointer)
  331. { newSaveHandlers.push(saveEventHandlers[i]); }
  332. }
  333. saveEventHandlers = newSaveHandlers;
  334. };
  335. this.getDataXml = function () {
  336. /// <summary>
  337. /// Returns a string representing the xml that will be sent to the server when the record is saved. Only data in fields that have changed are set to the server.
  338. /// </summary>
  339. /// <returns type="String" />
  340. var dataXml = [];
  341. var entityName = pageData.EntityName;
  342. dataXml.push("<" + entityName + ">");
  343. for (var attribute in _attDictionary) {
  344. var att = _attDictionary[attribute];
  345. var value = att.getValue();
  346. if (att.getIsDirty()) {
  347. if (value == null) {
  348. dataXml.push("<" + att.getName() + "/>")
  349. }
  350. else {
  351. switch (att.getAttributeType()) {
  352. case "lookup":
  353. //ActivityParty are formatted different from regular lookups
  354. var attributeName = att.getName()
  355. if ((attributeName == "allparties") ||
  356. (attributeName == "bcc") ||
  357. (attributeName == "cc") ||
  358. (attributeName == "customers") ||
  359. (attributeName == "from") ||
  360. (attributeName == "optionalattendees") ||
  361. (attributeName == "organizer") ||
  362. (attributeName == "partners") ||
  363. (attributeName == "requiredattendees") ||
  364. (attributeName == "resources") ||
  365. (attributeName == "to")) {
  366. dataXml.push("<" + attributeName + ">");
  367. for (var i = 0; i < value.length; i++) {
  368. dataXml.push("<activityparty>");
  369. dataXml.push("<partyid name=\"" + value[i].name + "\" type=\"" + value[i].entityType + "\">" + value[i].id + "</partyid>");
  370. dataXml.push("</activityparty>");
  371. }
  372. dataXml.push("</" + attributeName + ">");
  373. }
  374. else {
  375. var value = att.getValue();
  376. dataXml.push("<" + attributeName + " type=\"" + value[0].entityType + "\" name=\"" + value[0].name + "\">" + value[0].id + "</" + attributeName + ">")
  377. }
  378. break;
  379. default:
  380. dataXml.push("<" + att.getName() + ">" + value + "</" + att.getName() + ">")
  381. break;
  382. }
  383. }
  384. }
  385. }
  386. dataXml.push("</" + entityName + ">");
  387. return dataXml.join("");
  388. };
  389. this.getEntityName = function () {
  390. /// <summary>
  391. /// Returns a string representing the logical name of the entity for the record.
  392. /// </summary>
  393. /// <returns type="String" />
  394. return pageData.EntityName;
  395. };
  396. this.getId = function () {
  397. /// <summary>
  398. /// Returns a string representing the GUID id value for the record.
  399. /// </summary>
  400. /// <returns type="String" />
  401. return pageData.Id;
  402. };
  403. this.getIsDirty = function () {
  404. /// <summary>
  405. /// Returns a Boolean value that indicates if any fields in the form have been modified.
  406. /// </summary>
  407. /// <returns type="Boolean" />
  408. return pageData.IsDirty;
  409. };
  410. this.save = function (argument) {
  411. /// <summary>
  412. /// Saves the record.
  413. /// </summary>
  414. /// <param name="argument" type="String" mayBeNull="true" optional="true" >
  415. /// <para>1: None: If no parameter is included the record will simply be saved. </para>
  416. /// <para>2: "saveandclose" : Saves record and closes the form.</para>
  417. /// <para>3: "saveandnew" : Saves the record and opens a blank form for a new record.</para>
  418. /// </param>
  419. for (var i = 0; i < saveEventHandlers.length; i++) {
  420. saveEventHandlers[i]();
  421. }
  422. for (var attribute in _attDictionary) {
  423. _attDictionary[attribute]._setClean();
  424. }
  425. pageData.IsDirty = false;
  426. };
  427. this.attributes = new _attributesCollection();
  428. }
  429. _entity.prototype.toString = function () {
  430. var stringvalue = "[object entity : \'" + this.getEntityName() + "\' Id: '" + this.getId() + "\' isDirty: " + this.getIsDirty().toString() + "]";
  431. return stringvalue;
  432. }
  433. function _attributesCollection() {
  434. for (var i = 0; i < pageData.Attributes.length; i++) {
  435. var att = pageData.Attributes[i];
  436. switch (att.Type) {
  437. case "datetime":
  438. _attDictionary[att.Name] = new _datetimeAttribute(att);
  439. break;
  440. case "lookup":
  441. _attDictionary[att.Name] = new _lookupAttribute(att);
  442. break;
  443. case "memo":
  444. _attDictionary[att.Name] = new _memoAttribute(att);
  445. break;
  446. case "string":
  447. _attDictionary[att.Name] = new _stringAttribute(att);
  448. break;
  449. case "decimal":
  450. _attDictionary[att.Name] = new _decimalAttribute(att);
  451. break;
  452. case "double":
  453. _attDictionary[att.Name] = new _doubleAttribute(att);
  454. break;
  455. case "integer":
  456. _attDictionary[att.Name] = new _integerAttribute(att);
  457. break;
  458. case "money":
  459. _attDictionary[att.Name] = new _moneyAttribute(att);
  460. break;
  461. case "boolean":
  462. _attDictionary[att.Name] = new _booleanAttribute(att);
  463. break;
  464. case "optionset":
  465. _attDictionary[att.Name] = new _optionsetAttribute(att);
  466. break;
  467. default:
  468. throw new Error("Unrecognized attribute type:" + att.Type);
  469. break;
  470. }
  471. }
  472. this.forEach = function (delegate_function) {
  473. /// <summary>
  474. /// Applies the action contained within a delegate function.
  475. /// </summary>
  476. /// <param name="delegate_function" type="Function" mayBeNull="false" optional="false" >
  477. /// The delegate_function must include parameters for attribute and index. i.e : MyFunction(attribute,index).
  478. /// </param>
  479. // for (var i = 0; i < attributes.length; i++)
  480. // {
  481. // delegate_function(attributes[i], i);
  482. // }
  483. var i = 0;
  484. for (var attribute in _attDictionary) {
  485. delegate_function(_attDictionary[attribute], i);
  486. i++;
  487. }
  488. };
  489. this.get = function (argument) {
  490. /// <summary>
  491. /// Returns one or more attributes depending on the arguments passed.
  492. /// </summary>
  493. /// <param name="argument" mayBeNull="true" optional="true" >
  494. /// <para>1: None: Returns an array of all the attributes.</para>
  495. /// <para>2: String: Returns the attribute where the argument matches the name.</para>
  496. /// <para>3: Number: Returns the attribute where the argument matches the index.</para>
  497. /// <para>4: Function: Returns any attributes that cause the delegate function to return true.</para>
  498. /// </param>
  499. var argType = typeof argument;
  500. if (argument == null) {
  501. var allAttributes = [];
  502. for (var i in _attDictionary) {
  503. allAttributes.push(_attDictionary[i]);
  504. }
  505. return allAttributes;
  506. }
  507. switch (argType) {
  508. case "number":
  509. var i = 0;
  510. for (var attribute in _attDictionary) {
  511. if (argument == i) {
  512. return _attDictionary[attribute];
  513. }
  514. i++;
  515. }
  516. return null;
  517. break;
  518. case "string":
  519. return _attDictionary[argument];
  520. return null;
  521. break;
  522. case "function":
  523. var returnAtts = [];
  524. var i = 0;
  525. for (var attribute in _attDictionary) {
  526. if (argument(_attDictionary[attribute], i)) {
  527. returnAtts.push(_attDictionary[attribute]);
  528. }
  529. i++;
  530. }
  531. return returnAtts
  532. break;
  533. }
  534. };
  535. this.getLength = function () {
  536. /// <summary>
  537. /// Returns the number of items in the collection.
  538. /// </summary>
  539. /// <returns type="Number" />
  540. return pageData.Attributes.length;;
  541. };
  542. }
  543. _attributesCollection.prototype.toString = function () {
  544. var stringvalue = "[object Xrm.Page.data.entity.attributes: " + this.getLength() + " attributes ]";
  545. return stringvalue;
  546. }
  547. function _controlsCollection() {
  548. for (var i = 0; i < pageData.Controls.length; i++) {
  549. var ctrl = pageData.Controls[i];
  550. ctrl.parent = getControlParent(ctrl.Name);
  551. switch (ctrl.Type) {
  552. case "standard":
  553. _cntrlDictionary[ctrl.Name] = new _standardControl(ctrl);
  554. break;
  555. case "iframe":
  556. _cntrlDictionary[ctrl.Name] = new _iframeControl(ctrl);
  557. break;
  558. case "lookup":
  559. _cntrlDictionary[ctrl.Name] = new _lookupControl(ctrl);
  560. break;
  561. case "optionset":
  562. _cntrlDictionary[ctrl.Name] = new _optionsetControl(ctrl);
  563. break;
  564. case "subgrid":
  565. _cntrlDictionary[ctrl.Name] = new _subgridControl(ctrl);
  566. break;
  567. case "webresource":
  568. _cntrlDictionary[ctrl.Name] = new _webresourceControl(ctrl);
  569. break;
  570. case "notes":
  571. _cntrlDictionary[ctrl.Name] = new _notesControl(ctrl);
  572. break;
  573. default:
  574. throw new Error("Unrecognized control type:" + ctrl.Type);
  575. break;
  576. }
  577. }
  578. function getControlParent(controlName) {
  579. var parentSectionNotFound = true;
  580. for (var tab in pageData.Tabs) {
  581. for (var section in pageData.Tabs[tab].Sections) {
  582. for (var control in pageData.Tabs[tab].Sections[section].Controls) {
  583. if (pageData.Tabs[tab].Sections[section].Controls[control].Name == controlName) {
  584. parentSectionNotFound = false;
  585. return pageData.Tabs[tab].Sections[section].Name;
  586. }
  587. }
  588. }
  589. }
  590. if (parentSectionNotFound)
  591. { throw new Error("Parent section for control " + controlName + " was not found."); }
  592. }
  593. this.forEach = function (delegate_function) {
  594. /// <summary>
  595. /// Applies the action contained within a delegate function.
  596. /// </summary>
  597. /// <param name="delegate_function" type="Object" mayBeNull="false" optional="false" >
  598. /// The function must include parameters for control and index. i.e Myfunction(control, index).
  599. /// </param>
  600. var i = 0;
  601. for (var control in _cntrlDictionary) {
  602. delegate_function(_cntrlDictionary[control], i);
  603. i++;
  604. }
  605. };
  606. this.get = function (argument) {
  607. /// <summary>
  608. /// Returns one or more controls depending on the arguments passed.
  609. /// </summary>
  610. /// <param name="argument" type="Object" mayBeNull="true" optional="true" >
  611. /// <para>1: None: Returns an array of all the controls.</para>
  612. /// <para>2: String: Returns the control where the argument matches the name.</para>
  613. /// <para>3: Number: Returns the control where the argument matches the index.</para>
  614. /// <para>4: Function: Returns any controls that cause the delegate function to return true.</para>
  615. /// </param>
  616. var argType = typeof argument;
  617. if (argument == null) {
  618. var allControls = [];
  619. for (var i in _cntrlDictionary) {
  620. allControls.push(_cntrlDictionary[i]);
  621. }
  622. return allControls;
  623. }
  624. switch (argType) {
  625. case "number":
  626. var i = 0;
  627. for (var control in _cntrlDictionary) {
  628. if (argument == i) {
  629. return _cntrlDictionary[control];
  630. }
  631. i++;
  632. }
  633. return null;
  634. break;
  635. case "string":
  636. return _cntrlDictionary[argument];
  637. break;
  638. case "function":
  639. var returnControls = [];
  640. var i = 0;
  641. for (var control in _cntrlDictionary) {
  642. if (argument(_cntrlDictionary[control], i)) {
  643. returnControls.push(_cntrlDictionary[control]);
  644. }
  645. i++;
  646. }
  647. return returnControls
  648. break;
  649. }
  650. };
  651. this.getLength = function () {
  652. /// <summary>
  653. /// Returns the number of items in the collection.
  654. /// </summary>
  655. /// <returns type="Number" />
  656. return pageData.ControlsLength;
  657. };
  658. }
  659. _controlsCollection.prototype.toString = function () {
  660. var stringvalue = "[object Xrm.Page.ui.controls: " + this.getLength() + " controls ]";
  661. return stringvalue;
  662. }
  663. function _childControlsCollection(ControlNames) {
  664. var controlNames = ControlNames;
  665. this.forEach = function (delegate_function) {
  666. /// <summary>
  667. /// Applies the action contained within a delegate function.
  668. /// </summary>
  669. /// <param name="delegate_function" type="Object" mayBeNull="false" optional="false" >
  670. /// The function must include parameters for control and index. i.e Myfunction(control, index).
  671. /// </param>
  672. var parentControls = {}
  673. for (var i = 0; i < controlNames.length; i++) {
  674. parentControls[controlNames[i].Name] = _cntrlDictionary[controlNames[i].Name];
  675. }
  676. var i = 0;
  677. for (var control in parentControls) {
  678. delegate_function(parentControls[control], i);
  679. i++;
  680. }
  681. };
  682. this.get = function (argument) {
  683. /// <summary>
  684. /// Returns one or more controls depending on the arguments passed.
  685. /// </summary>
  686. /// <param name="argument" type="Object" mayBeNull="true" optional="true" >
  687. /// <para>1: None: Returns an array of all the controls.</para>
  688. /// <para>2: String: Returns the control where the argument matches the name.</para>
  689. /// <para>3: Number: Returns the control where the argument matches the index.</para>
  690. /// <para>4: Function: Returns any controls that cause the delegate function to return true.</para>
  691. /// </param>
  692. if (controlNames.length == 0) {
  693. return null;
  694. }
  695. else {
  696. var parentControls = {}
  697. for (var i = 0; i < controlNames.length; i++) {
  698. parentControls[controlNames[i].Name] = _cntrlDictionary[controlNames[i].Name];
  699. }
  700. var matchingControls = [];
  701. var argType = typeof argument;
  702. if (argument == null) {
  703. for (var control in parentControls) {
  704. matchingControls.push(parentControls[control]);
  705. }
  706. }
  707. switch (argType) {
  708. case "number":
  709. return parentControls[controlNames[argument].Name]
  710. break;
  711. case "string":
  712. return parentControls[argument];
  713. break;
  714. case "function":
  715. var i = 0;
  716. for (var control in parentControls) {
  717. if (argument(parentControls[control], i)) {
  718. matchingControls.push(parentControls[control]);
  719. }
  720. i++;
  721. }
  722. break;
  723. }
  724. return matchingControls;
  725. }
  726. };
  727. this.getLength = function () {
  728. /// <summary>
  729. /// Returns the number of items in the collection.
  730. /// </summary>
  731. /// <returns type="Number" />
  732. return ControlNames.length;
  733. };
  734. }
  735. _childControlsCollection.prototype.toString = function () {
  736. var stringvalue = "[object controls collection: " + this.getLength() + " controls]";
  737. return stringvalue;
  738. }
  739. function _formSelector() {
  740. if (pageData.Forms.length > 0) {
  741. _formsDictionary = {};
  742. for (var i = 0; i < pageData.Forms.length; i++) {
  743. _formsDictionary[pageData.Forms[i].Id] = new _formItem(pageData.Forms[i]);
  744. }
  745. }
  746. this.items = new _formItemsCollection();
  747. this.getCurrentItem = function () {
  748. if (_formsDictionary != null) {
  749. return _formsDictionary[pageData.CurrentForm.Id];
  750. }
  751. else { return null; }
  752. };
  753. }
  754. _formSelector.prototype.toString = function () {
  755. var stringvalue = "[object Xrm.Page.ui.formSelector: current item:" + ((this.getCurrentItem() == null) ? "null" : this.getCurrentItem().getLabel()) + "]";
  756. return stringvalue;
  757. }
  758. function _formItemsCollection() {
  759. this.forEach = function (delegateFunction) {
  760. /// <summary>
  761. /// Applies the action contained within a delegate function.
  762. /// </summary>
  763. /// <param name="delegate_function" type="Function" mayBeNull="false" optional="false" >
  764. /// The function must include parameters for form item and index. i.e Myfunction(item, index).
  765. /// </param>
  766. if (_formsDictionary != null) {
  767. var i = 0;
  768. for (var form in _formsDictionary) {
  769. delegateFunction(_formsDictionary[form], i);
  770. i++;
  771. }
  772. }
  773. };
  774. this.get = function (argument) {
  775. /// <summary>
  776. /// Returns one or more form items depending on the arguments passed.
  777. /// </summary>
  778. /// <param name="argument" mayBeNull="true" optional="true" >
  779. /// <para>1: None: Returns an array of all the form items.</para>
  780. /// <para>2: String: Returns the form item where the argument matches the id.</para>
  781. /// <para>3: Number: Returns the form item where the argument matches the index.</para>
  782. /// <para>4: Function: Returns any form items that cause the delegate function to return true.</para>
  783. /// </param>
  784. var matchedForms = [];
  785. if (argument == null) {
  786. if (_formsDictionary != null) {
  787. for (var form in _formsDictionary) {
  788. matchedForms.push(_formsDictionary[form]);
  789. }
  790. }
  791. }
  792. var argType = typeof argument;
  793. switch (argType) {
  794. case "number":
  795. var i = 0;
  796. for (var form in _formsDictionary) {
  797. if (i == argument) {
  798. return _formsDictionary[form];
  799. i++;
  800. }
  801. }
  802. break;
  803. case "string":
  804. return _formsDictionary[argument];
  805. break;
  806. case "function":
  807. var i = 0;
  808. for (var form in _formsDictionary) {
  809. if (argument(_formsDictionary[form], i)) {
  810. matchedForms.push(_formsDictionary[form]);
  811. }
  812. i++;
  813. }
  814. break;
  815. }
  816. return matchedForms;
  817. };
  818. this.getLength = function () {
  819. /// <summary>
  820. /// Returns the number of items in the collection.
  821. /// </summary>
  822. /// <returns type="Number" />
  823. return pageData.Forms.length;
  824. };
  825. }
  826. _formItemsCollection.prototype.toString = function () {
  827. var stringvalue = "[object Xrm.Page.ui.formSelector.items collection: " + this.getLength() + " items]";
  828. return stringvalue;
  829. }
  830. function _formItem(item) {
  831. var id = item.Id;
  832. var label = item.Label;
  833. this.getId = function () {
  834. /// <summary>
  835. /// Returns the id of the form item
  836. /// </summary>
  837. /// <returns type="String" />
  838. return id;
  839. };
  840. this.getLabel = function () {
  841. /// <summary>
  842. /// Returns the label for the form item
  843. /// </summary>
  844. /// <returns type="String" />
  845. return label;
  846. };
  847. this.navigate = function () {
  848. /// <summary>
  849. /// Closes the current form and opens the specified form.
  850. /// </summary>
  851. };
  852. }
  853. _formItem.prototype.toString = function () {
  854. var stringvalue = "[object form item: " + this.getLabel() + " id: " + this.getId() + "]";
  855. return stringvalue;
  856. }
  857. function _navItemCollection() {
  858. for (var i = 0; i < pageData.Navigation.length; i++) {
  859. var item = pageData.Navigation[i];
  860. _navItemDictionary[item.Id] = new _navItem(item);
  861. }
  862. this.forEach = function (delegate_function) {
  863. /// <summary>
  864. /// Applies the action contained within a delegate function.
  865. /// </summary>
  866. /// <param name="delegate_function" type="Function" mayBeNull="false" optional="false" >
  867. /// The function must include parameters for navigation item and index. i.e Myfunction(item, index).
  868. /// </param>
  869. var i = 0;
  870. for (var item in _navItemDictionary) {
  871. delegate_function(_navItemDictionary[item], i);
  872. i++;
  873. }
  874. };
  875. this.get = function (argument) {
  876. /// <summary>
  877. /// Returns one or more items depending on the arguments passed.
  878. /// </summary>
  879. /// <param name="argument" mayBeNull="true" optional="true" >
  880. /// <para>1: None: Returns an array of all the items.</para>
  881. /// <para>2: String: Returns the item where the argument matches the id.</para>
  882. /// <para>3: Number: Returns the item where the argument matches the index.</para>
  883. /// <para>4: Function: Returns any items that cause the delegate function to return true.</para>
  884. /// </param>
  885. var matchingItems = [];
  886. if (argument == null) {
  887. var matchingItems = [];
  888. for (var item in _navItemDictionary) {
  889. matchingItems.push(_navItemDictionary[item]);
  890. }
  891. return matchingItems;
  892. }
  893. var argType = typeof argument;
  894. switch (argType) {
  895. case "number":
  896. var index = 0;
  897. for (var item in _navItemDictionary) {
  898. if (index == argument) {
  899. return _navItemDictionary[item];
  900. }
  901. index++;
  902. }
  903. break;
  904. case "string":
  905. return _navItemDictionary[argument];
  906. break;
  907. case "function":
  908. var index = 0;
  909. for (var item in _navItemDictionary) {
  910. if (argument(_navItemDictionary[item], index)) {
  911. matchingItems.push(_navItemDictionary[item]);
  912. }
  913. index++;
  914. }
  915. break;
  916. }
  917. return matchingItems;
  918. };
  919. this.getLength = function () {
  920. /// <summary>
  921. /// Returns the number of items in the collection.
  922. /// </summary>
  923. /// <returns type="Number" />
  924. return pageData.Navigation.length;
  925. };
  926. }
  927. _navItemCollection.prototype.toString = function () {
  928. var stringvalue = "[object Xrm.Page.ui.navigation.items: " + this.getLength() + " items]";
  929. return stringvalue;
  930. }
  931. function _navItem(item) {
  932. var id, label, isVisible;
  933. id = item.Id;
  934. label = item.Label;
  935. isVisible = item.Visible;
  936. this.getId = function () {
  937. /// <summary>
  938. /// Returns the id of the item
  939. /// </summary>
  940. /// <returns type="String" />
  941. return id;
  942. };
  943. this.getLabel = function () {
  944. /// <summary>
  945. /// Returns the label for the item
  946. /// </summary>
  947. /// <returns type="String" />
  948. return label;
  949. };
  950. this.getVisible = function () {
  951. /// <summary>
  952. /// Returns whether the item is currently visible.
  953. /// </summary>
  954. /// <returns type="Boolean" />
  955. return isVisible;
  956. };
  957. this.setFocus = function () {
  958. /// <summary>
  959. /// Sets focus on the item
  960. /// </summary>
  961. };
  962. this.setLabel = function (labelText) {
  963. /// <summary>
  964. /// Sets the label text of the item.
  965. /// </summary>
  966. /// <param name="labelText" type="String" mayBeNull="false" optional="false" >
  967. /// The new text for the label.
  968. /// </param>
  969. if (typeof labelText == "string")
  970. { label = labelText; }
  971. else
  972. { throw new Error("Invalid argument. Expected string value."); }
  973. };
  974. this.setVisible = function (visible) {
  975. /// <summary>
  976. /// Sets whether the item is visible
  977. /// </summary>
  978. /// <param name="visible" type="Boolean" mayBeNull="false" optional="false" >
  979. /// The boolean value indicating whether the item is visible
  980. /// </param>
  981. if (typeof isVisible == "boolean") {
  982. isVisible = visible;
  983. }
  984. else { throw new Error("Invalid argument. Expected boolean value.") }
  985. };
  986. }
  987. _navItem.prototype.toString = function () {
  988. var stringvalue = "[object navigation item : \'" + this.getId() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  989. return stringvalue;
  990. }
  991. // =====================================================
  992. // ATTRIBUTES ==========================================
  993. // =====================================================
  994. //Start Attribute definitions -------------------------------------------------------------------
  995. // ATTRIBUTE Base ===================================================================
  996. function _attributeBase(att) {
  997. var name, format, isDirty, requiredLevel, submitMode, userPrivilege, controls, changeEventHandlers, errorMessage;
  998. name = att.Name;
  999. format = att.Format;
  1000. isDirty = att.IsDirty;
  1001. requiredLevel = att.RequiredLevel;
  1002. submitMode = att.SubmitMode;
  1003. userPrivilege = att.UserPrivilege;
  1004. controlNames = att.Controls;
  1005. changeEventHandlers = [];
  1006. this.addOnChange = function (functionPointer) {
  1007. /// <summary>
  1008. /// Adds an event handler function to the OnChange event for the attribute. It will be called after the other event handler functions in the event pipeline.
  1009. /// </summary>
  1010. if (typeof functionPointer == "function") {
  1011. changeEventHandlers.push(functionPointer);
  1012. }
  1013. else {
  1014. errorMessage = "Error using addOnChange with the " + name + " attribute. The parameter passed is not a function.";
  1015. throw new Error(errorMessage);
  1016. }
  1017. };
  1018. this.removeOnChange = function (functionPointer) {
  1019. /// <summary>
  1020. /// Removes and event handler function from the OnChange event for the attribute.
  1021. /// </summary>
  1022. if (typeof functionPointer != "function") {
  1023. errorMessage = "Error using removeOnChange with the " + name + " attribute. The parameter passed is not a function.";
  1024. throw new Error(errorMessage);
  1025. }
  1026. var newHandlers = [];
  1027. for (var i = 0; i < changeEventHandlers.length; i++) {
  1028. if (changeEventHandlers[i] != functionPointer) {
  1029. newHandlers.push(changeEventHandlers[i]);
  1030. }
  1031. }
  1032. changeEventHandlers = newHandlers;
  1033. };
  1034. this.fireOnChange = function () {
  1035. /// <summary>
  1036. /// Causes the OnChange event to occur on the attribute so that any script associated to that event can execute.
  1037. /// </summary>
  1038. isDirty = true;
  1039. pageData.IsDirty = true;
  1040. for (var i = 0; i < changeEventHandlers.length; i++) {
  1041. changeEventHandlers[i]();
  1042. }
  1043. };
  1044. this.getFormat = function () {
  1045. /// <summary>
  1046. /// Returns a string value that represents formatting options for the attribute. The value may be null.
  1047. /// </summary>
  1048. /// <returns type="String" />
  1049. return format;
  1050. };
  1051. this.getIsDirty = function () {
  1052. /// <summary>
  1053. /// Returns a Boolean value indicating if there are unsaved changes to the attribute value.
  1054. /// </summary>
  1055. /// <returns type="Boolean" />
  1056. return isDirty;
  1057. };
  1058. this.getName = function () {
  1059. /// <summary>
  1060. /// Returns a string representing the logical name of the attribute.
  1061. /// </summary>
  1062. /// <returns type="String" />
  1063. return name;
  1064. };
  1065. this.getParent = function () {
  1066. /// <summary>
  1067. /// Returns the entity object that is the parent to the attribute. In the case of an attribute this is Xrm.Page.data.entity.
  1068. /// </summary>
  1069. return function () { return Xrm.Page.data.entity; }();
  1070. };
  1071. this.getRequiredLevel = function () {
  1072. /// <summary>
  1073. /// Returns a string value indicating whether a value for the attribute is required or recommended. Will return either "none", "required", or "recommended".
  1074. /// </summary>
  1075. /// <returns type="String" />
  1076. return requiredLevel;
  1077. };
  1078. this.getSubmitMode = function () {
  1079. /// <summary>
  1080. /// Returns a string indicating when data from the attribute will be submitted when the record is saved. Will return either "always", "never", or "dirty".
  1081. /// </summary>
  1082. /// <returns type="String" />
  1083. return submitMode;
  1084. };
  1085. this.getUserPrivilege = function () {
  1086. /// <summary>
  1087. /// Returns an array of privileges that contain Boolean values indicating if the user can create, read or update data values for an attribute.
  1088. /// </summary>
  1089. /// <returns type="Array" />
  1090. return userPrivilege;
  1091. };
  1092. this.setRequiredLevel = function (level) {
  1093. /// <summary>
  1094. /// Sets the required level for the attribute
  1095. /// </summary>
  1096. /// <param name="level" type="String" mayBeNull="false" optional="false" >
  1097. /// Valid values include "none", "required", and "recommended".
  1098. /// </param>
  1099. if (level == "none" || level == "required" || level == "recommended")
  1100. { requiredLevel = level; }
  1101. else
  1102. {
  1103. errorMessage = "Error using setRequiredLevel on the " + name + " attribute. Invalid argument. Valid arguments for setRequiredLevel include \"none\", \"required\", and \"recommended\".";
  1104. throw new Error(errorMessage);
  1105. }
  1106. };
  1107. this.setSubmitMode = function (mode) {
  1108. /// <summary>
  1109. /// Sets whether data from the attribute will be submitted when the record is saved.
  1110. /// </summary>
  1111. /// <param name="mode" type="String" mayBeNull="false" optional="false" >
  1112. /// Valid values include "always", "never", and "dirty".
  1113. /// </param>
  1114. if (mode == "always" || mode == "never" || mode == "dirty")
  1115. { submitMode = mode; }
  1116. else
  1117. {
  1118. errorMessage = "Error using setSubmitMode on the " + name + " attribute. Invalid argument. Valid arguments for setSubmitMode include \"always\", \"never\", and \"dirty\".";
  1119. throw new Error(errorMessage);
  1120. }
  1121. };
  1122. this._setClean = function () {
  1123. /// <summary>
  1124. /// Private function for design time to be called when entity saved. Not an actual Microsoft CRM attribute method.
  1125. /// </summary>
  1126. isDirty = false;
  1127. }
  1128. this.controls = new _childControlsCollection(controlNames);
  1129. }
  1130. // NUMBER Base ===================================================================
  1131. function _numberBaseAttribute(att) {
  1132. _attributeBase.call(this, att);
  1133. var value, max, min, precision, errorMessage;
  1134. value = att.Value;
  1135. max = att.Max;
  1136. min = att.Min;
  1137. precision = att.Precision;
  1138. this.getMax = function () {
  1139. /// <summary>
  1140. /// Returns a number indicating the maximum allowed value for an attribute.
  1141. /// </summary>
  1142. /// <returns type="Number" />
  1143. return max;
  1144. };
  1145. this.getMin = function () {
  1146. /// <summary>
  1147. /// Returns a number indicating the minimum allowed value for an attribute.
  1148. /// </summary>
  1149. /// <returns type="Number" />
  1150. return min;
  1151. };
  1152. this.getPrecision = function () {
  1153. /// <summary>
  1154. /// Returns the number of digits allowed to the right of the decimal point.
  1155. /// </summary>
  1156. /// <returns type="Number" />
  1157. return precision;
  1158. };
  1159. this.getValue = function () {
  1160. /// <summary>
  1161. /// Retrieves the data value for the decimal attribute
  1162. /// </summary>
  1163. /// <returns type="Number" />
  1164. return value;
  1165. };
  1166. this.setValue = function (newValue) {
  1167. /// <summary>
  1168. /// Sets the data value for a decimal attribute.
  1169. /// </summary>
  1170. /// <param name="newValue" type="Number" mayBeNull="false" optional="false" >
  1171. /// The new value for the decimal attribute
  1172. /// </param>
  1173. if (newValue == null && value != null) {
  1174. value = newValue;
  1175. this.fireOnChange();
  1176. return;
  1177. }
  1178. if (typeof newValue == "number") {
  1179. if (value != newValue) {
  1180. if (newValue <= max && newValue >= min) {
  1181. value = newValue;
  1182. this.fireOnChange();
  1183. }
  1184. else {
  1185. errorMessage = "Out of Range. The value of the " + this.getName() + " attribute must be between " + min + " and " + max + "."
  1186. throw new Error(errorMessage);
  1187. }
  1188. }
  1189. }
  1190. else {
  1191. errorMessage = "Invalid argument setting " + this.getName() + ". Use a Number parameter value when using setValue on a " + this.getAttributeType() + " attribute."
  1192. throw new Error(message);
  1193. }
  1194. };
  1195. }
  1196. // BOOLEAN ===================================================================
  1197. function _booleanAttribute(att) {
  1198. _attributeBase.call(this, att);
  1199. var initialValue, value, errorMessage;
  1200. initialValue = att.InitialValue;
  1201. value = att.Value;
  1202. this.getAttributeType = function () {
  1203. /// <summary>
  1204. /// Returns a string value that represents the type of attribute. In this case 'boolean'.
  1205. /// </summary>
  1206. /// <returns type="String" />
  1207. return "boolean";
  1208. };
  1209. this.getInitialValue = function () {
  1210. /// <summary>
  1211. /// Returns the value of the attribute when the record was last saved or the default value before the record is saved.
  1212. /// </summary>
  1213. /// <returns type="Number" />
  1214. return initialValue;
  1215. }
  1216. this.getValue = function () {
  1217. /// <summary>
  1218. /// Retrieves the data value for the boolean attribute
  1219. /// </summary>
  1220. /// <returns type="Boolean" />
  1221. return value;
  1222. };
  1223. this.setValue = function (newValue) {
  1224. /// <summary>
  1225. /// Sets the data value for a Boolean attribute.
  1226. /// </summary>
  1227. /// <param name="newValue" type="Boolean" mayBeNull="false" optional="false" >
  1228. /// The new value for the boolean attribute
  1229. /// </param>
  1230. if (newValue != null && (typeof newValue == "boolean")) {
  1231. if (value != newValue) {
  1232. value = newValue;
  1233. this.fireOnChange();
  1234. }
  1235. }
  1236. else {
  1237. errorMessage = "Error using setValue on the " + this.getName() + " attribute. Invalid argument. Use a boolean parameter value when using setValue on a boolean attribute.";
  1238. throw new Error(errorMessage);
  1239. }
  1240. };
  1241. }
  1242. _booleanAttribute.prototype.toString = function () {
  1243. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : this.getValue().toString()) + "]";
  1244. return stringvalue;
  1245. }
  1246. // DATETIME ===================================================================
  1247. function _datetimeAttribute(att) {
  1248. var value;
  1249. _attributeBase.call(this, att);
  1250. if (att.Value != null) {
  1251. value = new Date(att.Value);
  1252. }
  1253. else { value = null; }
  1254. this.getAttributeType = function () {
  1255. /// <summary>
  1256. /// Returns a string value that represents the type of attribute. In this case 'datetime'.
  1257. /// </summary>
  1258. /// <returns type="String" />
  1259. return "datetime";
  1260. };
  1261. this.getValue = function () {
  1262. /// <summary>
  1263. /// Retrieves the data value for the datetime attribute
  1264. /// </summary>
  1265. /// <returns type="Date" />
  1266. return value;
  1267. };
  1268. this.setValue = function (newValue) {
  1269. /// <summary>
  1270. /// Sets the data value for a datetime attribute.
  1271. /// </summary>
  1272. /// <param name="newValue" type="Date" mayBeNull="false" optional="false" >
  1273. /// The new value for the datetime attribute
  1274. /// </param>
  1275. if (value != newValue) {
  1276. if (newValue == null) {
  1277. value = newValue;
  1278. this.fireOnChange();
  1279. }
  1280. else {
  1281. var test;
  1282. try {
  1283. test = newValue.getYear();
  1284. value = newValue;
  1285. this.fireOnChange();
  1286. }
  1287. catch (e) {
  1288. throw new Error("Invalid argument. Use a Date parameter value when using setValue on a datetime attribute.");
  1289. }
  1290. }
  1291. }
  1292. };
  1293. }
  1294. _datetimeAttribute.prototype.toString = function () {
  1295. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : "\'" + this.getValue().toString() + "\'") + "]";
  1296. return stringvalue;
  1297. }
  1298. // DECIMAL ===================================================================
  1299. function _decimalAttribute(att) {
  1300. var value = att.Value;
  1301. _numberBaseAttribute.call(this, att);
  1302. this.getAttributeType = function () {
  1303. /// <summary>
  1304. /// Returns a string value that represents the type of attribute. In this case 'decimal'.
  1305. /// </summary>
  1306. /// <returns type="String" />
  1307. return "decimal";
  1308. };
  1309. }
  1310. _decimalAttribute.prototype.toString = function () {
  1311. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : this.getValue().toString()) + "]";
  1312. return stringvalue;
  1313. }
  1314. // DOUBLE ===================================================================
  1315. function _doubleAttribute(att) {
  1316. var value = att.Value;
  1317. _numberBaseAttribute.call(this, att);
  1318. this.getAttributeType = function () {
  1319. /// <summary>
  1320. /// Returns a string value that represents the type of attribute. In this case 'double'.
  1321. /// </summary>
  1322. /// <returns type="String" />
  1323. return "double";
  1324. };
  1325. }
  1326. _doubleAttribute.prototype.toString = function () {
  1327. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : this.getValue().toString()) + "]";
  1328. return stringvalue;
  1329. }
  1330. // INTEGER ===================================================================
  1331. function _integerAttribute(att) {
  1332. var value = att.Value;
  1333. _numberBaseAttribute.call(this, att);
  1334. this.getAttributeType = function () {
  1335. /// <summary>
  1336. /// Returns a string value that represents the type of attribute. In this case 'integer'.
  1337. /// </summary>
  1338. /// <returns type="String" />
  1339. return "integer";
  1340. };
  1341. }
  1342. _integerAttribute.prototype.toString = function () {
  1343. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : this.getValue().toString()) + "]";
  1344. return stringvalue;
  1345. }
  1346. // LOOKUP ===================================================================
  1347. function _lookupAttribute(att) {
  1348. var value = att.Value;
  1349. _attributeBase.call(this, att);
  1350. this.getAttributeType = function () {
  1351. /// <summary>
  1352. /// Returns a string value that represents the type of attribute. In this case 'lookup'.
  1353. /// </summary>
  1354. /// <returns type="String" />
  1355. return "lookup";
  1356. };
  1357. this.getValue = function () {
  1358. /// <summary>
  1359. /// Retrieves the data value for the lookup attribute
  1360. /// </summary>
  1361. if (typeof value == "undefined")
  1362. { return null; }
  1363. else
  1364. {
  1365. return value;
  1366. }
  1367. };
  1368. this.setValue = function (newValue) {
  1369. /// <summary>
  1370. /// Sets the data value for a lookup attribute.
  1371. /// </summary>
  1372. /// <param name="newValue" type="Array" mayBeNull="true" optional="true" >
  1373. /// The new value for the lookup attribute. This value must be an array of lookup objects
  1374. /// </param>
  1375. if (newValue == null && value != null) {
  1376. value = newValue;
  1377. this.fireOnChange();
  1378. return;
  1379. }
  1380. //(newValue == null && value == null) --> Do nothing
  1381. if (value != newValue) {
  1382. var isValidArray = true;
  1383. for (var i = 0; i < newValue.length; i++) {
  1384. if (!(typeof newValue[i].entityType == "string" && typeof newValue[i].id == "string" && typeof newValue[i].name == "string")) {
  1385. isValidArray = false;
  1386. }
  1387. }
  1388. if (isValidArray) {
  1389. value = newValue;
  1390. this.fireOnChange();
  1391. }
  1392. else {
  1393. throw new Error("Invalid argument. Use a array of lookup objects parameter value when using setValue on a lookup attribute.");
  1394. }
  1395. }
  1396. };
  1397. }
  1398. _lookupAttribute.prototype.toString = function () {
  1399. var displayString = "";
  1400. if (this.getValue() == null) {
  1401. displayString = "null";
  1402. }
  1403. else {
  1404. var luov = this.getValue();
  1405. displayString = JSON.stringify(luov)
  1406. }
  1407. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + displayString + "]";
  1408. return stringvalue;
  1409. }
  1410. // MEMO ===================================================================
  1411. function _memoAttribute(att) {
  1412. var value, maxlength;
  1413. value = att.Value;
  1414. maxlength = att.MaxLength;
  1415. _attributeBase.call(this, att);
  1416. this.getAttributeType = function () {
  1417. /// <summary>
  1418. /// Returns a string value that represents the type of attribute. In this case 'memo'.
  1419. /// </summary>
  1420. /// <returns type="String" />
  1421. return "memo";
  1422. };
  1423. this.getValue = function () {
  1424. /// <summary>
  1425. /// Retrieves the data value for the memo attribute
  1426. /// </summary>
  1427. /// <returns type="String" />
  1428. return value;
  1429. };
  1430. this.setValue = function (newValue) {
  1431. /// <summary>
  1432. /// Sets the data value for a memo attribute.
  1433. /// </summary>
  1434. /// <param name="newValue" type="String" mayBeNull="true" optional="false" >
  1435. /// The new value for the memo attribute
  1436. /// </param>
  1437. if (newValue == null && value != null) {
  1438. value = newValue;
  1439. this.fireOnChange();
  1440. return;
  1441. }
  1442. //(newValue == null && value == null) --> Do nothing.
  1443. if (typeof newValue == "string") {
  1444. if (value != newValue) {
  1445. if (newValue.length <= maxlength) {
  1446. value = newValue;
  1447. this.fireOnChange();
  1448. }
  1449. else {
  1450. throw new Error("Value too long. The value of the " + this.getName() + " attribute must not exceed " + maxlength + " characters");
  1451. }
  1452. }
  1453. }
  1454. else {
  1455. throw new Error("Invalid argument. Use a null or string parameter value when using setValue on a memo attribute.");
  1456. }
  1457. };
  1458. //email.description is a memo field without a getMaxLength method.
  1459. this.getMaxLength = function () {/// <summary>
  1460. /// Returns a number indicating the maximum length of a string or memo attribute.
  1461. /// </summary>
  1462. /// <returns type="Number" />
  1463. return maxlength;
  1464. };
  1465. }
  1466. _memoAttribute.prototype.toString = function () {
  1467. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : "\'" + this.getValue().toString() + "\'") + "]";
  1468. return stringvalue;
  1469. }
  1470. // MONEY ===================================================================
  1471. function _moneyAttribute(att) {
  1472. var value = att.Value;
  1473. _numberBaseAttribute.call(this, att);
  1474. this.getAttributeType = function () {
  1475. /// <summary>
  1476. /// Returns a string value that represents the type of attribute. In this case 'money'.
  1477. /// </summary>
  1478. /// <returns type="String" />
  1479. return "money";
  1480. };
  1481. }
  1482. _moneyAttribute.prototype.toString = function () {
  1483. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : this.getValue().toString()) + "]";
  1484. return stringvalue;
  1485. }
  1486. // OPTIONSET ===================================================================
  1487. function _optionsetAttribute(att) {
  1488. var initialValue, options, value;
  1489. _attributeBase.call(this, att);
  1490. initialValue = att.InitialValue;
  1491. options = att.Options;
  1492. //Fix for the fact that options with null values are actually "null" but the form snapshot captures them as null.
  1493. for (var i = 0; i < options.length; i++) {
  1494. if (options[i].value == null)
  1495. { options[i].value = "null" }
  1496. }
  1497. value = att.Value;
  1498. this.getAttributeType = function () {
  1499. /// <summary>
  1500. /// Returns a string value that represents the type of attribute. In this case "optionset".
  1501. /// </summary>
  1502. /// <returns type="String" />
  1503. return "optionset";
  1504. };
  1505. this.getInitialValue = function () {
  1506. /// <summary>
  1507. /// Returns the value of the optionset when the record was last saved or the default value before the record is saved.
  1508. /// </summary>
  1509. /// <returns type="Number" />
  1510. return initialValue;
  1511. }
  1512. this.getValue = function () {
  1513. /// <summary>
  1514. /// Retrieves the data value for the optionset attribute
  1515. /// </summary>
  1516. /// <returns type="Number" />
  1517. return value;
  1518. };
  1519. this.getOption = function (value) {
  1520. /// <summary>
  1521. /// Returns an option object with the value matching the argument passed to the method.
  1522. /// </summary>
  1523. /// <returns type="Object" />
  1524. /// <param name="value" mayBeNull="false" optional="false" >
  1525. /// The value to use to select the option
  1526. /// </param>
  1527. if (value == null) {
  1528. throw new Error("Invalid argument. Use a Number or String parameter value when using getOption on a optionset attribute.");
  1529. }
  1530. var searchValue;
  1531. if (typeof value == "string") {
  1532. searchValue = parseInt(value, 10);
  1533. if (isNan(searchValue)) {
  1534. throw new Error("Invalid argument. String argument only valid if it can be converted to a number when using getOption on a optionset attribute.");
  1535. }
  1536. }
  1537. else {
  1538. if (typeof value == "number") {
  1539. searchValue = value;
  1540. }
  1541. else {
  1542. throw new Error("Invalid argument. Use a Number or String parameter value when using getOption on a optionset attribute.");
  1543. }
  1544. }
  1545. for (var i = 0; i < options.length; i++) {
  1546. if (searchValue == options[i].value) {
  1547. return options[i];
  1548. }
  1549. }
  1550. };
  1551. this.getSelectedOption = function () {
  1552. /// <summary>
  1553. /// Returns the currently selected option
  1554. /// </summary>
  1555. /// <returns type="Object" />
  1556. for (var i = 0; i < options.length; i++) {
  1557. if (value == options[i].value) {
  1558. return options[i];
  1559. }
  1560. }
  1561. };
  1562. this.getText = function () {
  1563. /// <summary>
  1564. /// Returns the text of the currently selected option;
  1565. /// </summary>
  1566. /// <returns type="String" />}
  1567. return this.getSelectedOption().text;
  1568. };
  1569. this.getOptions = function () {
  1570. /// <summary>
  1571. /// Retrieves the available options
  1572. /// </summary>
  1573. /// <returns type="Array" />
  1574. return options;
  1575. }
  1576. this.setValue = function (newValue) {
  1577. /// <summary>
  1578. /// Sets the data value for a optionset attribute.
  1579. /// </summary>
  1580. /// <param name="newValue" type="Number" mayBeNull="true" optional="false" >
  1581. /// The new value for the optionset attribute
  1582. /// </param>
  1583. if (newValue == null && value != null) {
  1584. value = newValue;
  1585. this.fireOnChange();
  1586. return;
  1587. }
  1588. //(newValue == null && value == null) --> Do nothing
  1589. if (typeof newValue == "number") {
  1590. if (value != newValue) {
  1591. var isValidValue = false;
  1592. for (var i = 0; i < options.length; i++) {
  1593. if (newValue = options[i].value) {
  1594. isValidValue = true;
  1595. break;
  1596. }
  1597. }
  1598. if (isValidValue) {
  1599. value = newValue;
  1600. this.fireOnChange();
  1601. }
  1602. else {
  1603. throw new Error("Invalid argument. " + newValue + " is not a valid parameter value when using setValue on the " + this.getName() + " optionset attribute.");
  1604. }
  1605. }
  1606. }
  1607. else {
  1608. throw new Error("Invalid argument. Use a null or Number parameter value when using setValue on a optionset attribute.");
  1609. }
  1610. };
  1611. }
  1612. _optionsetAttribute.prototype.toString = function () {
  1613. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : this.getValue().toString()) + "]";
  1614. return stringvalue;
  1615. }
  1616. // STRING ===================================================================
  1617. function _stringAttribute(att) {
  1618. var maxLength, value;
  1619. _attributeBase.call(this, att);
  1620. maxLength = att.MaxLength;
  1621. value = att.Value;
  1622. this.getAttributeType = function () {
  1623. /// <summary>
  1624. /// Returns a string value that represents the type of attribute. In this case, 'string'.
  1625. /// </summary>
  1626. /// <returns type="String" />
  1627. return "string";
  1628. };
  1629. this.getMaxLength = function () { /// <summary>
  1630. /// Returns a number indicating the maximum length of a string or memo attribute.
  1631. /// </summary>
  1632. /// <returns type="Number" />
  1633. return maxLength;
  1634. };
  1635. this.getValue = function () {
  1636. /// <summary>
  1637. /// Retrieves the data value for the string attribute
  1638. /// </summary>
  1639. /// <returns type="String" />
  1640. return value;
  1641. };
  1642. this.setValue = function (newValue) {
  1643. /// <summary>
  1644. /// Sets the data value for a string attribute.
  1645. /// </summary>
  1646. /// <param name="newValue" type="String" mayBeNull="true" optional="false" >
  1647. /// The new value for the String attribute
  1648. /// </param>
  1649. if (newValue == null && value != null) {
  1650. value = newValue;
  1651. this.fireOnChange();
  1652. return;
  1653. }
  1654. //(newValue == null && value == null) - > Do nothing.
  1655. if (typeof newValue == "string") {
  1656. if (value != newValue) {
  1657. if (newValue.length <= maxLength) {
  1658. value = newValue;
  1659. this.fireOnChange();
  1660. }
  1661. else {
  1662. throw new Error("Value too long. The maximum length for the " + this.getName() + " attribute is " + maxLength);
  1663. }
  1664. }
  1665. }
  1666. else {
  1667. throw new Error("Invalid argument. Use a null or String parameter value when using setValue on a string attribute.");
  1668. }
  1669. };
  1670. }
  1671. _stringAttribute.prototype.toString = function () {
  1672. var stringvalue = "[object " + this.getAttributeType() + " attribute : \'" + this.getName() + "\' : " + ((this.getValue() == null) ? "null" : "\'" + this.getValue().toString() + "\'") + "]";
  1673. return stringvalue;
  1674. }
  1675. //End Attribute definitions -------------------------------------------------------------------
  1676. // =====================================================
  1677. // TABS ==========================================
  1678. // =====================================================
  1679. //Start tabs definitions -------------------------------------------------------------------
  1680. function _tabCollection() {
  1681. var tabs = {};
  1682. for (var i = 0; i < pageData.Tabs.length; i++) {
  1683. var tab = pageData.Tabs[i];
  1684. tabs[tab.Name] = new _tab(tab);
  1685. }
  1686. this.forEach = function (delegate_function) {
  1687. /// <summary>
  1688. /// Applies the action contained within a delegate function.
  1689. /// </summary>
  1690. /// <param name="delegate_function" type="Function" mayBeNull="false" optional="false" >
  1691. /// The delegate_function must include parameters for tab and index. i.e : MyFunction(tab,index).
  1692. /// </param>
  1693. if (typeof delegate_function == "function") {
  1694. var i = 0;
  1695. for (var tab in tabs) {
  1696. delegate_function(tabs[tab], i);
  1697. i++;
  1698. }
  1699. }
  1700. else {
  1701. throw new Error("The tab collection forEach method requires a function as a parameter.");
  1702. }
  1703. };
  1704. this.get = function (argument) {
  1705. /// <summary>
  1706. /// Returns one or more tabs depending on the arguments passed.
  1707. /// </summary>
  1708. /// <param name="argument" mayBeNull="true" optional="true" >
  1709. /// <para>1: None: Returns an array of all the attributes.</para>
  1710. /// <para>2: String: Returns the attribute where the argument matches the Id.</para>
  1711. /// <para>3: Number: Returns the attribute where the argument matches the index.</para>
  1712. /// <para>4: Function: Returns any attributes that cause the delegate function to return true.</para>
  1713. /// </param>
  1714. var argType = typeof argument;
  1715. if (argument == null) {
  1716. var allTabs = [];
  1717. for (var tab in tabs) {
  1718. allTabs.push(tabs[tab]);
  1719. }
  1720. return allTabs;
  1721. }
  1722. switch (argType) {
  1723. case "number":
  1724. var i = 0;
  1725. for (var tab in tabs) {
  1726. if (argument == i) {
  1727. return tabs[tab];
  1728. }
  1729. i++;
  1730. }
  1731. return null;
  1732. break;
  1733. case "string":
  1734. return tabs[argument];
  1735. break;
  1736. case "function":
  1737. var returnTabs = [];
  1738. var i = 0;
  1739. for (var tab in tabs) {
  1740. if (argument(tabs[tab], i)) {
  1741. returnTabs.push(tabs[tab]);
  1742. }
  1743. i++;
  1744. }
  1745. return returnTabs
  1746. break;
  1747. }
  1748. };
  1749. this.getLength = function () {
  1750. /// <summary>
  1751. /// Returns the number of items in the collection.
  1752. /// </summary>
  1753. /// <returns type="Number" />
  1754. return pageData.Tabs.length;;
  1755. };
  1756. }
  1757. _tabCollection.prototype.toString = function () {
  1758. var stringvalue = "[object tab collection " + this.getLength() + " tabs]";
  1759. return stringvalue;
  1760. }
  1761. function _tab(tab) {
  1762. var label, name, displayState, visible, sections;
  1763. label = tab.Label;
  1764. name = tab.Name;
  1765. displayState = tab.DisplayState;
  1766. visible = tab.Visible;
  1767. this.sections = new _sectionCollection(tab.Sections, this);
  1768. this.getDisplayState = function () {
  1769. /// <summary>
  1770. /// Returns the display state for the tab
  1771. /// </summary>
  1772. /// <returns type="String" />
  1773. return displayState;
  1774. };
  1775. this.getLabel = function () {
  1776. /// <summary>
  1777. /// Returns the label for the tab
  1778. /// </summary>
  1779. /// <returns type="String" />
  1780. return label;
  1781. };
  1782. this.getName = function () {
  1783. /// <summary>
  1784. /// Returns the name for the tab
  1785. /// </summary>
  1786. /// <returns type="String" />
  1787. return name;
  1788. };
  1789. this.getParent = function () {
  1790. /// <summary>
  1791. /// Returns a reference to Xrm.Page.ui
  1792. /// </summary>
  1793. return function () { return Xrm.Page.ui; }()
  1794. };
  1795. this.getVisible = function () {
  1796. /// <summary>
  1797. /// Returns a value that indicates whether the tab is currently visible.
  1798. /// </summary>
  1799. /// <returns type="Boolean" />
  1800. return visible;
  1801. };
  1802. this.setDisplayState = function (state) {
  1803. /// <summary>
  1804. /// Sets the display state for the tab.
  1805. /// </summary>
  1806. /// <param name="state" type="String" mayBeNull="false" optional="false" >
  1807. /// The state of the tab either expanded or collapsed
  1808. /// </param>
  1809. if (state == "expanded" || state == "collapsed")
  1810. { displayState = state; }
  1811. else
  1812. { throw new Error("Invalid argument. Valid values are \"expanded\" and \"collapsed\".") }
  1813. };
  1814. this.setFocus = function () {
  1815. /// <summary>
  1816. /// Sets the focus on the tab.
  1817. /// </summary>
  1818. };
  1819. this.setLabel = function (newLabel) {
  1820. /// <summary>
  1821. /// Sets the label for the tab.
  1822. /// </summary>
  1823. /// <param name="newLabel" type="String" mayBeNull="false" optional="false" >
  1824. /// The text of the label.
  1825. /// </param>
  1826. if (typeof newLabel == "string") {
  1827. label = newLabel;
  1828. }
  1829. else { throw new Error("Invalid argument. String type expected.") }
  1830. };
  1831. this.setVisible = function (isVisible) {
  1832. /// <summary>
  1833. /// Sets a value that indicates whether the tab is visible.
  1834. /// </summary>
  1835. /// <param name="isVisible" type="Boolean" mayBeNull="false" optional="false" >
  1836. /// Whether the control is visible
  1837. /// </param>
  1838. if (typeof isVisible == "boolean") {
  1839. visible = isVisible;
  1840. }
  1841. else { throw new Error("Invalid argument. Boolean type expected.") }
  1842. };
  1843. }
  1844. _tab.prototype.toString = function () {
  1845. var stringvalue = "[object tab: '" + this.getName() + "' label: '" + this.getLabel() + "' visible: " + this.getVisible() + " displayState: " + this.getDisplayState() + "]";
  1846. return stringvalue;
  1847. }
  1848. //End tabs definitions -------------------------------------------------------------------
  1849. // =====================================================
  1850. // SECTIONS ==========================================
  1851. // =====================================================
  1852. //Start sections definitions -------------------------------------------------------------------
  1853. function _sectionCollection(sc, parentTab) {
  1854. var sections = {};
  1855. var length = sc.length;
  1856. for (var i = 0; i < sc.length; i++) {
  1857. sections[sc[i].Name] = new _section(sc[i], parentTab);
  1858. }
  1859. this.forEach = function (delegate_function) {
  1860. /// <summary>
  1861. /// Applies the action contained within a delegate function.
  1862. /// </summary>
  1863. /// <param name="delegate_function" type="Function" mayBeNull="false" optional="false" >
  1864. /// The delegate_function must include parameters for section and index. i.e : MyFunction(section,index).
  1865. /// </param>
  1866. var i = 0;
  1867. for (var sec in sections) {
  1868. delegate_function(sections[sec], i);
  1869. i++;
  1870. }
  1871. };
  1872. this.get = function (argument) {
  1873. /// <summary>
  1874. /// Returns one or more tabs depending on the arguments passed.
  1875. /// </summary>
  1876. /// <param name="argument" mayBeNull="true" optional="true" >
  1877. /// <para>1: None: Returns an array of all the attributes.</para>
  1878. /// <para>2: String: Returns the attribute where the argument matches the name.</para>
  1879. /// <para>3: Number: Returns the attribute where the argument matches the index.</para>
  1880. /// <para>4: Function: Returns any attributes that cause the delegate function to return true.</para>
  1881. /// </param>
  1882. var argType = typeof argument;
  1883. if (argument == null) {
  1884. var allSections = [];
  1885. for (var sec in sections) {
  1886. allSections.push(sections[sec]);
  1887. }
  1888. return allSections;
  1889. }
  1890. switch (argType) {
  1891. case "number":
  1892. var i = 0;
  1893. for (var sec in sections) {
  1894. if (i == argument) {
  1895. return sections[sec];
  1896. }
  1897. i++
  1898. }
  1899. return null;
  1900. break;
  1901. case "string":
  1902. return sections[argument];
  1903. break;
  1904. case "function":
  1905. var returnSections = [];
  1906. var i = 0;
  1907. for (var sec in sections) {
  1908. if (argument(sections[sec], i)) {
  1909. returnSections.push(sections[sec]);
  1910. }
  1911. i++;
  1912. }
  1913. return returnSections;
  1914. break;
  1915. }
  1916. };
  1917. this.getLength = function () {
  1918. /// <summary>
  1919. /// Returns the number of items in the collection.
  1920. /// </summary>
  1921. /// <returns type="Number" />
  1922. return length;
  1923. };
  1924. }
  1925. _sectionCollection.prototype.toString = function () {
  1926. var stringvalue = "[object section collection " + this.getLength() + " sections]";
  1927. return stringvalue;
  1928. }
  1929. function _section(s, parentTab) {
  1930. var label, name, visible, parent, controlNames;
  1931. label = s.Label;
  1932. name = s.Name;
  1933. visible = s.Visible;
  1934. parent = parentTab;
  1935. controlNames = [];
  1936. for (var i = 0; i < s.Controls.length; i++) {
  1937. controlNames.push(s.Controls[i]);
  1938. }
  1939. this.getLabel = function () {
  1940. /// <summary>
  1941. /// Returns the label for the section
  1942. /// </summary>
  1943. /// <returns type="String" />
  1944. return label;
  1945. };
  1946. this.getName = function () {
  1947. /// <summary>
  1948. /// Returns the name for the section
  1949. /// </summary>
  1950. /// <returns type="String" />
  1951. return name;
  1952. };
  1953. this.getParent = function () {
  1954. /// <summary>
  1955. /// Returns a reference to the tab object that contains the section.
  1956. /// </summary>
  1957. return parent;
  1958. };
  1959. this.getVisible = function () {
  1960. /// <summary>
  1961. /// Returns a value that indicates whether the section is currently visible.
  1962. /// </summary>
  1963. /// <returns type="Boolean" />
  1964. return visible;
  1965. };
  1966. this.setLabel = function (newLabel) {
  1967. /// <summary>
  1968. /// Sets the label for the section.
  1969. /// </summary>
  1970. /// <param name="label" type="String" mayBeNull="false" optional="false" >
  1971. /// The text of the label.
  1972. /// </param>
  1973. if (typeof newLabel == "string") {
  1974. label = newLabel;
  1975. }
  1976. else { throw new Error("Section setLabel method requires a string parameter value.") }
  1977. };
  1978. this.setVisible = function (isVisible) {
  1979. /// <summary>
  1980. /// Sets a value that indicates whether the section is visible.
  1981. /// </summary>
  1982. /// <param name="isVisible" type="Boolean" mayBeNull="false" optional="false" >
  1983. /// Whether the control is visible
  1984. /// </param>
  1985. if (typeof isVisible == "boolean") {
  1986. visible = isVisible;
  1987. }
  1988. else { throw new Error("Section setVisible method requires a boolean parameter value.") }
  1989. };
  1990. this.controls = new _childControlsCollection(controlNames);
  1991. }
  1992. _section.prototype.toString = function () {
  1993. var stringvalue = "[object section: '" + this.getName() + "' label: '" + this.getLabel() + "' visible: " + this.getVisible() + "]";
  1994. return stringvalue;
  1995. }
  1996. //End sections definitions -------------------------------------------------------------------
  1997. // =====================================================
  1998. // CONTROLS ==========================================
  1999. // =====================================================
  2000. //Start Control definitions -------------------------------------------------------------------
  2001. // BASE Control ===================================================================
  2002. function _baseControl(ctrl) {
  2003. var name, label, visible, parent;
  2004. name = ctrl.Name;
  2005. //disabled = ctrl.Disabled;
  2006. label = ctrl.Label;
  2007. visible = ctrl.Visible;
  2008. parent = ctrl.parent;
  2009. this.getName = function () {
  2010. /// <summary>
  2011. /// Returns a name for the control that is set at runtime.
  2012. /// </summary>
  2013. /// <returns type="String" />
  2014. return name;
  2015. };
  2016. this.getLabel = function () {
  2017. /// <summary>
  2018. /// Returns the label for the control
  2019. /// </summary>
  2020. /// <returns type="String" />
  2021. return label;
  2022. };
  2023. this.getParent = function () {
  2024. /// <summary>
  2025. /// Returns a reference to the section object that contains the control.
  2026. /// </summary>
  2027. var foundSection = null;
  2028. Xrm.Page.ui.tabs.forEach(function (tab, i) {
  2029. tab.sections.forEach(function (section, i) {
  2030. if (section.getName() == parent)
  2031. {
  2032. foundSection = section;
  2033. }
  2034. });
  2035. });
  2036. if (foundSection == null) {
  2037. throw new Error("Control " + parent + " parent section not found.");
  2038. }
  2039. return foundSection;
  2040. };
  2041. this.getVisible = function () {
  2042. /// <summary>
  2043. /// Returns a value that indicates whether the control is currently visible.
  2044. /// </summary>
  2045. /// <returns type="Boolean" />
  2046. return visible;
  2047. };
  2048. this.setFocus = function () {
  2049. /// <summary>
  2050. /// Sets the focus on the control.
  2051. /// </summary>
  2052. pageData.CurrentControl = name;
  2053. };
  2054. this.setLabel = function (newLabel) {
  2055. /// <summary>
  2056. /// Sets the label for the control.
  2057. /// </summary>
  2058. /// <param name="newLabel" type="String" mayBeNull="false" optional="false" >
  2059. /// The text of the label.
  2060. /// </param>
  2061. if (typeof newLabel == "string")
  2062. { label = newLabel; }
  2063. else
  2064. { throw new Error("Control setLabel method requires a string parameter value.") }
  2065. };
  2066. this.setVisible = function (isVisible) {
  2067. /// <summary>
  2068. /// Sets a value that indicates whether the control is visible.
  2069. /// </summary>
  2070. /// <param name="isVisible" type="Boolean" mayBeNull="false" optional="false" >
  2071. /// Whether the control is visible
  2072. /// </param>
  2073. if (typeof isVisible == "boolean")
  2074. {
  2075. visible = isVisible;
  2076. }
  2077. else
  2078. {
  2079. throw new Error("Control setVisible method requires a boolean parameter value.");
  2080. }
  2081. };
  2082. }
  2083. // STANDARD Control ===================================================================
  2084. function _standardControl(ctrl) {
  2085. _baseControl.call(this, ctrl);
  2086. var attribute = ctrl.Attribute;
  2087. var disabled = ctrl.Disabled;
  2088. this.getAttribute = function () {
  2089. /// <summary>
  2090. /// Returns the attribute that the control is bound to.
  2091. /// </summary>
  2092. if (attribute == null)
  2093. { return null; }
  2094. else
  2095. {
  2096. return _attDictionary[attribute];
  2097. }
  2098. };
  2099. this.getControlType = function () {
  2100. /// <summary>
  2101. /// Returns a String describing the type of control. In this case "standard".
  2102. /// </summary>
  2103. /// <returns type="String" />
  2104. return "standard";
  2105. };
  2106. this.getDisabled = function () {
  2107. /// <summary>
  2108. /// Returns whether the control is disabled.
  2109. /// </summary>
  2110. /// <returns type="Boolean" />
  2111. return disabled;
  2112. };
  2113. this.setDisabled = function (isDisabled) {
  2114. /// <summary>
  2115. /// Sets whether the control is disabled.
  2116. /// </summary>
  2117. /// <param name="isDisabled" type="Boolean" mayBeNull="false" optional="false" >
  2118. /// Whether the control is disabled.
  2119. /// </param>
  2120. if (typeof isDisabled == "boolean")
  2121. { disabled = isDisabled; }
  2122. else
  2123. { throw new Error("Control setDisabled method requires a Boolean parameter value.") }
  2124. };
  2125. }
  2126. _standardControl.prototype.toString = function () {
  2127. var stringvalue = "[object " + this.getControlType() + " control : \'" + this.getName() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  2128. return stringvalue;
  2129. }
  2130. // iframe Control ===================================================================
  2131. function _iframeControl(ctrl) {
  2132. _baseControl.call(this, ctrl);
  2133. var src, initialUrl;
  2134. src = ctrl.Src;
  2135. initialUrl = ctrl.InitialUrl;
  2136. var disabled = ctrl.Disabled;
  2137. this.getDisabled = function () {
  2138. /// <summary>
  2139. /// Returns whether the control is disabled.
  2140. /// </summary>
  2141. /// <returns type="Boolean" />
  2142. return disabled;
  2143. };
  2144. this.setDisabled = function (isDisabled) {
  2145. /// <summary>
  2146. /// Sets whether the control is disabled.
  2147. /// </summary>
  2148. /// <param name="isDisabled" type="Boolean" mayBeNull="false" optional="false" >
  2149. /// Whether the control is disabled.
  2150. /// </param>
  2151. if (typeof isDisabled == "boolean")
  2152. { disabled = isDisabled; }
  2153. else
  2154. { throw new Error("Control setDisabled method requires a Boolean parameter value.") }
  2155. };
  2156. this.getControlType = function () {
  2157. /// <summary>
  2158. /// Returns a String describing the type of control. In this case "iframe".
  2159. /// </summary>
  2160. /// <returns type="String" />
  2161. return "iframe";
  2162. };
  2163. this.getSrc = function () {
  2164. /// <summary>
  2165. /// Returns a value for the URL to be displayed in an IFrame.
  2166. /// </summary>
  2167. /// <returns type="String" />
  2168. return src;
  2169. };
  2170. this.setSrc = function (uri) {
  2171. /// <summary>
  2172. /// Sets the URL to be displayed in an IFrame.
  2173. /// </summary>
  2174. /// <param name="uri" type="Boolean" mayBeNull="false" optional="false" >
  2175. /// The URL to be displayed in an IFrame.
  2176. /// </param>
  2177. if (typeof uri == "string")
  2178. { src = uri; }
  2179. else
  2180. { throw new Error("IFRAME Control setSrc method requires a string parameter value.") }
  2181. }
  2182. this.getInitialUrl = function () {
  2183. /// <summary>
  2184. /// Returns the default URL that an IFrame control is configured to display.
  2185. /// </summary>
  2186. /// <returns type="String" />
  2187. return initialUrl;
  2188. };
  2189. }
  2190. _iframeControl.prototype.toString = function () {
  2191. var stringvalue = "[object" + this.getControlType() + " control : \'" + this.getName() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  2192. return stringvalue;
  2193. }
  2194. // Lookup Control ===================================================================
  2195. function _lookupControl(ctrl) {
  2196. _baseControl.call(this, ctrl);
  2197. var attribute, defaultView;
  2198. defaultView = ctrl.DefaultView
  2199. attribute = ctrl.Attribute;
  2200. var disabled = ctrl.Disabled;
  2201. this.getDisabled = function () {
  2202. /// <summary>
  2203. /// Returns whether the control is disabled.
  2204. /// </summary>
  2205. /// <returns type="Boolean" />
  2206. return disabled;
  2207. };
  2208. this.setDisabled = function (isDisabled) {
  2209. /// <summary>
  2210. /// Sets whether the control is disabled.
  2211. /// </summary>
  2212. /// <param name="isDisabled" type="Boolean" mayBeNull="false" optional="false" >
  2213. /// Whether the control is disabled.
  2214. /// </param>
  2215. if (typeof isDisabled == "boolean")
  2216. { disabled = isDisabled; }
  2217. else
  2218. { throw new Error("Control setDisabled method requires a Boolean parameter value.") }
  2219. };
  2220. this.addCustomView = function (viewId, entityName, viewDisplayName, fetchXml, layoutXml, isDefault) {
  2221. /// <summary>
  2222. /// Adds a new view for the lookup dialog.
  2223. /// </summary>
  2224. /// <param name="viewId" type="String" mayBeNull="false" optional="false" >
  2225. /// The string representation of a GUID Id for a view.
  2226. /// </param>
  2227. /// <param name="entityName" type="String" mayBeNull="false" optional="false" >
  2228. /// The name of the entity.
  2229. /// </param>
  2230. /// <param name="viewDisplayName" type="String" mayBeNull="false" optional="false" >
  2231. /// The name of the view.
  2232. /// </param>
  2233. /// <param name="fetchXml" type="String" mayBeNull="false" optional="false" >
  2234. /// The fetchXml query for the view.
  2235. /// </param>
  2236. /// <param name="layoutXml" type="String" mayBeNull="false" optional="false" >
  2237. /// The XML defining the layout of the view.
  2238. /// </param>
  2239. /// <param name="isDefault" type="Boolean" mayBeNull="false" optional="false" >
  2240. /// Whether the view should be the default view.
  2241. /// </param>
  2242. if (typeof viewId != "string" || typeof entityName != "string" || typeof viewDisplayName != "string" || typeof fetchXml != "string" || typeof layoutXml != "string" || typeof isDefault != "boolean") {
  2243. throw new Error("One or more of the parameters passed to the Lookup Control addCustomView method are not the correct type.");
  2244. }
  2245. if (isDefault)
  2246. { defaultView = viewId; }
  2247. };
  2248. this.getAttribute = function () {
  2249. /// <summary>
  2250. /// Returns the attribute that the control is bound to.
  2251. /// </summary>
  2252. return _attDictionary[attribute];
  2253. };
  2254. this.getControlType = function () {
  2255. /// <summary>
  2256. /// Returns a String describing the type of control. In this case "lookup".
  2257. /// </summary>
  2258. /// <returns type="String" />
  2259. return "lookup";
  2260. };
  2261. this.getDefaultView = function () {
  2262. /// <summary>
  2263. /// Returns the Id value of the default lookup dialog view.
  2264. /// </summary>
  2265. /// <returns type="String" />
  2266. return defaultView;
  2267. };
  2268. this.setDefaultView = function (viewGuid) {
  2269. /// <summary>
  2270. /// Sets the Id value of the default lookup dialog view.
  2271. /// </summary>
  2272. /// <returns type="String" />
  2273. /// <param name="viewGuid" type="String" mayBeNull="false" optional="false" >
  2274. /// String specifies the GUID for the default view
  2275. /// </param>
  2276. if (typeof viewGuid == "string") {
  2277. if (/\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\}/.test(viewGuid)) {
  2278. defaultView = viewGuid;
  2279. }
  2280. else {
  2281. throw new Error("Lookup control setDefaultView string parameter is not properly formatted to represent a GUID value. Example: {C7034F4F-6F92-4DD7-BD9D-9B9C1E996380}")
  2282. }
  2283. }
  2284. else { throw new Error("Lookup control setDefaultView requires a string parameter value.") }
  2285. };
  2286. }
  2287. _lookupControl.prototype.toString = function () {
  2288. var stringvalue = "[object " + this.getControlType() + " control : \'" + this.getName() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  2289. return stringvalue;
  2290. }
  2291. // optionset Control ===================================================================
  2292. function _optionsetControl(ctrl) {
  2293. _baseControl.call(this, ctrl);
  2294. var attribute, options;
  2295. attribute = ctrl.Attribute;
  2296. options = [];
  2297. var disabled = ctrl.Disabled;
  2298. try {
  2299. options = _attDictionary[attribute].getOptions();
  2300. }
  2301. catch (e) {
  2302. //If a Boolean Attribute is formatted as a list, it has a optionset control but the attribute
  2303. // doesn't support the getOptions methods resulting in the following error.
  2304. if (e.number == -2146827850) {
  2305. //Setting a pair of Boolean value options to simulate a boolean attribute.
  2306. options.push({ "text": "True", "value": 1 });
  2307. options.push({ "text": "False", "value": 0 });
  2308. }
  2309. else { throw (e); }
  2310. }
  2311. this.getDisabled = function () {
  2312. /// <summary>
  2313. /// Returns whether the control is disabled.
  2314. /// </summary>
  2315. /// <returns type="Boolean" />
  2316. return disabled;
  2317. };
  2318. this.setDisabled = function (isDisabled) {
  2319. /// <summary>
  2320. /// Sets whether the control is disabled.
  2321. /// </summary>
  2322. /// <param name="isDisabled" type="Boolean" mayBeNull="false" optional="false" >
  2323. /// Whether the control is disabled.
  2324. /// </param>
  2325. if (typeof isDisabled == "boolean")
  2326. { disabled = isDisabled; }
  2327. else
  2328. { throw new Error("Control setDisabled method requires a Boolean parameter value.") }
  2329. };
  2330. this.addOption = function (option, index) {
  2331. /// <summary>
  2332. /// Adds an option to an Option set control.
  2333. /// </summary>
  2334. /// <param name="option" type="Object" mayBeNull="false" optional="false" >
  2335. /// An option object to add to the OptionSet. For example: { "text": "Item A", "value": "100000000" }
  2336. /// </param>
  2337. /// <param name="index" type="Number" mayBeNull="true" optional="true" >
  2338. /// (Optional) The index position to place the new option. If not provided the option will be added to the end.
  2339. /// </param>
  2340. if ((option != null) && (typeof option.text == "string") && (typeof option.value == "number" || option.value == null))
  2341. {
  2342. if (index != null) {
  2343. var newOptions = [];
  2344. for (var i = 0; i < options; i++) {
  2345. if (i == index) {
  2346. newOptions.push(option);
  2347. i--;
  2348. }
  2349. else {
  2350. newOptions.push(options[i]);
  2351. }
  2352. }
  2353. options = newOptions;
  2354. }
  2355. else {
  2356. options.push(option);
  2357. }
  2358. }
  2359. else
  2360. {
  2361. throw new Error("Optionset control addOption method requires an option object with a string 'text' property and an number 'value' property.");
  2362. }
  2363. };
  2364. this.getAttribute = function () {
  2365. /// <summary>
  2366. /// Returns the attribute that the control is bound to.
  2367. /// </summary>
  2368. return _attDictionary[attribute];
  2369. };
  2370. this.getControlType = function () {
  2371. /// <summary>
  2372. /// Returns a String describing the type of control. In this case "optionset".
  2373. /// </summary>
  2374. /// <returns type="String" />
  2375. return "optionset";
  2376. };
  2377. this.clearOptions = function () {
  2378. /// <summary>
  2379. /// Clears all options from an Option Set control.
  2380. /// </summary>
  2381. options = [];
  2382. };
  2383. this.removeOption = function (value) {
  2384. /// <summary>
  2385. /// Removes an option from an Option Set control.
  2386. /// </summary>
  2387. /// <param name="value" type="Number" mayBeNull="false" optional="false" >
  2388. /// The value of the option you want to remove.
  2389. /// </param>
  2390. if (value != null && typeof value == "number") {
  2391. var newOptions = [];
  2392. for (var i = 0; i < options.length; i++) {
  2393. if (options[i].value == value) {
  2394. i++;
  2395. }
  2396. else {
  2397. newOptions.push(options[i]);
  2398. }
  2399. }
  2400. options = newOptions;
  2401. }
  2402. else { throw new Error("Optionset control removeOption method requires a number parameter value."); }
  2403. }
  2404. }
  2405. _optionsetControl.prototype.toString = function () {
  2406. var stringvalue = "[object " + this.getControlType() + " control : \'" + this.getName() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  2407. return stringvalue;
  2408. }
  2409. // subGrid Control ===================================================================
  2410. function _subgridControl(ctrl) {
  2411. _baseControl.call(this, ctrl);
  2412. this.getControlType = function () {
  2413. /// <summary>
  2414. /// Returns a String describing the type of control. In this case "subgrid".
  2415. /// </summary>
  2416. /// <returns type="String" />
  2417. return "subgrid";
  2418. };
  2419. this.refresh = function () {
  2420. /// <summary>
  2421. /// Refreshes the data displayed in a Sub-Grid
  2422. /// </summary>
  2423. };
  2424. }
  2425. _subgridControl.prototype.toString = function () {
  2426. var stringvalue = "[object " + this.getControlType() + " control : \'" + this.getName() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  2427. return stringvalue;
  2428. }
  2429. // webResource Control ===================================================================
  2430. function _webresourceControl(ctrl) {
  2431. _baseControl.call(this, ctrl);
  2432. var src = ctrl.Src;
  2433. this.getControlType = function () {
  2434. /// <summary>
  2435. /// Returns a String describing the type of control. In this case "webresource".
  2436. /// </summary>
  2437. /// <returns type="String" />
  2438. return "webresource";
  2439. };
  2440. this.getSrc = function () {
  2441. /// <summary>
  2442. /// Returns a value for the URL to be displayed in an Web Resource.
  2443. /// </summary>
  2444. /// <returns type="String" />
  2445. return src;
  2446. };
  2447. this.setSrc = function (uri) {
  2448. /// <summary>
  2449. /// Sets the URL to be displayed in an Web Resource.
  2450. /// </summary>
  2451. /// <param name="uri" type="Boolean" mayBeNull="false" optional="false" >
  2452. /// The URL to be displayed in an IFrame.
  2453. /// </param>
  2454. if (typeof uri == "string")
  2455. { src = uri; }
  2456. else
  2457. { throw new Error("Web resource control setSrc method requires a string parameter value."); }
  2458. }
  2459. }
  2460. _webresourceControl.prototype.toString = function () {
  2461. var stringvalue = "[object " + this.getControlType() + " control : \'" + this.getName() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  2462. return stringvalue;
  2463. }
  2464. // Notes Control ===================================================================
  2465. function _notesControl(ctrl) {
  2466. _baseControl.call(this, ctrl);
  2467. var disabled = ctrl.Disabled;
  2468. this.getControlType = function () {
  2469. /// <summary>
  2470. /// Returns a String describing the type of control. In this case "notes".
  2471. /// </summary>
  2472. /// <returns type="String" />
  2473. return "notes";
  2474. };
  2475. }
  2476. _notesControl.prototype.toString = function () {
  2477. var stringvalue = "[object " + this.getControlType() + " control : \'" + this.getName() + "\' label: '" + this.getLabel() + "\' visible: " + this.getVisible() + "]";
  2478. return stringvalue;
  2479. }
  2480. //End Control definitions -------------------------------------------------------------------
  2481. //Placeholders for the supported MS AJAX date functions found in the XrmPage.
  2482. //NOTE: These do not necessarily match the actual return values
  2483. // format method: See http://msdn.microsoft.com/en-us/library/bb384009.aspx
  2484. Date.prototype.format = function () {
  2485. /// <summary>
  2486. /// <para>Formats a date as a string using the user's Microsoft CRM locale preferences.</para>
  2487. /// <para>NOTE: This function is simulated in the XrmPageTemplate. It uses the operating system locale.</para>
  2488. /// </summary>
  2489. return this.toString();
  2490. };
  2491. // localeFormat method: See http://msdn.microsoft.com/en-us/library/bb383816.aspx
  2492. Date.prototype.localeFormat = function () {
  2493. /// <summary>
  2494. /// <para>Formats a date Formats a date as a string using the user's Microsoft CRM locale preferences.</para>
  2495. /// <para>NOTE: This function is simulated in the XrmPageTemplate. It uses the operating system locale.</para>
  2496. /// </summary>
  2497. return this.toLocaleString();
  2498. };