XPages: one template, two memory models? - xpages

I'd like to maintain one single master template for our XPages application, albeit with 2 different memory models and properties. The development template's model (master) should be on disk, no JS optimization and no dojo compression. The model in the derived template, to be used in client applications, we configure as in memory, optimized JS and compressed dojo.
When set the configuration parameters differently in each template and then refresh the design of the derived template, both templates end up identical (which might seem logical). What I mean: it is not possible to prohibit the XSP settings to be refreshed, like one can set on other elements.
But even if there were such a possibility, it isn't going to work because everything should be recompiled ("clean") otherwise the compressed JS and css aren't properly generated. I found no way to start a compilation on the derived template automatically.
Or is there a way?
Thanks!

Source control and branching should be the right way to handle it: https://www.ibm.com/support/knowledgecenter/en/SSVRGU_9.0.0/com.ibm.designer.domino.ui.doc/wpd_srcecontrol_top.html
Old fashioned way would be to "branch" your templates. Master template for your XSP development, and second template inheriting from the first one. In second template set "Prohibit design refresh or ..." property for XSP.properties design element. Then change its content to fit your needs.
Here's the story
Once upon a time there was a team of developers working on several databases, some of them marked as template for further deployment to production. One developer wanted to reuse some elements from another database - template. Copied, and pasted them into another database. Designer prompted: "Do you want to inherit design from template ...?". Ehm, no. So designer did not flag the design element with template name, what's OK. In addition, designer sets "Prohibit design refresh..." flag, though. Nobody noticed, until release day! New application behaves weirdly, some parts got updated, some not. It was quite easy to discover that "Prohibit..." flag was set, and fix it. But weirdness continues. And guess what? This flag was set on elements not having such check box in designer's GUI (in this case Java sources).
What worked
Create special view showing design elements http://www-10.lotus.com/ldd/ddwiki.nsf/dx/view-of-design-elements.htm.
Create another column showing, what elements are prohibited to refresh. Set "Display values as icon".
"Prohibit design refresh or replace to modify";
#If( #Contains( $Flags; "P" ); 80; 0 ) : #If( #Contains( $Flags; "r" ); 204; 0 )
Create a view action working with selected documents (ss.CurrentDatabase.UnprocessedDocuments for ticked ones, uiv.CaretNoteID and GetDocumentByID for focused only) and call this code to reset the flag.
Sub Prohibit(note As NotesDocument)
On Error Goto errHandler
Dim flags As String
Dim flagsNew As String
flags = note.GetItemValue( "$Flags" )(0)
flagsNew = Replace( flags, "P", "" )
If flags <> flagsNew Then
note.ReplaceItemValue "$Flags", flagsNew
note.Save True, False
End If
Exit Sub
errHandler:
Print "Error on " & note.UniversalID & " (" & note.GetItemValue( "$Title" )(0) & ")"
Exit Sub
End Sub
Disclaimer: in some cases this breaks element's signature - forced sign of whole database fixes it.
Note: That prompt about inheritance - it sets the flag "Prohibit..." if you answer No when copying FROM template TO template - even if it is the same database!
Conclusion
So, in your case, make the opposite - just set the flag by adding "P" to $Flags field of XSP.properties file. By the way, its $TITLE field is "WEB-INF/xsp.properties".
Enjoy!

Related

Design refresh in Lotus Domino does not include all design elements

