Widget to display JSON response

1043
10
Jump to solution
03-19-2019 06:47 AM
BrianBulla
Regular Contributor

Hi,

I'm a total beginner with WAB, but what I want to do is take a tool I have developed for ArcGIS Desktop and bring that into a web app.  How the tool works is:

1.  User selects a construction contract boundary from a polygon layer

2.  User clicks on the 'Document Manager' tool (in ArcGIS)

3.  A windows form opens up, connects to a web API which returns some JSON with the details on the contract boundary, based on the CONTRACT_NUMBER of the polygon.

4.  Information is displayed on the form.

See the screenshot below for an example.  All of the data here is returned via JSON.  How would I replicate this sort of behaviour with a Widget?  Where do I even start?  I realize in webapps there are no 'forms', but I guess some sort of panel to display the info would work??  I am not a web programmer at all, so just looking to get some ideas.

Thanks!

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Brian,

  So where to start is to create a widget (most widgets have a panel, where you can display your web service json results):

Create a custom in-panel widget—Web AppBuilder for ArcGIS (Developer Edition) | ArcGIS for Developer... 

You can pre-build your UI to look like what you are use to in your widget.html or you can keep your widget UI simple and have the widget popup a panel in the center of the app using a jimu\dijit\Popup.js

View solution in original post

10 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Brian,

  So where to start is to create a widget (most widgets have a panel, where you can display your web service json results):

Create a custom in-panel widget—Web AppBuilder for ArcGIS (Developer Edition) | ArcGIS for Developer... 

You can pre-build your UI to look like what you are use to in your widget.html or you can keep your widget UI simple and have the widget popup a panel in the center of the app using a jimu\dijit\Popup.js

BrianBulla
Regular Contributor

Great...thanks Robert.  I have worked through that tutorial, and I think I at least half know what I am doing now.  

Is there a way to 'Activate' a widget by clicking on text in the features 'Pop-Up' window??  What I'm thinking is that the user would scroll to the Contract Boundary they are interested in, and then click on some text to then open up the widget.  See below as an example.  Or do I need to go about this differently??

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Brian,

  Absolutely the best way to do that is add a widget feature action.

Create a feature action in your widget—Web AppBuilder for ArcGIS (Developer Edition) | ArcGIS for De... 

If you do not want your action to be inside the ... menu then you would have to add a custom code link to the maps popup (likely in the MapManager.js).

See this thread for some info:

Custom Link in Local Data Popup Click on the Map 

Limiting popup link to individual features 

https://community.esri.com/thread/204319-adding-a-link-to-a-popup-and-getting-a-value-from-the-selec...  

BrianBulla
Regular Contributor

Great....thanks again!  Things are slowly coming together.

Now I am trying to access the CONTRACTNO of the selected feature when the user clicks on the ... to open up the widget.  I'm just building on the .js file for the DEMO widget, but what I have does not seem seem to be working.  Any hints??  CONTRACTNO is the name of the attribute in the webservice for the layer.

define([
  'dojo/_base/declare',
  'jimu/BaseFeatureAction',
  'jimu/WidgetManager'
], function (declare, BaseFeatureAction, WidgetManager) {
    var clazz = declare(BaseFeatureAction, {

        iconFormat: 'png',

        isFeatureSupported: function (featureSet) {
            return featureSet.features.length > 0 && featureSet.features[0].geometry.type !== 'point';
        },

        onExecute: function (featureSet) {
            WidgetManager.getInstance().triggerWidgetOpen(this.widgetId)
            .then(function (myWidget) {
                var vertexCount = 0;
                featureSet.features.forEach(function (f) {
                    f.geometry.rings.forEach(function (r) {
                        vertexCount += r.length;
                    });
                });

                myWidget.showVertexCount(vertexCount);

                //Trying to access the CONTRACTNO attribute of the currently selected feature
                var contractNumber = "TEST";

                var feature = this.mapManager.map.infoWindow.getSelectedFeature();
                var contractNumber = feature.attributes.CONTRACTNO;

                myWidget.showContractNumber(contractNumber);
                
            });
        }

    });
    return clazz;
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Brain,

   The featureSet property that is passed into the onExecute should already have the popups selected feature information. do a console.log(featureSet);

0 Kudos
BrianBulla
Regular Contributor

Thanks again Robert.  Now I am trying to get the response from the web api that I use for querying a remote database.  In a C# windows form, I have no problems doing this, but in this widget I am not totally sure where to put my code.  I'm currently just hardcoding some sample data to see if I can get some results, but after the myWidget.showContractNumber, the code stops working.  What should be happening is just 3 consecutive message boxes with the name showing.

Any advice on where I am going wrong??

define([
  'dojo/_base/declare',
  'jimu/BaseFeatureAction',
  'jimu/WidgetManager'
],

function (declare, BaseFeatureAction, WidgetManager)
{
    var clazz = declare(BaseFeatureAction,
        {
            iconFormat: 'png',

            isFeatureSupported: function (featureSet)
            {
                return featureSet.features.length > 0 && featureSet.features[0].geometry.type !== 'point';
            },

            onExecute: function (featureSet)
            {
                WidgetManager.getInstance().triggerWidgetOpen(this.widgetId)
                .then(function (myWidget)
                {
                    var vertexCount = 0;
                    var contractNumber = "TEST";

                    featureSet.features.forEach(function (f)
                    {
                        f.geometry.rings.forEach(function (r)
                        {
                            vertexCount += r.length;
                        });
                        contractNumber = f.attributes.CONTRACTNO;
                    });

                    myWidget.showVertexCount(vertexCount);
                    myWidget.showContractNumber(contractNumber);

//Get the real JSON through the web api here

                    $(document).ready(function () {

                        var jsonData = [{
                            "itemsPerPage": 25,
                            "list": [{
                                "id": "1018",
                                "name": "abc"
                            }, {
                                "id": "1019",
                                "name": "acd"
                            }, {
                                "id": "1025",
                                "name": "kjk"
                            }]
                        }];

                        //Read the value and assign to textbox
                        $.each(jsonData, function (i, item) {
                            //loop through each result
                            $(item.list).each(function (key, value) {
                                //get the name here
                                alert(value.name);
                            });
                        });
                    });
                });
            },
        });
    return clazz;
});
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Brain,

  So in your actually widget.js code do you have a showContractNumber function?

0 Kudos
BrianBulla
Regular Contributor

Yes....everything works fine up to that point.  It's when I try to run the jQuery stuff after the showContractNumber function, that I run into problems.

I'm just trying to run some sample code I found on the web to make sure I am doing things in the right spot.  Eventually I will replace that with the 'real' code.

Can I run jQuery code from the widget.js file?  Or should I be putting it somewhere else??  This is the error I get from the Console window in Chrome:

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Brain,

   The issue is the 3rd party library jQuery is not loaded in WAB. My personal preference is not a add Another library like jQuery. Dojo is already part of the JS API and there is nothing you can do in jQuery that can not be done using Dojo. The document is already ready so there is no need for that jQuery call and the next jQuery call you use is for simple array looping which can be done in vanilla JavaScript to using dojo array.

0 Kudos