Custom widget: combine attribute inspector & live video feed into one widget

1464
7
Jump to solution
06-29-2018 01:05 PM
LStroupe
New Contributor III

Greetings!

I am trying to create a custom widget that combines the attribute inspector in one tab, and a live video feed in another tab. I'm currently stuck on populating the contents of each tab. I'm trying to accomplish this via functions, but my results keep showing up as 'undefined' when i run it in the sandbox: ArcGIS API for JavaScript Sandbox  

Any help would be greatly appreciated!!

Thank you 

-Laura

<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">

<link rel="stylesheet" href="https://js.arcgis.com/3.24/esri/css/esri.css">
<style>
html,
body,
#mapDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}

body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
</style>

<script src="https://js.arcgis.com/3.24/"></script>
<script>
require([
"esri/map",
"esri/InfoTemplate",
"esri/layers/FeatureLayer",
"esri/tasks/query",
"esri/dijit/AttributeInspector",
"esri/dijit/InfoWindow",

"esri/config",

"dojo/dom",
"dojo/dom-construct",
"dojo/number",
"dojo/on",
"dojo/parser",

"dijit/layout/TabContainer",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/form/Button",

"dojo/domReady!"
],
function (
Map, InfoTemplate, FeatureLayer, Query, AttributeInspector, InfoWindow,
esriConfig,
dom, domConstruct, number, on, parser,
TabContainer, BorderContainer, ContentPane, Button
) {
parser.parse();

//create the infoWindow
var infoWindow = new InfoWindow({}, domConstruct.create("div"));
infoWindow.startup();

//create the map
var map = new Map("mapDiv", {
basemap: "topo",
center: [-96.755, 33.176],
zoom: 18,
infoWindow: infoWindow
});

//set the infoTemplate for the new infoWindow
var infoTemplate = new InfoTemplate();
infoTemplate.setTitle("${CAMERA_NAME}");
infoTemplate.setContent(getWindowContent);

//define the camera layer that will be added to map
var cameras = new FeatureLayer("myURL", {
mode: FeatureLayer.MODE_SNAPSHOT,
infoTemplate: infoTemplate,
outFields: ["*"]
});

//add the camera layer to the map
map.addLayers([cameras]);

//resize the infoWindow
map.infoWindow.resize(300, 300);

//function that formats and populates the infoWindow content's 2 tabs
function getWindowContent(graphic) {
//make a container for tabs
var tc = new dijit.layout.TabContainer({
style: "height: 100%; width: 100%;"
}, dojo.create("div"));

//tab 1
var cp1 = new dijit.layout.ContentPane({
title: "Video"
});
cp1.setContent(getVideo);
tc.addChild(cp1);

//tab 2
var cp2 = new dijit.layout.ContentPane({
title: "Edit"
});
cp2.setContent(initSelectToolbar);
tc.addChild(cp2);

return tc.domNode;
};

//function that gets the camera url to open and display in tab1
function getVideo(evt) {
selectedCamera = evt.feature.attributes.URL;
return selectedCamera;
};

//function that creates the attribute inspector tab2
function initSelectToolbar(evt) {
var selectQuery = new Query();

map.on("click", function (evt) {
selectQuery.geometry = evt.mapPoint;
selectQuery.distance = 4;
selectQuery.units = "feet"
selectQuery.returnGeometry = true;
cameras.selectFeatures(selectQuery, FeatureLayer.SELECTION_NEW, function (features) {
if (features.length > 0) {
//store the current feature
updateFeature = features[0];
map.infoWindow.setTitle(features[0].getLayer().name);
map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));
}
else {
map.infoWindow.hide();
}
});
});

map.infoWindow.on("hide", function () {
cameras.clearSelection();
});

var layerInfos = [
{
'featureLayer': cameras,
'showAttachments': false,
'isEditable': true,
'fieldInfos': [
{ 'fieldName': 'CAMERA_NAME', 'label': 'Name', 'isEditable': false },
{ 'fieldName': 'VideoStream', 'label': 'Video Stream?', 'isEditable': true },
{ 'fieldName': 'CorrectView', 'label': 'Correct View?', 'isEditable': true },
{ 'fieldName': 'Comments', 'label': 'Comments', 'isEditable': true }
]
}
];
//Initialize Attribute Inspector
var attInspector = new AttributeInspector({
layerInfos: layerInfos
}, domConstruct.create("div"));

//add a save button next to the delete button
var saveButton = new Button({ label: "Save", "class": "saveButton" }, domConstruct.create("div"));
domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");

saveButton.on("click", function () {
updateFeature.getLayer().applyEdits(null, [updateFeature], null);
});

//adds a close button next to the save button
var closeButton = new Button({ label: "Close", "class": "closeButton" }, domConstruct.create("div"));
domConstruct.place(closeButton.domNode, saveButton.domNode, "after");

//by clicking the close button the following action will happen
closeButton.on("click", function () {
map.infoWindow.hide();
});

attInspector.on("attribute-change", function (evt) {
//store the updates to apply when the save button is clicked
updateFeature.attributes[evt.fieldName] = evt.fieldValue;
});

attInspector.on("next", function (evt) {
updateFeature = evt.feature;
console.log("Next " + updateFeature.attributes.OBJECTID);
});

attInspector.on("delete", function (evt) {
evt.feature.getLayer().applyEdits(null, null, [evt.feature]);
map.infoWindow.hide();
});
map.infoWindow.setContent(attInspector.domNode);
}

});

