@DocNumber in a category

Posted on 2004-08-15
Last Modified: 2013-12-18
I've struck another wall....
I'm using R6 to create a website with navigation as offered on (vertical with frames). I want the "menu"-lines ("....menu1...", "...menu1_1...", "...menu1_2...") generated from a view, so I can easily hide a button if the database is restricted.
I need multiple sets of menus to control at least two languages, of perhaps later multiple sites.
I thought of using a single category enbedded view to do this. @DocChildren will count the no. op sub-entries and @DocNumber("_") takes care of the menu numbering.
Problem is the single category: a category would add an additional level in the count and I NEED to start off on "menu1".
If I don't use the category, the counting is ok but I'd have to use a @DbLookup.... fine with me if it would deliver response documents as well.
Leaving the responses out as well, the whole counting system collapses!
Any good ideas?
I wish I could perform a @ReplaceSubstring on @DocNumber's result....
Question by:CRAK
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +1
LVL 15

Expert Comment

ID: 11807232
Use 2 views ?
LVL 13

Author Comment

ID: 11808608
Can you be more specific?

I thought of another way that might work (haven't tried it yet): use javascript to modify the retrieved lines and "document.write" the results.

Expert Comment

ID: 11809763
It's not ideal, but you could replace the @DocNumber column with your own "DocNumber" field, then use an agent to populate that field.  The agent could be set to run when any of the documents change, just in case that changes the menu for you.  Basically, you'd just need to loop through the view using a ViewNavigator and set the field based on the GetPos method.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 15

Accepted Solution

Bozzie4 earned 125 total points
ID: 11810085
I mean, use 1 view that's simply sorted, and that you can use to retrieve your starting point, and use the second view with the @docnumbers to do the rest of the lookups.

But although using @docnumber sounds interesting, it really isn't.  It only comes in handy when using it on the browser (javascript can parse it, because it's text in the browser).
It's probably easier to just make a lookup routine - not based on number in the view, but on position in a tree :

Use a 'key' to sort :
First document:

Submenu's for startmenu:

sub-sub menu's :

I use this also in a multilanguage application, where the first element in a key is the language :

EN#First Item
EN#Second Item


So a @dblookup for all EN items is possible using the PartialResult parameter in R6.  Parsing would be quite easy, in formula or in javascript.


LVL 13

Author Comment

ID: 11810106
I thought of that, but it's not what I try top archieve:
Imagine that I have a menu definition like:
  menu1 = ....
  menu1_1 = ....
  menu1_2 = ....
  menu1_3 = ....
  menu2 = ....

Now one of the users is not permitted to access menu1_2.
In his menu, "our" menu1_3 should shift up and be shown as the new menu1_2.

