Populating html form from widget.js

478
7
Jump to solution
01-18-2019 11:47 AM
FranklinAlexander
Occasional Contributor II

In one of our old flex viewer apps, we had a custom widget that fetched results from a spatial query and created a report in the form of a .swf file which is basically deprecated now. I am trying to re-create the widget, using the eSearch widget to fetch results, then just add a button to the results pane to send to the report. I created a new report template html doc and placed it in the eSearch widget folder, but am having difficulty figuring out how to access it in order to programmatically ad the search results to the fields in the form. I thought that maybe placing a reference to the form template in the widget.html doc would be the best way, but I am still missing something, because when I try and call the form elements, I just get undefined or null. 

I am attaching a snippet from the form template as well as my relevant widget.html code. I know I am close, but need a little push!! 

 Here is a snippet from my Form: (the form works fine. It opens in a new window and takes input)

<form class="icsForm" data-dojo-type="dijit/form/Form" id="ics..." data-dojo-id="ics...">
    <link rel="stylesheet" href="css/style_ics.css">
    <div class="ics-section" id="sect1">
        <table class="ics-subsection" style="paddingLeft:10px">
            <tr>
                <th class style="font-size:18px"><b>1. Incident Name</b></th>
                <th class style="font-size:18px; padding-left:10px">2. Operational Period (Date/Time)</th>
                <th style="text-align:right; font-size:20px; padding-right:20px">RESOURCES AT RISK SUMMARY</th>
            </tr>
            <tr>
                <td><input style="width:280px; height:30px; padding-left:10px" id="incidentName" maxChars="100"  class="inputText"></td>
                <td style="padding-left:10px">
                    <span><b>From:</b></span>
                    <span><input style="width:135px; height:30px; padding-left:10px" id="opPeriodFrom" maxChars="15" class="inputText"></input>
                    <span><b>&nbspTo:</b></span>
                    <span><input style="width:135px; height:30px; padding-left:10px" id="opPeriodTo" maxChars="15" class="inputText"></input>
                </td>
                <th style="text-align:right; font-size:20px; padding-right:20px">ICS 232-CG</th>
            </tr>
        </table>
    </div>

    <div class="ics-section" id="sect2" style= "width:100%; margin-top:5px; border-bottom:3px solid #000000">
        <div class="ics-subsection" style="width:100%; paddingLeft:10px">
            <span style="margin-top:10px; font-size:18px"><b>3. Environmentally-Sensitive Areas...</b></span>
            <div class="ics-label" style="width:100%; margin-top:10px">
                <label style="margin-left:2em; margin-right:2em">Site #</label>
                <label>Priority</label>
                <label style="margin-left:3.2em; margin-right:3.5em">Site Name and/or Physical Location</label>
                <label style="margin-left:13em">Site Issues</label>
            </div>
        </div>
        <div class="ics-subsection">
            <input class="ics-site" id="Site0" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-priority" id="Priority0" name="Priority0" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-name" id="Name0" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-issues" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
        </div>
        <div class="ics-subsection">
            <input class="ics-site" id="Site1" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-priority" id="Priority1" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-name" id="Name1" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-issues" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
        </div>
        <div class="ics-subsection">
            <input class="ics-site" id="Site2" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-priority" id="Priority2" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-name" id="Name2" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
            <input class="ics-issues" type="text" value="" data-dojo-type="dijit/form/textbox"></input>
        </div>

This is how I am trying to connect it to the jsavascript (from the widget.html doc)

<div class="search-tab-node-hidden" data-dojo-attach-point="tabNode4" style="overflow: hidden;">
      <div data-dojo-attach-point="progressbar"></div>
      <div data-dojo-attach-point="divResultMessage" class="esearch-noResults"></div>
      <div class="popup-menu-button esearch-result-action-button" data-dojo-attach-event="click:_onBtnMenuClicked" data-dojo-attach-point="divOptions" title="${nls.resultactions}" style="display:none;"></div>
      <div data-dojo-attach-point="listDiv"></div>
      <label data-dojo-attach-point="divSum" class="esearch-sum" style="display:none;"></label>
      <div class="report-btn" data-dojo-attach-point="btnClear5"><a href="widgets/eSearch/ICSForm.html" target="_blank">${nls.report}</a></div>
      <div data-dojo-attach-point="icsForm" href="ICSForm.html"></div>
    </div>
  </div>