I have one template from which I'm trying to refresh the design in my database.
However when I run "load design -f database.nsf" or select "Refresh design..." in the context menu in the Domino Designer it always skips the same design elements when updating.
There doesn't seem to be anything wrong with the settings on database level since some elements are updated properly. But I don't know of any other setting on element level than "Prohibit design refresh" that would result in this behavior. If I delete all forms in the database and refresh design again, only those elements that aren't skipped are added to the database.
I have tried creating new copies of database and template, compact, fixup, updall.
Ideas anyone?
UPDATE 1
Checked my elements (forms) access settings like Knut Herrman suggested, but this doesn't seem to be the issue either. The settings on the access tab is "All readers and above" and "All authors and above". (Would have posted picture, but sadly I don't have enough reputation)
UPDATE 2
Tried deleting all elements in the main database and refreshing after with the result that it skips the same elements as mentioned above.
UPDATE 3
I have uploaded a small example with a one template and one database, and only two forms for design elements, if someone wants to check it out. One of the forms is updated on Refresh, the other is not.
If I use Replace instead it works fine btw.
There is an issue with a Language setting that was applied to FormOne in your example database. I think the refresh is ignoring elements in the template that it does not think match your current language.
When I looked at the fields tab in the FormOne design properties, I saw an item called $BabelInfo. This item does not exist in FormTwo. My hunch was that this has something to do with Language settings, so I went looking for the Language settings in Domino Designer. I couldn't find them in the regular dialogs and editing panes! But when I looked at both forms in DXL¹ there was a Language property set to EN-gb for FormOne, and there was no Language setting for FormTwo.
Using the DXL editor, I removed the Language setting from FormOne. On first attempt, this had no effect, but then deleted FormOne from the database - which I presumed had inherited the Language setting, though I'm not sure I checked that. I did a refresh and it added FormOne to the database. Then I made another change to FormOne in the template and refreshed again, and FormOne in the database was correctly updated.
¹ I had to search around before I figured out how to get at the form data in DXL. A right click in the forms list in navigation pane brings up "Edit in DXL". That option is not available in the list of forms in the main pane.
Most likely, your missing design elements need a certain role.
Define those roles in your destination database's ACL and set the roles for you, your servers and relevant users.
It could also be the dates in the main and the template database, that somehow the element in the main db is newer.
Quick solution: delete the element in the main database and refresh it from the template.
This might seem rather obvious, but double-check that the "Prohibit design refresh or replace to modify" property is not selected in your design element properties, i.e. there should be no ticks in the column highlighted in the image below if you want all elements to refresh.
I suspect this may not be the solution, as you said Replace is working, but I thought I'd mention it.

Xpages using 'flags' for different doc. structure on same xpage

My scenario:
The xpage ( document content ) has a complex structure. I have a 1st button which opens this xpage, having in the postNewDocument:
Contr.replaceItemValue("txt_codformularmain","01") // I use this field as a flag.
Now, there is another button which compose the same xpage ... but in this case, I do want the xpage to be different, in other words to have some additional / showed fields.
I could add another code at the postNewDocument, like this:
Contr.replaceItemValue("txt_codformularmain2","01")
Later on, in some views I will filter the listed documents by this 2 fields: some views will be listing the documents where txt_codformularmain=01, other views for txt_codformularmain2=01, and so on.
All the fields are on the same form element. ( I could create easily 2 different xpages, with 2 document contents, but in the form Properties at onOpen and onWebAccess settings, I can add only one xpage )
But, I think it isn't the best approach for this. Because in both cases, postNewDocument takes place, and both fields are having the value 01.
In classic lotus notes programming, I had used only one field ( flag ) and for every different button, inside the button's code I just changed the field value: 01, 02, and so on, before the newDocument had been composed.
Should I use another/ a better approach?
I might go for creating a new form with the fields needed there, and creating a new XPage binded to that form...
dominoDocument.isNewNote() will tell you if it's a new document or not. You can compute visibility based on that.
If it's based on a field value, then again set the visibility based on what the value should be for the panel to be visible - instead of getComponent().getValue() use dominoDocument.getItemValueString() assuming it's a Text field for best practice. In the onblur event of the control that's bound to the field you're checking against, trigger a partial refresh. You will need to amend the default partial refresh settings if there is validation on the page.
Once you're comfortable with that technique, start thinking about using a dataContext to hold whether or not an area should be visible, and referencing that dataContext variable in the rendered property. The benefits of this are not only performance, but youo can give a better variable name to the dataContext to make it clearer when supporting the application what the logic is behind it being visible. For someone supporting the Notes Client app, for example, it's unclear without hunting what state "01" or "02" means. Descriptors like "newDoc", "published", etc have an advantage there.
Another method of optimisation would be to use a Dynamic Content control.
But it sounds like your XPage is going to be complex enough without adding more complexity at this stage.

Create domino view dynamically in XPages

