Git Product home page Git Product logo

Comments (7)

jgravois avatar jgravois commented on August 26, 2024

thanks for taking the time to report your findings. this is because map.geographicExtent (in the API itself) is only available for web mercator applications. the relevant code in the template is here

Its possible to enhance to add similar support for other coordinate systems, but it would require a fairly significant refactor and an external request to a external geometry service to retrieve lat/longs.

from viewer.

tscharff avatar tscharff commented on August 26, 2024

Thank you for the quick reply.

Yeah, that was my guess, but there were 2 contributing factors that made it less clear: I couldn't find documentation about it for the Basic Viewer (and Classic Viewer); and the share function works as expected for the webmap, itself (inside the map viewer).

We are trying to deploy an application that will display capital projects throughout a service area. Our webmaster would like to launch the app from a list of projects... when the user clicks on a project, the app will open with the map automatically zoomed to the project area. I was originally trying to find a way to zoom to a feature using URL parameters, but was willing to use the extent as a workaround. Without the capability, the webmaster is proposing to use Google maps.

If URL parameters for zoom to extent represents a significant effort for other coordinate systems, perhaps the effort to implement URL parameters for zoom to feature would require much less effort (since the app is already capable of zooming to features via context menu and pop-ups, etc).

Below are a few links to related ArcGIS Ideas... it appears there is support from the user community to add related functionality.

ArcGIS Idea for consistent share function...
https://c.na9.visual.force.com/apex/ideaView?id=087E00000005Aw7IAE

ArcGIS Ideas for URL parameters to zoom to feature...
https://c.na9.visual.force.com/apex/ideaView?id=087E00000005IDR&returnUrl=%2Fapex%2FideaList%3Fc%3D09a300000004xET%26category%3DArcGIS%2BOnline

https://c.na9.visual.force.com/apex/ideaView?id=08730000000bsud&returnUrl=%2Fapex%2FideaList%3Fc%3D09a300000004xET%26category%3DArcGIS%2BOnline

from viewer.

jgravois avatar jgravois commented on August 26, 2024

we appreciate the feedback @tscharff. that type of functionality could make its way into the Viewer in a future release, but the code itself is extensible and written using your JavaScript API so you are welcome to incorporate it in your own project immediately.

the code i referenced in my earlier reply demonstrates how to parse values from a url query so please feel free to use it as an example if you'd like to incorporate your own alternative custom logic.

from viewer.

kellyhutchins avatar kellyhutchins commented on August 26, 2024

@tscharff There may be some options for working around this issue I'd just like to understand a bit more about your map. Are you using the hosted template or have you downloaded the code and have it hosted on your own web server? Do you add your locally hosted service to the map after its created?

from viewer.

tscharff avatar tscharff commented on August 26, 2024

We are using a hosted template.

I created a new webmap that uses a locally hosted (non ArcGIS.com) basemap, and that also contains our locally hosted service containing the capital projects. (Both services are in a state plane projection.) Afterward, I saved the map, and then created the web map application based on a template.

Hope that helps. If you need more info, please let me know. Thanks!

from viewer.

kellyhutchins avatar kellyhutchins commented on August 26, 2024

@tscharff I have an updated version of ShareDialog.js that I think will work for your situation. Can you test and let me know? If it does work for you I'll work on incorporating this logic (after more testing on my end) into the Viewer template for the next release.