</script>
</head>

<body class="soria">
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:true" style="width: 100%; height: 100%; margin: 0;">
<div id="mapDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>

</html>
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Laura,

   Here is you code updated to work:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">

  <link rel="stylesheet" href="https://js.arcgis.com/3.24/dijit/themes/soria/soria.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.24/dojox/layout/resources/ExpandoPane.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.24/esri/css/esri.css">
  <style>
    html,
    body,
    #mapDiv {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #FFF;
      overflow: hidden;
      font-family: "Trebuchet MS";
    }
  </style>

  <script src="https://js.arcgis.com/3.24/"></script>
  <script>
    var atInspContent, videoContent;
    var map, updateFeature, cameras;
    require([
        "esri/map",
        "esri/InfoTemplate",
        "esri/layers/FeatureLayer",
        "esri/tasks/query",
        "esri/dijit/AttributeInspector",
        "esri/dijit/InfoWindow",

        "esri/config",

        "dojo/dom",
        "dojo/dom-construct",
        "dojo/number",
        "dojo/on",
        "dojo/parser",

        "dijit/layout/TabContainer",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dijit/form/Button",

        "dojo/domReady!"
      ],
      function(
        Map, InfoTemplate, FeatureLayer, Query, AttributeInspector, InfoWindow,
        esriConfig,
        dom, domConstruct, number, on, parser,
        TabContainer, BorderContainer, ContentPane, Button
      ) {
        parser.parse();

        //create the infoWindow
        var infoWindow = new InfoWindow({}, domConstruct.create("div"));
        infoWindow.startup();

        //create the map
        var map = new Map("mapDiv", {
          basemap: "topo",
          center: [-96.755, 33.176],
          zoom: 18,
          infoWindow: infoWindow
        });

        //set the infoTemplate for the new infoWindow
        var infoTemplate = new InfoTemplate();
        infoTemplate.setTitle("${CAMERA_NAME}");
        infoTemplate.setContent(setWindowContent());

        //define the camera layer that will be added to map
        cameras = new FeatureLayer("your url", {
          mode: FeatureLayer.MODE_SNAPSHOT,
          infoTemplate: infoTemplate,
          outFields: ["*"]
        });
        map.on("layers-add-result", initSelectToolbar);

        //add the camera layer to the map
        map.addLayers([cameras]);

        //resize the infoWindow
        map.infoWindow.resize(300, 300);

        //function that formats and populates the infoWindow content's 2 tabs
        function setWindowContent(evt) {
          //make a container for tabs
          var tc = new TabContainer({
            style: "height: 100%; width: 100%;"
          }, dojo.create("div"));

          //tab 1
          videoContent = new ContentPane({
            title: "Video"
          });
          tc.addChild(videoContent);

          //tab 2
          atInspContent = new ContentPane({
            title: "Edit"
          });
          tc.addChild(atInspContent);

          return tc.domNode;
        };

        //function that gets the camera url to open and display in tab1
        function getVideo(evt) {
          selectedCamera = evt.attributes.URL;
          return selectedCamera;
        };

        //function that creates the attribute inspector tab2
        function initSelectToolbar(evt) {
          var selectQuery = new Query();

          map.on("click", function(evt) {
            selectQuery.geometry = evt.mapPoint;
            selectQuery.distance = 40;
            selectQuery.units = "feet"
            selectQuery.returnGeometry = true;
            selectQuery.outSpatialReference = map.spatialReference;
            cameras.selectFeatures(selectQuery, FeatureLayer.SELECTION_NEW, function(features) {
              if (features.length > 0) {
                //store the current feature
                updateFeature = features[0];
                map.infoWindow.setTitle(features[0].getLayer().name);
                map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));
                videoContent.setContent(getVideo(features[0]));
              } else {
                map.infoWindow.hide();
              }
            });
          });

          map.infoWindow.on("hide", function() {
            cameras.clearSelection();
          });

          var layerInfos = [{
            'featureLayer': cameras,
            'showAttachments': false,
            'isEditable': true,
            'fieldInfos': [{
                'fieldName': 'CAMERA_NAME',
                'label': 'Name',
                'isEditable': false
              },
              {
                'fieldName': 'VideoStream',
                'label': 'Video Stream?',
                'isEditable': true
              },
              {
                'fieldName': 'CorrectView',
                'label': 'Correct View?',
                'isEditable': true
              },
              {
                'fieldName': 'Comments',
                'label': 'Comments',
                'isEditable': true
              }
            ]
          }];
          
          //Initialize Attribute Inspector
          var attInspector = new AttributeInspector({
            layerInfos: layerInfos
          }, domConstruct.create("div"));

          //add a save button next to the delete button
          var saveButton = new Button({
            label: "Save",
            "class": "saveButton"
          }, domConstruct.create("div"));
          domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");

          saveButton.on("click", function() {
            updateFeature.getLayer().applyEdits(null, [updateFeature], null);
          });

          //adds a close button next to the save button
          var closeButton = new Button({
            label: "Close",
            "class": "closeButton"
          }, domConstruct.create("div"));
          domConstruct.place(closeButton.domNode, saveButton.domNode, "after");

          //by clicking the close button the following action will happen
          closeButton.on("click", function() {
            map.infoWindow.hide();
          });

          attInspector.on("attribute-change", function(evt) {
            //store the updates to apply when the save button is clicked
            updateFeature.attributes[evt.fieldName] = evt.fieldValue;
          });

          attInspector.on("next", function(evt) {
            updateFeature = evt.feature;
            console.log("Next " + updateFeature.attributes.OBJECTID);
          });

          attInspector.on("delete", function(evt) {
            evt.feature.getLayer().applyEdits(null, null, [evt.feature]);
            map.infoWindow.hide();
          });
          atInspContent.setContent(attInspector.domNode);
        }

      });
  </script>
