cmv-app
cmv-app copied to clipboard
Floating Pane - Created Floating Pane instead of sidebar
Hi, I am working on create dynamic toolbar toggle button widgets that configured in viewer.js file. The button is linked with Floating pane widgets open/close, expand/collapse & movable. Instead of sidebar I try to load Draw widgets in floating panel and it's loading and working fine. The same way I am trying to load LayerControl widgets in Floating pane but unable to load.
I am able to load Draw widgets, and I want to have LayerControl in my Floating Pane and later I have plan to use other widgets.
Any idea how to load LayerControl in floating panel. There is something I am missing, I tried to find but not getting exact point where to do and what parameter to pass?
Here is my steps to get it done for Draw widgets and same way I am trying for LayerControl.
- In Viewe.js - in return statement
"theme": "black",
"toolbarEnabled": true,
"extentWidgetEnabled": false,
"searchWidgetEnabled": true,
"graphicsWidgetEnabled": true,
"layerControlWidgetEnabled": true,
- Then I have the widgets list in viewer.js
toolbarwidgets: {
//This toolbar is for Toolbar button - Create Menu widgets configured in viewer and display Icon
toolbar:
{
showCount: 2,
},
// this is search widget
search:
{
},
// this is Draw widgets - This one is working and able to load in Floating Pane widgets
graphics:
{
},
layerControl:
{
map: map,
separated: true,
vectorReorder: true,
overlayReorder: true,
layerInfos:layerInfos,
layerInfos: [{
layer: new ArcGISDynamicMapServiceLayer("http://myserverurl/arcgis/rest/services/UAT/ROADS/MapServer", {
"opacity": 1,
visible: false,
id: 'mymap'
}),
type: 'dynamic',
title: 'Roads',
controlOptions: {
swipe: true,
metadataUrl: true,
expanded: true
// see Control Options
}
}],
}
- Then in Controller.js file - I am calling this this.loadtoolbarWidgets() in initWidgets functions
this.loadtoolbarWidgets();
- This function is below how I call the widgets, create menu, floating pane etc..
loadtoolbarWidgets: function (widgetConfig, position) {
debugger;
var toolbarWidgetList = []; // array to store widgets list
var tabWidgetIndex = 1;
var toolbarEnabled = this.config.toolbarEnabled;
// Check here if widgets enabled true/false and how I call the widgets
//this is the Draw widgets and its working and loading in floating pane
if (this.config.graphicsWidgetEnabled == true) {
var container = domConstruct.create('div', { id: "graphicsWidgetDiv", class: "toolbarButton" });
domConstruct.place(container, this.map.container);
this.graphicsWidget = new GraphicsWidget({
map: this.map,
theme: this.config.theme,
config: this.config.toolbarwidgets.graphics
}, container);
this.graphicsWidget.startup();
toolbarWidgetList.push(this.graphicsWidget);
}
// LayerControl widget - This is what I am calling and trying to load in Floating Pane Widgets
if (this.config.layerControlWidgetEnabled == true)
{
var container = domConstruct.create('div', { id: "layerControlWidgetDiv", class: "toolbarButton" });
domConstruct.place(container, this.map.container);
this.layerControlWidget = new LayerControl({
map: this.map,
theme: this.config.theme,
config: this.config.toolbarwidgets.layerControl
// see LayerInfos
}, container);
this.layerControlWidget.startup();
toolbarWidgetList.push(this.layerControlWidget);
}
// this is for create toolbar - Menubar with icons.
if (toolbarEnabled == true) {
this.toolbar = new ToolbarWidget({
map: this.map,
widgets: toolbarWidgetList,
showCount: this.config.toolbarwidgets.toolbar.showCount
}, "toolbarWidgetDiv");
this.toolbar.startup();
}
}
- Here is the LayerControl.js file - I have added 2 more functions to linked the widgets with toggle menu button and create Floating pane widgets - below is the changes in LayerControl.js file
define([
'dojo/_base/declare',
'dojo/_base/array',
'dojo/_base/lang',
'dojo/topic',
'dojo/dom-attr',
'dojo/dom-construct',
"dojo/dom-class",
"gis/dijit/floatWidgetBase",
'dijit/_WidgetBase',
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
'dijit/_Container',
'dijit/layout/ContentPane',
'dijit/form/Button',
"dojo/text!./LayerControl/templates/button.html",
'esri/tasks/ProjectParameters',
'esri/config',
'require',
'xstyle/css!./LayerControl/css/LayerControl.css'
], function (
declare,
array,
lang,
topic,
domAttr,
domConst,
domClass,
floatWidgetBase,
_WidgetBase,
_TemplatedMixin,
_WidgetsInTemplateMixin,
Container,
ContentPane,
Button,
buttonTemplate,
ProjectParameters,
esriConfig,
require
) {
(function () {
var css = [require.toUrl("gis/dijit/Graphics/css/graphics.css")];
var head = document.getElementsByTagName("head").item(0),
link;
for (var i = 0, il = css.length; i < il; i++) {
link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = css[i].toString();
head.appendChild(link);
}
}());
// Create button in Toolbar
var layerControlButton = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin],
{
widgetsInTemplate: true,
templateString: buttonTemplate,
baseClass: 'widget_LayerControl',
buttonClass: 'toolbarButton',
postCreate: function () {
debugger;
//initialize the widget
this.inherited(arguments);
domClass.add(this.toolbarButton.domNode);//, "toolbarButtonIcon "+this.theme);
var props = {
map: this.map, theme: this.theme,config:this.config, //layerInfos: this.config.layerInfos,
//separated: this.config.separated, vectorReorder: this.config.vectorReorder,
//overlayReorder: this.config.overlayReorder
};
this.widget = new floatWidget(props);
this.widget.startup();
},
toggleWidget: function () {
//debugger;
if (this.widget.visible)
this.widget.close();
else
this.widget.show();
}
});
// this is for create floating pane widgets
var floatWidget = declare([floatWidgetBase],
{
widgetsInTemplate: false,
baseClass: 'widget_LayerControl',
title: 'Layers',
postCreate: function () {
debugger;
this.inherited(arguments);
//debugger;
console.log("LayerControl");
this.floatIconStyle += " " + this.theme;
this.resizable = true,
this.top = 100;
this.left = 100;
this.contentHeight = 150;
this.contentWidth = 500;
this.initFloat();
this.initUI();
},
initUI: function () {
var props = {
parentContainer: this.floatingPane.containerNode, map: this.map,
layerInfos: this.config.layerInfos, separated: this.config.separated,
vectorReorder: this.config.vectorReorder,
overlayReorder: this.config.overlayReorder
};
debugger;
this.ui = new LayerControl(props);
this.ui.startup();
}
});
// Here is Our LayerControl actual code goes
var LayerControl = declare([_WidgetBase, Container], {
.....
....
});
return LayerControl, layerControlButton;
});
- This is floatWidgetBase.js file - create Floating pane Dynamically
define(["dojo/_base/declare",
"dijit/_WidgetBase",
"dojo/dom-construct",
"dojo/query",
"dojo/on",
'dojo/dom',
"dojo/_base/lang",
"dojo/dom-style",
"dojo/dom-class",
"dojox/layout/FloatingPane",
"dijit/layout/ContentPane",
"dojo/dnd/move",
],
function (declare, _WidgetBase, domConstruct, query, on, dom, lang, domStyle, domClass, FloatingPane, ContentPane, dndMove) {
var ConstrainedFloatingPane = dojo.declare(dojox.layout.FloatingPane, {
postCreate: function () {
this.inherited(arguments);
this.moveable = new dojo.dnd.move.constrainedMoveable(
this.domNode, {
handle: this.focusNode,
constraints: function () {
var coordsBody = dojo.coords(dojo.body());
// or
var coordsWindow = {
l: 0,
t: 0,
w: window.innerWidth,
h: window.innerHeight
};
return coordsWindow;
},
within: true
}
);
}
});
return declare([_WidgetBase], {
//id:"floatWidget",
parentId:null,
baseContainer:null,
title:"Floating Widget",
floatIconStyle:"floatingPaneIcon",
minimizeBtn:null,
maximizeBtn:null,
closeBtn:null,
floatingPane:null,
visible:false,
minimized:false,
top:100,
left:10,
contentWidth:330,
contentHeight:400,
maxWidth:999999,
postCreate: function () {
//debugger;
this.parentId = dijit.getEnclosingWidget(this.domNode).id;
this.baseContainer = domConstruct.create('div', {
class : "float",
id : this.id+"fPanefloatWidget",
style : ""
});
domConstruct.place(this.baseContainer, this.map.container, 'first');
},
initFloat:function()
{
debugger;
this.floatingPane = new ConstrainedFloatingPane({
title: "<span class='paneTitleText'>"+this.title+"</span>",
resizable: this.resizable,//true,
dockable: false,
closable: false,
style: "position:absolute;z-index:1000;top:"+this.top+"px;left:"+this.left+"px;width:"+this.contentWidth+"px;height:"+this.contentHeight+"px;overflow: hidden;visibility:hidden;",
id: this.id+"_fPane",
'class': "floatingPane "+this.baseClass}, this.baseContainer);
this.floatingPane.hide();
this.floatingPane.startup();
var lTitlePane = query("#"+this.id+"_fPane"+' .dojoxFloatingPaneTitle')[0];
this.closeBtn= domConstruct.create("div", {
class:"closeBtn",
style : "width:20px;height:20px;overflow: hidden;"
});
on(this.closeBtn,"click",lang.hitch(this,"close"));
this.minimizeBtn = domConstruct.create("div", {
class:"minimizeBtn",
style : "width:20px;height:20px;overflow: hidden;"
});
on(this.minimizeBtn,"click",lang.hitch(this,"minimize"));
this.maximizeBtn= domConstruct.create("div", {
class:"maximizeBtn",
style : "width:20px;height:20px;overflow: hidden;visibility:hidden;"
});
on(this.maximizeBtn,"click",lang.hitch(this,"maximize"));
domConstruct.place(this.closeBtn, lTitlePane, "after");
domConstruct.place(this.minimizeBtn, lTitlePane, "after");
domConstruct.place(this.maximizeBtn, lTitlePane, "after");
var lIconPane = query("#"+this.id+"_fPane")[0];
//var logoDiv = domConstruct.create('div',{class:this.floatIconStyle},lIconPane);
var logoDiv = domConstruct.create('div',{class:this.floatIconStyle},lIconPane);
var self = this;
},
show:function()
{
this.floatingPane.bringToTop();
this.maximize();
this.floatingPane.show();
this.visible = true;
},
close:function()
{
this.floatingPane.hide();
this.visible = false;
if (!this.minimized)
{
this.contentWidth = this.floatingPane.domNode.style.width;
this.contentHeight = this.floatingPane.domNode.style.height;
}
},
minimize:function()
{
//store current sizing
this.contentWidth = this.floatingPane.domNode.style.width;
this.contentHeight = this.floatingPane.domNode.style.height;
this.minimized = true;
//minmize control
domStyle.set(this.floatingPane.domNode, "height", "25px");
domStyle.set(this.floatingPane.domNode, "width", "180px");
//remove resize control
domStyle.set(this.floatingPane.canvas.children[1],"visibility","hidden");
//swap buttons
domStyle.set(this.minimizeBtn,'visibility', 'hidden');
domStyle.set(this.maximizeBtn,'visibility', 'visible');
},
maximize:function()
{
//restore control
domStyle.set(this.floatingPane.domNode, "height", this.contentHeight);
domStyle.set(this.floatingPane.domNode, "width", this.contentWidth);
this.minimized = false;
//domStyle.set(this.floatingPane.canvas.children[0],'height', this.contentHeight);
//add resize control
domStyle.set(this.floatingPane.canvas.children[1],"visibility","visible");
//swap buttons
domStyle.set(this.minimizeBtn,'visibility', 'visible');
domStyle.set(this.maximizeBtn,'visibility', 'hidden');
}
});
});
- finally toolbarwidgets.js file for Create Dynamic toolbar menu Button
define(["dojo/_base/declare",
"dojo/_base/html",
"dojo/on",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
"dojo/text!./Toolbar/templates/buttons.html",
"dijit/form/Button",
"dojo/dom-construct",
"dojo/dom-class",
"dojo/dom-style",
'xstyle/css!./Toolbar/css/toolbar.css']
,function(declare, html, on, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, extentTemplate, Button,domConstruct,domClass,domStyle)
{
//function to load CSS files required for this module
(function () {
var css = [require.toUrl("gis/dijit/Toolbar/css/toolbar.css")];
var head = document.getElementsByTagName("head").item(0),
link;
for (var i = 0, il = css.length; i < il; i++) {
link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = css[i].toString();
head.appendChild(link);
}
}());
return declare("toolbarWidget", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin],
{
widgetsInTemplate: true,
templateString: extentTemplate,
baseClass: 'widgets_Toolbar',
buttonClass: 'extentButton',
leftButtonClass: 'slideLeftButton',
rightButtonClass: 'slideRightButton',
//mobileHelper: new MobileHelper(),
postCreate: function () {
debugger;
//initialize the widget
this.inherited(arguments);
//this.mobileHelper.collectInfo();
var availableWidth = this.getLayoutWidth();
var widgetDisplayWidth = 33 * this.widgets.length;
if ((this.widgets) && (this.widgets.length > 0)) {
for (var i in this.widgets)
{
var w = this.widgets[i];
var li = domConstruct.create("li");
domConstruct.place(w.domNode,li,'first');
this.toolList.appendChild(li);
}
}
this.setLayout();
var self = this;
//on(this.mobileHelper, "orientationChange", function (e) {
// self.setLayout();
//});
},
setLayout: function () {
if ((this.widgets) && (this.widgets.length > 0) && (this.widgets.length > this.showCount)) {
var availableWidth = this.getLayoutWidth();
var widgetDisplayWidth = 33 * this.widgets.length;
if (availableWidth < widgetDisplayWidth) {
domStyle.set(this.mask, "width", (33 * this.showCount) + "px");
domStyle.set(this.toolList, "width", (widgetDisplayWidth) + "px");
this.createKeyFramesRulesLeftRight((-34.5 * (this.widgets.length - this.showCount)));
domClass.replace(this.btnScrollRight, "scrollButton", "scrollButton hidden");
domClass.replace(this.btnScrollLeft, "scrollButton", "scrollButton hidden");
} else {
domStyle.set(this.mask, "width", (widgetDisplayWidth) + "px");
this.moveLeft();
domClass.replace(this.btnScrollRight, "scrollButton hidden", "scrollButton");
domClass.replace(this.btnScrollLeft, "scrollButton hidden", "scrollButton");
}
}
},
getLayoutWidth: function () {
//debugger;
var layoutBox = html.getMarginBox(this.map.id);
return layoutBox.w - 280;
},
moveLeft: function () {
var node = this.toolList;
domStyle.set(node, "MozAnimation", "cssAnimationLeft 1s 1 linear forwards");
domStyle.set(node, "WebkitAnimation", "cssAnimationLeft 1s 1 linear forwards");
domStyle.set(node, "OAnimation", "cssAnimationLeft 1s 1 linear forwards");
domStyle.set(node, "animation", "cssAnimationLeft 1s 1 linear forwards");
domStyle.set(node, "MozAnimationPlayState", "running");
domStyle.set(node, "WebkitAnimationPlayState", "running");
domStyle.set(node, "OAnimationPlayState", "running");
domStyle.set(node, "AnimationPlayState", "running");
},
stopMove: function () {
var node = this.toolList;
domStyle.set(node, "MozAnimationPlayState", "paused");
domStyle.set(node, "WebkitAnimationPlayState", "paused");
domStyle.set(node, "OAnimationPlayState", "paused");
domStyle.set(node, "AnimationPlayState", "paused");
},
moveRight: function () {
var node = this.toolList;
domStyle.set(node, "MozAnimation", "cssAnimationRight 1s 1 linear forwards");
domStyle.set(node, "WebkitAnimation", "cssAnimationRight 1s 1 linear forwards");
domStyle.set(node, "OAnimation", "cssAnimationRight 1s 1 linear forwards");
domStyle.set(node, "animation", "cssAnimationRight 1s 1 linear forwards");
domStyle.set(node, "MozAnimationPlayState", "running");
domStyle.set(node, "WebkitAnimationPlayState", "running");
domStyle.set(node, "OAnimationPlayState", "running");
domStyle.set(node, "AnimationPlayState", "running");
},
createKeyFramesRulesLeftRight: function (val) {
console.log(val);
// gather all stylesheets into an array
var head = document.getElementsByTagName("head").item(0);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-moz-keyframes cssAnimationLeft{' +
'0% { left: ' + val + 'px}' +
'100% { left: 0px; }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-webkit-keyframes cssAnimationLeft{' +
'0% { left: ' + val + 'px}' +
'100% { left: 0px; }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@keyframes cssAnimationLeft{' +
'0% { left: ' + val + 'px}' +
'100% { left: 0px; }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-moz-keyframes cssAnimationRight{' +
'0% { left: 0px}' +
'100% { left: ' + val + 'px }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode(' @-webkit-keyframes cssAnimationRight{' +
'0% { left: 0px}' +
'100% { left: ' + val + 'px }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode(' @keyframes cssAnimationRight{' +
'0% { left: 0px}' +
'100% { left: ' + val + 'px }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
},
createKeyFramesRulesUpDown: function (val) {
console.log(val);
// gather all stylesheets into an array
var head = document.getElementsByTagName("head").item(0);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-moz-keyframes cssAnimationUp{' +
'0% { top: ' + val + 'px}' +
'100% { top: 0px; }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-webkit-keyframes cssAnimationUp{' +
'0% { top: ' + val + 'px}' +
'100% { top: 0px; }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-moz-keyframes cssAnimationDown{' +
'0% { top: 0px}' +
'100% { top: ' + val + 'px }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode(' @-webkit-keyframes cssAnimationDown{' +
'0% { top: 0px}' +
'100% { top: ' + val + 'px }' +
'}');
cssAnimation.appendChild(rules);
head.appendChild(cssAnimation);
}
});
});

@mayur9785 Looks like a lot of interesting work.
It would be much easier to visualize this (and possibly contribute) if you provided a working example with demo in a github repo.
Also: check out my cmv-calcite-maps repo. All of the cmv core widgets are there in floating windows. They are not draggable windows since the calcite maps template doesn't currently support that. There were no modifications to titlePane widgets required to include them in the floating window. There were no modifications to core CMV required. Only a few methods were overridden in the _CalciteMixin I recommend you follow a similar methodology in your approach to keep modifications to the core CMV to a minimum (or none, if possible). This allows for easier upgrades in the future.
I look forward to see your toolbar/window approach in action!
@tmcgee I have created repo CMVFloatingPane here to download the file. As of now it is working for Draw widget only and my priority is for LayerControl now, but its not loading into the Floating pane. Later I have plan to use other CMV widgets and WAB widgets in my app with the same Floating pane created dynamically and load the actual widgets in it.
Hi @mayur9785 please add all the individual files in the repo instead of a single rar file. That would greatly help myself and others that may want to contribute. :) Thanks.
Hi @tmcgee I have added the all files in repo CMV Floating Pane. Please have a look into that and help how other cmv widgets and WAB widgets we can load in Floating pane.
:) Thank you very much your support.