I want to know if I can click a button in my XPage and dynamically create a Domino View and then show it in a panel control on the same page. The reason I want to do this is because I have a categorized view and I don't want to lose category data by using full text search. So I am thinking of creating a new view dynamically and pass my search parameters, like end date or start date, into the view selection formula.
Is it possible? Any other alternative solution is also welcome.
yes you can, but you don't want to. A Domino view takes space in the database and quite some time for its first use. So you end up with a lot of views taking space and the need to adjust database space after removal. Your response times will suck big time.
Categories as shown in Notes views are no web interaction pattern, so you might want to solve a problem that actually shouldn't exist.
The preferred method for Domino application is navigation / drill down over search. But you could do a FTSearch where you add your category to the search parameters and render your results in a repeat control instead of a view control. There you have more control over the look and feel.
Whether or not it's the best solution, the answer to the immediate question about creating a view on the fly is yes: the Database class has a couple "createView" methods to allow you to create a new view, either entirely from scratch or based on a named other view. From there, you can use the "setSelectionFormula" and "createColumn" methods in the created View to build what you want. You can't do EVERYTHING with those methods, but it may be enough.
One problem you'd likely run into is ACL access: you'll need Designer rights to the database, which a normal user most likely wouldn't have. If you use the sessionAsSigner object to fetch a signer version of the DB (say, "var signerDB = sessionAsSigner.getDatabase(database.getServer(), database.getFilePath())"), you can work from there. Off the top of my head, I don't remember if you will also have to up the "Maximum Internet access" setting on the last tab of the ACL to Designer as well, but you may.
I am assuming that you are referring to the problem that exists when you choose the documents based on the category. This is something that I find highly annoying and I wish that it was possible to turn this on and off. It makes sense for embedded views, but not for much else.
What I did to solve this was to include the category value in the next column. In this way that text could still be seen, even if it was a flat view.
Alternatively, you could also look into using a repeater control and create your own way of presenting the information. This would be used instead of a (Dynamic)ViewPanel control. You could then present the information any way you wanted as long as it is returned in the viewrow set.
Happy Programming!

Lotus notes - error accessing shared private on first use view from LotusScript

Good morning,
I have develop a note application which is used to make a booking. This application is used by multiple user at the same time.
I am quiet new to this development and now I would like to develop a functionality so that user can print a export data to excel.
I have created a view (Shared) where its Selection Formula is base on critical each user specify in a search form. I have problem when a user is being printing and yet finished, the other users is also clicking printing same time, the result of export data on the sides are the same to the one who created first.
I was thought may be using the kind of (Shared, Private on first Use View) but it generated an error [Notes error: Index is not to be generated on server ("view name") ] at the points where I called
view.Clear
view.SelectionFormula = formula
uiw.ViewRebuild
I have no idea how to solve this problem. Could you please advice how this problem could be solved?
Thanks your in advance for your great help.
Best regards,
Veasna
There are different ways to do this. One possibility is to use a "shared, private on first use" (spofu) view: then every user gets his own copy of the view, and they don't impact each other. But I think it is not a good idea to do it like that, as every user needs designer rights to change the selection formula of the view. This is something you do not want.
A better way would be to use a spofu folder for each user and put the documents in it like this:
Dim ses as New NotesSession
Dim db as NotesDatabase
Dim dc as NotesDocumentCollection
Dim folder As NotesView
Dim formula as String
Set db = ses.currentDatabase
Set folder = db.GetView("NameOfTheSpofuFolder" )
'Make it empty
Call folder.AllEntries.RemoveFromFolder("NameOfTheSpofuFolder")
'Search documents based on the formula
Formula = "Field1 = 2 & Field2 = 5"
Set dc = db.Search( formula, Nothing, 0)
Call dc.PutInFolder("NameOfTheSpofuFolder")
Spofu folders need a little "care" but usually they work quite nicely.
This code is not tested and just written down without syntax check etc. It might contain typos, but should give you an idea how to start.
You could create a Lotusscript agent to export the data the users specify.
Get the search criteria from the form, then use db.Search or (preferably) db.FTSearch to get the documents to export.
Now you can export the data of those documents to Excel, using one of the techniques described here:
http://blog.texasswede.com/export-from-notes-to-excel-3-different-ways/
If you want to export as CSV, you can use this code as a start: http://blog.texasswede.com/export-notes-view-to-excel-with-multi-value-fields/
According to this thread on the Notes 6/7 forum, there may be a workaround for this problem. You haven't shown enough code to know for sure. If you are using getView() to access the Shared - Private On First Use (SPOFU) view, that doesn't work. The workaround is to loop through the db.Views() array, checking both the Name and Readers properties in order to make sure that you get a handle on the private instance of the view instead of the shared instance.

Enable/disable editing of a form field from code

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.

Resources