define([ "dojo/_base/declare", // declare "dojo/_base/lang", // lang.getObject... "dojo/_base/connect", // connect.connect, connect.subscribe "dojo/_base/fx", // fx.fadeOut "dojo/dom-style", // domStyle.set "dojo/dom-class", // domClass.add "dojo/dom-geometry", // domGeometry.getMarginBox "dijit/registry", // registry.getUniqueId() "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/BackgroundIframe", "dojo/fx", "dojo/has", "dojo/_base/window", "dojo/window" ], function (declare, lang, connect, baseFx, domStyle, domClass, domGeometry, registry, WidgetBase, Templated, BackgroundIframe, coreFx, has, baseWindow, window) { lang.getObject("dojox.widget", true); var capitalize = function ( /* String */ w) { return w.substring(0, 1).toUpperCase() + w.substring(1); }; //MODIFY dojox.widget.Toaster to mods.widget.MapToaster return declare("mods.widget.MapToaster", [WidgetBase, Templated], { // summary: // Message that slides in from the corner of the screen, used for notifications // like "new email". //MODIFY add "Map" to classes templateString: '<div class="dijitMapToasterClip" dojoAttachPoint="clipNode"><div class="dijitMapToasterContainer" dojoAttachPoint="containerNode" dojoAttachEvent="onclick:onSelect"><div class="dijitMapToasterContent" dojoAttachPoint="contentNode"></div></div></div>', // messageTopic: String // Name of topic; anything published to this topic will be displayed as a message. // Message format is either String or an object like // {message: "hello word", type: "error", duration: 500} messageTopic: "", // messageTypes: Enumeration // Possible message types. messageTypes: { MESSAGE: "message", WARNING: "warning", ERROR: "error", FATAL: "fatal" }, // defaultType: String // If message type isn't specified (see "messageTopic" parameter), // then display message as this type. // Possible values in messageTypes enumeration ("message", "warning", "error", "fatal") defaultType: "message", // positionDirection: String // Position from which message slides into screen, one of // ["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right"] //MODIFY default to "tc-down" positionDirection: "tc-down", // positionDirectionTypes: Array // Possible values for positionDirection parameter //MODIFY add direction types "bc-up" and "tc-down" positionDirectionTypes: ["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right", "bc-up", "tc-down"], // duration: Integer // Number of milliseconds to show message duration: 2000, // slideDuration: Integer // Number of milliseconds for the slide animation, increasing will cause the Toaster // to slide in more slowly. slideDuration: 500, // separator: String // String used to separate messages if consecutive calls are made to setContent before previous messages go away //MODIFY no need for separator - see _setContent //separator: "<hr></hr>", //MODIFY map div (or other container) id mapId: 'map', postCreate: function () { this.inherited(arguments); this.hide(); // place node as a child of body for positioning baseWindow.body().appendChild(this.domNode); if (this.messageTopic) { connect.subscribe(this.messageTopic, this, "_handleMessage"); } }, _handleMessage: function ( /*String|Object*/ message) { if (lang.isString(message)) { this.setContent(message); } else { this.setContent(message.message, message.type, message.duration); } }, setContent: function ( /*String|Function*/ message, /*String*/ messageType, /*int?*/ duration) { // summary: // sets and displays the given message and show duration // message: // the message. If this is a function, it will be called with this toaster widget as the only argument. // messageType: // type of message; possible values in messageTypes enumeration ("message", "warning", "error", "fatal") // duration: // duration in milliseconds to display message before removing it. Widget has default value. duration = duration || this.duration; // sync animations so there are no ghosted fades and such if (this.slideAnim) { if (this.slideAnim.status() != "playing") { this.slideAnim.stop(); } if (this.slideAnim.status() == "playing" || (this.fadeAnim && this.fadeAnim.status() == "playing")) { setTimeout(lang.hitch(this, function () { this.setContent(message, messageType, duration); }), 50); return; } } // determine type of content and apply appropriately for (var type in this.messageTypes) { //MODIFY add "Map" to classes domClass.remove(this.containerNode, "dijitMapToaster" + capitalize(this.messageTypes[type])); } domStyle.set(this.containerNode, "opacity", 1); this._setContent(message); //MODIFY add "Map" to classes domClass.add(this.containerNode, "dijitMapToaster" + capitalize(messageType || this.defaultType)); // now do funky animation of widget appearing from // bottom right of page and up this.show(); var nodeSize = domGeometry.getMarginBox(this.containerNode); this._cancelHideTimer(); if (this.isVisible) { this._placeClip(); //update hide timer if no sticky message in stack if (!this._stickyMessage) { this._setHideTimer(duration); } } else { var style = this.containerNode.style; var pd = this.positionDirection; // sets up initial position of container node and slide-out direction if (pd.indexOf("-up") >= 0) { style.left = 0 + "px"; style.top = nodeSize.h + 10 + "px"; } else if (pd.indexOf("-left") >= 0) { style.left = nodeSize.w + 10 + "px"; style.top = 0 + "px"; } else if (pd.indexOf("-right") >= 0) { style.left = 0 - nodeSize.w - 10 + "px"; style.top = 0 + "px"; } else if (pd.indexOf("-down") >= 0) { style.left = 0 + "px"; style.top = 0 - nodeSize.h - 10 + "px"; } else { throw new Error(this.id + ".positionDirection is invalid: " + pd); } this.slideAnim = coreFx.slideTo({ node: this.containerNode, top: 0, left: 0, duration: this.slideDuration }); this.connect(this.slideAnim, "onEnd", function (nodes, anim) { //we build the fadeAnim here so we dont have to duplicate it later // can't do a fadeHide because we're fading the // inner node rather than the clipping node this.fadeAnim = baseFx.fadeOut({ node: this.containerNode, duration: 1000 }); this.connect(this.fadeAnim, "onEnd", function (evt) { this.isVisible = false; this.hide(); }); this._setHideTimer(duration); this.connect(this, 'onSelect', function (evt) { this._cancelHideTimer(); //force clear sticky message this._stickyMessage = false; this.fadeAnim.play(); }); this.isVisible = true; }); this.slideAnim.play(); } }, //CONTINUED IN NEXT POST
//CONTINUED FROM LAST POST _setContent: function (message) { if (lang.isFunction(message)) { message(this); return; } //MODIFY if the toaster is visible simply switch out the current message with new message /*if(message && this.isVisible){ message = this.contentNode.innerHTML + this.separator + message; }*/ this.contentNode.innerHTML = message; }, _cancelHideTimer: function () { if (this._hideTimer) { clearTimeout(this._hideTimer); this._hideTimer = null; } }, _setHideTimer: function (duration) { this._cancelHideTimer(); //if duration == 0 we keep the message displayed until clicked if (duration > 0) { this._cancelHideTimer(); this._hideTimer = setTimeout(lang.hitch(this, function (evt) { // we must hide the iframe in order to fade // TODO: figure out how to fade with a BackgroundIframe if (this.bgIframe && this.bgIframe.iframe) { this.bgIframe.iframe.style.display = "none"; } this._hideTimer = null; //force clear sticky message this._stickyMessage = false; this.fadeAnim.play(); }), duration); } else this._stickyMessage = true; }, _placeClip: function () { //MODIFY view is the map (or other container) and border is its border //var view = window.getBox(); var pos = domGeometry.position(this.mapId); var view = { w: pos.w, h: pos.h, t: pos.y, l: pos.x }; var border = domGeometry.getBorderExtents(this.mapId); var nodeSize = domGeometry.getMarginBox(this.containerNode); var style = this.clipNode.style; // sets up the size of the clipping node style.height = nodeSize.h + "px"; style.width = nodeSize.w + "px"; // sets up the position of the clipping node var pd = this.positionDirection; if (pd.match(/^t/)) { //MODIFY + border top //style.top = view.t+"px"; style.top = (view.t + border.t) + "px"; } else if (pd.match(/^b/)) { //MODIFY + border top //style.top = (view.h - nodeSize.h - 2 + view.t)+"px"; style.top = (view.h - nodeSize.h - 2 + view.t + border.t) + "px"; } if (pd.match(/^[tb]r-/)) { style.left = (view.w - nodeSize.w - 1 - view.l) + "px"; } else if (pd.match(/^[tb]l-/)) { //MODIFY [top/bottom]-left set to view left + left border width //style.left = 0 + "px"; style.left = (view.l + border.l) + "px"; } else if (pd.match(/^[tb]c-/)) { //MODIFY [top/bottom]-center is view/2 + view left + border left - node/2 //style.left = Math.round((view.w - nodeSize.w - 1 - view.l)/2)+"px"; style.left = (Math.round(view.w / 2) + view.l + border.l - (nodeSize.w / 2)) + "px"; } style.clip = "rect(0px, " + nodeSize.w + "px, " + nodeSize.h + "px, 0px)"; if (has("ie")) { if (!this.bgIframe) { //MODIFY registry.getUniqueId //this.clipNode.id = registry.getUniqueId("dojox_widget_Toaster_clipNode"); this.clipNode.id = registry.getUniqueId("mods_widget_MapToaster_clipNode"); this.bgIframe = new BackgroundIframe(this.clipNode); } var iframe = this.bgIframe.iframe; if (iframe) { iframe.style.display = "block"; } } }, onSelect: function ( /*Event*/ e) { // summary: // callback for when user clicks the message }, show: function () { // summary:' // show the Toaster domStyle.set(this.domNode, 'display', 'block'); this._placeClip(); if (!this._scrollConnected) { this._scrollConnected = connect.connect(window, "onscroll", this, this._placeClip); } }, hide: function () { // summary: // hide the Toaster domStyle.set(this.domNode, 'display', 'none'); if (this._scrollConnected) { connect.disconnect(this._scrollConnected); this._scrollConnected = false; } domStyle.set(this.containerNode, "opacity", 1); } }); });
/* map toaster */ .dijitMapToasterContent { padding:0.75em; background:#B5BCC7; /*background-color:rgb(181,188,199); background-color:rgba(181,188,199,0.9);*/ text-align:center; -webkit-border-radius:0px 0px 10px 10px; border-radius:0px 0px 10px 10px; } .dijitMapToasterMessage{ /*color:#fff;*/ } .dijitMapToasterWarning, .dijitMapToasterError, .dijitMapToasterFatal{ font-weight:bold; color:#fff; } .dijitMapToasterWarning .dijitMapToasterContent{ background:#900; } .dijitMapToasterError .dijitMapToasterContent{ background:#990; } .dijitMapToasterClip { position: absolute; z-index: 5000; overflow: hidden; } .dijitMapToasterContainer { display: block; position: absolute; width: 200px; margin: 0px; /*font:0.75em;*/ }
app.map.toaster = new mods.widget.MapToaster({ mapId: 'center-map', defaultType: 'message', duration: 3500, positionDirection: 'tc-down' });
app.map.toaster.setContent('Click map to draw point.');
Aangemelde leden kunnen berichten plaatsen, updates volgen en meer. Nieuw hier? Registreer een gratis account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.