</head>

<body class="soria">
  <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:true" style="width: 100%; height: 100%; margin: 0;">
    <div id="mapDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
  </div>
</body>

</html>

View solution in original post

7 Replies
RobertScheitlin__GISP
MVP Emeritus

Laura,

   Here is you code updated to work:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">

  <link rel="stylesheet" href="https://js.arcgis.com/3.24/dijit/themes/soria/soria.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.24/dojox/layout/resources/ExpandoPane.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.24/esri/css/esri.css">
  <style>
    html,
    body,
    #mapDiv {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #FFF;
      overflow: hidden;
      font-family: "Trebuchet MS";
    }
  </style>

  <script src="https://js.arcgis.com/3.24/"></script>
  <script>
    var atInspContent, videoContent;
    var map, updateFeature, cameras;
    require([
        "esri/map",
        "esri/InfoTemplate",
        "esri/layers/FeatureLayer",
        "esri/tasks/query",
        "esri/dijit/AttributeInspector",
        "esri/dijit/InfoWindow",

        "esri/config",

        "dojo/dom",
        "dojo/dom-construct",
        "dojo/number",
        "dojo/on",
        "dojo/parser",

        "dijit/layout/TabContainer",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dijit/form/Button",

        "dojo/domReady!"
      ],
      function(
        Map, InfoTemplate, FeatureLayer, Query, AttributeInspector, InfoWindow,
        esriConfig,
        dom, domConstruct, number, on, parser,
        TabContainer, BorderContainer, ContentPane, Button
      ) {
        parser.parse();

        //create the infoWindow
        var infoWindow = new InfoWindow({}, domConstruct.create("div"));
        infoWindow.startup();

        //create the map
        var map = new Map("mapDiv", {
          basemap: "topo",
          center: [-96.755, 33.176],
          zoom: 18,
          infoWindow: infoWindow
        });

        //set the infoTemplate for the new infoWindow
        var infoTemplate = new InfoTemplate();
        infoTemplate.setTitle("${CAMERA_NAME}");
        infoTemplate.setContent(setWindowContent());

        //define the camera layer that will be added to map
        cameras = new FeatureLayer("your url", {
          mode: FeatureLayer.MODE_SNAPSHOT,
          infoTemplate: infoTemplate,
          outFields: ["*"]
        });
        map.on("layers-add-result", initSelectToolbar);

        //add the camera layer to the map
        map.addLayers([cameras]);

        //resize the infoWindow
        map.infoWindow.resize(300, 300);

        //function that formats and populates the infoWindow content's 2 tabs
        function setWindowContent(evt) {
          //make a container for tabs
          var tc = new TabContainer({
            style: "height: 100%; width: 100%;"
          }, dojo.create("div"));

          //tab 1
          videoContent = new ContentPane({
            title: "Video"
          });
          tc.addChild(videoContent);

          //tab 2
          atInspContent = new ContentPane({
            title: "Edit"
          });
          tc.addChild(atInspContent);

          return tc.domNode;
        };

        //function that gets the camera url to open and display in tab1
        function getVideo(evt) {
          selectedCamera = evt.attributes.URL;
          return selectedCamera;
        };

        //function that creates the attribute inspector tab2
        function initSelectToolbar(evt) {
          var selectQuery = new Query();

          map.on("click", function(evt) {
            selectQuery.geometry = evt.mapPoint;
            selectQuery.distance = 40;
            selectQuery.units = "feet"
            selectQuery.returnGeometry = true;
            selectQuery.outSpatialReference = map.spatialReference;
            cameras.selectFeatures(selectQuery, FeatureLayer.SELECTION_NEW, function(features) {
              if (features.length > 0) {
                //store the current feature
                updateFeature = features[0];
                map.infoWindow.setTitle(features[0].getLayer().name);
                map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));
                videoContent.setContent(getVideo(features[0]));
              } else {
                map.infoWindow.hide();
              }
            });
          });

          map.infoWindow.on("hide", function() {
            cameras.clearSelection();
          });

          var layerInfos = [{
            'featureLayer': cameras,
            'showAttachments': false,
            'isEditable': true,
            'fieldInfos': [{
                'fieldName': 'CAMERA_NAME',
                'label': 'Name',
                'isEditable': false
              },
              {
                'fieldName': 'VideoStream',
                'label': 'Video Stream?',
                'isEditable': true
              },
              {
                'fieldName': 'CorrectView',
                'label': 'Correct View?',
                'isEditable': true
              },
              {
                'fieldName': 'Comments',
                'label': 'Comments',
                'isEditable': true
              }
            ]
          }];
          
          //Initialize Attribute Inspector
          var attInspector = new AttributeInspector({
            layerInfos: layerInfos
          }, domConstruct.create("div"));

          //add a save button next to the delete button
          var saveButton = new Button({
            label: "Save",
            "class": "saveButton"
          }, domConstruct.create("div"));
          domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");

          saveButton.on("click", function() {
            updateFeature.getLayer().applyEdits(null, [updateFeature], null);
          });

          //adds a close button next to the save button
          var closeButton = new Button({
            label: "Close",
            "class": "closeButton"
          }, domConstruct.create("div"));
          domConstruct.place(closeButton.domNode, saveButton.domNode, "after");

          //by clicking the close button the following action will happen
          closeButton.on("click", function() {
            map.infoWindow.hide();
          });

          attInspector.on("attribute-change", function(evt) {
            //store the updates to apply when the save button is clicked
            updateFeature.attributes[evt.fieldName] = evt.fieldValue;
          });

          attInspector.on("next", function(evt) {
            updateFeature = evt.feature;
            console.log("Next " + updateFeature.attributes.OBJECTID);
          });

          attInspector.on("delete", function(evt) {
            evt.feature.getLayer().applyEdits(null, null, [evt.feature]);
            map.infoWindow.hide();
          });
          atInspContent.setContent(attInspector.domNode);
        }

      });
  </script>
