Пример #1
0
        init: function (options) {
            var inst = {
                opt: objectExtend({}, this.getFactory().defaults, options)
            };

            PRIVATE.set(this, inst);

            this.$ui = parseHTML(
                fillTemplate(this.getTemplate(), inst.opt)
            ).firstChild;

            inst.$removeBtn = this.$ui.querySelector("." + CSS_CLASS_REMOVE_BUTTON);

            domAddEventListener(inst.$removeBtn, "click", function(ev){
                ev.stopPropagation();
                /**
                 * User clicked on the Remove button. The `item` object provided on input
                 * will be given to listeners of this event.
                 *
                 * @event SelectedItem#remove
                 * @type {Object}
                 */
                this.emit("remove", inst.opt.item);
            }.bind(this));

            this.onDestroy(function () {
                PRIVATE.delete(this);
            }.bind(this));
        },
Пример #2
0
            onEachValue:    function(filterVal){
                var isValidCamlXMLTag = (/<userid\/>/i).test(filterVal);

                return fillTemplate(template, {
                    colName:    colName,
                    cOP:        compareOperator,
                    colValue:   isValidCamlXMLTag ? filterVal : xmlEscape.escape(filterVal)
                });
            }
Пример #3
0
    init: function (options) {
        if (PRIVATE.has(this)) {
            return;
        }

        let opt = objectExtend({}, this.getFactory().defaults, options);
        let inst = {
            opt,
            iconClass: opt.iconClass,
            $icon: null
        };

        PRIVATE.set(this, inst);


        opt.type = opt.type.toLowerCase();

        if (!inst.iconClass) {
            inst.iconClass = getIconForMsgType(opt.type);
        }

        let $ui = this.$ui = parseHTML(fillTemplate(MessageTemplate, inst)).firstChild;

        inst.$icon = $ui.querySelector(".ms-Icon");

        inst.moreEv = domAddEventHandler($ui.querySelector(`.${ CSS_CLASS_MESSAGE_MSG }-showMore`), "click", () => {
            domToggleClass($ui, CSS_CLASS_MESSAGE_MSG_SHOW_MORE);
        });

        this.setType(opt.type);
        this.setExtendedMessage(opt.extendedMessage);

        this.onDestroy(() => {
            // Destroy all Compose object
            Object.keys(inst).forEach(function (prop) {
                if (inst[prop]) {
                    [
                        "destroy",      // Compose
                        "remove",       // DOM Events Listeners
                        "off"           // EventEmitter Listeners
                    ].some((method) => {
                        if (inst[prop][method]) {
                            inst[prop][method]();
                            return true;
                        }
                    });

                    inst[prop] = undefined;
                }
            });

            PRIVATE['delete'](this);
        });
    },
Пример #4
0
            choice.on("change", function(){
                this.evalDirtyState();

                var totalSelected = choice.getValue().length;

                if (totalSelected) {
                    this.setKeywordInfo(fillTemplate(opt.labels.totalSelected, {total: totalSelected}));

                } else {
                    this.setKeywordInfo("");
                }
            }.bind(this));
Пример #5
0
    init: function (options) {
        var inst = {
            opt: objectExtend({}, DateTimeFieldDemo.defaults, options)
        };

        PRIVATE.set(this, inst);

        this.$ui = parseHTML(
            fillTemplate(DateTimeFieldDemoTemplate, inst.opt)
        ).firstChild;

        inst.uiFind = this.$ui.querySelector.bind(this.$ui);

        setupDemo1.call(this);

        this.onDestroy(function () {
            Object.keys(inst).forEach(function(prop){
                if (inst[prop] && inst[prop].destroy) {
                    inst[prop].destroy();
                }
            });
            PRIVATE.delete(this);
        }.bind(this));
    }
