PageSourceSearch

https://portal.uicalaska.com/Scripts/sockeye.xrm.ui.js

js uicalaska.com collected 2026-10-02 16:44:17 UTC 40,945 bytes, 850 lines download raw bytes

1
2
3// CONTROL HELPERS
4// setRequired
5(function ($) {
6    $.fn.setRequired = function (required) {
7        this.rules('add', { required: required });
8        this.decorateRequired(required);
9        return this;
10    }
11})(jQuery);
12
13(function ($) {
14    $.fn.decorateRequired = function (required) {
15        this.each(function () {
16            if (required) {
17                var label = $(this).closest(".xrmform-cell").find("label.xrmform-cell-label, label.checkbox-inline").not(".xrmform-cell-label-hidden");
18                if (label && label.find('span.required-field-decorator').length == 0) {
19                    label.append("<span class='required-field-decorator' style='color: red; font-weight: bold' title='Required Field'> *</span>");
20                }
21            } else {
22                var label = $(this).closest(".xrmform-cell").find('span.required-field-decorator').remove();
23            }
24        });
25        return this;
26    }
27})(jQuery);
28
29jQuery.getScrollBarSize = function () {
30    var $c = $("<div style='position:absolute; top:-10000px; left:-10000px; width:100px; height:100px; overflow:scroll;'></div>")
31        .appendTo("body");
32    var dim = [
33        $c.width() - $c[0].clientWidth,
34        $c.height() - $c[0].clientHeight
35    ];
36    $c.remove();
37    return dim;
38};
39
40// disableControls
41(function ($) {
42    $.fn.disableControls = function () {
43
44
45
46        return this;
47    }
48})(jQuery);
49
50function formatCurrency(value, precision) {
51    if (!precision) { return value; }
52    var mult = Math.pow(10, precision);
53    return (Math.round(value * mult) / mult).toFixed(precision);
54}
55
56// xrmSetPrecision
57(function ($) {
58    $.fn.xrmSetPrecision = function (precision) {
59        var value = $(this).val();
60        var precision = precision ? precision : this.data("precision");
61        if (value === "" || isNaN(value) ||
62            precision === "" || isNaN(precision)) { return this; }
63        var mult = Math.pow(10, precision);
64        this.val((Math.round(value * mult) / mult).toFixed(precision));
65        return this;
66    }
67})(jQuery);
68
69// xrmFormatCurrency
70(function ($) {
71    $.fn.xrmFormatCurrency = function (precision) {
72        var value = $(this).val();
73        var precision = precision ? precision : this.data("precision");
74        if (value === "" || isNaN(value) ||
75            precision === "" || isNaN(precision)) { return this; }
76        this.val(commaSeparateNumber(formatCurrency(value, precision)));
77        return this;
78    }
79})(jQuery);
80
81// Busy Indicator
82(function ($) {
83    $.fn.busyIndicator = function (display, message, noIcon, indicatorClass) {
84        var $loadingModal = $('#loading-dialog');
85        if ($loadingModal.length == 0) {
86            $loadingModal = $('<div class="modal" id="loading-dialog" style="z-index: 9999;" data-keyboard="false" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> \
87                                <div class="vertical-alignment-helper"> \
88                                    <div class="modal-dialog modal-sm vertical-align-center"> \
89                                        <div class="modal-content"> \
90                                            <div class="modal-header"> \
91                                                <h4 class="modal-title" id="myModalLabel"></h4> \
92                                            </div> \
93                                            <div class="modal-body" style="text-align:center;"> \
94                                                <div class="inline-icon searching" style="height: 50px; width: 37px; margin: 0 auto; padding-left:0px; background-image:url(' + applicationBaseUrl + 'Images/progress_32.gif)" /> \
95                                            </div> \
96                                            <div class="modal-footer" style="display:none;"> </div> \
97                                        </div> \
98                                    </div> \
99                                </div > \
100                            </div>');
101        }
102        $loadingModal.find(".modal-title").empty().append(message);
103        $("body").append($loadingModal);
104        if (display) {
105            $loadingModal.modal('show');
106        } else {
107            $loadingModal.modal('hide');
108        }
109        return this;
110    }
111})(jQuery);
112
113(function ($) {
114    $.fn.disable = function () {
115        $(this).attr("disabled", "disabled");
116        $(this).addClass("disabled");
117        return this;
118    }
119})(jQuery);
120
121(function ($) {
122    $.fn.enable = function () {
123        $(this).removeAttr("disabled");
124        $(this).removeClass("disabled");
125        return this;
126    }
127})(jQuery);
128
129// Trigger Change
130(function ($) {
131    $.fn.triggerChange = function () {
132        if ($(this).attr("type") != "button" &&
133            $(this).attr("type") != "hidden" &&
134            $(this).closest(".slick-cell").length == 0 && //Exclude changes made in a grid, they will be captured differently.
135            $(this).not(".xrm-grid-search, .ignore-change, :disabled, #FormIsReadOnly").length > 0) {
136            $(this).closest("form.xrmform").data("isDirty", true);
137            $(this).closest("form.xrmform").trigger("change");
138        }
139        return this;
140    }
141})(jQuery);
142
143// ResizeXrmControl
144(function ($) {
145    $.fn.resizeXrmControl = function (minHeight, autoExpand, offset) {
146        offset = offset || 0;
147        if (this.is(":visible")) {
148            // Determine Width.
149            var $container = this.closest("div.xrmform-cell, .xrmform-tab-column-container, .xrmform-tab-container").first();
150            if ($container.length == 0) { $container = this.parent(); }
151            //var width = $container.outerWidth() - 2;
152            var height = minHeight;
153            if (autoExpand) {
154                // Handle Lookup Windows
155                if ($(this).closest("div.modal-grid").length > 0) {
156                    height = $(this).closest("div.modal-grid").outerHeight() - offset;
157                    console.log("minHeight: " + minHeight + "; offset: " + offset + "; height: " + height);
158                }
159                // Check if we are in an xrm form tabbed interface...
160                else if ($(this).closest(".xrmform-tab-container").length > 0) {
161                    // Inside a tab, size element to be the size of the tab... (similar to Xrm functionality)
162                    var $tabContainer = $(this).closest(".xrmform-tab-container");
163                    // If we are inside a section, add room for a single header.
164                    if ($(this).closest(".xrmform-section").length > 0) {
165                        offset += $(this).closest(".xrmform-section, .xrmform-tab-container").find(".xrmform-section-header").outerHeight() + 20;
166                    }
167                    var height = $tabContainer.height() - offset - 3;
168                }
169
170                // Check if we are wrapped in an xrm form.
171                else if (getCurrentFormContainer().length > 0) {
172                    height = $(window).height() - $(this).offset().top - offset - $("#xrmform-footer").outerHeight() - 3;
173                }
174            }
175            $(this).height(height);
176            $(this).css("min-height", minHeight);
177        }
178
179        return this;
180    }
181})(jQuery);
182
183// filterAndFind
184(function ($) {
185    $.fn.filterAndFind = function (selector) {
186        return this.filter(selector).add(this.find(selector));
187    }
188})(jQuery);
189
190// initializeXrmControls
191(function ($) {
192    $.fn.initializeXrmControls = function () {
193        //return this;
194        this.filterAndFind("a").each(function () {
195            var that = $(this);
196            if (that.attr("href") && (that.attr("href").indexOf('Enrollment/GetFile/') != -1 || that.attr("href").indexOf('FileManager/GetFile/') != -1 || that.attr("href").indexOf("Print/GetReport") != -1)) {
197                that.click(function (e) {
198                    if (!that.data("nodownload")) {
199                        e.preventDefault();
200                        $.fileDownload(that.attr("href"), {
201                            failCallback: function (html, url) {
202                                alert('An error occured during the download. Please inform us about this.');
203                            }
204                        });
205                    }
206                });
207            }
208        });
209
210        // Format Email and Web Addresses
211        this.filterAndFind("input.xrm-ui-text").each(function () {
212            var that = this;
213            switch ($(this).data("format")) {
214                case "email":
215                //$(this).addXrmInputButton("ui-icon-mail-closed", "Send Email", null, true);
216                //// Wrap button in hyperlink
217                //var $btn = $(this).closest("tr").find("button").addClass("readonly-enabled");
218                //$btn.wrap($("<a href='mailto:" + $(this).val() + "'></a>").css("display", "inline-block").click(function (e) {
219                //    if ($(that).validateByRule("email")) {
220                //        ignoreUnload = true;
221                //    } else {
222                //        e.preventDefault();
223                //    }
224                //}));
225                //if ($(this).validateByRule("email")) { $btn.removeClass("ui-state-disabled").closest("a"); }
226                //$(this).on("keyup", function () {
227                //    // Check if field is valid, if so, enable link, if not, disable link.
228                //    $btn.closest("a").attr("href", "mailto:" + $(this).val());
229                //    if ($(that).validateByRule("email")) { $btn.removeClass("ui-state-disabled").closest("a"); }
230                //    else { $btn.addClass("ui-state-disabled").closest("a"); }
231                //});
232                //break;
233                case "url":
234                //$(this).addXrmInputButton("ui-icon-extlink", "Open Link", null, true);
235                //// Wrap button in hyperlink
236                //var $btn = $(this).closest("tr").find("button").addClass("readonly-enabled");
237                //$btn.wrap($("<a href='" + ($(this).val().indexOf("://") == -1 ? "http://" + $(this).val() : $(this).val()) + "' target='_blank' disabled='disabled'></a>").css("display", "inline-block"));
238                //if ($(this).val() !== "") { $btn.removeClass("ui-state-disabled").closest('a').removeAttr('disabled'); }
239                //$(this).on("keyup", function () {
240                //    $btn.closest("a").attr("href", ($(this).val().indexOf("://") == -1 ? "http://" + $(this).val() : $(this).val()));
241                //    if ($(that).val() !== "") { $btn.removeClass("ui-state-disabled").closest("a").removeAttr('disabled'); }
242                //    else { $btn.addClass("ui-state-disabled").closest("a").attr('disabled', 'disabled'); }
243                //});
244                //break;
245                case "text":
246                default:
247                    // Do Nothing
248                    break;
249            }
250            if ($(this).data("formatter") && $(this).data("formatter") != "none") {
251                $(this).blur(function () { $(that).val(Formatters[$(that).data("formatter")]($(that).val())); });
252            }
253        });
254
255        // Setup Text Area Controls
256        this.filterAndFind("textarea.xrm-ui-textarea").each(function (idx, item) {
257            var height = $(this).data("height");
258            var autoExpand = $(this).data("autoexpand");
259            if (null == height) {
260                height = $(this).data("rows") * 30;
261            }
262            $(this).resizeXrmControl(height, autoExpand);
263
264        });
265
266        // Setup Numeric Controls
267        this.filterAndFind("input.xrm-ui-numeric").each(function () {
268            $(this).xrmSetPrecision()
269                .on("keypress", function (e) {
270                    e = (e) ? e : window.event;
271                    var charCode = (e.which) ? e.which : e.keyCode;
272                    if (charCode > 31 && (charCode < 48 || charCode >
272 57) && charCode != 45 && charCode != 46) {
273                        return false;
274                    }
275                    return true;
276                })
277                .on("focus", function () {
278                    $(this).val($(this).val().replace(/[,]/gi, ''));
279                    $(this).select();
280                })
281                .on("blur", function (evt) {
282                    $(this).xrmSetPrecision();
283                    $(this).val(commaSeparateNumber($(this).val()));
284                });
285            $(this).val(commaSeparateNumber($(this).val()));
286        });
287
288        // setup Money Controls
289        this.filterAndFind("input.xrm-ui-money").each(function (idx, item) {
290            var number = $(item).val().replace(/[\$,]/gi, '');
291            number = parseFloat(number);
292            if (isNaN(number)) {
293                $(item).val('');
294            } else {
295                var formatted = commaSeparateNumber(formatCurrency(number, $(this).data("precision")));
296                //if (number >= 0) {
297                $(item).val('$ ' + formatted);
298                //} else {
299                //    $(item).val('$ ' + formatted);
300                // }
301            }
302            $(this).xrmSetPrecision()
303                .on("focus", function () {
304                    $(this).val($(this).val().replace(/[\$,]/gi, ''));
305                    $(this).select();
306                })
307                .on("blur", function () {
308                    var number = $(this).val().replace(/[\$,]/gi, '');
309                    number = parseFloat(number);
310                    if (isNaN(number)) {
311                        $("input[name='" + $(this).attr("name") + ".Value']").val("");
312                    }
313                    else {
314                        $("input[name='" + $(this).attr("name") + ".Value']").val(number);
315                        var formatted = commaSeparateNumber(formatCurrency(number, $(this).data("precision")));
316                        //if (number >= 0) {
317                        $(this).val('$ ' + formatted);
318                        //} else {
319                        //    $(this).val('-$ ' + formatted);
320                        //}
321                    }
322                    $("input[name='" + $(this).attr("name") + ".Value']").trigger('change');
323                })
324        });
325
326        // Setup date picker controls
327        this.filterAndFind("div.input-group.xrm-ui-date").each(function (idx, item) {
328            var input = $(item).find("input");
329            var format = $(input).data("dateformat");
330            var curVal = $(input).val();
331            $(input).val(curVal ? moment(curVal, format).format(format) : "");
332            $(item).datetimepicker({
333                format: format,
334                extraFormats: [format, "YYYY-MM-DD", "MM/DD/YY", "MM/DD/YYYY", "YYYY-MM-DD"],
335                stepping: 15
336            });
337        });
338
339        // Setup datetime picker controls
340        this.filterAndFind("div.input-group.xrm-ui-datetime").each(function (idx, item) {
341            var input = $(item).find("input");
342            var format = $(input).data("dateformat") + " " + $(input).data("timeformat");
343            var curVal = $(input).val();
344            $(input).val(curVal ? moment(curVal, format).format(format) : "");
345            $(item).datetimepicker({
346                format: format,
347                extraFormats: [format, "YYYY-MM-DD HH:mm", "MM/DD/YY HH:mm", "MM/DD/YYYY h:mm A", "YYYY-MM-DD h:mm A"],
348                stepping: 15
349            });
350
351            // Change validation to datetime
352            //msg = $(input).data("val-date");
353            //$(input).removeData("val-date");
354            //$(input).rules("remove", "date");
355            //$(input).removeAttr("data-val-date");
356            //$(input).attr("data-val-datetime", msg.replace("a date", "a date and time"));
357        });
358
359        // Setup OptionSet Controls
360        this.filterAndFind("select.xrm-ui-optionset").each(function (idx, item) {
361            var current = item;
362            $(current).select2({
363                allowClear: true,
364                minimumResultsForSearch: 6
365            });
366            $(current).parent().find("button").click(function () {
367                $(current).select2("open");
368            });
369            // Force validation when select value changes.
370            $(current).on("change", function () {
371                if ($(this).is(":enabled")) {
372                    $(this).valid();
373                }
374            });
375        });
376
377        // Setup Check Boxes
378        this.filterAndFind("input.xrm-ui-checkbox").each(function (index, element) {
379            $(element).closest('div.xrm-ui-input').css('background-color', 'transparent');
380            $(element).on("change", function () {
381                if ($(this).closest(".xrm-ui-checkbox-wrapper").find("input.xrm-ui-checkbox-value").val() == "true") {
382                    $(this).removeAttr("checked");
383                    $(this).closest(".xrm-ui-checkbox-wrapper").find("input.xrm-ui-checkbox-value").val("false");
384                }
385                else {
386                    $(this).attr("checked", "checked");
387                    $(this).closest(".xrm-ui-checkbox-wrapper").find("input.xrm-ui-checkbox-value").val("true");
388                }
389            });
390        });
391
392        this.filterAndFind("input.xrm-ui-autocomplete").each(function (index, element) {
393            var target = $(element).data("target");
394            var view = $(element).data("view");
395            $(element).attr("autocomplete", false);
396            $(element).select2(
397                {
398                    placeholder: "...",
399                    allowClear: true,
400                    minimumInputLength: 1,
401                    ajax: {
402                        type: 'POST',
403                        quietMillis: 100,
404                        url: window.applicationBaseUrl + 'XrmGrid/List',
405                        data: function (t) {
406                            var target = $(element).data("target");
407                            var defaultView = $(element).data("view");
408                            return $.toDictionary({
409                                isAutoComplete: true,
410                                provideAllColumns: false,
411                                config: {
412                                    gridType: 64, // Lookup
413                                    targetEntity: $(element).data("target"),
414                                    view: $(element).data("view"),
415                                    isManyToMany: false,
416                                    provideAllAttributes: false,
417                                    filterOnField: $(element).data("sourcefield")
418                                },
419                                query: {
420                                    pageSize: 50,
421                                    page: 1,
422                                    searchText: t
423                                }
424                            });
425                        },
426                        cache: false,
427                        results: function (data, page, query) {
428                            var termInResults = false;
429                            var results = $.map(data.results, function (item) {
430                                value = item.record.Attributes.filter(function (item) { return item.Key === $(element).data("sourcefield"); })[0].Value;
431
432                                termInResults |= query.term == value;
433                                return {
434                                    id: value,
435                                    text: value
436                                };
437                            });
438                            // Add currently typed value as an option
439                            if (!termInResults) {
440                                results.splice(0, 0, { id: query.term, text: query.term });
441                            }
442                            return { results: results };
443                        }
444                    },
445                    initSelection: function (element, callback) {
446                        callback({
447                            text: $(element).attr("value")
448                        });
449                    },
450                    sortResults: function (results, container, query) {
451                        // prefer starts with, then contains, then ends with.
452                        if (query.term) {
453                            var search = query.term.toLowerCase();
454                            // use the built in javascript sort function
455                            return results.sort(function (a, b) {
456                                var aText = a.text.toLowerCase();
457                                var bText = b.text.toLowerCase();
458                                var aLocation = aText.indexOf(search);
459                                var bLocation = bText.indexOf(search);
460                                if (aText == search && bText != search) { return -1; }
461                                else if (aText != search && bText == search) { return 1; }
462                                else if (aLocation < bLocation) { return -1; }
463                                else if (bLocation < aLocation) { return 1; }
464                                else {
465                                    if (aText > bText) {
466                                        return 1;
467                                    } else if (aText < bText) {
468                                        return -1;
469                                    } else {
470                                        return 0;
471                                    }
472                                }
473                            });
474                        }
475                        return results;
476                    }
477                });
478        });
479
480        // Setup Lookup Controls
481        this.filterAndFind("input.xrm-ui-lookup").each(function (index, element) {
482            //$(element).css("width", "100%");
483            var target = $(element).data("lookuptargets")[0].value;
484            var defaultView = $(element).data("defaultview");
485            var customViews = $(element).data("customviews");
486            var isCustom = customViews && customViews[target] && customViews[target][defaultView];
487            $(element).select2(
488                {
489                    minimumResultsForSearch: -1,
490                    placeholder: "...",
491                    allowClear: true,
492                    minimumInputLength: 1,
493                    ajax: {
494                        type: 'POST',
495                        delay: 250,
496                        url: window.applicationBaseUrl + 'XrmGrid/List',
497                        data: function (t) {
498                            var target = $(element).data("lookuptargets")[0].value;
499                            var defaultView = $(element).data("defaultview");
500                            var customViews = $(element).data("customviews");
501                            var isCustom = customViews && customViews[target] && customViews[target][defaultView];
502                            return $.toDictionary({
503                                isAutoComplete: true,
504                                config: {
505                                    gridType: 64, // Lookup
506                                    targetEntity: $(element).data("lookuptargets")[0].value,
507                                    view: $(element).data("defaultview"),
508                                    isManyToMany: false,
509                                    parentRelationshipName: $(element).data("parentrelationshipname"),
510                                    parentEntity: $(element).data("parententity"),
511                                    parentEntityId: $(element).data("parententityid")
512                                },
513                                query: {
514                                    pageSize: 50,
515                                    page: 1,
516                                    searchText: t,
517                                    fetch: isCustom ? customViews[target][defaultView].fetch : "",
518                                    relatedRecordFilter: {
519                                        filteringRelationship: $(element).data("filteringrelationship"),
520                                        filteringAttribute: $(element).data("filteringattribute"),
521                                        filteringType: $(element).data("filteringtype"),
522                                        filteringValue: $('[Name="' + $(element).data("filteringattribute") + '.Id"]').val()
523                                    }
524                                }
525                            });
526                        },
527                        cache: false,
528                        results: function (data, page) {
529                            return {
530                                results: $.map(data.results, function (item) {
531                                    return {
532                                        id: item.reference.Id,
533                                        text: item.reference.Name,
534                                        logicalName: item.reference.LogicalName
535                                    };
536                                })
537                            };
538                        }
539                    },
540                    initSelection: function (element, callback) {
541                        var ctrl = $(element).closest("div.xrm-ui-ctrl");
542                        callback({
543                            id: ctrl.find("input[name$='.Id']").val(),
544                            logicalName: ctrl.find("input[name$='.LogicalName']").val(),
545                            text: ctrl.find("input[name$='.Name']").val()
546                        });
547                    },
548                    formatSelection: function (item, container) {
549                        //return "<img src='" + window.applicationBaseUrl + "XrmIcon/small/" + item.logicalName + "' /> " + item.text;
550
551                        return "<span style='background-image: url(" + window.applicationBaseUrl + "XrmIcon/small/" + item.logicalName + "); background-size: 14px 14px' class='inline-icon'>" + item.text + "</span>";
552                    },
553                    formatResult: function (item, container) {
554                        //return "<img src='" + window.applicationBaseUrl + "XrmIcon/small/" + item.logicalName + "' /> " + item.text;
555                        return "<span style='background-image: url(" + window.applicationBaseUrl + "XrmIcon/small/" + item.logicalName + "); background-size: 14px 14px' class='inline-icon'>" + item.text + "</span>";
556                    }
557                });
558
559            $(element).on("change", function (e) {
560                var ctrl = $(element).closest("div.xrm-ui-ctrl");
561                var data = $(element).select2("data");
562                if (data == null) {
563                    ctrl.find("input[name$='.Id']").val(null);
564                    ctrl.find("input[name$='.LogicalName']").val(null);
565                    ctrl.find("input[name$='.Name']").val(null);
566                }
567                else {
568                    ctrl.find("input[name$='.Id']").val(data.id);
569                    ctrl.find("input[name$='.LogicalName']").val(data.logicalName);
570                    ctrl.find("input[name$='.Name']").val(data.text);
571                }
572                $(element).triggerChange();
573                // Force validation.
574                if ($(element).is(":enabled")) {
575                    $(element).valid();
576                }
577            });
578
579
580            $(element).closest(".input-group").find("span.input-group-btn > button").on("click", function () {
581                // Get Grid Options
582                var lookupOptions = {
583                    id: $(element).attr("name"),
584                    gridType: 64, // Lookup
585                    viewPickerEnabled: true,
586                    target: $(element).data("lookuptargets")[0].value,
587                    lookupTargets: $(element).data("lookuptargets"),
588                    targetViews: $(element).data("targetviews"),
589                    customViews: $(element).data("customviews"),
590                    autoExpand: true,
591                    editBehavior: $(element).data("editbehavior"),
592                    canCreate: $(element).data("cancreate"),
593                    canEdit: $(element).data("canedit"),
594                    canDelete: $(element).data("candelete"),
595                    defaultView: $(element).data("defaultview"),
596                    softDelete: $(element).data("softdelete"),
597                    url: $(element).data("url"),
598                    createUrl: $(element).data("createurl"),
599                    deleteUrl: $(element).data("deleteurl"),
600                    searchEnabled: $(element).data("searchenabled"),
601                    relatedRecordFilter: {
602                        filteringRelationship: $(element).data("filteringrelationship"),
603                        filteringAttribute: $(element).data("filteringattribute"),
604                        filteringType: $(element).data("filteringtype")
605                    },
606                    parentContainer: $(this)
607                };
608
609                lookup($(element).attr("id"), $('label[for="' + $(element).attr('id') + '"]').text() || "Lookup Record", lookupOptions, $(element).val() != '')
610                    .done(function (result) {
611                        if (result != null && $.isArray(result)) {
612                            var ctrl = $(element).closest("div.xrm-ui-ctrl");
613                            if (result.length == 0) {
614                                ctrl.find("input[name$='.Id']").val(null);
615                                ctrl.find("input[name$='.LogicalName']").val(null);
616                                ctrl.find("input[name$='.Name']").val(null);
617                                ctrl.find("input[name$='.Lookup']").val(null);
618                            }
619                            else {
620                                ctrl.find("input[name$='.Id']").val(result[0].Id);
621                                ctrl.find("input[name$='.LogicalName']").val(result[0].LogicalName);
622                                ctrl.find("input[name$='.Name']").val(result[0].Name);
623                                ctrl.find("input[name$='.Lookup']").val(result[0].Name);
624                            }
625                            $(element).trigger('change');
626                        }
627                        //$(element).open();
628                    });
629            });
630
631        });
632
633        // Setup SubGrids
634        this.filterAndFind("div.xrm-ui-grid").each(function (index, element) {
635            $(element).xrmgrid({
636                id: $(element).attr("id"),
637                viewPickerEnabled: $(element).data("viewpickerenabled"),
638                isDisabled: $(element).data("isdisabled"),
639                isEditable: $(element).data("inlineedit"),
640                parentFieldName: $(element).data("parentfieldname"),
641                isManyToMany: $(element).data("ismanytomany"),
642                selectMultiple: $(element).data("ismanytomany"), // Only allow multiple selection for many to many grids.
643                target: $(element).data("targetentity"),
644                targetViews: $(element).data("targetviews"),
645                parentRelationshipName: $(element).data("parentrelationshipname"),
646                parentEntity: $(element).data("parententity"),
647                parentEntityId: $(element).data("parententityid"),
648                parentEntityName: $(element).data("parententityname"),
649                pageSize: $(element).data("pagesize"),
650                autoExpand: $(element).data("autoexpand"),
651                canCreate: $(element).data("cancreate"),
652                canEdit: $(element).data("canedit"),
653                canDelete: $(element).data("candelete"),
654                canAssociate: $(element).data("canassociate"),
655                editBehavior: $(element).data("editbehavior"),
656                gridType: 2, // Subgrid
657                defaultView: $(element).data("defaultview"),
658                parentContainer: $(element).closest("div.xrmform-tab"),
659                viewName: $(element).data("viewname"),
660                softDelete: $(element).data("softdelete"),
661                url: $(element).data("url"),
662                createUrl: $(element).data("createurl"),
663                deleteUrl: $(element).data("deleteurl"),
664                searchEnabled: $(element).data("searchenabled"),
665                relatedRecordFilter: {
666                    filteringRelationship: $(element).data("filteringrelationship"),
667                    filteringAttribute: $(element).data("filteringattribute"),
668                    filteringType: $(element).data("filteringtype"),
669                    filteringValue: $(element).data("filteringvalue")
670                }
671            });
672        });
673
674        // Setup FileManagers
675        this.filterAndFind("div.xrm-ui-filemanager").each(function (index, element) {
676            $(element).xrmFileManager({
677                id: $(element).attr("id"),
678                canUpload: $(element).data("canupload"),
679                canDownload: $(element).data("candownload"),
680                canDelete: $(element).data("candelete"),
681                context: {
682                    entityName: $(element).data("entityname"),
683                    recordId: $(element).data("recordid")
684                },
685                parentContainer: $(element).closest("div.xrmform-tab")
686            });
687        });
688
689        this.filterAndFind(".xrm-ui-text").each(function (index, element) {
690            if ($(element).attr("data-inputmask")) {
691                var mask = $(element).attr("data-inputmask");
692                //strip out '<', '>', and '|' 
693                var workingMask = "";
694                for (var i = 0; i < mask.length; ++i) {
695                    if (mask.charAt(i) != '<' && mask.charAt(i) != '<' && mask.charAt(i) != '<') {
696                        workingMask += mask.charAt(i);
697                    }
698                }
699
700                $(element).mask(workingMask
701                    , {
702                        'translation': {
703                            '0': { pattern: /\d/ },
704                            '9': { pattern: /\d/, optional: true },
705                            '#': { pattern: /[0-9, \s, +, -]/ },
706                            '#': { pattern: /[0-9, \s, +, -]/ },
707                            'A': { pattern: /[0-9a-zA-Z]/ },
708                            'a': { pattern: /[0-9a-zA-Z, \s]/ },
709                            'L': { pattern: /[a-zA-Z]/ },
710                            'l': { pattern: /[a-zA-Z, \s]/ },
711
712                        },
713                        onKeyPress: function (cep, event, currentField, options) {
714                            console.log('A key was pressed!:', cep, ' event: ', event,
715                                'currentField: ', currentField, ' options: ', options);
716                        },
717                    }
718                );
719            }
720        });
721
722        return this;
723    }
724})(jQuery);
725
726function commaSeparateNumber(val) {
727    if (!val || val === "") { return val; }
728    // grab everything prior to the decimal point
729    var pieces = val.toString().split(".");
730
731    while (/(\d+)(\d{3})/.test(pieces[0])) {
732        pieces[0] = pieces[0].replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
733    }
734    return pieces.join(".");
735}
736
737function getRootUrl(url) {
738    return url.toString().replace(/^(.*\/\/[^\/?#]*).*$/, "$1") + "/";
739}
740
741function closeXrmForm() {
742    $(".xrmform-iframe").parent().dialog("close");
743    return false;
744};
745
746var Formatters = {
747    "phonenumber": function (str) {
748        sTmp = str.replace(/[^0-9]/g, "");
749        switch (sTmp.length) {
750            case 7:
751                return "(907) " + sTmp.substr(0, 3) + "-" + sTmp.substr(3);
752                break;
753            case 10:
754                return "(" + sTmp.substr(0, 3) + ") " + sTmp.substr(3, 3) + "-" + sTmp.substr(6);
755                break;
756            default:
757                // Can't format
758                return str;
759                break;
760        }
761    }
762}
763
764function lookup(id, title, gridOptions, hasCurrentValue) {
765    var d = $.Deferred();
766    var lookupResults = null;
767    // determine if we have a lookup element for this id yet.
768    var $modal = $("#lookup-modal-" + id).remove();
769    $modal = $('<div class="modal" id="lookup-modal-' + id + '" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">' +
770        '<div class="vertical-alignment-helper">' +
771        '<div class="modal-dialog modal-lg vertical-align-center">' +
772        '<div class="modal-content">' +
773        '<div class="modal-header">' +
774        '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>' +
775        '<h4 class="modal-title" id="myModalLabel"><span class="glyphicon glyphicon-search"></span> ' + title + '</h4>' +
776        '</div>' +
777        '<div class="modal-body">' +
778        '<div class="modal-grid xrmform-cell"></div>' +
779        '</div>' +
780        '<div class="modal-footer">' +
781        '<button type="button" class="btn btn-default lookup-close" data-dismiss="modal">Cancel</button>' +
782        '<button type="button" class="btn btn-primary lookup-ok disabled">Select</button>' +
783        '<button type="button" class="btn btn-default lookup-remove">Remove Value</button>' +
784        '</div>' +
785        '</div>' +
786        '</div>' +
787        '</div>' +
788        '</div>"').appendTo('body');
789
790    // If we have a current value, show the Remove Value Button
791    if (hasCurrentValue) { $("button.lookup-remove", $modal).show(); }
792    else { $("button.lookup-remove", $modal).hide(); }
793    $modal
794        .off("click", ".close, .lookup-close").on("click", ".close, .lookup-close", function () {
795            lookupResults = null;
796        })
797        // wire up modal dialog button events
798        .off("click", "button.lookup-ok").on("click", "button.lookup-ok", function (e) {
799            // selection changed is responsible for setting the lookup results.
800            if (lookupResults != null && $.isArray(lookupResults) && lookupResults.length > 0) {
801                $modal.modal('hide');
802            }
803        })
804        .off("click", "button.lookup-remove").on("click", "button.lookup-remove", function (e) {
805            // set lookupresults to an empty array (to indicate the selection was removed.)
806            lookupResults = [];
807            $modal.modal('hide');
808        })
809        // wire up hide/show events
810        .off('shown.bs.modal').on('shown.bs.modal', function () {
811            var $lookupgrid = $(this).find("div.modal-grid");
812            var offset = $(this).find(".modal-header").height() + $(this).find(".modal-footer").height();
813            if ($(this).find("div.slick-viewport").length == 0) {
814                // initialize grid
815                $lookupgrid
816                    .css("min-height", (($(window).height() * .7) - offset) + "px")
817                    .xrmgrid(gridOptions);
818            } else {
819                $lookupgrid
820                    .css("min-height", (($(window).height() * .7) - offset) + "px")
821                    .xrmgrid("resize")
822                    .xrmgrid("loadRecords");
823            }
824            // wire up grid selection events
825            $lookupgrid.off('xrmgridselectionchanged').on('xrmgridselectionchanged', function (e, data) {
826                if (data.selection.length == 0) {
827                    $modal.find("button.lookup-ok").addClass("disabled");
828                } else {
829                    lookupResults = data.selection;
830                    $modal.find("button.lookup-ok").removeClass("disabled");
831                }
832            });
833            $lookupgrid.off('xrmgriddoubleclick').on('xrmgriddoubleclick', function (e, data) {
834                if (data.selection.length > 0) {
835                    lookupResults = data.selection;
836                    $modal.modal('hide');
837                }
838            });
839
840        })
841        .off('hidden.bs.modal').on('hidden.bs.modal', function () {
842            d.resolve(lookupResults);
843        });
844
845
846    $modal.modal({ backdrop: 'static' });
847
848    return d;
849}
850

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.