define(["dojo/Evented", "dojo/_base/declare", "dojo/Deferred", "dojo/_base/lang", "dojo/has", "esri/kernel", "esri/config", "esri/SpatialReference", "dijit/_WidgetBase", "dijit/a11yclick", "dijit/_TemplatedMixin", "dojo/on",
// load template
"dojo/text!application/dijit/templates/ShareDialog.html", "dojo/i18n!application/nls/ShareDialog", "dojo/dom-class", "dojo/dom-style", "dojo/dom-attr", "dojo/dom-construct", "esri/request", "esri/urlUtils", "dijit/Dialog", "dojo/number", "dojo/_base/event"], function (
Evented, declare, Deferred, lang, has, esriNS, esriConfig, SpatialReference, _WidgetBase, a11yclick, _TemplatedMixin, on, dijitTemplate, i18n, domClass, domStyle, domAttr, domConstruct, esriRequest, urlUtils, Dialog, number, event) {
    var Widget = declare("esri.dijit.ShareDialog", [_WidgetBase, _TemplatedMixin, Evented], {
        templateString: dijitTemplate,
        options: {
            theme: "ShareDialog",
            dialog: null,
            useExtent: false,
            map: null,
            url: window.location.href,
            image: "",
            title: window.document.title,
            summary: "",
            hashtags: "",
            mailURL: "mailto:%20?subject={title}&body={summary}%20{url}",
            facebookURL: "https://www.facebook.com/sharer/sharer.php?s=100&p[url]={url}&p[images][0]={image}&p[title]={title}&p[summary]={summary}",
            twitterURL: "https://twitter.com/intent/tweet?url={url}&text={title}&hashtags={hashtags}",
            googlePlusURL: "https://plus.google.com/share?url={url}",
            bitlyAPI: location.protocol === "https:" ? "https://api-ssl.bitly.com/v3/shorten" : "http://api.bit.ly/v3/shorten",
            bitlyLogin: "",
            bitlyKey: "",
            embedSizes: [{
                "width": "100%",
                "height": "640px"
            },
            {
                "width": "100%",
                "height": "480px"
            },
            {
                "width": "100%",
                "height": "320px"
            },
            {
                "width": "800px",
                "height": "600px"
            },
            {
                "width": "640px",
                "height": "480px"
            },
            {
                "width": "480px",
                "height": "320px"
            }]
        },
        // lifecycle: 1
        constructor: function (options, srcRefNode) {
            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);
            // widget node
            this.domNode = srcRefNode;
            this._i18n = i18n;
            // properties
            this.set("theme", defaults.theme);
            this.set("url", defaults.url);
            this.set("visible", defaults.visible);
            this.set("dialog", defaults.dialog);
            this.set("embedSizes", defaults.embedSizes);
            this.set("embedHeight", defaults.embedHeight);
            this.set("embedWidth", defaults.embedWidth);
            this.set("mailURL", defaults.mailURL);
            this.set("facebookURL", defaults.facebookURL);
            this.set("twitterURL", defaults.twitterURL);
            this.set("googlePlusURL", defaults.googlePlusURL);
            this.set("bitlyAPI", defaults.bitlyAPI);
            this.set("bitlyLogin", defaults.bitlyLogin);
            this.set("bitlyKey", defaults.bitlyKey);
            this.set("image", defaults.image);
            this.set("title", defaults.title);
            this.set("summary", defaults.summary);
            this.set("hashtags", defaults.hashtags);
            this.set("useExtent", defaults.useExtent);
            // listeners
            this.watch("theme", this._updateThemeWatch);
            this.watch("url", this._updateUrl);
            this.watch("visible", this._visible);
            this.watch("embedSizes", this._setSizeOptions);
            this.watch("embed", this._updateEmbed);
            this.watch("bitlyUrl", this._updateBitlyUrl);
            this.watch("useExtent", this._useExtentChanged);
            // classes
            this.css = {
                container: "button-container",
                embed: "embed-page",
                button: "toggle-grey",
                buttonSelected: "toggle-grey-on",
                icon: "icon-share",
                linkIcon: "icon-link share-dialog-icon",
                facebookIcon: "icon-facebook-squared share-dialog-icon",
                twitterIcon: "icon-twitter share-dialog-icon",
                gplusIcon: "icon-gplus share-dialog-icon",
                emailIcon: "icon-mail-alt share-dialog-icon",
                mapSizeLabel: "map-size-label",
                shareMapURL: "share-map-url",
                iconContainer: "icon-container",
                embedMapSizeDropDown: "embed-map-size-dropdown",
                shareDialogContent: "dialog-content",
                shareDialogSubHeader: "share-dialog-subheader",
                shareDialogTextarea: "share-dialog-textarea",
                shareDialogExtent: "share-dialog-extent",
                shareDialogExtentChk: "share-dialog-checkbox",
                mapSizeContainer: "map-size-container",
                embedMapSizeClear: "embed-map-size-clear",
                iconClear: "icon-clear"
            };
        },
        // bind listener for button to action
        postCreate: function () {
            this.inherited(arguments);
            this._setExtentChecked();
            this._shareLink();
            this.own(on(this._extentInput, a11yclick, lang.hitch(this, this._useExtentUpdate)));
        },
        // start widget. called by user
        startup: function () {
            this._init();

        },
        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function () {
            this.inherited(arguments);
        },
        /* ---------------- */
        /* Public Events */
        /* ---------------- */
        // load
        /* ---------------- */
        /* Public Functions */
        /* ---------------- */


        /* ---------------- */
        /* Private Functions */
        /* ---------------- */
        _setExtentChecked: function () {
            domAttr.set(this._extentInput, "checked", this.get("useExtent"));
        },
        _useExtentUpdate: function () {
            var value = domAttr.get(this._extentInput, "checked");
            this.set("useExtent", value);
        },
        _useExtentChanged: function () {
            this._updateUrl();
            this._shareLink();
        },
        _setSizeOptions: function () {
            // clear select menu
            this._comboBoxNode.innerHTML = "";
            // if embed sizes exist
            if (this.get("embedSizes") && this.get("embedSizes").length) {
                // map sizes
                for (var i = 0; i < this.get("embedSizes").length; i++) {
                    if (i === 0) {
                        this.set("embedWidth", this.get("embedSizes")[i].width);
                        this.set("embedHeight", this.get("embedSizes")[i].height);
                    }
                    var option = domConstruct.create("option", {
                        value: i,
                        innerHTML: this.get("embedSizes")[i].width + " x " + this.get("embedSizes")[i].height
                    });
                    domConstruct.place(option, this._comboBoxNode, "last");
                }
            }
        },
        _updateUrl: function () {
            // nothing currently shortened
            this._shortened = null;
            // no bitly shortened
            this.set("bitlyUrl", null);
            // vars
            var map = this.get("map"),
                url = this.get("url"),
                useSeparator;
            // get url params
            var urlObject = urlUtils.urlToObject(window.location.href);
            urlObject.query = urlObject.query || {};
            urlObject.query.extent = null;
            // include extent in url
/* if (this.get("useExtent") && map) {
                    this._projectGeometry(map);
                }*/
            this._projectGeometry().then(lang.hitch(this, function (result) {
                if (result) {
                    var gExtent = result;
                    urlObject.query.extent = gExtent.xmin.toFixed(4) + ',' + gExtent.ymin.toFixed(4) + ',' + gExtent.xmax.toFixed(4) + ',' + gExtent.ymax.toFixed(4);
                }
                // create base url
                url = window.location.protocol + "//" + window.location.host + window.location.pathname;
                // each param
                for (var i in urlObject.query) {
                    if (urlObject.query[i]) {
                        // use separator 
                        if (useSeparator) {
                            url += "&";
                        } else {
                            url += "?";
                            useSeparator = true;
                        }
                        url += i + "=" + urlObject.query[i];
                    }
                }
                // update url
                this.set("url", url);
                // reset embed code
                this._setEmbedCode();
                // set url value
                domAttr.set(this._shareMapUrlText, "value", url);
                domAttr.set(this._linkButton, "href", url);
            }));

        },
        _projectGeometry: function () {
            var deferred = new Deferred();
            var map = this.get("map");
            if (this.get("useExtent") && map) {
                // get map extent in geographic
                if (map.geographicExtent) {
                    deferred.resolve(map.geographicExtent);
                    // var gExtent = map.geographicExtent;
                    // set extent string
                    //urlObject.query.extent = gExtent.xmin.toFixed(4) + ',' + gExtent.ymin.toFixed(4) + ',' + gExtent.xmax.toFixed(4) + ',' + gExtent.ymax.toFixed(4);
                } else {
                    //project the extent to geographic
                    var outSR = new SpatialReference({
                        "wkid": 4326
                    });
                    esriConfig.defaults.geometryService.project([map.extent], outSR).then(lang.hitch(this, function (result) {
                        if (result.length) {
                            var projectedExtent = result[0];
                            deferred.resolve(projectedExtent);
                            //urlObject.query.extent = projectedExtent.xmin.toFixed(4) + ',' + projectedExtent.ymin.toFixed(4) + ',' + projectedExtent.xmax.toFixed(4) + ',' + projectedExtent.ymax.toFixed(4);
                        }
                    }));

                }

            } else {
                deferred.resolve(null);
            }

            return deferred.promise;

        },
        _init: function () {
            // set sizes for select box
            this._setSizeOptions();

            var dialog = new Dialog({
                title: i18n.widgets.ShareDialog.title,
                draggable: false
            }, domConstruct.create("div"));
            this.set("dialog", dialog);


            // set embed url
            this._updateUrl();
            // select menu change
            this.own(on(this._comboBoxNode, "change", lang.hitch(this, function (evt) {
                this.set("embedWidth", this.get("embedSizes")[parseInt(evt.currentTarget.value, 10)].width);
                this.set("embedHeight", this.get("embedSizes")[parseInt(evt.currentTarget.value, 10)].height);
                this._setEmbedCode();
            })));
            // facebook click
            this.own(on(this._facebookButton, a11yclick, lang.hitch(this, function () {
                this._configureShareLink(this.get("facebookURL"));
            })));
            // twitter click
            this.own(on(this._twitterButton, a11yclick, lang.hitch(this, function () {
                this._configureShareLink(this.get("twitterURL"));
            })));
            // google plus click
            this.own(on(this._gpulsButton, a11yclick, lang.hitch(this, function () {
                this._configureShareLink(this.get("googlePlusURL"));
            })));
            // email click
            this.own(on(this._emailButton, a11yclick, lang.hitch(this, function () {
                this._configureShareLink(this.get("mailURL"), true);
            })));
            // link box click
            this.own(on(this._shareMapUrlText, a11yclick, lang.hitch(this, function () {
                this._shareMapUrlText.setSelectionRange(0, 9999);
            })));
            // link box mouseup stop for touch devices
            this.own(on(this._shareMapUrlText, "mouseup", function (evt) {
                event.stop(evt);
            }));
            // embed box click
            this.own(on(this._embedNode, a11yclick, lang.hitch(this, function () {
                this._embedNode.setSelectionRange(0, 9999);
            })));
            // embed box mouseup stop for touch devices
            this.own(on(this._embedNode, "mouseup", function (evt) {
                event.stop(evt);
            }));

            // loaded
            this.set("loaded", true);
            this.emit("load", {});
        },
        _updateEmbed: function () {
            domAttr.set(this._embedNode, "value", this.get("embed"));
        },
        _setEmbedCode: function () {
            var es = "<iframe width='" + this.get("embedWidth") + "' height='" + this.get("embedHeight") + "' src='" + this.get("url") + "' frameborder='0' scrolling='no'></iframe>";
            this.set("embed", es);
        },
        _updateBitlyUrl: function () {
            var bitly = this.get("bitlyUrl");
            if (bitly) {
                domAttr.set(this._shareMapUrlText, "value", bitly);
                domAttr.set(this._linkButton, "href", bitly);
            }
        },
        _shareLink: function () {
            if (this.get("bitlyAPI") && this.get("bitlyLogin") && this.get("bitlyKey")) {
                var currentUrl = this.get("url");
                // not already shortened
                if (currentUrl !== this._shortened) {
                    // set shortened
                    this._shortened = currentUrl;
                    // make request
                    esriRequest({
                        url: this.get("bitlyAPI"),
                        callbackParamName: "callback",
                        content: {
                            uri: currentUrl,
                            login: this.get("bitlyLogin"),
                            apiKey: this.get("bitlyKey"),
                            f: "json"
                        },
                        load: lang.hitch(this, function (response) {
                            if (response && response.data && response.data.url) {
                                this.set("bitlyUrl", response.data.url);
                            }
                        }),
                        error: function (error) {
                            console.log(error);
                        }
                    });
                }
            }
        },
        _configureShareLink: function (Link, isMail) {
            // replace strings
            var fullLink = lang.replace(Link, {
                url: encodeURIComponent(this.get("bitlyUrl") ? this.get("bitlyUrl") : this.get("url")),
                image: encodeURIComponent(this.get("image")),
                title: encodeURIComponent(this.get("title")),
                summary: encodeURIComponent(this.get("summary")),
                hashtags: encodeURIComponent(this.get("hashtags"))
            });
            // email link
            if (isMail) {
                window.location.href = fullLink;
            } else {
                window.open(fullLink, "share", true);
            }
        }
    });
    if (has("extend-esri")) {
        lang.setObject("dijit.ShareDialog", Widget, esriNS);
    }
    return Widget;
});

from viewer.

tscharff avatar tscharff commented on August 26, 2024

Sorry for the late reply... I've been out sick for about 1.5 weeks, and still only back on a very part-time basis.

We were using a hosted template, but when I return to work I will download the code and test the ShareDialog.js that you provided above. Thanks!

from viewer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.