Under the form, I have a save button that will be disabled after the form submission. The button should be enabled if any changes are made to the data or a comment is added.Any help will be appreciated.
Discussion posts and replies are publicly visible
I recommend to not implement one huge form covering all use cases. This becomes complex and hard to maintain.
But, to answer your question, add a local variable "isModified" and default it to false. Then add a a!save() to all fields to update isModified to true(). Then use that status to add some logic to the submit button.
Now, check my first sentence ...
do u have any example to quote?
A simplified example:
a!textField( label: "my data", value: ri!textField1Value, saveInto: { ri!textField1Value, a!save( local!isModified, true() ) } )
if there are nested interfaces, where the above example for data comparison cant be used?
for any child interfaces where data could also be modified, and which would thus need to trip the "isModified" flag, simply pass in the "isModified" local variable into a rule input in the child(ren), and save into it from any relevant field(s) there.
a!localVariables( local!data: { ri!datasubset, ri!transValue, ri!orgValue, ri!ageValue }, local!originalData:local!data, local!modified: not( exact( tostring(local!data), tostring(local!originalData) ) ), a!formLayout( buttons: a!buttonLayout( primaryButtons: if( ri!isEditable, { if( ri!canSubmit, a!buttonWidget( label: cons!BUTTON_VAL_SUBMIT, style: "PRIMARY", submit: true(), validate: true(), value: cons!BUTTON_VAL_SUBMIT, saveInto: ri!buttonAction, disabled: if( and(rule!APN_hasValue ( ri!SubmissionDate),local!originalData<>local!modified), false(), true(), ) ), {} ), a!buttonWidgetSubmit( label: cons!BUTTON_VAL_SAVE, style: if( ri!canSubmit, "NORMAL", "PRIMARY" ), submit: true(), validate: true(), value: cons!BUTTON_VAL_SAVE, saveInto: ri!buttonAction, disabled: if( and(rule!APN_hasValue ( ri!SubmissionDate),local!originalData<>local!modified), false(), true(), ) ) }, {} ) ) ) )
I tried this code for the interface with multiple child interfaces. buts it's not working.even if data is changed , the buttons are not getting enabled. Any suggestions?
This would work except the way you've declared local!originalData, is causing it to automatically update any time any change is made to local!data.
Remember that a!localVariables() variables have a default behavior which assumes "refresh on referenced var change" is TRUE. That means, as you have it written, if you save anything into ri!orgValue (for instance), it automatically refreshes local!data, which by update chaining, updates local!originalData (which you don't want).
Luckily the fix is very simple.
local!originalData: a!refreshVariable( value: local!data, refreshOnReferencedVarChange: false() )
With the above change in place, your "local!modified" variable should now properly hold its existing value in spite of updates made to the referenced variable.
I tried this way and it seems it's not performing data comparison. Is there any other possible way, it can perform a logical comparison and gets enables button with the changes
Where and how are you saving the updates to the "local!data" variable (and/or its refernced variables)?
a!localVariables( local!data: { ri!datasubset, ri!transValue, ri!orgValue, ri!ageValue }, local!originalData:a!refreshVariables( value:local!data, refreshOnReferenceVarChange:false() ), local!modified: not( exact( tostring(local!data), tostring(local!originalData) ) ), a!formLayout( buttons: a!buttonLayout( primaryButtons: if( ri!isEditable, { if( ri!canSubmit, a!buttonWidget( label: cons!BUTTON_VAL_SUBMIT, style: "PRIMARY", submit: true(), validate: true(), value: cons!BUTTON_VAL_SUBMIT, saveInto: ri!buttonAction, disabled: if( and(rule!APN_hasValue ( ri!SubmissionDate),local!originalData<>local!modified), false(), true(), ) ), {} ), a!buttonWidgetSubmit( label: cons!BUTTON_VAL_SAVE, style: if( ri!canSubmit, "NORMAL", "PRIMARY" ), submit: true(), validate: true(), value: cons!BUTTON_VAL_SAVE, saveInto: ri!buttonAction, disabled: if( and(rule!APN_hasValue ( ri!SubmissionDate),not(local!modified), false(), true(), ) ) }, {} ) ) ) )
I'm confused though, because the updated code you've attached here doesn't seem to have any places where local!data and/or any of the 4 RI variables it references, get modified whatsoever. So how are you actually performing changes to the underlying data to verify that local!modified isn't working correctly?
Also, this is not the correct name
The actual function name is "a!refreshVariable()"
Additionally the correct spelling of the parameter name is "refreshOnReferencedVarChange" - not "refreshOnReferenceVarChange". The interface designer's built-in error messages should prompt you for these things.
Here's a simplified, ready-to-paste example of exactly how this sort of thing can-and-should work, FWIW.
a!localVariables( local!name: "Mike", local!date: today()-4, local!data: { local!name, local!date /*ri!datasubset, ri!transValue, ri!orgValue, ri!ageValue*/ }, local!originalData: a!refreshVariable( value: local!data, refreshOnReferencedVarChange: false() ), local!modified: not( exact( tostring(local!data), tostring(local!originalData) ) ), a!formLayout( contents: { a!textField( label: "Name", value: local!name, saveInto: local!name ), a!dateField( label: "Date", value: local!date, saveInto: local!date ), a!richTextDisplayField( value: { a!richTextItem( text: "not modified...", showWhen: not(local!modified), style: "EMPHASIS", color: "SECONDARY" ), a!richTextItem( showWhen: local!modified, text: "Modified!", color: "POSITIVE", style: "STRONG" ) } ) } ) )
These mistakes happened as I updated my initial code in this thread but in designer, it's correctly spelled. But somehow I feel this logic is not working . Whenever I do some changes to data buttons are not getting enabled. Adding is modified rule input to all nested interfaces will be hard. it will break the correct working from