Creating In-line Response Documents
More often that not a Domino database will have some type of parent-child document relationship. When the authoring of such documents is implemented in the browser I think we should all be familiar with the way these relationships function and behave. Let's take the Discussion Forum on Notes.net for example. When you go in and read a document you have the option to add your replies in order to help out the troubled person. To do this you find the link to the Response form, wait for the page to open and then fill out the form before finally submitting your response. Not only can this sometimes be slow it is an extra step we can easily do without. That is what I will discuss how to do in this article.
By giving the user the ability to add their responses directly from the parent document that they are reading we can make their life an awful lot easier. Another bonus to this approach is that the user never has to leave the page they are reading and hence they can easily check what it was they were actaully reading as it's still on that page. To see what I mean you can see this approach being used in the blog on the homepage of codestore. If you open one of the posts then you will notice that there is a form at the bottom. Filling out the fields and pressing the post button adds a repsonse to it and then returns you to the blog document again. You can see this layout in the screen-grab below:
Notice that below the actual content of the document we also have a view of the blog's responses and then we have the form that means we can add our own.
How can we possibly do this:
To create a document in a Domino database without actually opening the form itself we make use of the ?CreateDocument URL Command. When we use this as the action for the POST request of our form we can pass in field values and Domino will be non-the-wiser as to how we created the document. In the case of a Response document architecture the URL that we would normally expect as the form's action is something like this:
db.nsf/ResponseForm?CreateDocument&ParentUNID=2935DC...72
All we have to do is add a form to all our documents and make sure that the action attribute of the form points to the right place and that it has all the rquired fields on it in order to create the necessary response document.
Before I describe the ins and outs I will assume that you have some kind of web-enabled Domino Discussion database at hand. If not you can create one from the template or, better yet, download my example which has this trick built in already and which I will be describing.
What I am not going to be talking about is how to set up your documents so that they actually function in a parent/child relationship. This is "beyond the scope", as they say.
The quick and easy form:
First thing to do is open your parent form. In the case of my database it is called "Document". At the end of your standard form (i.e under all your fields) we need to add some Passthru HTML that will close off Domino's own form, letting us create our own. The HTML for this is:
</form>
<form action="Response?CreateDocument&ParentUNID=<Computed Value>" method="post" onsubmit="return validatePost(this);" enctype="multipart/form-data">
Notice in the above code that we have pointed the form to the response form which is called, wait for it, "Response". Note also that we have passed to it the ParentUNID parameter which tells it which document it is to become a child of and inherit its values from. The Computed Value you can see above is simply the Document Unique ID of the parent and is just the following @Formula:
@Text(@DocumentUniqueID)
All we need to do now is add the fields that are going to be passed in, via our new form, to the child document. To do this we can use more Passthru HTML as the fields don't need to exist on the main form (although they DO need to be on the target form for it to work). How many fields you need to add depends on how many there are on the actual response form. In the case of my example there are only three and I add them like the one below:
<input name="Title" type="text" value="<Computed Value>" />
In this field's case the Computed Value is there simply to give this field a default value and I have used the following formula:
"Re: " + Title
This way it defaults to looking like it is a response to the document which you are currently in, which also has a field called "Title".
Now the important part - The "Submit" button. Because we've created our own form we can't rely on Domino to create the button for us and so we need to create our own. Here's the HTML I added to the form to do this:
<input type="button" value="Submit" onclick="this.form.submit()" />
Notice how I used JavaScript to tell the button to submit this form. Even when in read-mode, Domino, for some unknown reason, generates its own form by default. This means there are two forms in the page and so we could equally have the JavaScript for the button access the form object as document.forms[1]. However, I find it's cleaner to use this.form where "this" is the button object and "form" is its parent form object. How you do it is up to you.
You now have all you need for the new form. Note that there is no need for the closing tag of the form that we have opened as this will be closed by the tag that Domino created in order to close its own form.
The only thing left to do is check that the Response form is setup properly and that all the fields you created using Passthru are in place. You can then add a $$Return field in which you can redirect the response to browser after the form is submitted back to the original document if you like.
Having added the form to the Parent document you now need to repeat the procedure for the Response form as well. Once you've done the user can add responses to any document from anywhere in the hierarchy of posts.
All in all, your forms should look something like the one shown in the sreengrab below:
Okay, I know, it looks a bit messy and may seem like a bit of a hack. Something I am too aware of is that having years of experience with Domino leaves you with the impression that this is what you have to do if you really want to get the most out of it. Learn to apply combinations of all the tricks you learn along the way and you're on to a winner.
A little bit of tidying up:
There are of course a few things I've neglected to mention in the course of describing this to you. Hopefully they will all be fairly obvious when you start to look at the example database. Things like hiding our new form when @IsNewDoc or when in edit mode...
Another point worth consideration is the "Generate HTML for all fields" feature. Why anybody would ever want to use it is beyond me but, all the same, people do. If your parent form has it enabled and you use this approach you may observer strange side-effects. This is becasue Domino will add all these "hidden" fields at the bottom and so they will be a part our new form. Hence, not only will the reponse documents inherit all these fields, you will see errors if any of these fields happen to not feature in the design of the receiving form. If you want my opinion - turn it off!
Tip has XML alongside it...
...in the side bar...problem with your new site design?
Good article. Noticed this response is not in-line. It might be useful to make it so to allow ref to longer articles when commenting.
By the way, great site - one of my regular reads!
Reply
Re: Tip has XML alongside it...
Yes, I thought that XML categorisation odd also...
Anyway, I'm guessing that Jake doesn't make use of this functionality with regards articles & their comments, because this could conceivably mean very long (and therefore slow-loading) pages?
A few comments against a daily changing blog are one thing, but 20 / 30 / 40 "in-line" comments in an article would render it unwieldy. PLus it would look cack in printing!
Reply
Show the rest of this thread
Genius as usual
What can I say, Jake?
You always suprise us with small beautiful things like this one....
The solution is elegant, precise, not messy and very useful.
I'll implement it in my own site (giving you the credits of course)
:-P
Cheers!
.::Alex::. Dominocode.Net
Reply
Thanks Alex
Simple yet useful is what I aim for so I must be doing something right ;o)
Jake -webmaster
Reply
Nice work!
Jake,
A great read as usual. Especially enjoyed looking through your example db and picking up some of the "little things" like your use of comments and colors in subforms that I'll add to my list of best practices.
I was a bit surprised by your closing comment about turning off "generate HTML for all fields". If you do this, how do you get javascript to get a handle on any of the hidden fields? This is the only reason that I have this turned on most of the time.
Thanks again.
Curtis
Reply
Re: Nice work!
If you have fields that you need to access with JS then deal with them on a field-by-field basis. Displaying ALL fields is a little over the top.
For more on dealing with hidden fields. [<a href="unid/DOMM-4R3E3U?OpenDocument">Read this</a>].
Glad you liked it btw ;o)
Jake
Reply
Show the rest of this thread
Another great way of using ParentUNID parameter
I´ve been using this parameter for a while now and a great way of using it is on dialogboxes on the webb. when you know that the main document are saved. No code for retrieving data between main document and the dialog box.
Happy ParentUNID:ing
Fredrik
Reply
Need to have consistent fields
Great article.
One thing that you mention is the need to have the same fields on the Domino form as on the HTML form ie. fields used for browser display purposes only still need to be on the underlying Domino form. If you don't do this, then you get an error on submitting the form.
I know you mentioned this in the article, it's just that it stumped me for ages!
Also, doesn't passing the ParentUNID into the form generate a parent-child relationship anyway?
Finally, this is a great technique to get any sort of feedback from a web page eg. quick polls, ratings, etc.
AS
Reply
Special characters Ð Þ í ó æ etc.
Hi Jake
I've implemented your inline comment system but the comments are not in english so I need to be able to use : ð þ æ ó í ú ý Ð ø å etc.
Like this guy -> http://www-10.lotus.com/ldd/nd6forum.nsf/DateAllFlatweb/3e8fa4ede1f48a3a85256c53 00242dd5?OpenDocument I'm having problems with "special" characters coming in as pipes which display as black boxes on the web.I'm wondering if your setup can handle this?
The POST seems to be handled differently when using the ?CreateDocument method because there is no problem when I post a notes form the "normal" way, that is ?OpenForm&ParentUNID=ad..23d&seq=1
Any Ideas?
Reply
Re: Special characters Ð Þ í ó æ etc.
Hi Jon,
Not sure what is wrong with what you have done. I just tried it out and it seems to work. Might be something to do with the version of Notes you're using...
Jake -admin
Reply
Release 6
This is a great technique and I've been using this technique successfully in Release 5. But when I've tried it in Release 6 I get the following error message:
Http Status Code: 400
Reason: Unknown or unsupported protocol version
anyone got any ideas?
Reply
Re: Release 6
If I take out the "enctype="multipart/form-data">"
the error changes to:
Http Status Code: 405
Reason: Request method is not allowed by the server
Could it be some server setting? (I'm looking into that now).
Oh and I forgot to mention - the documents are actually created but there's nothing in the user defined fields.
This is unrelated to the problem but you can create documents using this method using simply "?CreateDocument" withouth the &ParentUNID=<Computed Value>" bit.
Reply
Show the rest of this thread
How to get a handle on 'child' DocID?
Jake, How do I get a handle on the newly created 'child' DocID, so I can email a URL?
Reply
Re: How to get a handle on 'child' DocID?
You can use the WebQuerySave agent of the Resonse form. In there get a handle on the DocumentContext object and then on its UniversalID
Jake
Reply
View Problems
Hi Jake --
I am new pretty new to developing web applications and I found your solution to be an interesting way to handle in-line responses. However, I am trying to implement a solution similar to yours, but I have a few problems. First, can I have a dbcolumn on the comment form (for responses)?
Second, would this type of solution work for adding responses to responses? In other word, my users create a main document, save it, then create a first level response, save it, and then create a response to a response. I am not sure sure how far nested this solution can be used for.
TIA, Donna
Reply
Re: View Problems
Hi Donna,
Not sure what you mean by having a dbcolumn on the form. To do what? I don't see any reason why you shouldn't be able to...
You can use the same for for Responses to Responses and it should work the same. Personally I only have ONE form of type Response and never bother with a Responses to Response type form. There seems to be no need ;o)
Jake
Reply
Show the rest of this thread
Edit Response doc: submit returns runtime error
Jake, Glad to hear you had a good Holiday. Thanks for the help on 12/10 - I have that working now (it's great!)
However, when I edit a response, and try to save it, I get a runtime error: Line 25 Error: Object expected
I tested using the unaltered inline.nsf, with IE5 and IE6. I tried to look at JS for the error, but I am not very good.
Thanks in advance for your help!
Reply
Re: Edit Response doc: submit returns runtime error
I found the answer - in the Inline Response instructions! The Save button needs to be pass-thru html - like this: <input type="button" value="Save" onclick="this.form.submit()" />
The Inline.nsf sample database Save button uses: @Command([FileSave]); @Command([FileCloseWindow]);
Reply
File Upload Control Inline?
Jake, I have tried unsuccessfully to integrate a file upload into the inline response. I have tried inserting the Domino File Upload Control into the pass-thru javascript, including the way you did it in the Attachments Manager, but I can't see it on the web.
I can create a standard file upload using Javascript: <input type="file">
However, Domino won't save the attachment without a Domino-generated name, like this: <input type="file" name="%%File2b8bdadd0d4e57a680256c1a0065d5f1.$Body.0.CDA">
Any idea how to implement?
Reply
Re: File Upload Control Inline?
If you want to pass a file along with the form you will have to add the following paramter to the FORM tag in the pass-thru:
ENCTYPE="multipart/form-data"
Look at the source of a Domino form with an upload to see exactly where it goes...
Jake
Reply
Show the rest of this thread
Thank-you, Jake
Thank you so much for presenting this. I'm using it now in a web-only documentation/discussion database and it's a huge hit.
Reply
Question about the ThreadMapDisplay field
Dear Jake,
Your website has been a great resource to me from the moment I've found it. I greatly appreciate the time you spend sharing your knowledge and experience with others. I have found answers to many of my questions on codestore.net. Thank you again!
I'd like to ask you, or anyone else who may know the answer and familiar with your sample database. What I am doing now is a few checks within the ThreadMapDisplay field. When I present a response to comment, I am also looking to display some additional information about the author of the comment. So, I have a view, where I do a @DbLookup, and say, depending on "from" field I can see who the Author is, and then display his location, or his status, etc.
Here's where I am stuck. As you have shown in your example, I do a @Implode ( x1 + x2 + x3) where x1, x2 and x3 are the HTML code with included fields displaying who the author is, where he's from etc. What I can't seem to figure out is how to do a few checks. Say, if the author is anonymous, I don't want to display x1 in my @Implode, but rather xA. Yet, due to the way @Implode works I can't seem to run anything of this sort:
@Implode ( @If(author = "Anonymous"; xA; x1) + x2 + x3 ) --- since if I do it, all the consecutive results use xA whether the author anonymous or not.
I tried to do an @If check right within the x1 html, say like:
x1 := < some html here > @If(author = "Anonymous"; "Anonymous"; author) ... etc
and that does not work either.
If you follow my explanation so far, do you think I've made a mistake somewhere or is it actually a limitation of the recursiveness of the @Implode?
Appreciate your time and possible hint for a direction to fix this! - Alex
Reply
Re: Question about the ThreadMapDisplay field
Hi Alex,
Glad you like the site ;o)
Have you tried:
@If( Author = "Anonymous"; @Implode ( xA + x2 + x3 ); @Implode ( x1 + x2 + x3 ) )
Jake
Reply
Show the rest of this thread
Appending n response documents in main
I have a problem related to this topic only.Hope any of the gurus will be able to provide me solution. Whole functionality is on web only Problem is: I have a main document and can have ´n´ number of response documents.User wants to select the main document and with click on button a document should be dispayed on web with all the main document contents and response documents content.
Hopefully i am clear Thanks and regards
Reply
Re: Appending n response documents in main
As far as my knowledge you have to traverse through all the responses for the parent document you selected and then build HTML dynamically for all the response docs (including parent doc) in the specified format.
HTH
--Kiran
Reply
THis is Good Tip
This is really cool Tip
Reply