I'm pretty close to a solution that will work for me. I have to integrate in a call to a web service (preferably asynch) before I'm done.
But assuming you can compute the values you need without doing all that, here's what will work.
The solution was complicated by an unexpected "feature" of the product. When I am using the edit widget and click on the map, a point is actually created in the database and ONLY THEN is the user asked for input on the attribute values.
I had assumed that an object was created in memory, displayed on the map, the user was asked for input on the attribute values, and ONLY THEN was the database record inserted. That's not as nice an arrangement when it comes to improving data quality as what I expected, but such is life.
Once that misconception was corrected, I needed to find a way to intercept between the request to insert the records and the actual insert. It turns out that the javascript api FeatureLayer class has an event that I can attach a custom function to. I can change the attribute values in that custom function at runtime and the changed values will be written to the database before the user is given a say on attribute values.
And, of course, I had to find the correct place to update that feature layer's event handler.
The good and bad portion of this approach is that any object that gets the featureLayer in question from the map object should have this set of rules applied once the edit widget has been opened. In theory, that would apply to other widgets that change the data, but I haven't proven that (yet).
I recommend cloning the edit widget set of files and making your own custom edit widget, just in case you ever need to fall back to plain vanilla edits.
Here goes:
(in the edit widget 'widget.js' file)
// The widgets.js file is one long list of variables and function definitions. I popped in this code after the
// comment "Methods for prepare to create Editor" as a convenient place to put it.
onBeforeApplyEditsForMyFeatureLayer: function (toDoList) {
var iMax = 0;
if (toDoList) {
if (toDoList.adds && toDoList.adds.length > 0) {
iMax = toDoList.adds.length;
for (var i = 0; i < iMax; i++) {
// Use the attribute names, algorithms, and values that meet your needs.
toDoList.adds.attributes.MyAttributeName = 'my custom run-time defined value';
}
// Repeat above code for toDoList.updates and toDoList.deletes as desired.
}
}
},
Then I modified the _getLayerInfosParam function in the same file.
_getLayerInfosParam: function() {
// ... some code at the start of the function that you leave alone until you get to here...
array.forEach(layerInfos, function (layerInfo) {
var layerObject = this.map.getLayer(layerInfo.featureLayer.id);
// insert this if statement here using the appropriate id for the feature...
if (layerObject && layerInfo.featureLayer.id === 'MyFeatureId') {
on(layerObject, 'before-apply-edits', lang.hitch(this, this.onBeforeApplyEditsForMyFeature));
}
// ... some more code after the change you must made, that you also leave alone.
// Existing closing braces are shown below for clarity
}
// ... more code after the change that you leave alone.
},
Hope this helps someone else.