I'm creating a student assignment submission application using xpages (8.5.3 FP3 UP1). The details are:
Student can do any number of submission. For each submission, a unique SubmitID will be created. For now,
a. The Form (Submit) - 2 fields only (SubmitID, SoftCopy-RTF type)
b. The View (Submit) - 2 column only (SubmitID, AttachmentNames)
c. Examples of SubmitID are: submit1, submit2
For each submission, student must select what course/subject that submission is for (eg: Maths, Physics etc). Therefore I've already created another form for the teacher to create the list of subject
a. The Form (Subject) - 1 field only (SubjectName)
b. The View (Subject) - 1 column only (SubjectName)
c. Say for now 2 subject has been created - Maths & Physics
I've created 2 xpage:
a. Submit.xsp - to create new submission (using form - Submit)
b. SubmitView.xsp - to display the list of submission (using view - Submit)
For Submit.xsp, here's where my problem begins:
a. The controls in here are as follows: SubmitID EditBox, Repeat Control(inside is a CheckBox, a fileUpload, and a fileDownload)
b. The repeat is based on the list of subject available. The CheckBox title will be each of the SubjectName. In the OnChange event of the fileUpload control, each time after a file is browsed, the checkbox will get checked and this worked.
c. The fileUpload should only update the accompanying fileDownload but instead the attachment that I just uploaded is reflected to every other fileDownload control. I'm doing full refresh on the fileUpload OnChange because that's the only way for the fileDownload to be updated. What is wrong here and what should I do to get the result that I wanted? Saving the document and opening it later in both read-only or edit mode is fine although each subject still display the same list of uploaded files. Both fileUpload and fileDownload are binded to the SoftCopy field.
Unless I'm not correctly interpreting your description, you're binding multiple upload / download controls to the same item ("SoftCopy"). Because these controls are always bound to an item, not to each other, a download control will show any attachments stored within the source item, regardless of how they got there. To limit display of attachments in a download control to those sent via a specific upload control, they must be stored in an item unique to that pair.
For example, if each pair were bound to a subject-specific item, such as "SoftCopy_Maths" or "SoftCopy_Physics", then each download would only display attachments stored within that specific item. You don't know what subjects will be defined, so you can't define these fields on the form, but that's okay... you don't need to. NSF has no schema, so a field need not be defined on a form for a control to be bound to it; the item will be created when the document is saved, even if the form does not define it. Strictly speaking, even the form itself need not exist.
We typically bind controls to items using dot syntax, e.g. #{currentDocument.SoftCopy}, but array syntax is equally valid, e.g. #{currentDocument["SoftCopy"]}. So if you wrap these controls in something that establishes the dynamic item name as a variable or property, you can use array syntax to target that dynamic item. Two of the best ways to do this are data contexts and custom controls.
For instance, you could surround the contents of the repeat in a panel, and define a panel-specific dataContext that associates the variable attachmentItemName with the concatenation of the item name prefix and the specific subject. Your upload and download controls can then be bound to #{currentDocument[attachmentItemName]}.
Alternatively, you can move the same content to a custom control that accepts the data source and item name as properties, in which case your value binding might look like #{compositeData.dataSource[compositeData.attachmentItemName]}.
Apart from very minor differences in runtime performance, either approach is equally valid.
Related
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.
I have 3 forms (A,B,C) in my database. I am using LocNumber as the unique key to bind them together (although I could of course use UNID).
I want to present the user(s) with one Xpage that has these three forms. I have made a CC for A,B, and C and bound them to the correct form in the datasource.
My save button does a validate and then saves datasources.
But how do I "bind" the three cc's together on the page? In form B I have a LocNumber field. Do I create a field in cc B for LocNumber bind it to LocNumber on the form but load it with the value from UNID on form 1?
This must be a solved problem.
BTW, I choose to chunk everything like this as I will have a separate group of people to edit each set of fields (in form A,B,C).
I also prefer to use a uniqueKey like #Unique() for instance. Though in XPages you need to wrap it in a session.evaluate() to get the old school style.
Anyway - first you might want to rethink this. there isn't a need to chunk this up between 3 forms/documents. You could do it all with one and put each chunk into a Panel and compute the read only property so it's true for people that don't have editor access and false for people that do. That works really well.
for the custom controls. I would pass in the key as a custom property. Then inside each use that to compute to the document so it's available to you. SSJS to getdocumentbykey type of thing.
I'd like to add a list of strings to a Dialog list with an Java agent. Item's value changes but it doesn't show the values on form.
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
Database db=session.getCurrentDatabase();
Form form = db.getForm("UOs_AD");
Document document = agentContext.getDocumentContext();
Item item = document.getFirstItem("UO_AD");
Vector v = new Vector();
v.addElement("Bicycle");
v.addElement("Train");
v.addElement("Foot");
Item textListItem = document.replaceItemValue("UO_AD", null);
textListItem.setValues(v);
textListItem.setSummary(true);
document.save(true, true);
I'm not sure that I understand your question. Are you trying to update the Form so that "Bicycle", "Train" and "Foot" will be choices in the dialog list whenever someone creates or edits a document? Or are you trying to update a specific document so that these three values are selected for the field value? Your code appears to be updating the Document.
If you are just trying to get those three values to appear as selected, then make sure that your field has the "Allow values not in list" property selected in Domino Designer. Also, make sure that the "Allow multiple values" property is selected.
replaceItemValue() only replaces the value of a field in the current document (which you got via agentContext.getDocumentContext()) and not the choices that, for example, a Combobox tied to that field offers the user.
If the choices a Combobox offers are static you need to use Domino Designer to open the form the document is based on and change the values offered for the choices in that field. If you want to do that programmatically, you would have to work with DXL.
OK, so based on your latest feedback, your question really should have been:
How can I display the result of an LDAP query (in my case a list of OUs), done with some Java code, in a IBM Notes Dialog List?
You are out of luck with "classic" Domino Designer. A classic notes form only offers you (either via the Designer, but also via DXL) the following options for a dialog list:
Enter choices (one per line): Type a list of choices in the edit box.
Use formula for choices: Type a Lotus Notes formula in the formula window to generate a list of choices.
Use Address dialog for choices: This option displays the Names dialog box so users can select names from a Personal Address Book or Domino Directory.
Use Access Control list for choices: This option brings up a list of people, servers, groups, and roles in the access control list for the database
Use View dialog for choices: This option brings up a dialog box containing entries from a column in a view
So no way of adding the output of some Java code to the Dialog List.
What you can do is:
Use XPages. With XPages, you can have Java code to fill any kind of List, Dialog Box, ...
Use your Java code in a scheduled Notes Agent to "sync" the LDAP entries into the Notes database by creating notes documents, eg. "OU" which represent the LDAP entries. Using a View, you could then use the "Use View dialog for choices" option of the Dialog List to display them to the user.
Use TDI (entitlement for this comes with Domino) to sync the LDAP entries into the Notes database by creating notes documents, eg. "OU" which represent the LDAP entries. Using a View, you could then use the "Use View dialog for choices" option of the Dialog List to display them to the user.
Use your Java code in a scheduled Notes Agent to update a field inside a profile document with the list of "OUs". Then use a #-formula to display the values in the Dialog List.
Solution (2), (3) and (4) have the disadvantage of not displaying "realtime" info of the LDAP directory.
I hope I understood your problem correctly. If so, please edit content and title of your question acccordingly.
My application has documents for Companies, and for Clients. This is a many to many relationship; a company can have any number of clients, and a client can be a client of many companies. The relationships are stored by creating a response document to the company, with a field containing the ID of the client document.
I would like to be able to show fields from the client document on the company's XPage, and I've been trying to do this with repeat controls. I created a view of all the link documents, and used that to create a repeat, filtering it with the current document ID to collect all the links that the current company has. This allows me to list all the IDs of the client documents associated with that company.
I have been trying to work out how to pass this ID to a repeat control nested within the first one, either to use it as a filter on a view of all the client documents, or to use it as the data source document ID directly. Is this possible? If not, how would I go about showing data from the client document on the company page?
When you specify a repeat control you specify the variable that contains the instance value. This variable name is visible to anything inside the repeat control. So your variable would contain the UNID of the client documents one at a time. E.g you call it ClientDocID. You put a panel inside that repeat control. That panel can have its own DominoDocument data source. The datasource can have new, display or edit as default action. You pick "display" which requires a DocumentId to be provided. Select "computed" and simply use ClientDocID as formula.
You can suppress rendering of HTML for the panel (check the properties), so it would fit e.g. inside a xp:tr.
Hope that helps
I have a page layout in a solution I have deployed. The page layout also has a custom content type associated.
I wish to update this page layout and content type, but only for a specific place on the site. The reason is that for important "operation updates" we want the ability to send out SMS's to subscribed users (a built-in feature of Sharepoint for lists) as well as e-mail them.
The way this works is that I wish to add a boolean field that decides whether SMS's are send or not, and a field to put in e-mail adresses you want notified of the message.
My approach so far has been:
Create an event receiver that checks whether the fields are selected / filled out and do the actual sending.
Alter the layout page with the 2 new fields.
Alter the content type with the 2 new fields.
However, I am afraid of the complications for the rest of the site. For now, future uses of the page layout is not a concern, just the existing uses.
I know that updating a content type through XML definitions does not happen automatically, so on that side I'm safe, but how do I keep the layout page "contained" to the specific page in question?
EDIT: How do I show the two fields only when editing the page, not when showing it? Currently, my development site shows the edit form just right, but when I go to show the page it shows "yes" where boolean field is located and any e-mail adresses entered where the e-mail field.
Are you sure the page layout is associated with the content type, and that it's not a page that is associated with the content type?
If you want fields to be automatically added, you can:
Create a custom rendering template
that is used by the New/Edit/Display
forms for your list
(http://weblogs.asp.net/sharadkumar/archive/2008/07/07/how-to-customize-rendering-of-sharepoint-list-form-fields-part-1.aspx)
Create a custom ListFieldIterator (or use the default one)
that will automatically pick up new
fields in your content type
(http://msdn.microsoft.com/en-us/library/aa543922.aspx)
Use code in a DLL to iterate through
your content type's fields and thus
create the necessary controls for
your page all in code. If you use
FieldControls
(http://msdn.microsoft.com/en-us/library/dd571480.aspx),
it will automatically create the
default template rendering for the
field (i.e., it will display radio
buttons, drop down boxes, etc., as
defined by the fields in the content
type).
In your EDIT, when you say 'when editing the page', I'm assuming you mean 'when viewing the edit page for the list', and not 'when editing the page definition in Sharepoint Designer'.
Assuming that assumption is accurate, you can have the edit page for the list show something completely different from the view page for the list (and from the new page for the list). The pages are, by default, defined completely separately, and are edited completely separately. However, if you are using something (such as the ListFieldIterator) that automatically picks up the list of fields for the content type, you can create a custom Field Control for the fields you want to hide and have the view template for the field control set to display nothing.