Just a note. I am not trying to submit any data, just want to fill out the report from the query results and print. I have everything else working, so once I figure out how 'see' the report elements from the javascript, the rest should be easy! 

Thanks!!

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Franklin,

   Sorry this is where things get real complicated. You can not build a html page in code (clientside) and have it open in a browser tab or new widow. That would be a serious security issue that hackers and malware individuals would exploit. So I am try to think of how I can dumb my method for achieving this down to something you can use.

I guess I should try and explain how I do the tax report on my WAB website.

https://gis.calhouncounty.org/Parcelviewer2/?psearch=2103061007024000&slayer=0&exprnum=1 

I have a widget called the Parcel Search (which is basically the eSearch modified). My Parcel Search has links in the results that open a few different popup like reports. They are not opened in a new tab but inside a mobile popup in WAB (this is the first layer of complexity my mobile popup is a subclass of the jimu popup dijit). Each of my reports are their own js and html template. The js portion declares itself as a MobilePopup and uses the html template as a template for building the basic html stuff of the report. Well this is getting pretty complicated to even explain.

Basically you can use domConstruct to add dynamically created html element to the existing WAB app (ie. some dom element that already exists in the WAB apps document). If you want to build and open some new tab/html document then you need to consider server side technology like asp.net.

View solution in original post

0 Kudos
7 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Franklin,

   Hmm. Have never seen it approached this way. To access the ICSForm from the widget.js you need to use this.icsForm this will get you a reference to the div element. Now how you get to elements in the form, like incidentName is the issue... Can I assume you have tried to use dom.byId?

0 Kudos
FranklinAlexander
Occasional Contributor II

Yes, this is exactly the challenge so far. I have tried this.icsForm and I get the div element, but not seeing any of the elements inside the form template. I have also tried dojoQuery, dom.byId, and even document.forms["ics232cg"] and all return either null or undefined. I also tried locating the form template in the main app folder, but no luck so far. 

I have a feeling this is probably just a syntax issue, unless there is a better way to go about this?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Franklin,

  The issue is likely that a div does not have a href property (to my knowledge at least). I would normally build my report in code using domConstruct.

0 Kudos
FranklinAlexander
Occasional Contributor II

Yep, got it. I tried it with the <a> tag, but that just opens the form in another window, which is fine but doesn't solve my problem. So if I use domConstruct, I would be creating the report dynamically in the javascript file, such as on the onClick event? So when the 'report' button is clicked, the report would be created, populated, and opened in a new window. Am I on the right track?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Franklin,

   Sorry this is where things get real complicated. You can not build a html page in code (clientside) and have it open in a browser tab or new widow. That would be a serious security issue that hackers and malware individuals would exploit. So I am try to think of how I can dumb my method for achieving this down to something you can use.

I guess I should try and explain how I do the tax report on my WAB website.

https://gis.calhouncounty.org/Parcelviewer2/?psearch=2103061007024000&slayer=0&exprnum=1 

I have a widget called the Parcel Search (which is basically the eSearch modified). My Parcel Search has links in the results that open a few different popup like reports. They are not opened in a new tab but inside a mobile popup in WAB (this is the first layer of complexity my mobile popup is a subclass of the jimu popup dijit). Each of my reports are their own js and html template. The js portion declares itself as a MobilePopup and uses the html template as a template for building the basic html stuff of the report. Well this is getting pretty complicated to even explain.

Basically you can use domConstruct to add dynamically created html element to the existing WAB app (ie. some dom element that already exists in the WAB apps document). If you want to build and open some new tab/html document then you need to consider server side technology like asp.net.

View solution in original post

0 Kudos
FranklinAlexander
Occasional Contributor II

Robert,

Thanks for your input! This will be a challenge, but after looking at your website (and code), It gives me a clear direction. I do like the idea of a popup in the map vs the browser tab, so I will give it a try. I may come back to you with a question or two if I get stuck, and will definitely refer to your code it that is ok.