@DocNumber does recalc in this case I hope.... (i.e. it doesn't skip menu1_2)...? I haven't tried yet as I am developping on a client only.
LVL 13

Author Comment

ID: 11810109
That was a comment to HappyFunBall....

Assisted Solution

HappyFunBall earned 125 total points
ID: 11812086
I like Bozzie4's idea.  It is very flexible and much easier to code.

The only alternative I can come up with right now is outputting all the menu code via an agent rather than a view.  The agent would use Print statements to dynamically output the same code the view does.  This way you can control everything that gets output.  

Talk about reinventing the wheel...
LVL 15

Expert Comment

ID: 11812921
Yes, an agent is very good to combine with the way to sort data.

<script language src="/db.nsf/agent?openagent"></script>

Your agent can use print statement , and to output javascript code, do it like this pseudocode

Print "ContentType: text/javascript"
do while not doc is nothing
Print "menu=" + doc.url
set doc = view.getnextdocument(doc)
LVL 13

Author Comment

ID: 11815466
Both could work, but I think I have just mastered a 3rd, more exotic way.....

I start off in the categorized view that delivers the additional level (Menu1_1 instead of Menu1).
I set that view to show HTML and modify it to trigger a js conversion function.
Col 1 = Menu name (categorized)
Col 2 = Menu entry sorting (sorted)
Col 3 = "convertMenuEntry('Menu" + @DocNumber("_") + "= new Array(" + <required parameters part 1> + @Text(@DocChildren) + <required parameters part 2> + ");');" + @NewLine

It's a bit of fuss as some parameters may contain links like "javascript: alert('unavailable')". I need to mark quotes (single/double) with backslashes, or JS won't be able to handle them correctly.

I have created two of these views: one for dutch menus, another for english ones (and a third as UI view).
The views are embedded by computation on a form. Both the language and the manu name are provided as URL parameters. Viewheaders are hidden.

Around the embedded view I have added some more JS:

[<Script language="javascript">
function convertMenuEntry(txt)
document.writeln('<scr' + 'ipt>' + 'Menu' + txt.substring(txt.indexOf('_')+1, txt.length) + '</scr' + 'ipt>');
<This is where the view goes>
alert('Result:\n' + Menu1);

At this stage the contents of the Menu1-array is shown in an alert-box.

Note that " '<scr' + 'ipt>' " and " '</scr' + 'ipt>' " look weird, but are quite important.
I found it on EE:.... plain " '<script>' " and " '</script>' " won't get you there!

It required no agents, additional refreshes of documents, no lookups etc. Yet it's fast, automatic and on the fly!

It's been another great day!  ;-))

Splitting point for your (also feasible) solutions....
Thanks for your thoughts!
LVL 13

Author Comment

ID: 11865474
For anyone visiting this "PAQ":
It looked promising at first, by the solution I described will cause a lot of problems.
As I reread designer help on @DocNumber, I found one line that said it all:
"You cannot use this function in Web applications."

I don't understand why I saw it work at first, including hiding entries for certain userroles, but it's easy to hit error in a few trials! Don't go for it!
LVL 19

Expert Comment

ID: 11867395
Help tells @MailSend won't work.

Some times it works for users.

And @iSDocbeingSaved won't work on web.  But it is not documented.

Thanks for pointing CRAK.
LVL 13

Author Comment

ID: 11958044
Since I have always enjoyed odd solutions, I'll post my current solution.
Remember that my server is only a tiny little thing... JS is helping me out shifting pressure from the server to clients...

I am using 3 views:
One showing the menu structures in both languages (for editing)
Two (a dutch and an english one) to feed en embedded view with menu data.

These latter two are categorized (for menu selection through single category views), a hidden column to force sorting, another to count the number of top-level documents (1 for doc, 0 for response), and a last column...
This last one is JS code. In pseudo code:
appendToMenuArray(<doc id>, $ref, <menu fields>)

<menu fields> contains colors, button labels etc. And @DocChildren (glad that one works perfectly!)

appendToMenuEntry is defined (along with the embedded view) on a subform, after I defined an arrray:
var cAr = -1;
var ar = new Array();

function appendToMenuArray(p1, p2, p3)
   ar[cAr]=new Array(p1,p2,p3);

Instead of an independant set of arrays, all data is now stored in a array(0-n).

Below the embedded view, I launch another JS function:

defined as:
function buildMenuConstructor()
   var cPar=0;
   for (var m=0; m<ar.length; m++)
      if (ar[m][1]=='')
      var cSub = 0;
      for (var n=(m+1); n<ar.length; n++)
         if (ar[n][1]==vPar)

   for (var m=0; m<ar.length; m++)
      document.writeln('<scr' + 'ipt>Menu' + ar[m][1] + ' = new Array(' + ar[m][2] + ')</scr' + 'ipt>\n');

Based on the contents of the doc id and $ref, the Menu-vars (numbers) are defined.... as dynamically defined JS! (ever seen JS writing new JS before?)

Last hard-coded fragment is:
document.writeln('START<BR><script type=\'text/javascript\' src=\'<computed value>\'></script>');
<computed value> provides the url of menu13_com.js, the menu's JS engine.
Using the writeln, I make sure this code is only launched AFTER Menu1 and simular dynamically defined vars were defined.

Hiding a button might result in the definition of a JS var like Menu<doc id>, but that won't harm the menu's JS engine: it'll only look for sequential ranges of menu vars.

I've only done a few tests, based on a single userrole. Nothing hard yet, but it appears to work smoothly!


Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

For Desktop Techs: How to retain a user's Notes configuration data when swapping out the end user's computer. (Assuming that you are not upgrading to a completely different version of Notes client) All you need to do is: 1) install Notes o…
You’ve got a lotus Domino web server, and you have been told that “leverage browser caching” is a must do. This means that we have to tell the browser everywhere in the web to use cache. In other words, we set (and send) an expiration date in the HT…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question