</head>

<body class="soria">
  <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:true" style="width: 100%; height: 100%; margin: 0;">
    <div id="mapDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
  </div>
</body>

</html>
LStroupe
New Contributor III

Robert thank you so much! The editor part of the widget is working great! My only issue left is to get the video feed to display in the first tab. Any further insight would be much appreciated. And thank you again! -Laura

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Laura,

   If your url attribute is just the url to a video then you need some js component that can play that video added to that tab. Like the HTML video tag.

HTML video src Attribute 

Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.

0 Kudos
LStroupe
New Contributor III

Rob,

I am unable to view the video stream. The video box appears but the video never loads. This is what I tried using last:

function getVideo(evt) {
videoWindow = '<video controls="true" height="260" width="330"><source src=' + evt.attributes.HYPERLINK + ' ></source></video>';
return videoWindow;
};

I've also tried this below, with no luck either.

function getVideo(evt) {

url=evt.attributes.HYPERLINK;
videoWindow = '<video controls="true" height="260" width="330"><source src=' + url + ' ></source></video>';
return videoWindow;
};

Any help would be greatly appreciated.

Thank you

-Laura

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Laura,

   What is the video link url look like? Can you share an example?

0 Kudos
LStroupe
New Contributor III

Unfortunately they are secured feeds and I can't share them. However they are similar in format to this url: https://ourOrg.org/viewer.html?camera=1 

