I'm trying to add a button to a custom pallete to call a function "uiFileInputDlg" which is in the workspace that uses the widget. The upbtn appears on the pallete, but it is not triggering the DoUpload function which is connected in postcreate to then call on "uiFileInputDlg".
works flawlessly in firefox.
we're user dojo 1.7.2
-----------THE TEMPLATE-------------------------
<div class="dijitInline dijitColorPalette">
<div class="dijitColorPaletteInner" data-dojo-attach-point="divNode" role="grid" tabIndex="${tabIndex}">
</div>
<button type="button" id="upbtn"
data-dojo-type="dijit.form.Button"
data-dojo-props="id:'upbtn'"
data-dojo-attach-point="btnUpNode">
Upload New Image
</button>
</div>
-------------------------THE WIDGET--------------------------
//dojo.provide("meemli.UploadPalette");
define([ 'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dojo/i18n!dijit/nls/common',
'dojo/text!./templates/UploadPalette.html',
'dijit/_WidgetsInTemplateMixin',
'dojo/_base/lang'
],
function(declare, w, t, i18n, template, witm, lang){
console.log('meemli.UploadPalette: Requiring dijit/nls/common.js INSTEAD OF dojo/nls/common' + i18n.invalidMessage);
return declare("meemli.UploadPalette",
[dijit._Widget, dijit._Templated],
{
// summary: A keyboard accessible color-picking widget
// description:
// Grid showing various colors, so the user can pick a certain color
// Can be used standalone, or as a popup.
//
// example:
// | <div dojoType="dijit.ColorPalette"></div>
//
// example:
// | var picker = new dijit.ColorPalette({ },srcNode);
// | picker.startup();
//
// defaultTimeout: Number
// number of milliseconds before a held key or button becomes typematic
defaultTimeout: 500,
// timeoutChangeRate: Number
// fraction of time used to change the typematic timer between events
// 1.0 means that each typematic event fires at defaultTimeout intervals
// < 1.0 means that each typematic event fires at an increasing faster rate
timeoutChangeRate: 0.90,
// palette: String
// Size of grid, either "7x10" or "3x4".
palette: "3x3",
//_value: String
// The value of the selected color.
value: null,
//_currentFocus: Integer
// Index of the currently focused color.
_currentFocus: 0,
// _xDim: Integer
// This is the number of colors horizontally across.
_xDim: null,
// _yDim: Integer
/// This is the number of colors vertically down.
_yDim: null,
// _palettes: Map
// This represents the value of the colors.
// The first level is a hashmap of the different arrays available
// The next two dimensions represent the columns and rows of colors.
_palettes: {
"3x3": [],
"3x2": ["/images/icons/1.png", "/images/icons/2.png", "/images/icons/3.png","/images/icons/4.png", "/images/icons/5.png", "/images/icons/6.png"]
},
// _imagePaths: Map
// This is stores the path to the palette images
// _imagePaths: {
// "3x3": dojo.moduleUrl("dijit", "templates/icons3x3.png")
// },
// _paletteCoords: Map
// This is a map that is used to calculate the coordinates of the
// images that make up the palette.
_paletteCoords: {
"leftOffset": 3, "topOffset": 3,
"cWidth": 50, "cHeight": 50
},
// templatePath: String
// Path to the template of this widget.
// templateString: dojo.cache("meemli", "templates/UploadPalette.html"),
templateString: template,
// _paletteDims: Object
// Size of the supported palettes for alignment purposes.
_paletteDims: {
"3x3": {"width": "156px", "height": "156px"}, // 48*3 + 3px left/top border + 3px right/bottom border...
"3x2": {"width": "156px", "height": "109px"} // 48*3 + 3px left/top border + 3px right/bottom border...
},
// tabIndex: String
// Widget tabindex.
maxCols: 3,
tabIndex: "0",
_curIndex: 0,
DoUpload: function(){
alert('hello');
uiFileInputDlg(); // function out in the workspace
},
_addImage: function(url) {
row = Math.floor(this._curIndex / this.maxCols);
col = this._curIndex - (row * this.maxCols);
this._curIndex++;
this._yDim = Math.floor(this._curIndex / this.maxCols);
this._xDim = this._curIndex - (row * this.maxCols);
var imgNode = dojo.doc.createElement("img");
imgNode.src = url;
//imgNode.style.height = imgNode.style.width = "48px";
var cellNode = dojo.doc.createElement("span");
cellNode.appendChild(imgNode);
cellNode.connectionRefs = new Array();
dojo.forEach(["Dijitclick", "MouseEnter", "Focus", "Blur"], function(handler) {
cellNode.connectionRefs.push(this.connect(cellNode, "on" + handler.toLowerCase(), "_onCell" + handler));
}, this);
this.divNode.appendChild(cellNode);
var cellStyle = cellNode.style;
cellStyle.top = this._paletteCoords.topOffset + (row * this._paletteCoords.cHeight) + "px";
cellStyle.left = this._paletteCoords.leftOffset + (col * this._paletteCoords.cWidth) + "px";
cellStyle.height = this._paletteCoords.cHeight + "px";
cellStyle.width = this._paletteCoords.cWidth + "px";
// console.debug( "tlhw: " + cellStyle.top + ", " + cellStyle.left + ", " + cellStyle.height + ", " + cellStyle.width );
// adjust size when the bits come...
// this.xh = this.xw = "32px";
//console.log('this.xh => ' + this.xh);
dojo.connect( imgNode,"onload", this, function() {
//console.log('IN: CONNECT...this.xh => ' + this.xh);
this.xh = imgNode.height;
this.xw = imgNode.width;
this.xh = (this.xh==0) ? this.xh="32px" : (this.xh + "");
this.xw = (this.xw==0) ? this.xw="32px" : (this.xw + "");
// var h = parseInt( this.xh );
// var w = parseInt( this.xw );
var hArr = this.xh.split('p');
var wArr = this.xw.split('p');
var h =hArr[0];
var w = wArr[0];
var THUMBNAIL_MAX_WIDTH = 50;
var THUMBNAIL_MAX_HEIGHT = 50;
var hLim = Math.min(THUMBNAIL_MAX_HEIGHT, this._paletteCoords.cHeight);
var wLim = Math.min(THUMBNAIL_MAX_WIDTH, this._paletteCoords.cWidth);
var scale = 1.0;
if( h > hLim || w > wLim ) {
if( h / w < 1.0 ) { // width is bigger than height
scale = wLim / w;
}
else {
scale = hLim / h;
}
}
imgNode.style.height = (scale * h) + "px";
imgNode.style.width = (scale * w) + "px";
console.debug( imgNode.src + ' loaded.'
+ "old: h " + h + ", w " + w + ", scale " + scale
+ ". new: h " + imgNode.style.height + ", w " + imgNode.style.width );
} );
if(dojo.isIE){
// hack to force event firing in IE
// image quirks doc'd in dojox/image/Lightbox.js :: show: function.
// imgNode.src = imgNode.src;
}
dojo.attr(cellNode, "tabindex", "-1");
dojo.addClass(cellNode, "imagePaletteCell");
dijit.setWaiRole(cellNode, "gridcell");
cellNode.index = this._cellNodes.length;
this._cellNodes.push(cellNode);
},
_clearImages: function() {
for(var i = 0; i < this._cellNodes.length; i++) {
this._cellNodes[i].parentNode.removeChild(this._cellNodes[i]);
}
this._currentFocus = 0;
this._curIndex = 0;
this._yDim = 0;
this._xDim = 0;
this._cellNodes = [];
},
setImages: function(imageList) {
this._clearImages();
for(var i = 0; i < imageList.length; i++) {
this._addImage(imageList[i]);
}
},
postCreate: function(){
// A name has to be given to the colorMap, this needs to be unique per Palette.
dojo.mixin(this.divNode.style, this._paletteDims[this.palette]);
// this.imageNode.setAttribute("src", this._imagePaths[this.palette]);
this.domNode.style.position = "relative";
this._cellNodes = [];
this.setImages(this._palettes[this.palette]);
this.connect(this.divNode, "onfocus", "_onDivNodeFocus");
this.connect(this.btnUpNode, "onclick", "DoUpload");
// Now set all events
// The palette itself is navigated to with the tab key on the keyboard
// Keyboard navigation within the Palette is with the arrow keys
// Spacebar selects the color.
// For the up key the index is changed by negative the x dimension.
var keyIncrementMap = {
UP_ARROW: -this._xDim,
// The down key the index is increase by the x dimension.
DOWN_ARROW: this._xDim,
// Right and left move the index by 1.
RIGHT_ARROW: 1,
LEFT_ARROW: -1
};
for(var key in keyIncrementMap){
this._connects.push(dijit.typematic.addKeyListener(this.domNode,
{keyCode:dojo.keys[key], ctrlKey:false, altKey:false, shiftKey:false},
this,
function(){
var increment = keyIncrementMap[key];
return function(count){ this._navigateByKey(increment, count); };
}(),
this.timeoutChangeRate, this.defaultTimeout));
}
},
focus: function(){
// summary:
// Focus this ColorPalette. Puts focus on the first swatch.
this._focusFirst();
},
onChange: function(url, hsz, wsz){
// summary:
// Callback when a image is selected.
// url, hsz, wsz, strings
// height and width string .
// console.debug("img selected: "+url);
},
_focusFirst: function(){
this._currentFocus = 0;
var cellNode = this._cellNodes[this._currentFocus];
window.setTimeout(function(){dijit.focus(cellNode);}, 0);
},
_onDivNodeFocus: function(evt){
// focus bubbles on Firefox 2, so just make sure that focus has really
// gone to the container
if(evt.target === this.divNode){
this._focusFirst();
}
},
_onFocus: function(){
// while focus is on the palette, set its tabindex to -1 so that on a
// shift-tab from a cell, the container is not in the tab order
dojo.attr(this.divNode, "tabindex", "-1");
},
_onBlur: function(){
this._removeCellHighlight(this._currentFocus);
// when focus leaves the palette, restore its tabindex, since it was
// modified by _onFocus().
dojo.attr(this.divNode, "tabindex", this.tabIndex);
},
_onCellDijitclick: function(/*Event*/ evt){
// summary:
// Handler for click, enter key & space key. Selects the color.
// evt:
// The event.
var target = evt.currentTarget;
if (this._currentFocus != target.index){
this._currentFocus = target.index;
window.setTimeout(function(){dijit.focus(target);}, 0);
}
this._selectColor(target);
dojo.stopEvent(evt);
},
_onCellMouseEnter: function(/*Event*/ evt){
// summary:
// Handler for onMouseOver. Put focus on the color under the mouse.
// evt:
// The mouse event.
var target = evt.currentTarget;
window.setTimeout(function(){dijit.focus(target);}, 0);
},
_onCellFocus: function(/*Event*/ evt){
// summary:
// Handler for onFocus. Removes highlight of
// the color that just lost focus, and highlights
// the new color.
// evt:
// The focus event.
this._removeCellHighlight(this._currentFocus);
this._currentFocus = evt.currentTarget.index;
dojo.addClass(evt.currentTarget, "imagePaletteCellHighlight");
},
_onCellBlur: function(/*Event*/ evt){
// summary:
// needed for Firefox 2 on Mac OS X
this._removeCellHighlight(this._currentFocus);
},
_removeCellHighlight: function(index){
dojo.removeClass(this._cellNodes[index], "imagePaletteCellHighlight");
},
_selectColor: function(selectNode){
// summary:
// This selects a color. It triggers the onChange event
// area:
// The area node that covers the color being selected.
var img = selectNode.getElementsByTagName("img")[0];
this.onChange(this.value = img.src, this.xh, this.xw);
},
_navigateByKey: function(increment, typeCount){
// summary:
// This is the callback for typematic.
// It changes the focus and the highlighed color.
// increment:
// How much the key is navigated.
// typeCount:
// How many times typematic has fired.
// typecount == -1 means the key is released.
if(typeCount == -1){ return; }
var newFocusIndex = this._currentFocus + increment;
if(newFocusIndex < this._cellNodes.length && newFocusIndex > -1)
{
var focusNode = this._cellNodes[newFocusIndex];
focusNode.focus();
}
}
});
});
Update
this.connect(this.btnUpNode, "onclick", "DoUpload");
to be
this.connect(this.btnUpNode, "onClick", "DoUpload");
onclick is a dom event, onClick is a dijit event. Since you are using a dijit button you want to use the latter.
Related
I Have a Problem with my Script and hope helping me, and thanks in advance, i still learning javascript and try to learn somthing new everyday, i have a script that draw modeless interface (palette) and have button including (option) that make another new palette (for options), i made the variables as globals for the option palette, but the problem is the global variables is only called once!, and the script lose the global variable scope!.
enter image description here
so my question is how to make the variables not losing its scope and retain in the memory? as long the script run, as an Example if the user move the slider and hit (Show alert due options) its only run once and then lose the scope, even the slider no longer interact with the user and update text box, please test the code to see the problem, and thank again for any help or advice.
Best
M.Hasanain
//Global Variables only Called Once then Lost their Scope!
#targetengine "session1";
var w = new Window("palette", {independent:true}); //Main Palette Windows
var findoptions = new Window("palette"); //Options Palette
function Main() {
// Check to see whether any InDesign documents are open.
// If no documents are open, display an error message.
if (app.documents.length > 0) {
var myDoc = app.activeDocument;
}else{
// No documents are open, so display an error message.
alert("No InDesign documents are open. Please open a document and try again.");
}
}
//---------------------------------------------------------
//Making Palettes Windows
//---------------------------------------------------------
#targetengine "session1";
var w = new Window("palette", {independent:true}); //Main Palette Windows
var findoptions = new Window("palette"); //Options Palette
//gqmanager is the (GREP Query Manager) outside the main Function
w.text = "Test the Connection Between Global Variables and Palettes";
w.preferredSize.width = 500;
w.alignChildren = ["center", "center"]; //"left";
w.orientation = "column"; //"row";
w.spacing = 10;
w.margins = 16;
//Parent - Input Panel Prepare
var InputPanel = w.add("panel", undefined, undefined, { name: "panel1" });
InputPanel.text = "Text Find : ";
InputPanel.preferredSize.width = 1000;
InputPanel.orientation = "row";
InputPanel.alignChildren = ["center", "center"];
InputPanel.spacing = 10;
InputPanel.margins = 16;
//Children - input Panel Inside Prepare
var myInputPanelInside = InputPanel.add("group", undefined, { name: "myInput" });
//--Adding Find What
myInputPanelInside.add("statictext", undefined, "Find What :");
//myInputPanelInside.alignment = "center";
var myGREPString = myInputPanelInside.add("edittext", undefined, "SAMPLE");
myGREPString.helpTip = "Enter Your Text"
myGREPString.characters = 20;
myGREPString.enabled = true;
myGREPString.preferredSize.width = 460;
var Button1 = myInputPanelInside.add("button", undefined, "Options");
//Parent - Radio Panel Prepare
var RadioPanel = w.add("panel", undefined, undefined, { name: "panel2" });
RadioPanel.text = "Select Desired Option : ";
RadioPanel.preferredSize.width = 1000;
RadioPanel.orientation = "row";
RadioPanel.alignChildren = ["center", "center"];
RadioPanel.spacing = 10;
RadioPanel.margins = 16;
//Children - input Panel Inside Prepare
var myRadioPanelInside = RadioPanel.add("group", undefined, { name: "myRadio" });
myRadioPanelInside.preferredSize.width = 500;
myRadioPanelInside.alignChildren = ["center", "center"];
//Adding Radio Buttons
var radio1 = myRadioPanelInside.add("radiobutton", undefined, "Option 1");
var radio2 = myRadioPanelInside.add("radiobutton", undefined, "Option 2");
var radio3 = myRadioPanelInside.add("radiobutton", undefined, "Option 3");
radio1.preferredSize.width = 200;
radio2.preferredSize.width = 200;
radio3.preferredSize.width = 200;
//Previous Default Condition
radio1.value = true;
var myButtonGroup = w.add("group");
myButtonGroup.alignment = "center";
var Button2 = myButtonGroup.add("button", undefined, "Show Alert Due Options");
var Button3 = myButtonGroup.add("button", undefined, "Exit");
Button1.onClick = function () {
CalltheFindOptions();
}
Button2.onClick = function () { Find(); };
function Find() {
doRadioButtonOpt();
}
Button3.onClick = function() {Canceled();};
function Canceled() {
ExitSure();
}
//After Drawing Interface
var a = w.show();
function ExitSure() {
var a = w.close();
exit(0);
}
//User Selection for Radio Buttons
function doRadioButtonOpt() {
myDoc = app.activeDocument;
if (radio1.value == true) {
TestVars();
}
}
function TestVars() {
#targetengine "session1";
var myDoc = app.activeDocument
var TimeMs = Number(SliderControlText.text); //Converting Text to Number
//Show Results Found as User Wish
if (DontShowResults.value == true) { //no Show only Apply
alert("you Select not to Show Results!");
}else{ //Direct Show and Apply
if (ShowResultsDirect.value == true) {
alert("you Select to Show Results in real time!");
}else{ //Show and Apply By WaitinhTime!
if (ShowResults.value == true) { //Show and Apply
alert("you Select to Show Results with Specific time!");
$.sleep(TimeMs); //Wait ms
}
}
}
alert("Do you need somthing else?, try again", "Finish Report");
}
var DontShowResults;
var ShowResultsDirect;
var ShowResults;
var SliderControlText;
var slider;
//--------------------------------------------Building the Find Options Palette-----------------------------------------//
//--------------------------------------------------------------------------------------------------------------------------------//
function CalltheFindOptions() {
#targetengine "session1";
//Find Options Window
findoptions.text = "Find Options";
//Parent - Input Panel Prepare
SelectPanel = findoptions.add("panel", undefined, undefined, { name: "panel1" });
SelectPanel.text = " Find Options : ";
SelectPanel.preferredSize.width = 1000;
SelectPanel.orientation = "row";
SelectPanel.alignChildren = ["center", "center"];
SelectPanel.spacing = 10;
SelectPanel.margins = 16;
//Children - input Panel Inside Prepare
mySelectPanelInside = SelectPanel.add("group", undefined, { name: "mySelOpt" });
DontShowResults = mySelectPanelInside.add("checkbox", undefined, "Don't Show Results");
DontShowResults.value = true; //by Default
DontShowResults.alignment = "left";
ShowResultsDirect = mySelectPanelInside.add("checkbox", undefined, "Show Results");
ShowResultsDirect.value = false; //by Default
ShowResults = mySelectPanelInside.add("checkbox", undefined, "Show Results Delayed in milliseconds(Ms) :");
ShowResults.value = false; //by Default
//Adding Slider to Control MS Time
SliderControlText = mySelectPanelInside.add ("edittext", undefined, 10, {readonly: false}); //read only prevent user Entering Nums
SliderControlText.characters = 3;
slider = mySelectPanelInside.add ("slider {minvalue: 1, maxvalue: 100, value: 10}");
//Slider Listener Plus SliderControl Text Listener
slider.onChanging = function () {SliderControlText.text = slider.value;} //Listen to Slider
var c = findoptions.show();
}
If I understand you correctly you need to use as global variables values rather than the objects. And you can change the values of global variables by onClick events.
Here is the bottom part of your code (the rest part of the code wasn't changed):
...
function TestVars() {
#targetengine "session1";
var myDoc = app.activeDocument
var TimeMs = Number(SliderControlText_text); //Converting Text to Number
//Show Results Found as User Wish
if (DontShowResults_value == true) { //no Show only Apply
alert("you Select not to Show Results!");
} else { //Direct Show and Apply
if (ShowResultsDirect_value == true) {
alert("you Select to Show Results in real time!");
} else { //Show and Apply By WaitinhTime!
if (ShowResults_value == true) { //Show and Apply
alert("you Select to Show Results with Specific time!");
$.sleep(TimeMs); //Wait ms
}
}
}
alert("Do you need somthing else?, try again", "Finish Report");
}
// values! not objects
var DontShowResults_value = true;
var ShowResultsDirect_value = false;
var ShowResults_value = false;
var SliderControlText_text = '10';
var slider_value = 10;
//--------------------------------------------Building the Find Options Palette-----------------------------------------//
//--------------------------------------------------------------------------------------------------------------------------------//
function CalltheFindOptions() {
#targetengine "session1";
//Find Options Window
findoptions.text = "Find Options";
//Parent - Input Panel Prepare
SelectPanel = findoptions.add("panel", undefined, undefined, {
name: "panel1"
});
SelectPanel.text = " Find Options : ";
SelectPanel.preferredSize.width = 1000;
SelectPanel.orientation = "row";
SelectPanel.alignChildren = ["center", "center"];
SelectPanel.spacing = 10;
SelectPanel.margins = 16;
//Children - input Panel Inside Prepare
var mySelectPanelInside = SelectPanel.add("group", undefined, {
name: "mySelOpt"
});
var DontShowResults = mySelectPanelInside.add("checkbox", undefined, "Don't Show Results");
DontShowResults.value = DontShowResults_value; //by Default
DontShowResults.alignment = "left";
// change the global variable by click
DontShowResults.onClick = function() { DontShowResults_value = DontShowResults.value }
var ShowResultsDirect = mySelectPanelInside.add("checkbox", undefined, "Show Results");
ShowResultsDirect.value = false; //by Default
// change the global variable by click
ShowResultsDirect.onClick = function() { ShowResultsDirect_value = ShowResultsDirect.value }
var ShowResults = mySelectPanelInside.add("checkbox", undefined, "Show Results Delayed in milliseconds(Ms) :");
ShowResults.value = ShowResults_value; //by Default
// change the global variable by click
ShowResults.onClick = function() { ShowResults_value = ShowResults.value }
//Adding Slider to Control MS Time
// SliderControlText = mySelectPanelInside.add("edittext", undefined, 10, {
var SliderControlText = mySelectPanelInside.add("edittext", undefined, SliderControlText_text, {
readonly: false
}); //read only prevent user Entering Nums
SliderControlText.characters = 3;
var slider = mySelectPanelInside.add("slider {minvalue: 1, maxvalue: 100, value: 10}");
// change slider every time as numbers is changes
SliderControlText.onChanging = function() {slider.value = SliderControlText.text};
//Slider Listener Plus SliderControl Text Listener
slider.onChanging = function () {
SliderControlText.text = slider.value;
// change the global variable by onChange
SliderControlText_text = SliderControlText.text;
} //Listen to Slider
findoptions.show();
}
It seems it works as intended.
As far as I can tell (I can be wrong), the cause of the problem was that the objects ShowResultsDirect, ShowResultsDirect, etc, disappears as soon as you close the palette. Because they are elements of the palette. They can't keep values if the palette is closed. That why they worked well only when you open the palette first time.
I have an overlay control on my leaflet map in a vue.js application. It contains two layers. The ILZipCodes layer renders perfectly. However, the "markers" layer does not appear when I select the checkbox in the layer control. Why is this? I reckon I may be setting up the layer control and populating the clusters in the wrong sequence.
Cheers
<template>
<div>
<div class="mx-auto my-6 loader" v-if="isSearching"></div>
<div class="tooManyResultsError" v-if="tooManyResults">
Your search brought back too many results to display. Please zoom in or refine your search with the text box and
filters.
</div>
<div id="leafletMapId"></div>
</div>
</template>
<script>
//The center coordinate and zoom level that the map should initialize to
// to capture all of the continental United States
const INITIAL_CENTER_LATITUDE = 34;
const INITIAL_CENTER_LONGITUDE = -96;
const INITIAL_ZOOM = 4;
/* Leaflet performs slowly with reactivity ("observable" data object variables).
* To work around this, I removed myMap and markers from the data object.
*/
/* If the user zooms out or pans beyond the boundaries of the previous fetch's dataset, then
* the client fetches location data from the server to replace the previous map data. If the user
* zooms or pans but stays within the boundaries of the dataset currently displayed on the map, then
* the client does not run another fetch.
* */
import axios from "axios";
import store from "../store.js";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
import "leaflet.markercluster/dist/leaflet.markercluster-src.js";
import "leaflet-ajax/dist/leaflet.ajax.js";
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
export default {
name: "ContactsMap",
mounted() {
this.fetchAggregatedDistrictStats();
},
methods: {
async fetchAggregatedDistrictStats() {
axios.get(... // fetches some statistics for the other overlay layers
);
},
createMapWithLeafletAndMapTiler() {
var $this = this;
var streetTilesLayer = L.tileLayer(MAPTILER_STREETS_URL, {
maxZoom: 18,
minZoom: 2,
attribution: MAPBOX_ATTRIBUTION,
tileSize: 512,
zoomOffset: -1
});
// eslint-disable-next-line
var satelliteTilesLayer = L.tileLayer(MAPTILER_SATELLITE_URL, {
maxZoom: 18,
minZoom: 2,
tileSize: 512,
zoomOffset: -1
});
var baseMaps = {
Satellite: satelliteTilesLayer,
Streets: streetTilesLayer
};
if (myMap != undefined) {
myMap.remove();
}
var myMap = L.map("leafletMapId", {
layers: [streetTilesLayer],
}).setView(this.center, this.zoom);
var markers = L.markerClusterGroup({
iconCreateFunction: function(cluster) {
var count = cluster.getChildCount();
var digits = (count + "").length;
return L.divIcon({
html: "<b>" + count + "</b>" + digits,
className: "cluster digits-" + digits,
iconSize: 22 + 10 * digits
});
}
});
async function fetchLocations(shouldProgrammaticallyFitBounds) {
markers.clearLayers();
markers = L.markerClusterGroup({
chunkedLoading: true,
iconCreateFunction: function(cluster) {
var count = cluster.getChildCount();
var digits = (count + "").length;
return L.divIcon({
html: "<b>" + count + "</b>",
className: "cluster digits-" + digits,
iconSize: 22 + 10 * digits
});
}
});
axios
.get("/maps/" + $this.list.list_id, {
//fetches markerclusters
})
.then(
response => {
$this.tooManyResults = false;
var addressPoints = response.data.recordsList;
for (var i = 0; i < addressPoints.length; i++) {
var a = addressPoints[i];
var title = a[2];
var marker = L.marker(L.latLng(a[0], a[1]));
marker.bindPopup(title);
markers.addLayer(marker); // This is where I'm adding the markers and markerclusters to the layer titled "markers"
// myMap.addLayer(markers); //If I uncomment this, then the markers layer is always on the map, i.e. not as an overlay layer
}
},
error => {
$this.isSearching = false;
document.getElementById("leafletMapId").style.display = "block";
store.setErrorMessage("Network error searching list", error);
}
);
}
myMap.on("zoomend", handlerFunction);
myMap.on("dragend", handlerFunction);
var defaultPolygonStyle = {
color: "black",
weight: 1,
opacity: 0.8,
fillOpacity: 0.1
};
var NationalCongressional = new L.geoJson.ajax(
"http://localhost:8080/assets/geo/NationalCongressional.json",
{
style: defaultPolygonStyle,
onEachFeature: function(feature, layer) {
layer.bindPopup(feature.properties.NAMELSAD);
if (feature.properties.NAMELSAD == "Congressional District 8") {
layer.setStyle({ color: "orange" });
}
}
}
);
function getColorFromRedBlueRange(d) {
return d > 0.8
? "#FF0000"
: d > 0.7
? "#FF006F"
: d > 0.55
? "#FF00EF"
: d > 0.45
? "#DE00FF"
: d > 0.3
? "#BC00FF"
: d > 0.2
? "#6600FF"
: "#00009FF";
}
var ILZipCodes = new L.geoJson.ajax(
"https://raw.githubusercontent.com/OpenDataDE/State-zip-code-GeoJSON/master/il_illinois_zip_codes_geo.min.json",
{
// style: defaultPolygonStyle,
onEachFeature: function(feature, layer) {
layer.bindPopup(
feature.properties.ZCTA5CE10 +
", " +
$this.zipData[feature.properties.ZCTA5CE10]
);
layer.setStyle({
color: getColorFromRedBlueRange(
$this.zipData[feature.properties.ZCTA5CE10]
),
weight: 0,
fillOpacity: 0.3
});
}
}
);
var overlays = {
Voters: voterGroup,
ILZipCodes: ILZipCodes,
};
L.control.layers(baseMaps, overlays).addTo(myMap);
fetchLocations(true);
}
}
};
You add voterGroup to your Layers Control, instead of your markers.
Then simply do not re-assign a MarkerClusterGroup into your markers variable (after you use clearLayers) and you should be fine.
I have a question about the pie chart in c3.js.
How can I add the total count of a pie chart in the title??
var title = new Array('data1.sql','data2.sql')
var dtitle = new Array('title1','title2')
var chart = new Array('chart0', 'chart1')
for(var i = 0; i < title.length; i++){
chart[i] = c3.generate({
bindto : '#chart' + i,
size: {
height: 550,
width: 800
},
data : {
url : '/json/sql/data/test/' + title[i],
mimeType : 'json',
type : 'donut'
},
donut: {
title: dtitle[i] + ' - Total:' ,
label: {
format: function(value, ratio, id) {
return value;
}
}
}
});
}
The annoying thing here is that the title option can take a function, but the chart variable is not initialised within it so using the c3 api methods can't be done at this point.
So the best (maybe only) way is to add an onrendered callback that adds up the data as you'd need to anyways and then replace the text in the chart's title text using a spot of d3:
onrendered: function () {
var data = this.api.data();
var total = data.reduce (function (subtotal, t) {
return subtotal + t.values.reduce (function (subsubtotal,b) { return subsubtotal + b.value; }, 0);
}, 0);
d3.select(this.config.bindto + " .c3-chart-arcs-title").text("Total: "+total);
}
Edit: If you want it to keep track of a total as you hide/show series use this
var data = this.api.data.shown.call (this.api);
instead of
var data = this.api.data();
As I am new to KineticJs so, I have tried implementing the functionality using Kinectic js for drawing the multiple image on different- different x and y. Now I wanted to resize the stage layer or canvas. I have done that by using the code given below
window.onresize = function (event) {
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
var _images = layer.getChildren();
for (var i = 0; i < _images.length; i++) {
if (typeof _images[i].getId() != 'undefined') {
//alert(stage.getScale().x);
_images[i].setX(_images[i].getX() * stage.getScale().x);
layer.draw();
}
}
}
but now the problem is the are being defined and now if browser resize than stage is resized but the images on the prev x and y are fixed . I would like to keep them fixed on the position on resizing of stage layer or canvas.Here are the link of the image before resize and after resizing.beforeresize and afterResize .
Here is my entire code given below:-
$("#tabs li").each(function () {
$(this).live("click", function () {
clearInterval(_timer);
var tabname = $(this).find("a").attr('name');
tabname = $.trim(tabname.replace("#tab", ""));
var tabId = $(this).find("a").attr('href');
tabId = $.trim(tabId.replace("#", ""));
$.ajax({
url: "/Home/GetTabsDetail",
dataType: 'json',
type: 'GET',
data: { tabId: tabId },
cache: false,
success: function (data) {
var bayStatus = [];
var i = 0;
var image_array = [];
var BayExist = false;
var BayCondition;
var imgSrc;
var CanvasBacgroundImage;
var _X;
var _bayNumber;
var _Y;
var _ZoneName;
$(data).each(function (i, val) {
i = i + 1;
if (!BayExist) {
bayStatus = val.BayStatus;
CanvasBacgroundImage = val.TabImageLocation;
BayExist = true;
}
$.each(val, function (k, v) {
if (k == "BayNumber") {
BayCondition = bayStatus[v];
_bayNumber = v;
if (BayCondition == "O")
imgSrc = "../../images/Parking/OccupiedCar.gif"
else if (BayCondition == "N")
imgSrc = "../../images/Parking/OpenCar.gif";
}
if (k == "BayX")
_X = v;
if (k == "BayY")
_Y = v;
if (k == "ZoneName")
_ZoneName = v;
});
image_array.push({ img: imgSrc, xAxis: _X, yAxis: _Y, toolTip: _bayNumber, ZoneName: _ZoneName });
});
var imageUrl = CanvasBacgroundImage;
if ($('#tab' + tabId).length) {
// $('#tab' + tabId).css('background-image', 'url("../../images/Parking/' + imageUrl + '")');
var stage = new Kinetic.Stage({
container: 'tab' + tabId,
width: ($('#tab' + tabId).innerWidth() / 100) * 80, // 80% width of the window.
height: 308
});
window.onresize = function (event) {
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
}
$('#tab' + tabId).find('.kineticjs-content').css({ 'background-image': 'url("../../images/Parking/' + imageUrl + '")', 'background-repeat': ' no-repeat', 'background-size': '100% 100%' });
var layer = new Kinetic.Layer();
var planetOverlay;
function writeMessage(message, _x, _y) {
text.setX(_x + 20);
text.setY(_y + 1);
text.setText(message);
layer.draw();
}
var text = new Kinetic.Text({
fontFamily: 'Arial',
fontSize: 14,
text: '',
fill: '#000',
width: 200,
height: 60,
align: 'center'
});
var opentooltip = new Opentip(
"div#tab" + tabId, //target element
"dummy", // will be replaced
"", // title
{
showOn: null // I'll manually manage the showOn effect
});
Opentip.styles.win = {
borderColor: "black",
shadow: false,
background: "#EAEAEA"
};
Opentip.defaultStyle = "win";
// _timer = setInterval(function () {
for (i = 0; i < image_array.length; i++) {
img = new Image();
img.src = image_array[i].img;
planetOverlay = new Kinetic.Image({
x: image_array[i].xAxis,
y: image_array[i].yAxis,
image: img,
height: 18,
width: 18,
id: image_array[i].toolTip,
name: image_array[i].ZoneName
});
planetOverlay.on('mouseover', function () {
opentooltip.setContent("<span style='color:#87898C;'><b>Bay:</b></span> <span style='color:#25A0D3;'>" + this.getId() + "</span><br> <span style='color:#87898C;'><b>Zone:</b></span><span style='color:#25A0D3;'>" + this.getName() + "</span>");
//writeMessage("Bay: " + this.getId() + " , Zone: " + this.getName(), this.getX(), this.getY());//other way of showing tooltip
opentooltip.show();
$("#opentip-1").offset({ left: this.getX(), top: this.getY() });
});
planetOverlay.on('mouseout', function () {
opentooltip.hide();
// writeMessage('');
});
planetOverlay.createImageHitRegion(function () {
layer.draw();
});
layer.add(planetOverlay);
layer.add(text);
stage.add(layer);
}
// clearInterval(_timer);
//$("#tab3 .kineticjs-content").find("canvas").css('background-image', 'url("' + imageUrl + '")');
// },
// 500)
}
}
,
error: function (result) {
alert('error');
}
});
});
});
I want to keep the icons on the position where they were before resizing. I have tried but could not get the right solution to get this done.
How can How can I update x,y position for the images . Any suggestions would be appreciated.
Thanks is advance.
In window.resize, you're changing the stage width by a scaling factor.
Save that scaling factor.
Then multiply the 'x' coordinate of your images by that scaling factor.
You can reset the 'x' position of your image like this:
yourImage.setX( yourImage.getX() * scalingFactor );
layer.draw();
In the above mentioned code for window.onresize. The code has been modified which as follow:-
window.onresize = function (event) {
_orignalWidth = stage.getWidth();
var _orignalHeight = stage.getHeight();
// alert(_orignalWidth);
// alert($('#tab' + tabId).outerHeight());
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
//stage.setHeight(($('#tab' + tabId).outerHeight() / 100) * 80);
_resizedWidth = stage.getWidth();
_resizedHeight = stage.getHeight();
// alert(_resizedWidth);
_scaleFactorX = _resizedWidth / _orignalWidth;
var _scaleFactorY = _resizedHeight / _orignalHeight;
//alert(_scaleFactor);
var _images = layer.getChildren();
for (var i = 0; i < _images.length; i++) {
if (typeof _images[i].getId() != 'undefined') {
//alert(stage.getScale().x);
_images[i].setX(_images[i].getX() * _scaleFactorX);
//_images[i].setY(_images[i].getY() * _scaleFactorY);
layer.draw();
}
}
}
I have a search page in which I am displaying properties from my database as markers in google map. Now I want to modify this search page so that any user will draw either a circle or polygon in the google map and will get properties from our database only in the selected area (drawn by user itself). I am attaching my code so far here.
The circle in the image shows the selected area and the result must display properties available in the selected region. My table contains 2 different fields for latitude and longitude of each property.
Javascript code:
<script type="text/javascript">
var drawingManager;
var all_overlays = [];
var selectedShape;
var colors = ['#1E90FF', '#FF1493', '#32CD32', '#FF8C00', '#4B0082'];
var selectedColor;
var colorButtons = {};
function clearSelection() {
if (selectedShape) {
selectedShape.setEditable(false);
selectedShape = null;
}
}
function setSelection(shape) {
clearSelection();
selectedShape = shape;
shape.setEditable(true);
selectColor(shape.get('fillColor') || shape.get('strokeColor'));
}
function deleteSelectedShape() {
if (selectedShape) {
selectedShape.setMap(null);
}
}
function deleteAllShape() {
for (var i = 0; i < all_overlays.length; i++) {
all_overlays[i].overlay.setMap(null);
}
all_overlays = [];
}
function selectColor(color) {
selectedColor = color;
for (var i = 0; i < colors.length; ++i) {
var currColor = colors[i];
colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
}
// Retrieves the current options from the drawing manager and replaces the
// stroke or fill color as appropriate.
var polylineOptions = drawingManager.get('polylineOptions');
polylineOptions.strokeColor = color;
drawingManager.set('polylineOptions', polylineOptions);
var rectangleOptions = drawingManager.get('rectangleOptions');
rectangleOptions.fillColor = color;
drawingManager.set('rectangleOptions', rectangleOptions);
var circleOptions = drawingManager.get('circleOptions');
circleOptions.fillColor = color;
drawingManager.set('circleOptions', circleOptions);
var polygonOptions = drawingManager.get('polygonOptions');
polygonOptions.fillColor = color;
drawingManager.set('polygonOptions', polygonOptions);
}
function setSelectedShapeColor(color) {
if (selectedShape) {
if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
selectedShape.set('strokeColor', color);
} else {
selectedShape.set('fillColor', color);
}
}
}
function makeColorButton(color) {
var button = document.createElement('span');
button.className = 'color-button';
button.style.backgroundColor = color;
google.maps.event.addDomListener(button, 'click', function () {
selectColor(color);
setSelectedShapeColor(color);
});
return button;
}
function buildColorPalette() {
var colorPalette = document.getElementById('color-palette');
for (var i = 0; i < colors.length; ++i) {
var currColor = colors[i];
var colorButton = makeColorButton(currColor);
colorPalette.appendChild(colorButton);
colorButtons[currColor] = colorButton;
}
selectColor(colors[0]);
}
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: new google.maps.LatLng(22, 77),
mapTypeId: google.maps.MapTypeId.HYBRID,
disableDefaultUI: true,
zoomControl: true
});
var polyOptions = {
strokeWeight: 0,
fillOpacity: 0.45,
editable: true
};
// Creates a drawing manager attached to the map that allows the user to draw
// markers, lines, and shapes.
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.POLYGON,
markerOptions: {
draggable: true
},
polylineOptions: {
editable: true
},
rectangleOptions: polyOptions,
circleOptions: polyOptions,
polygonOptions: polyOptions,
map: map
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
all_overlays.push(e);
if (e.type != google.maps.drawing.OverlayType.MARKER) {
// Switch back to non-drawing mode after drawing a shape.
drawingManager.setDrawingMode(null);
// Add an event listener that selects the newly-drawn shape when the user
// mouses down on it.
var newShape = e.overlay;
newShape.type = e.type;
google.maps.event.addListener(newShape, 'click', function () {
setSelection(newShape);
});
setSelection(newShape);
}
});
// Clear the current selection when the drawing mode is changed, or when the
// map is clicked.
google.maps.event.addListener(drawingManager, 'drawingmode_changed', clearSelection);
google.maps.event.addListener(map, 'click', clearSelection);
google.maps.event.addDomListener(document.getElementById('delete-button'), 'click', deleteSelectedShape);
google.maps.event.addDomListener(document.getElementById('delete-all-button'), 'click', deleteAllShape);
buildColorPalette();
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
The code above contains some events to handle the user interaction in search page to draw cirle,polygone to search property in selected region.
The display property button in the image must show property markers in the selected area.
How would I get the latitude and longitude of selected area of circle or polygon?
How Would I query my database for that range of co-ordinates?
Thanking you very much in advance for your kind help...
I suppose you have found a solution since you post this question.
However, if someone else needs an answer, this is how you can get lat / lng of a drawing polygon :
google.maps.event.addDomListener(drawingManager, 'polygoncomplete', function(polygon) {
var polygonBounds = polygon.getPath();
}
The bounds of each vertices of your polygon are now in polygonBounds, just iterate over it and do what you want with lat / lng
For a circle, you just need lat / lng of the center, and its radius
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
var radius = circle.getRadius();
var center = circle.getCenter();
}
Hope it can help someone
PS : I'm using GoogleMaps v3.14, I never test with other versions.