How to invoke the custom widget setting page from the widget (not the builder)?

1078
6
Jump to solution
06-14-2017 01:16 PM
DavidWendelken
Occasional Contributor

Currently at version 2.3, hopefully soon at 2.4.

The Query widget is pretty close to what my users want, but it lacks a really important feature.   The queries are defined at design time instead of at run time.   My users want to define queries at run time.  

It occurred to me that if the users could invoke the settings.js page from the page based on widget.js, they would be able to define new queries without me having to write as much code.   All I would have to do is add a flag so that the new configuration data would not be written back to the config file (when invoked in this manner), it would just be forgotten when the user left the application.

Boy, howdy, for something that I thought would be easy, it hasn't been.

The code that invokes the settings page seems to be in either client\builder\main.js or client\builder\plugins\widget-config\WidgetSettingPage.js.   Neither of those are available from within a built application (or at least I don't think they are).

Anyone have any ideas, other than (a) giving up on the approach or (b) slogging thru minimized code to clone the relevant methods?   I'm hoping someone will chime in and say, "Oh, this is an easy way to do it!"

0 Kudos
1 Solution

Accepted Solutions
DavidWendelken
Occasional Contributor

I worked this issue on and off over the last 2 weeks.   It can be done.   I'm untrained on dojo/dijit UI classes so it's been slow going.   I was able to get the setting page to display and function.   Didn't get around to making the changes to disable writing back to the config file because I found a better solution.

I found out that the same query capability at run time was available built into the map.  There is a little Up-arrow on a tab at the bottom of the map.  If you click on it you see tabs with the different feature layers on them.  Each tab has an Options menu with a Filter option.  Once I found this functionality I stopped work on this issue.

As for getting the setting page to show up, the setting.js and setting.html files in a widget do not include the Ok, Cancel or Close window buttons.  Nor do they include the code to change the widget icon.  You'll have to code your own container to load the setting page into.   Subtle differences between my container and the container they use caused the display of the fields to be horribly wrong.  I had to change a few style settings at run time to get it to work.   Since your container may be different from my own, comparing style settings of the page you invoke with your code and the same page invoked with their code will identify the differences.

The key to starting up the page after coding a container for it was finding the lines of code necessary to do so.

A call to

widgetManager.tryLoadWidgetConfig(setting)

asynchronously starts off the load process.

When it returns with a result, you'll need to lang.hitch a function to invoke

    widgetManager.loadWidgetSettingPage(setting)

asynchronously.  When that returns, place it in your container and run the setting page object's startup() method.

As for the setting object so casually passed around above, I went into the debugger and checked out what was in it when the setting page was invoked in the web appbuilder client.   It turns out that all the necessary values to construct a setting object of my own were available as this.* values in the widget.js file.


The setting page appears to write to the config file on startup, which was a bit surprising.  I suspect it has to do with setting up an initial default page if one isn't there.  As I stopped work on this task about the time I noticed that, I can't add more detail.

As for node.js dependencies, haven't found any.  All the code I've had to call to make this happen has been automatically deployed to each application.

I hope this will help others who find themselves wanting to do something similar.

View solution in original post

6 Replies
RobertScheitlin__GISP
MVP Emeritus

David,

   I am going to go out on a limb here and say that this is not going to work. The builder portion is run using NodeJS which has file system access to write the json files. Your attempted use of the settings file will not have that access on the client and will assuredly fail.

DavidWendelken
Occasional Contributor

Should not be a problem because the users won't be writing back to the file system.   The json file gets loaded into memory and the widget uses the values in memory to make its decision.  I'll be modifying the back-end to disable any attempts to write the changes back to the file system when invoked from the runtime.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Good luck is all I can say. I can't imagine how many NodeJS dependencies you are going to run into.

0 Kudos
DavidWendelken
Occasional Contributor

Good point.   I'll find out.

0 Kudos
DavidWendelken
Occasional Contributor

I worked this issue on and off over the last 2 weeks.   It can be done.   I'm untrained on dojo/dijit UI classes so it's been slow going.   I was able to get the setting page to display and function.   Didn't get around to making the changes to disable writing back to the config file because I found a better solution.

I found out that the same query capability at run time was available built into the map.  There is a little Up-arrow on a tab at the bottom of the map.  If you click on it you see tabs with the different feature layers on them.  Each tab has an Options menu with a Filter option.  Once I found this functionality I stopped work on this issue.

As for getting the setting page to show up, the setting.js and setting.html files in a widget do not include the Ok, Cancel or Close window buttons.  Nor do they include the code to change the widget icon.  You'll have to code your own container to load the setting page into.   Subtle differences between my container and the container they use caused the display of the fields to be horribly wrong.  I had to change a few style settings at run time to get it to work.   Since your container may be different from my own, comparing style settings of the page you invoke with your code and the same page invoked with their code will identify the differences.

The key to starting up the page after coding a container for it was finding the lines of code necessary to do so.

A call to

widgetManager.tryLoadWidgetConfig(setting)

asynchronously starts off the load process.

When it returns with a result, you'll need to lang.hitch a function to invoke

    widgetManager.loadWidgetSettingPage(setting)

asynchronously.  When that returns, place it in your container and run the setting page object's startup() method.

As for the setting object so casually passed around above, I went into the debugger and checked out what was in it when the setting page was invoked in the web appbuilder client.   It turns out that all the necessary values to construct a setting object of my own were available as this.* values in the widget.js file.


The setting page appears to write to the config file on startup, which was a bit surprising.  I suspect it has to do with setting up an initial default page if one isn't there.  As I stopped work on this task about the time I noticed that, I can't add more detail.

As for node.js dependencies, haven't found any.  All the code I've had to call to make this happen has been automatically deployed to each application.

I hope this will help others who find themselves wanting to do something similar.

DavidWendelken
Occasional Contributor

As a new dojo/dijit UI coder, it's a bit disorienting because the html files in the widget and the html output I can see in the page debugger are extremely different.   I found that adding id attributes to the elements defined in the html files really helped me figure out what run time generated html went with what.

0 Kudos