PageRenderTime 63ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/scripts/XrmPageTemplate.js

#
JavaScript | 2658 lines | 1634 code | 160 blank | 864 comment | 363 complexity | cd7069f0b78a74c601d0665624d47bdf MD5 | raw file

Large files files are truncated, but you can click here to view the full 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. /// <r…

Large files files are truncated, but you can click here to view the full file