POST
|
Theres a screenshot in this post showing something like what you are asking. I dont know anything about it. I just got it as a hit when I was searching for something else earlier. https://community.esri.com/t5/arcgis-experience-builder-questions/editor-widget-and-picking-up-the-current-selection/m-p/1072372
... View more
12-04-2023
01:16 PM
|
0
|
0
|
154
|
POST
|
So a VP asked me to revise our experience builder editor app which is using the default editor widget. THey dont want the label 'Editor', the Settings, thing, the "Edit features", the Select arrow, or the Create features filter box in it. Basically they want it to look like the Smart Editor from WAB, which we've used numerous times in the past. Anybody got any options for me? I looked at the sample code for the Editor (https://github.com/Esri/arcgis-experience-builder-sdk-resources/blob/master/widgets/editor/src/runtime/widget.tsx) and it looks to me like all of that is in some hidden code and will always pop up anytime you use an editor widget? So I'm guessing I'm out of luck unless I want to code up a new editor from scratch?
... View more
12-04-2023
01:07 PM
|
1
|
1
|
216
|
POST
|
Augh! That was so helpful, thank you! I turned all the lower case values into Values where appropriate. Then it started recognizing stuff. I've gotten it to where this is now valid, but I have some kind of incrementing mismatch. I've gotten an initial value set here of 35 for the Latitude text box. Whatever I have the value to here appears to becoming the default constructor (props) {
super(props)
this.state = {
jimuMapView: null,
totalNumOfLayers: 0,
setlatTextBoxValue: 0,
latTextBoxValue: 35,
updateInputLat: 0,
LongTextBoxValue: -86.9,
StructureHeightTextBoxValue: 0
} Then later we get to the revised input listener updateInputLat=(event)=>{
console.log("Latitude box change")
console.log("event.target.value : ");
console.log(event.target.value || "undefined"); //this does get the right value.
try{this.setState({latTextBoxValue: event.target.value})}
catch{console.log("line 319 failed")} //this is not erroring out?
try{console.log("this.state.latTextBoxValue: ")
console.log(this.state.latTextBoxValue) //succeeds but is 1 off from event.target value???
}
catch{console.log("line 325 failed")} //this is not erroring out? but now, despite all the values working as variables... the values arent syncing up between event.target value and this.state.latTextBoxValue Each red line in the screenshot below represents the console changes when clicking on the Latitude box's up arrows. Any ideas why latTextBoxValue is 1 off from event.target.value?
... View more
11-21-2023
04:29 PM
|
0
|
2
|
536
|
POST
|
We have an existing WAB app that has a Latitude box, Longitude box, and a 3rd box for structure height. It has a calculate button. You can either click on the button or click on the map and it will update the lat/long boxes and use the structure height value to run a brief analysis by getting a pixel value from a hosted raster image service layer. It works great, we've used it for several projects with various tweaks over the years. But now we need to move it to Experience Builder. I was starting from scratch but realized that one of Robert Scheitlin's Feature Panel Widget did much of the base stuff we needed. So I started with it and heavily modified it. Commented out all of the attribute stuff. Replaced its disabled popup with a new one that returns the values from the raster. I recreated our lat/long/height boxes in the side panel. I've got half the stuff I needed done. But I can't figure out how to pass variables or values around between parts of the code. Which is what I need to do to get the Calculate button to trigger the popup based on the entered lat/long. In WAB I would have inspected the DOM elements and modified their values. But in React this is apparently Very Bad To Do. All of the stuff I've read says to use States and particularly 'useState', but I cannot get them to work. Here's my lat/long/height boxes and calculate button. This code is in the render section. They all show up and exist. You can use the arrow buttons or enter numbers and those change the values in the boxes. Latitude: <input type="number" id="LatTextBox" defaultValue="34.7" style={this.latlongboxStyles} onChange={this.updateInputLat} value={this.state.latTextBoxvalue}/> Decimal Degrees Longitude: <input type="number" id="LongTextBox" defaultValue="-86.9" style={this.latlongboxStyles} onChange={this.updateInputLong}/> Decimal Degrees <br></br> <div className="StructureHeightDiv"> Structure Height: <input type="number" id="StructureHeightTextBox" defaultValue="0" style={this.latlongboxStyles} onChange={this.updateInputStructHeight}/> Feet </div> <div className="CalculateButtnDiv"> <button className="CalculateButton" type="button" onClick={this.handleCalculateButton}>Calculate</button> </div> and my updateInputLat listener passes the event value succesfully updateInputLat=(event)=>{ console.log("event.target.value : "); console.log(event.target.value || "undefined"); //this does get the right value. } But I cannot figure out how to pass that value to a variable that I can access outside of updateInputLat try{ { console.log("this.latTextBoxvalue: ") console.log(this.state.latTextBoxvalue) }} catch{ console.log("this.latTextBoxvalue is undefined") } try{ { console.log("trying setlatTextBoxValue(event.target.value);: ") //console.log(this.latTextBoxvalue) this.setlatTextBoxValue(event.target.value); console.log("returning setlatTextBoxValue") console.log(setlatTextBoxValue) console.log("returning latTextBoxValue") console.log(latTextBoxValue) }} catch{ console.log("error between 337 to 341") } this.setState({latTextBoxValue: event.target.value}) console.log("2: latTextBoxValue???") console.log(latTextBoxValue) So in short, I have no idea how to define a global variable to pass around the... classes? functions? what are they even called? And I cant find any esri documentation on this. Eveyrthing I find for react doesnt work. I've tried declaring these variables all over the place and just cant figure it out. Thanks for any help!
... View more
11-21-2023
02:17 PM
|
0
|
4
|
611
|
POST
|
Robert, Does this count even if it opens from over in this area, and not from the buttons located within the header controller?
... View more
11-17-2021
10:17 AM
|
0
|
1
|
455
|
POST
|
Ah... Figured out that event.preventDefault() was the functional bit I was looking for which locks down the rest of the page from interaction. It's present in the splash widget and in code for launching Messages. And Messages do pretty much we want our splash button call to do, lock down the page and demand a response. event.preventDefault();
var helpMessage = '<div class="intro">' +
'this is a disclaimer popup'+
//this.nls.helppopupmsg + // to make the real disclaimer, put it in strings.js
'</div>';
new Message({message: helpMessage}); Robert, do you know if we can add custom buttons or listen to the "Ok" button associated with a Message created from jimu/dijit/Message? I figure we can show the disclaimer message then load our custom widget after the message closes. I see in jimu/dijit/Message.js it has a function called _preProcessing which looks for buttons and adds an ok button if none are present, so apparently we CAN add buttons but I'm not sure how. Also that function isnt called from within Message.js so how does it even run?
... View more
11-16-2021
04:33 PM
|
0
|
2
|
573
|
POST
|
not a great solution, but a possible work around. The esri default Splash widget has events at the bottom that publish 'splashPopupShow' and 'splashPopupHide'. So if you have a splash widget, you could try listening to that. The user might still click through it faster than it takes to get the map stuff loaded? Also try googling for something like 'how to find out what javascript events are running'? https://stackoverflow.com/questions/3787555/how-to-find-out-which-javascript-events-fired
... View more
11-16-2021
12:18 PM
|
1
|
0
|
338
|
POST
|
We added an on screen widget and made the button invisible per client request; they want it to open from somewhere else. Client has 2 sets of layers they want showing, in separate layer lists/table of contents (TOC) widgets. We got that working, basically by adding a second widget and configuring it to the second set of layers. We added a button to the bottom of the second TOC widget. So right now you can click the first TOC widget icon, see its layers listed, then click the second TOC widget icon, and it's layers also get listed, but it has a 'launch report' button at the bottom which launches our custom widget. The problem is once you click that button, after succesfully launching the custom widget, it closes the 2nd TOC list and switches back to the 1st TOC widget, since they shared the same panel. How we made the button work: 1) added code to the 2nd TOC's html file <a style="float:left; margin-right:10px; font-weight: bold; font-size: large;" href="#" data-dojo-attach-point="btnLaunchReport">Launch Report</a> 2) added code to the TOC's widget.js file //under bindEvents
this.own(on(this.btnLaunchReport,
'click',
lang.hitch(this, this._reportWidget)));
//new function
_reportWidget: function() {
var widgetCfg = this._getWidgetConfig('reportWidget');
widgetCfg.visible = true;
var headerCfg = this._getWidgetConfig('HeaderController');
var headerWidget = this.widgetManager.getWidgetByLabel(headerCfg.label);
//This is need to show the widgets icon in the header
headerWidget.resize();
//This actually open the widget
headerWidget.setOpenedIds([widgetCfg.id]);
console.log(widgetCfg.id);
}, this initially gave us errors saying that the config object was missing so we added code (lines 10-12, and 15) to the header controller widget.js below. //this is in themes/FoldableTheme/widgets/HeaderController
//we tweaked the original setOpenedIds function to look for our widget's config if it gets here and cant find one
setOpenedIds: function(ids) {
console.log("This is the ID test " + ids);
if (ids.length === 0) {
return;
}
var config = this.getConfigById(ids[0]);
if(ids[0] == "_49"){ // set to our widget ID number
config = this._getWidgetConfig('reportWidget');
}
if (!config) {
console.log("No config found for " + ids[0]);
return;
}
if(this.openedId){
this._switchNodeToClose(this.openedId);
}
this.openedId = ids[0];
if (config.widgets && config.openType === 'openAll') {
this._switchNodeToOpen(config.id);
} else if (!config.widgets) {
if(this._getIconNodeById(config.id)){
this._switchNodeToOpen(config.id);
}else{
this._showIconContent(config);
}
}
}, It worked, successfully launching the custom widget, but side effect is it closes the TOC widget which shows all the layers, so the user would have to open it again. Minor bug but still a bug. It also launches an error in the console "TypeError:can't access property "className", b is null in the _showIconContent line, which implies that the code is hitting the header controller widget again after launching the custom report widget. So I'm not sure what's going on there. I'm sure we're doing it wrong. Any help would be appreciated.
... View more
11-16-2021
11:20 AM
|
0
|
3
|
493
|
POST
|
Robert, I was looking at that code, I'll try to dive deeper into it.
... View more
11-16-2021
10:49 AM
|
0
|
0
|
600
|
POST
|
Hello. I've been trying to figure out how to launch a splash screen repeatably from other widgets or buttons. Splash screen being defined as either the splash widget or something else that is customizable with images + texts + "I agree" checkbox. The client asked us to isolate some layers into a seperate table of contents/layer list widget. We did that and got that mostly working. But the client wants a disclaimer/splash screen to pop up when the button which launches that seperate list is clicked. Additionally they want the disclaimer/splash to launch when another custom reporting widget is launched. So this splash screen a) is not supposed to launch at the start of the app like the default splash widget, b) has to launch when a button in the headercontroller is clicked which launches the TOC widget and c) when a custom 'button' we added to the TOC is clicked, which launches yet another widget. I looked at the default Esri splash widget.js code to try and figure out what makes it tick and couldnt quite figure it out. I saw that theres .focus and .blur (commenting .blur out did nothing), and various places that check for if the requires checkbox setup has been toggled on, but I'm not sure what like, actually locks off the rest of the screen from working or requires the checkbox be hit. So I don't really know how to proceed. Non Web-App-Builder javascript guides basically say just show a div over your screen and/or put the rest of your page in another div and hide it while the splash screen is up. I'm afraid trying that would break everything and am hesitant to try a non-WAB/non-Dojo solution if there is actually a WAB/Dojo solution out there. While I wait and see if anyone here has suggestions I'm going to look into 'help dialogue' boxes because I recall making one of those in the past and those are kinda similar.
... View more
11-16-2021
10:12 AM
|
0
|
5
|
623
|
POST
|
We're using the Identify widget as the base of our widget, and started back in October. Well AGOL added grouped layers a couple of months ago. For stability reasons we switched our map to one that has grouped layers in it, and we can't really switch back because the client it's going to will keep it that way. The identify widget does generate it's results correctly in that all of the layers that we add in the UI get recognized, but now they don't seem to fully honor the order that we specified in the widget setup UI or the order in the table of contents of the map. The first tier of groups seems to be correct, but the stuff within them doesnt. We have subgroups within the groups and they seem to get placed out of order, and their children layers seem to also be placed out of order. I was impressed that it worked with the grouped layers without any additional changes, but then I realized we lost our ordering. Any thoughts on code we can add to change this? Since we didnt modify anything to do with the sorting portion of the Identify widget, I'm not sure that I have any code or anything that I can post here. Let me know if you need anything further from me to help answer this question!
... View more
07-15-2020
05:10 PM
|
0
|
0
|
268
|
POST
|
Development overview—ArcGIS Web AppBuilder (Developer Edition) | ArcGIS for Developers See that page.
... View more
07-08-2020
09:32 AM
|
0
|
0
|
378
|
POST
|
I've gotten this to work with geojson files. I have added a button that exports drawn shapes (generated in Robert's Modify Widget, which uses DrawBox to make them). I did not get it to work with kml/z and I found the same thing you did about shapefiles. Export to them is unsupported, probably because to import them they have to be zipped, so they didnt want to figure the inverse of that out. _onExportDrawnArea: function(){
//get graphics layer
//export graphics layer as geojson
require(["jimu/BaseFeatureAction", "jimu/exportUtils", "jimu/FeatureActionManager", "esri/tasks/FeatureSet"], lang.hitch(this, function( BaseFeatureAction, exportUtils, FeatureActionManager, FeatureSet) {
var graphicFeatures= [];
var graphicsLayerGraphics = this.graphicsLayer.graphics;
for (var f = 0; f < graphicsLayerGraphics.length; f++)
{
//console.log("graphicsLayerGraphics.length"+graphicsLayerGraphics.length);
//console.log(graphicsLayerGraphics );
graphicFeatures.push(graphicsLayerGraphics[f]);
};
var drawnShapeData = new FeatureSet();
drawnShapeData.features = graphicFeatures;
var ds = exportUtils.createDataSource({
type: exportUtils.TYPE_FEATURESET,
filename: 'features',
data: drawnShapeData
});
ds.setFormat(exportUtils.FORMAT_GEOJSON);
ds.download();
}));
},
... View more
06-10-2020
02:07 PM
|
0
|
0
|
1470
|
POST
|
So in that script above, var tables = $('table'); What this boils down to is that its using jquery (the dollar sign '$' is shorthand for jquery code) to search for any elements with the name 'table' in them. That's just a standard html formatted table. It finds all of the elements with the table tag and puts them into the 'tables' variable. After that it's using that large complicated looking for loop that comes next to recode the contents of the table so it can export it properly for the xml standard (again: this is an xml table it's exporting which excel can read). for (var i = 0; i < tables.length; i++) {
for (var j = 0; j < tables[i].rows.length; j++) {
rowsXML += '<Row>'
for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
dataValue = (dataValue) ? dataValue : tables[i].rows[j].cells[k].innerHTML;
var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
dataFormula = (dataFormula) ? dataFormula : (appname == 'Calc' && dataType == 'DateTime') ? dataValue : null;
ctx = {
attributeStyleID: (dataStyle == 'Currency' || dataStyle == 'Date') ? ' ss:StyleID="' + dataStyle + '"' : ''
, nameType: (dataType == 'Number' || dataType == 'DateTime' || dataType == 'Boolean' || dataType == 'Error') ? dataType : 'String'
, data: (dataFormula) ? '' : dataValue.replace('<br>', '')
, attributeFormula: (dataFormula) ? ' ss:Formula="' + dataFormula + '"' : ''
};
rowsXML += format(tmplCellXML, ctx);
}
rowsXML += '</Row>'
}
worksheetNameDirty = (i+1)+"_"+wsnames[i];
worksheetNameClean=worksheetNameDirty.replace(/[^a-zA-Z0-9]/g,'_').replace(/_{2,}/g,'_').slice(0,31);
ctx = { rows: rowsXML, nameWS: worksheetNameClean || 'Sheet' + i };
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
} So you would want to have your widget create an html table (it can be hidden so the user doesnt actually see it) in your page somewhere, and you would want to feed the info that you want returned into that html table. If you want to exclude certain rows or certain columns, you would need to program those in as if loops. I would exclude them from the table you create You can have multiple tables. The code will iterate through all of them, any one of them that has the html tag for 'table'. For help on generating a table, I'd refer you to the internet. HTML Tables - Learn web development | MDN javascript - Populate table element using string - Stack Overflow Dynamically creating a HTML table with JavaScript Styling tables - Learn web development | MDN (Note: Styles will not transfer to the generated excel file. There's no way to programattically make that thing look the way you want it to. But this is good for if you want to show the table on a page for the user to view) Look at the source code on this page for the definitive example of an html table in existence Planets data (this is linked to via one of those first MDN links)
... View more
05-11-2020
10:22 AM
|
1
|
1
|
3695
|
Title | Kudos | Posted |
---|---|---|
1 | 12-04-2023 01:07 PM | |
1 | 11-16-2021 12:18 PM | |
1 | 05-11-2020 10:22 AM | |
2 | 05-06-2020 02:01 PM | |
2 | 12-23-2019 12:26 PM |
Online Status |
Offline
|
Date Last Visited |
9 hours ago
|