I'm working on a Lotusscript at the moment which places a menu of actions on the $Inbox (and thereby any folders derived from that design). This action menu has several items with "Hide action if formula is true" selected. The logic behind all of this works perfectly, however I now have the need to re-evaluate these formulas if the user performs certain actions within the folder (eg: if the action is hidden because a certain flag has been set, and that flag is changed I would then like to re-evaluate the formula so the action now appears). I can't seem to find any way to reload a folder or re-evaluate these formulas. Does anyone know of a way to do this?
There is a RefreshHideFormulas method for the NotesUIDocument, but not for a view. You may be able to call the ReloadWindow() method of NotesUIWorkspace, though, so that's worth a try.
As an alternative, triggering an agent that calls the #Command RefreshHideFormulas may also work for you:
Here is some code (borrowed from http://ideajam.net/ideajam/p/ij.nsf/0/3BBA7E25A972ABD88625759600445A50?OpenDocument)
1) Create an #Formula Agent called "RefreshActions", Agent List Trigger with the following code:
#SetTargetFrame("YourFrame");
#UpdateFormulaContext;
#Command([RefreshHideFormulas]);
2) In your Lotusscript, where you want to insert a "refresh frame" call, add this:
Dim agent As NotesAgent
Set agent = db.Getagent("RefreshActions")
Call agent.Run()
You can use property "Evaluate actions for every document change" found in view properties, [i] tab. Every selection (click, arrows) of document will trigger reevaluating hide whens for actions. Maybe it will work after refreshing view by some action.
Related
I have created a form in which the user enters values, then clicks "Add". This then creates a table in a Rich Text field on the form.
This is done by creating a temporary document with a richtextitem on it, expoting this via DXL, inserting the table in DXL into the richtextitem, and importing in back. Then I use uidoc.ImportItem to copy the table from the temporary document into my uidoc.
This works just fine, and I'm rather pleased with myself. In addition, the user can "Add" further rows. This is done by deleting the table (using Call uidoc.FieldSetText("table", "")) and recreating the table from the new values, as above.
However, each row of the document has two buttons, "Edit" and "Delete", so that the user can either edit a row, or delete it, after the table has been created.
So far, I am concentrating on coding the "Delete", and it works. However, when the code reaches any uidoc action, e.g. Call uidoc.FieldSetText("table", "") or Call uidoc.EditGotoField("Table") I get the dreaded "Error - Script is Busy" message in the status bar, and Notes crashes when I close the document.
I presume this is caused by the button thinking it's in a different document, so when it moves focus to a field in what it considers to be a different uidocument, it causes a problem.
I've tried a few different approaches, e.g. having the button set fields on the NotesDocument, and then refresh, using a hidden value to trigger the updateTable Sub. I've also experimented with triggering an agent, but as the uidoc has not been saved, I can't get a session.documentcontext, and of course I can't access the UI in an agent.
One thing I haven't tried yet, is making the Delete button trigger an formula command that would cause the uidoc to be refreshed, and set off the updateTable Sub from the PostRecalc event.
If anyone has any other suggestions, I'd be very grateful as this is the one niggle that is preventing me improving the performance of one of our legacy forms by about 1000%.
OK, so I tried using Formula language instead of Lotusscript in my DXL-created button in a rich text table in a rich text field in an unsaved uidoc. And it worked :-)
#Setfield("deleteRow"; 1);
#Command([ViewRefreshFields])
Obviously, the LotusScript that creates the DXL document subsitutes the approriate row number in each button's #Setfield. Also, I now have LotusScript in the QueryCalc event that checks the value of doc.deleteRow(0), and calls the updateTable subroutine if it's greater than 0.
This process has been yet more evidence that explaining one's problems to someone else can often trigger the thought that leads to the solution.
The dialog prompts for a 'min score' value which the workflow needs as a parameter. I have tried saving the parameter somewhere in the record that was selected for the dialog. That works, but depending upon the result of one step in the workflow, it might need to clear it out again. The condition that determines whether the clear is necessary does not seem to return the correct result, so the value gets cleared out anyway. But rather than debugging that very clumsy method, I wonder if there is a better way to pass the parameter from the dialog to the workflow? Is the system job record associated with the dialog available to the child workflow, for example?
Workflows can't have parameters like Dialogs, but you could simulate the same thing. The dialogue could set some field values on the entity and then a workflow could trigger from those field values changing. It could be as simple as having a hidden "Start Workflow X" checkbox that fires a workflow when set to true. The workflow would probably need to clear that checkbox as the last step to be ready for next time.
What you are looking for is called a Custom workflow .
They can be used as steps in your dialog and they do accept Arguments.
for more information visit this tutorial as it is a nice walk-through for this approach.
it would be a time-taking way to do this though, but if you really need to use dialogs and pass parameters from them, you need to implement all your workflow functionality in a Custom Workflow.
I have a fairly straightforward and common use case. A panel, in which resides a repeat control. The repeat control gets its content from a view lookup by key. Below that repeat control is another panel. This panel has a data binding to a new notesdocument. The panel has a couple of fields on it for the new document and a submit button.
It all works, however after submit (presumably in the "postSaveDocument()" event) I want to call back up to the repeat control and have it re-perform its lookup and refresh its content.
I'm looking to understand syntactically, how I can reference the repeat control and its properties and methods from elsewhere on the document -- and secondarily (though I can look this up once I get the first part figured out) what the refresh() method would be for that that repeat control.
Ideally, I think its something like: xp:page.repeatcontrolname.refresh() -- though I know that isn't right.
I'm sure once I see an example, it will apply to a myriad of other things.
Update :
I discovered that the repeated elements were actually refreshing but I wasn't seeing a new entry added to the list. The reason, ultimately, turned out to be that to add another entry to the repeat list I needed a new "control" -- but I'd checked that box (on the repeat control) that said "Create Controls at Page Creation". It was preventing my XPage from creating another entry for the new document to display!
This article explains the syntax for doing what you describe:
http://avatar.red-pill.mobi/tim/blog.nsf/d6plinks/TTRY-84B6VP
I have a feeling that this one captures the actual use case.
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Create_and_display_responses
The key setting that people tend to miss is "ignoreRequestParams".
Andrew,
The 'XSP.PartialRefreshGet' call was broken in Domino release 8.5.3 which results in the '_c9 is undefined' error.
Have a look at the article posted by Tommy Valand:
http://dontpanic82.blogspot.com.au/2012/03/patch-for-bug-in-xsppartialrefreshget.html
Basically to work around the problem a second argument is required to be passed to the call, for example:
XSP.partialRefreshGet("#{id:ExistingDevicesList}", "")
I'm not a Notes programmer, however, for my sins, have been working on some Notes features for an in-house project recently. I need to enable/disable editing of a field depending on circumstances. It seems to me to be a fairly standard feature, I need, but I can't find any information on how to do this anywhere.
In form setup (and other field's onchange) code, something like the following:
if some requirement = true then
textField.enable = true
else
textField.enable = false
end if
I've seen other places where there's a workaround of conditionally hiding paragraphs based on some code, having 2 paragraphs with opposite hiding conditions, one with an editable field, the other with a computed field. However, I don't know enough about Notes to see how this is implemented (I can see it done on other forms, but there seem to be some 'magic' steps within Notes which I either can't see or don't get).
[EDIT]
The reply from Kerr seems to be what I'm looking for, but I still can't find out where the InputEnabled property is located. Should have said in the initial question, I'm using Notes 7.0.3.
In fairness, it doesn't matter what the circumstances are for when to enable/disable the field, it's just some boolean condition that is set, in my case only on form loading so I don't even have to worry about this changing dynamically while the form is displayed.
I've got a few issues with Notes, my largest bugbear being that it's so tied so tightly to the Designer UI, which is utter shite. I can do this sort of thing programmatically in most GUI languages (C#, Java, Delphi, even VB), but I need to open property boxes in Notes and set them correctly.
This would be OK as an optional method, but forcing you to go this way means you can only work as well as the IDE lets you in this case, and the IDE here seems to actively work against you. You can't open multiple functions/scripts, you can't swap from one script to another without going back to the menus on the left, you can't easily search the codebase for occurrences of variables/fields (and believe me, this is a major failing for me because either Notes or the internal codebase in my case seems to make a lot of use of global variables!), you can only work with fields through the property boxes that get displayed, you can't edit code in Designer while debugging through the main Notes client.
While the Java side of the coding is better than LotusScript, it's still fairly crappy (why can't you debug INTO Java code?? Why do you need to re-import JAR files for each Java class, does each class have a different CLASSPATH???). Possibly this was improved in Notes 8, I hear it's based on Eclipse. Does anyone know whether this is true or not?
It would help to hear more specifics about the 'circumstances', but the most common way to handle this is to use a hide when formula on the field you want to enable/disable.
Technically you are not enabling or disabling the field, just hiding it, but usually that works just as well.
Since there are few events to work with in Notes, developers commonly use the document refresh as the 'event' to cause the field to hide or show.
Let's assume you have two fields called TriggerField and Subject. Say also you want to disable the Subject based on a value in the TriggerField. The easiest way to do so is to set the TriggerField as a Dialog List type and check the "Refresh fields on keyword change" option. This means when the value of the dialog list changes, the entire document will get refreshed.
Then in your hide when formula for the Subject field, you specify your criteria for when to show or hide that field. Anytime field values change, followed by a refresh of the document (i.e. form), that hide when formula will be re-evaluated.
There are other ways, depending on your circumstances, to solve this problem. If you want to let the user refresh the form themselves, put a button on the form that calls the #Command([ViewRefreshFields]) command. You can add any other formulas to that button before the refresh command if you want to make other changes to the form at the same time.
Another option is to make a certain field display-only. Then create a button that runs LotusScript to allow users to change that display-only field. In the script you can propmt the user for a value, set the display-only field, and then call for a document refresh.
In ND7 and up if you want to just disable the field for input, write an appropriate formula in the InputEnabled section of the field you want to disable.
So I have two fields one called Trigger, a checkbox with the value "On" and another Subject that is a text field. When Trigger is checked I want the value Subject to be enabled.
I simply put the following formula in the Input Enabled element of the field Subject:
Trigger = "On"
I also want this to be recalculated whenever the value of Trigger changes so I select the "Refresh fields on keyword change" option on the Trigger field.
If you're stuck in an older version you need to to hide paragraphs appropriately.
I am using VSTO 3.0 and the ribbon designer gives me a ribbon that is apparently shared across documents.
So if I have Document specific state( number of XML marked up tags say) that needs to show up in the ribbon( or a toggle button ) then all documents seem to share the ribbon instance
How can I fix this
TIA
You can use Application.DocumentChange event or Application.WindowActivate event.
The first is fired then you change the current active document, but in the arguments there's no information about that document, so it's difficult to work with because you'll have to figure that out.
The latter is similar and it's fired every time you change of window but in this case it passes the current active document as an argument, so it's easier to change the ribbon if you need to check the value of any document property. That worked for me.
Hook into an appropriate event (such as when the active document is changed) within the document model, and in that event invalidate the appropriate ribbon button (you'll need the id of the element from the original Ribbon xml you load).
Then, when the refresh state callback for that button occurs, you can update the caption/image/enabled as required.