Hey there folks,
Is it possible to have a calculated expression on a field, and still let it be edited?
The case is: When a user create a new feature, there's a field that contains data that needs to be inputed manually (needs to be editable), but it would be very useful if the user received an "sugestion" on what needs to be writen.
That "sugestion" is obtainable with a Arcade expression, but when I use a calculated expression on a field, and mark it as editable, the expression doesn't get executed, only when it's not editable.
Appears to me that the field can't have both capabilities, am I right? Or there's a workaround?
Thanks.
Ideally that would be solved with a hintExpression. That would allow for dynamic hints, but this isn't a capability of FM maps yet. If you don't need the hint to be dynamic then all you need to do is define the placeholder text on the field.
To address the other part of the question with regards to form calculations that are editable, the answer is that is natively possible to configure in Field Maps Designer if you are using AGOL or Enterprise 11.x.
You would need an additional expression on the field to make it work.
The rules are as follows:
It kinda works, but the field becomes editable only after saved and selected for editing. I'm using AGOL.
The editableExpression I've used is:
if ($originalFeature["field_name"] == null || IsEmpty($originalFeature["field_name"])) {
return false
} else {
return true
}
The calculated expression is:
var intersect_layer = Intersects(
FeatureSetByName($map, "Roads"),
BufferGeodetic($feature, 1, "kilometers")
);
var segment_start;
var segment_end;
var lower_dist = 1;
for (var f in intersect_layer){
var road_dist = Round(Distance(f, $feature, "kilometers"),2);
if (road_dist < lower_dist) {
segment_start= f.start;
segment_end= f.end;
lower_dist = road_dist;
}
};
return Concatenate([segment_start, ' - ', segment_end]);
It appears that the editableExpression is only checked when the form is opened, and changes to the field won't change the field state, only after saving an reopen. Is there a way to make it "reload" the editableExpression? I'd like to be possible for the user to edit the field value on the fly, and not needing to save and reopen (that would be hard to explain to the users).
Note: This is meant for using with the Smart Forms in MapViewer, not the FieldMaps App.
Thanks.
Original Feature may not be doing what you think it is. $OriginalFeauture is only applicable if the edit context is "UPDATE". On "INSERT" the object is null or does not exist, so the way you have written your editable expression is only valid when editing an existing feature. Also, $OriginalFeature does not change state during editing... it is fixed to the state of the feature as last submitted to the database, hence the original state of all the fields when you start an editing session will not change during the current edit session... only after submitting the feature.
Your logic can be probably just be simplified to the following
//editableExpression
if (IsEmpty($feature.field_name)) { return true };
return false;
If, however, you want to mess with $originalFeature, it is probably best to only do so if the edit context is "UPDATE". So check the editType before accessing $originalFeature.
//editableExpression
if ($editcontext.editType == 'UPDATE') {
// Lock manual editing, be sure to set equal to itself in the form calculation.
if (!IsEmpty($originalFeature.field_name)) { return false };
};
// on INSERT or on UPDATE if field is Empty
if (IsEmpty($feature.field_name)) { return true };
return false;
//formCalculation
if ($editcontext.editType == 'UPDATE') {
// Maintian the $originalFeature field value by setting it to itself
if (!IsEmpty($originalFeature.field_name)) { return $originalFeature.field_name };
};
// else if not UPDATE or original field IsEmpty on UPDATE then we do the things below.
var intersect_layer = Intersects(
FeatureSetByName($map, "Roads"),
BufferGeodetic($feature, 1, "kilometers")
);
var segment_start;
var segment_end;
var lower_dist = 1;
for (var f in intersect_layer){
var road_dist = Round(Distance(f, $feature, "kilometers"),2);
if (road_dist < lower_dist) {
segment_start= f.start;
segment_end= f.end;
lower_dist = road_dist;
}
};
return Concatenate([segment_start, ' - ', segment_end]);
Wouldn't be the other way around?
//editableExpression
//If empty return false, so the expression get executed
//If not empty, enable the editing
if (IsEmpty($feature.field_name)) { return false};
return true;
Sorry, but I can't get this to work the way I want to.
I've tried with both $originalFeature and $feature, and you're right, using $feature will change the state of the field, but for me here what's happening, in order:
On Inserting:
On Updating:
This way, to get this to work, the user have to:
If it can't be done, it's ok, I'll leave this out. Just wanna make sure because it could be very useful.
Just an FYI. I don't know if something changed in a new release of AGOL since last summer, but I was able to accomplish what I believe you were looking to do.
// editableExpression
If you have the time, would you mind confirming that this setup/logic is similar to yours? When I implement, I am not seeing this functionality- it will either prevent editing still or, the calculation no longer is triggered. You're not using the FM Designer beta, right?
//edit expression
if ($feature.Q2 == null) {
return true
}
else {
return false
}
//calculate expressions
var yesno = $feature.Q1
if(yesno == 'yes'){
return $feature.otherAttribute
}
Hi Jessy,
I think you have some logic crossed.
To have the following logic, your expressions for Q2 would look like the following:
/* Q2, Editable Expression - edt_q2 */
if (Lower($feature.Q1) == 'yes') { return false }; /* false -> Allow Calc */
return true; /* true -> Allow User to Edit */
/* Q2, valueExpression, val_q2 */
/*
Note:
As long as there is an editableExpression checking the yes/no field
there is no need to check it again in the value expression.
*/
return $feature.otherAttribute;
Thank you for the reply, but I get the same behavior with this logic, too. I may continue to play around with it, however it seems I’m running low on things to try. Again, I appreciate your time!