0 Kudos
LStroupe
New Contributor III

UPDATE 7/10/2018

In case anyone was curious, I managed to get the video feed working by using the code below. The only issue I noticed is that every time it updates the feed using the setInterval function, the picture flashes as its being updated. A little annoying and not sure how to get around that.

Thank you! -Laura

 

<!DOCTYPE html>

<html>

 

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">

    <link rel="stylesheet" href="https://js.arcgis.com/3.24/dijit/themes/soria/soria.css">

    <link rel="stylesheet" href="https://js.arcgis.com/3.24/esri/css/esri.css">

 

    <style>

        html,

        body,

        #mapDiv {

            height: 100%;

            width: 100%;

            margin: 0;

            padding: 0;

        }

        body {

            background-color: #FFF;

            overflow: hidden;

            font-family: "Trebuchet MS";

        }

    </style>

 

    <script src="https://js.arcgis.com/3.24/"></script>

    <script>

        var atInspContent, videoContent;

        var map, updateFeature, cameras;

        require([

            "dojo/dom-construct",

            "esri/map",

            "esri/dijit/InfoWindow",

            "esri/layers/FeatureLayer",

            "esri/InfoTemplate",

            "esri/tasks/query",

            "esri/dijit/AttributeInspector",

 

            "esri/config",

 

            "dojo/number",

            "dojo/on",

 

            "dijit/layout/TabContainer",

            "dijit/layout/BorderContainer",

            "dijit/layout/ContentPane",

            "dijit/form/Button",

 

            "dojo/domReady!"

        ],

            function (

                domConstruct, Map, InfoWindow, FeatureLayer, InfoTemplate, Query, AttributeInspector,

                esriConfig,

                number, on,

                TabContainer, BorderContainer, ContentPane, Button

            ) {

 

                //infoWindow: Creation

                var infoWindow = new InfoWindow({}, domConstruct.create("div"));

                infoWindow.startup();

 

                //Map: Creation

                var map = new Map("mapDiv", {

                    basemap: "topo",

                    center: [-96.755, 33.176],

                    zoom: 20,

                    infoWindow: infoWindow

                });

 

                //infoTemplate: Creation

                var infoTemplate = new InfoTemplate();

                infoTemplate.setTitle("${CAMERA_NAME}");

                infoTemplate.setContent(setWindowContent());

 

                //Layer: Creation

                var cameras = new FeatureLayer("MY_CAMERA_URL", {

                    mode: FeatureLayer.MODE_SNAPSHOT,

                    infoTemplate: infoTemplate,

                    outFields: ["*"]

                });

 

//Map & infoWindow: Actions

                //when the camera layer is added to the map, the Attribute Inspector tool (TAB 2) is initialized

                map.on("layers-add-result", initSelectToolbar);

 

                //adds camera layer to map

                map.addLayers([cameras]);

 

                //resizes the infoWindow

                map.infoWindow.resize(450, 410);

 

//infoWindow Container: Creation

                function setWindowContent(evt) {

                    //makes a container for tabs

                    var tc = new TabContainer({

                        style: "height: 100%; width: 100%;"

                    }, dojo.create("div"));

 

                    //creates tab 1

                    videoContent = new ContentPane({

                        title: "Video"

                    });

                    tc.addChild(videoContent);

 

                    //creates tab 2

                    atInspContent = new ContentPane({

                        title: "Edit"

                    });

                    tc.addChild(atInspContent);

 

                    return tc.domNode;

                };

 

//infoWindow TAB 1: Gets the camera video feed--------------------------------------------------------//

                function getVideo(evt) {

                    cameraURL = evt.attributes.URL;

 

                    setInterval(function () {

                        //assigns the selected camera url to the src attribute of the html iframe

                        document.getElementById('video').src = cameraURL;

                        //sets the cadence for refreshing the image - in this case it's every 1 second

                    }, 1000);

                    return document.getElementById('video');

                };

 

//infoWindow TAB 2: Gets the Attribute Inspector tool--------------------------------------------------//

                function initSelectToolbar(evt) {

                    var selectQuery = new Query();

                    map.on("click", function (evt) {

                        selectQuery.geometry = evt.mapPoint;

                        selectQuery.distance = 4;

                        selectQuery.units = "feet"

                        selectQuery.returnGeometry = true;

                        selectQuery.outSpatialReference = map.spatialReference;

                        cameras.selectFeatures(selectQuery, FeatureLayer.SELECTION_NEW, function (features) {

                            if (features.length > 0) {

                                updateFeature = features[0];

                                map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));

                                videoContent.setContent(getVideo(features[0]));

                            } else {

                                map.infoWindow.hide();

                            }

                        });

                    });

                   

                    //infoWindow: Action

                    map.infoWindow.on("hide", function () {

                        cameras.clearSelection();

                    });

 

                    //Editable Fields: Configuration

                    var layerInfos = [{

                        'featureLayer': cameras,

                        'showAttachments': false,

                        'isEditable': true,

                        'fieldInfos': [{

                            'fieldName': 'CAMERA_NAME',

                            'label': 'Name',

                            'isEditable': false

                        },

                        {

                            'fieldName': 'VideoStream',

                            'label': 'Video Stream?',

                            'isEditable': true

                        },

                        {

                            'fieldName': 'CorrectView',

                            'label': 'Correct View?',

                            'isEditable': true

                        },

                        {

                            'fieldName': 'Comments',

                            'label': 'Comments',

                            'isEditable': true

                        }

                        ]

                    }];

 

                    //Attribute Inspector: Initialize

                    var attInspector = new AttributeInspector({

                        layerInfos: layerInfos

                    }, domConstruct.create("div"));

 

                    //Attribute Inspector: Adds save button next to delete button

                    var saveButton = new Button({

                        label: "Save",

                        "class": "saveButton"

                    }, domConstruct.create("div"));

                    domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");

 

                    //Save Button: Action

                    saveButton.on("click", function () {

                        updateFeature.getLayer().applyEdits(null, [updateFeature], null);

                    });

 

                    //Attribute Inspector: Adds close button next to save button

                    var closeButton = new Button({

                        label: "Close",

                        "class": "closeButton"

                    }, domConstruct.create("div"));

                    domConstruct.place(closeButton.domNode, saveButton.domNode, "after");

 

                    //Close Button: Action

                    closeButton.on("click", function () {

                        map.infoWindow.hide();

                    });

 

                    //Attribute Inspector: Action

                    attInspector.on("attribute-change", function (evt) {

                        //stores the updates to apply when the save button is clicked

                        updateFeature.attributes[evt.fieldName] = evt.fieldValue;

                    });

 

                    //Attribute Inspector: Action

                    attInspector.on("next", function (evt) {

                        updateFeature = evt.feature;

                    });

 

                    atInspContent.setContent(attInspector.domNode);

                };

            });

    </script>

</head>

 

<body class="soria">

 

    <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:true" style="width: 100%; height: 100%; margin: 0;">

        <div id="mapDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'censater'">

        </div>

    </div>

 

    <iframe id="video" width="400" height="330" frameborder="0" src="">

    </iframe>

 

</body>

 

</html>

0 Kudos