Пример #6
0
            selected: null
        };

        PRIVATE.set(this, inst);

        let $ui         = this.$ui = this.getTemplate();

        if (typeof $ui === "string") {
            $ui = this.$ui = parseHTML(fillTemplate($ui, {
                _actionsHTML: fillTemplate(
                    this.getActionTemplate(),
                    inst.opt.actions.map((action) => {
                        if (!action.id) {
                            action.id = uuid.generate();
                        }

                        if (action.selected) {
                            inst.selected = action;
                        }

                        return action;
                    })
                )
            })).firstChild;
        }

        inst.uiFind = $ui.querySelector.bind($ui);

        if (inst.selected) {
            this.setSelected(inst.selected);
        }
Пример #7
0
        let opt = inst.opt;

        if (!opt.id) {
            opt.id = uuidGenerate();
        }

        // Set the MS Type which is used in the class name
        if (opt.type.toLowerCase() === "checkbox") {
            inst.msType = "CheckBox";
        }

        let $ui = this.$ui = this.getTemplate();

        if (typeof $ui === "string") {
            $ui = this.$ui = parseHTML(fillTemplate($ui, inst)).firstChild;
        }

        let uiFind = $ui.querySelector.bind($ui);

        inst.$input = uiFind(`.${ CSS_CLASS_BASE }-input`);
        inst.$label = uiFind(`.${ CSS_CLASS_BASE }-label`);

        inst.uiClickEv = domAddEventListener(inst.$input, "click", (/*ev*/) => {
            markChoiceField.call(this);

            /**
             * The state of the Choice item has changed
             *
             * @event ChoiceItem#change
             */
Пример #8
0
    init: function (options) {
        let inst = {
            opt:            objectExtend({}, this.getFactory().defaults, options),
            resultGroup:    null,
            bodyClickEv:    null,
            lastSearchInput:"",
            lastSearchId:   1,
            isSilentFocus:  false,
            selected:       [] // array of Persona widgets
        };

        inst.opt.UserProfileModel = inst.opt.UserProfileModel.extend({webURL: inst.opt.webURL});
        PRIVATE.set(this, inst);

        let opt         = inst.opt;
        let $ui         = this.$ui = parseHTML(fillTemplate(SPPeoplePickerTemplate, opt)).firstChild;
        let uiFind      = $ui.querySelector.bind($ui);
        let $input      = inst.$input = uiFind("input[name='search']");
        let $searchBox  = inst.$searchBox = uiFind("." + CSS_CLASS_MS_PICKER_SEARCHBOX);
        let $suggestions= inst.$suggestions   = uiFind(SELECTOR_BASE + "-suggestions");
        let requestSuggestions;

        inst.$groups        = uiFind(SELECTOR_BASE + "-suggestions-groups");
        inst.$inputCntr     = uiFind(SELECTOR_BASE + "-searchFieldCntr");

        // Detach the Suggestions element
        // FIXME: need to move this to a Popup widget
        $suggestions.parentNode.removeChild($suggestions);

        if (opt.resultsZIndex) {
            domSetStyle($suggestions, {zIndex: opt.resultsZIndex});
        }

        if (opt.resultsMaxHeight) {
            domSetStyle(inst.$groups, { maxHeight: opt.resultsMaxHeight });
        }

        // Add keyboard interaction to the Input field
        let keyboardInteraction = inst.keyboardInteraction = DomKeyboardInteraction.create({
            input:          $input,
            eleGroup:       inst.$groups,
            eleSelector:    `.${CSS_CLASS_BASE}-Result`,
            focusClass:     `${CSS_CLASS_BASE}-Result--focus`
        });

        keyboardInteraction.on("keyEnter", function(){
            if (inst.resultGroup) {
                inst.resultGroup.selectCurrent();
                requestAnimationFrame(function(){
                    $input.value = "";
                });
            }
        });

        keyboardInteraction.on("keyEsc", function(){
            if (!$input.value) {
                domTriggerEvent(BODY, "click");
                $input.blur();
            }
            $input.value = "";
        });

        // Cancel bubbling of mouse clicks inside the suggestions (results)
        domAddEventListener($suggestions, "click", (ev) => ev.stopPropagation() && ev.preventDefault());

        // Focusing on the Input field, show the suggestions
        // and sets up the event to close it clicking outside of it.
        domAddEventListener($input, "focus", function(){
            if (!inst.isSilentFocus) {
                this.showResults();
            }
        }.bind(this));

        // On blur: we want to hide the results popup, but only if the user
        // did not leave the input to actually click on a result item. so,
        // we delay the hiding of the results and check later if it was realy
        // a true blur
        // FIXME: blur not realy playing well with results.
        //domAddEventListener($input, "blur", function(){
        //    this.hideResults();
        //}.bind(this));

        // When user types, get suggestions
        domAddEventListener($input, "keyup", function(/*ev*/){
            var //key         = ev.which || ev.keyCode,
                searchInput = String($input.value).trim();

            if (inst.lastSearchInput === searchInput) {
                return;
            }
            inst.lastSearchInput = searchInput;

            if (!searchInput) {
                inst.lastSearchId++;
                requestSuggestions = undefined;
                clearSuggestions.call(this);
                return;
            }

            // If not min length, exit
            if (searchInput.length < inst.opt.minLength) {
                inst.lastSearchId++;
                clearSuggestions.call(this);
                return;
            }

            let exec = function(){
                if (exec === requestSuggestions) {
                    inst.lastSearchId++;
                    let searchId = inst.lastSearchId;

                    domAddClass($ui, CSS_CLASS_IS_SEARCHING);
                    domAddClass($suggestions, CSS_CLASS_IS_SEARCHING);
                    clearSuggestions.call(this);
                    getSuggestions.call(this)
                        .then(function(peopleList){
                            // if already stale, then do nothing
                            if (searchId !== inst.lastSearchId) {
                                domRemoveClass($ui, CSS_CLASS_IS_SEARCHING);
                                domRemoveClass($suggestions, CSS_CLASS_IS_SEARCHING);
                                return;
                            }

                            showSuggestions.call(this, peopleList);
                            domRemoveClass($ui, CSS_CLASS_IS_SEARCHING);
                            domRemoveClass($suggestions, CSS_CLASS_IS_SEARCHING);
                        }.bind(this))["catch"](function(e){
                            console.log(e); // jshint ignore:line
                        });
                }
            }.bind(this);

            requestSuggestions = exec;

            // After brief delay: get suggestion
            setTimeout(function(){
                exec();
            }, 250);
        }.bind(this));

        // Clicking inside of this widget, but not on a selected element or
        // the input element, places focus on the input
        domAddEventListener($searchBox, "click", function(ev){
            if (ev.target === $searchBox) {
                $input.focus();
            }
        }.bind(this));

        // Listen for when selected users are removed
        this.on("selected-remove", function(userWdg){
            var personModel = userWdg.getUserProfile(),
                selectedIndex;

            userWdg.destroy();

            inst.selected.some(function(selectedWdg, index){
                if (selectedWdg === userWdg) {
                    selectedIndex = index;
                    return true;
                }
            });

            if (typeof selectedIndex !== "undefined") {
                inst.selected.splice(selectedIndex, 1);
            }

            positionResultsPopup.call(this);
            domTriggerEvent($input, "keyup");

            /**
             * A selection was removed
             *
             * @event PeoplePicker#remove
             *
             * @type {UserProfileModel}
             */
            this.emit("remove", personModel);
        }.bind(this));

        // If user Set 'suggestionsRightAlign' then align suggestions to the right
        if (inst.opt.suggestionsRightAlign){
            domAddClass($ui, CSS_CLASS_SUGGESTIONS_RIGHT_ALIGN);
        }

        // If selected people were defined on input, call add()
        if (inst.opt.selected) {
            this.add(inst.opt.selected);
        }

        this.onDestroy(function(){
            // Since the suggestion UI was detached from the widget, need to
            // ensure it is also destroyed.
            if ($suggestions.parentNode) {
                $suggestions.parentNode.removeChild($suggestions);
            }

            inst.selected.forEach(function(wdg){
                if (wdg) {
                    wdg.destroy();
                }
            });
            inst.selected.splice(0);

            // Destroy all Compose object
            Object.keys(inst).forEach(function (prop) {
                if (inst[prop]) {
                    // Widgets
                    if (inst[prop].destroy) {
                        inst[prop].destroy();

                        // DOM events
                    } else if (inst[prop].remove) {
                        inst[prop].remove();

                        // EventEmitter events
                    } else if (inst[prop].off) {
                        inst[prop].off();
                    }

                    inst[prop] = undefined;
                }
            });

            PRIVATE['delete'](this);
        }.bind(this));
    },
Пример #9
0
    init: function (options) {
        var inst = {
            opt:        objectExtend({}, this.getFactory().defaults, options),
            uiFind:     null,
            body:       null,
            infoMsg:    null,
            colsWdg:    {}      // List of columns currently shown
        },
        opt = inst.opt;

        PRIVATE.set(this, inst);

        var me  = this,
            $ui = me.$ui = parseHTML(
                fillTemplate(SPFilterPanelTemplate, inst.opt)
            ).firstChild,
            uiFind          = inst.uiFind = $ui.querySelector.bind($ui),
            BASE_SELECTOR   = "." + CSS_CLASS_BASE,
            emit            = me.emit.bind(me);


        inst.main = uiFind(BASE_SELECTOR + "-main");
        inst.body = uiFind(BASE_SELECTOR + "-body");
        inst.find = uiFind(BASE_SELECTOR + "-footer-action-find");

        // Apply modifiers
        if (opt.hideHeader) {
            domAddClass($ui, CSS_CLASS_NO_HEADER);
        }
        if (opt.hideFindButton) {
            domAddClass($ui, CSS_CLASS_NO_FIND_BUTTON);
        }

        if (opt.bodyHeight) {
            this.setBodyHeight(opt.bodyHeight);
        }


        // Info widget
        inst.infoMsg = Widget.extend({$ui: parseHTML('<div style="padding: 2em 5%;"/>').firstChild}).create();
        Message.create({ message: opt.labels.msg }).appendTo(inst.infoMsg.getEle());
        inst.infoMsg.appendTo(inst.body);

        // Column selector widget
        inst.columnSelector = ColumnSelector.create(opt);
        inst.columnSelector.pipe(this, "columnSelector:");

        if (opt.filters && opt.filters.length) {
            this.setFilters(opt.filters);
        }

        //----------------------------------------
        // Initialize event handlers
        //----------------------------------------
        domAddEventListener(uiFind(BASE_SELECTOR + "-footer-action-add"), "click", function(){
            inst.columnSelector.appendTo($ui);
            inst.columnSelector.show();
        });

        domAddEventListener(uiFind(BASE_SELECTOR + "-footer-action-clear"), "click", function(){
            this.clear();

            /**
             * Defined filters were cleared
             *
             * @event FilterPanel#clear
             */
            emit("clear");
        }.bind(this));

        domAddEventListener(inst.find, "click", function(){
            /**
             * Find button was clicked
             *
             * @event FilterPanel#find
             */
            emit("find");
        });

        domAddEventListener(uiFind(BASE_SELECTOR + "-header-close"), "click", function(){
            /**
             * Close button was clicked
             *
             * @event FilterPanel#close
             */
            emit("close");
        });

        // FIXME: handle move up|down of columns
        // See snippet from stackoverflow on movement:
        // http://stackoverflow.com/questions/5306680/move-an-array-element-from-one-array-position-to-another
        //    Array.prototype.move = function (old_index, new_index) {
        //        if (new_index >= this.length) {
        //            var k = new_index - this.length;
        //            while ((k--) + 1) {
        //                this.push(undefined);
        //            }
        //        }
        //        this.splice(new_index, 0, this.splice(old_index, 1)[0]);
        //        return this; // for testing purposes
        //    };

        me.on("columnSelector:cancel", function(){
            inst.columnSelector.hide();
        });

        me.on("columnSelector:ok", function(){
            inst.columnSelector.hide();
        });

        me.on("columnSelector:select", function(colDef){
            addColumns.call(me, [colDef], null, true);
        });

        me.on("columnSelector:unselect", function(colDef){
            hideFilterColumn.call(me, colDef.Name);
        });

        me.on("filterColumn:change", function(){
            if (this.isDirty()) {
                domAddClass(inst.find, CSS_CLASS_MS_BUTTON_PRIMARY);
            } else {
                domRemoveClass(inst.find, CSS_CLASS_MS_BUTTON_PRIMARY);
            }
        }.bind(this));

        //--------------------------------------
        // Destroy logic
        //--------------------------------------
        this.onDestroy(function () {
            PRIVATE.delete(this);
            Object.keys(inst).forEach(function(prop){
                if (inst[prop] && inst[prop].destroy) {
                    inst[prop].destroy();
                    inst[prop] = undefined;
                }
            });
        }.bind(this));
    },
Пример #10
0
    init: function (options) {
        var inst = {
            opt:                objectExtend({}, this.getFactory().defaults, options),
            sizeModifier:       "",
            presenceModifier:   "offline",
            variant:            "",
            initialsColor:      ""
        };

        PRIVATE.set(this, inst);

        let opt     = inst.opt;
        let emit    = this.emit.bind(this);

        this._model = opt.userProfile;

        let $ui = this.$ui = parseHTML(
            fillTemplate(this.getTemplate(), opt.userProfile)
        ).firstChild;
        let uiFind = $ui.querySelector.bind($ui);

        inst.$imgArea = uiFind("." + CSS_CLASS_MS_PERSONA + "-imageArea");
        inst.$initials  = uiFind(`.${CSS_CLASS_MS_PERSONA}-initials`);

        // Find the persona element, which might not be the top element,
        // since this widget could have been extended and UI might be wrapped
        // in other elements (ex. people picker)
        inst.$persona = domClosest(inst.$imgArea, `.${CSS_CLASS_MS_PERSONA}`);

        let $userPhotoImg = uiFind(`.${CSS_CLASS_MS_PERSONA}-imageArea img`);
        domAddEventListener($userPhotoImg, "error", handleUserPhotoLoadFailure.bind(this, $userPhotoImg));

        inst.imgFailedEv = this.once("photo-load-failed", this.showInitials.bind(this));

        if (opt.size) {
            this.setSize(opt.size);
        }

        if (opt.hideDetails) {
            this.hideDetails();
        }

        if (opt.variant) {
            this.setVariant(opt.variant);
        }

        if (opt.showInitials) {
            this.showInitials();
        }

        if (opt.initialsColor) {
            this.setInitialsColor(opt.initialsColor);

        } else if (opt.initialsColor === null && opt.userProfile && opt.userProfile.Color) {
            this.setInitialsColor(opt.userProfile.Color);
        }

        if (opt.presence) {
            this.setPresence(opt.presence);
        }

        if (opt.hideAction) {
            domAddClass($ui, `${CSS_CLASS_BASE}--noAction`);
        }

        domAddEventListener(uiFind(`.${CSS_CLASS_MS_PERSONA}-actionIcon`), "click", (ev) => {
            /**
             * User clicked on the Persona's action button
             *
             * @event Persona#action-click
             */
            emit("action-click");
            ev.stopPropagation();
        });

        domAddEventListener($ui, "click", () => {
            /**
             * Persona Element was clicked on by user
             *
             * @event Persona#click
             */
            emit("click");
        });

        this.onDestroy(function(){
            // Destroy all Compose object
            Object.keys(inst).forEach(function (prop) {
                if (inst[prop]) {
                    // Widgets
                    if (inst[prop].destroy) {
                        inst[prop].destroy();

                    // DOM events
                    } else if (inst[prop].remove) {
                        inst[prop].remove();

                    // EventEmitter events
                    } else if (inst[prop].off) {
                        inst[prop].off();
                    }

                    inst[prop] = undefined;
                }
            });

            PRIVATE["delete"](this);
        }.bind(this));
    },