Thanks again,

Franklin(Gene) Alexander

Research Assistant/Web Developer

FranklinAlexander
Occasional Contributor II

Robert,

Your right, this was quite a challenge, but I got it to work. My form was a lot different than yours, because it needs to take user input as well as query result values. I am posting some code snippets from the relevant places just in case any one else is trying to do something similar. Thanks again, I never would have figured this out! 

report screenshot

//from the widget.js file

_createICSReport: function(siteID, clayer){

//this.closeOpenReports();

this.shelter.show();
window.resultsLength = this.queryResults.features.length;
var qr = this.queryResults.features;
var defs = [];
var props = {
height: 1000,
titleLabel: "ICS 232-CG Report",
map: this.map,
layer: clayer||this.currentLayerAdded,
folderurl: this.folderUrl
};
//console.log("features ", results);
for(var i = 0; i < qr.length; i++) {
var atts = qr[i].attributes;
//console.log("feature " + i + " = ", atts);
defs.push(atts);
}
if(defs) {
var Site, Priority, Name;
let count = 0;
let results = defs;
for(var i = 0; i < defs.length; i++) {
let key = "json" + count;
let value = "results[" + i + "],";
props[key] = results[i];
//console.log("result = ", results);
count ++;
}
}
//console.log("test report ", props);
this.shelter.hide();
all(defs).then(lang.hitch(this, function (results) {
this.icsReport = new ICSReport(props);
}), lang.hitch(this, function(err){
this.shelter.hide();
console.info(err);
}));
},

//////// from the ICSReport.js file//////////

_dataMixin: function(){
let json0 = this.json0;
let json1 = this.json1;
let json2 = this.json2;
let json3 = this.json3;
let json4 = this.json4;
let json5 = this.json5;
let json6 = this.json6;
let json7 = this.json7;
let json8 = this.json8;
let json9 = this.json9;
let valArray = [json0, json1, json2, json3, json4, json5, json6, json7, json8,
json9];
//console.log("results length ", resultsLength);
if(resultsLength <= 10) {
for(let i = 0; i < resultsLength; i++) {
//console.log("results: ", valArray);
dom.byId('Site' + i).setAttribute("value", valArray[i].ID);
dom.byId('Priority' + i).setAttribute("value", valArray[i].SUMMER_PRI);
dom.byId('Name' + i).innerHTML = valArray[i].NAME;
}
} else {
for(let i = 0; i < 10; i++) {
dom.byId('Site' + i).setAttribute("value", valArray[i].ID);
dom.byId('Priority' + i).setAttribute("value", valArray[i].SUMMER_PRI);
dom.byId('Name' + i).innerHTML = valArray[i].NAME;
}
let msg = "Maximum record count exceeded. " + (resultsLength-10) + "
records will be missing from report."
this._showMessage(msg);
}
let dt = new Date();
let dtm = (("0"+dt.getMonth()+1).slice(-2)) +"."+ (("0"+
(dt.getDate())).slice(-2)) +"."+ (dt.getFullYear()) +" "+
(("0"+dt.getHours()).slice(-2)) +":"+
(("0"+dt.getMinutes()).slice(-2));
dom.byId('dateTime').setAttribute("value", dtm);
var spacer = domConstruct.toDom('<div style="height:10px;width:740px;">
</div>');

domConstruct.place(spacer, dom.byId('map'), 'last');
this.map.infoWindow.hide();
var oWid = this.map.width;
var oHgt = this.map.height;
var printTask = new PrintTask('https://ocean.floridamarine.org/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task');
var template = new PrintTemplate();
//this.imgHeight = (740/oWid) * oHgt;
template.exportOptions = {
width: 1542,
height: (1542/oWid) * oHgt,
dpi: 200
};
template.format = "jpg";
template.layout = "MAP_ONLY";
template.preserveScale = false;
template.showAttribution = false;

var params = new PrintParameters();
//params.map = this.map;
params.template = template;
printTask.execute(params, lang.hitch(this, this.printResult));
},
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos