JSON


Introduction


Domino has direct support for JSON in views with the &outputformat=JSON parameter. If you want to send information or need additional controls on the information, then you must resort to development. You can use an agent to return or accept JSON and you will have the full control that LotusScript or Java agents provide. There are some LotusScript libraries available that will output a object such as a view or document in JSON format. This is like the view where you get a fixed format with all data. If you are building view widgets or or other generic controls, then this will work. But to keep the data set small, you will have to use an agent or page to pre-process the data before it's returned to the browser. The main benefit is that you get only the data you need and it's in your format.

The other concern you have to think about with views, is access. The user will need to have at least readers access to the view, which means they could see all the data in the view unless the documents have readers fields. The name of the view is in the code sent to the browser, so the user can find it. If you want to control the access to the data, then use a page or agent where you can hide the view and provide additional validation of the user.

The JSON object is usually the result of an XMLHTTPRequest sent to a server. This is referred to as Asynchronous JavaScript and XML (AJAX ) even though you use JSON instead of XML. All of the popular JavaScript libraries include support for creating the request and processing the resultant string. You pass to the request function the URL that is used to access the server. For example, when getting all the entries under "Riverbend" in a view you can use the following URL:

/database.nsf/viewname?readviewentries&outputformat=JSON&RestrictToCategory=riverbend

This returns a string that contains all the view entries with the category of "Riverbend" in the JSON format.

Getting JSON from Domino views


By using the following Domino URL, the view entries in the JSON format will be returned. You can then access any column or row in the view by accessing the JSON object.

 

/database.nsf/viewname?readviewentries&outputformat=JSON

 

    Important

    Remember to add &count=xx. Otherwise the number of entries defined in the view properties will be returned. If you first call with &count=0, you can use the value that is returned by @toplevelentries, which is the number of entries or categories in the view.



The following example shows a sample Domino view with categories in JSON.

    { "@toplevelentries": "1",

         "viewentry":
         {        "@position": "1",
                 "@noteid": "80000004",
                 "@children": "2",
                 "@descendants": "2",
                 "@siblings": "1",
                 "entrydata": [
                 {        "@columnnumber": "0",
                         "@name": "companyid",
                         "@category": "true",
                         "text": {"0": "003BE9"}
                 }]
         },
         {        "@position": "1.1",
                 "@unid": "6AFB146AABDED0568625741200540B96",
                 "@noteid": "3E2E2",
                 "@siblings": "2",
                 "entrydata": [
                 {        "@columnnumber": "1",
                         "@name": "Firstname",
                         "text": {"0": "Bruce"}
                 },
                 {        "@columnnumber": "2",
                         "@name": "$29",
                         "text": {"0": ""}
                 }]
         },
         {        "@position": "1.2",
                 "@unid": "78053C46688490AD8625741200540B97",
                 "@noteid": "3E2E6",
                 "@siblings": "2",
                 "entrydata": [
                 {        "@columnnumber": "1",
                         "@name": "Firstname",
                         "text": {"0": "Melanie"}
                 },
                 {        "@columnnumber": "2",
                         "@name": "$29",
                         "text": {"0": ""}
                 }]
         }]
    }
To visualize and to help validate your JSON object, you can use the JSON 2 HTML http://json.bloople.net/ Web page. You paste in your JSON object and it displays it graphically or tells you to fix it. View of the JSON structure of a Domino view The JSON from the Domino view has objects and arrays that are defined. The following table lists the objects and their descriptions.
Object name Description
@toplevelentries The number of top level entries in the view, this would be the number of categories in a categorized view.
viewentry An array of the entries returned
@position The current entry's position in the view, similar to @docnumber. Examples: 1,2,3.1,3.1.1
@noteid NoteID of the current entry
@unid UNID of the current entry
@children Number of children for the current entry
@descendants Number of descendants for the current entry
@siblings Number of siblings for the current entry
entrydata An array of the current entry's columns
@columnnumber Column number starting with 0
@name The name of the column from the properties box under Programmatic Use.
@category Is the current entry a category
text The text returned in the column. If the column had multiple values, each would be an additional object in the text object.
Object names The format of Object names returned by Domino views requires that you use the array notation to access the data. Domino uses the at sign (@ )to indicate object names in the view such as @toplevelentries.
To get the number of entries or categories returned, you can use JavaScript to access the information. The following example shows sample JavaScript:
var text = xhr.responseText;
var data=eval("(" + text + ")");
var top = parseInt(data["@toplevelentries"]);
Pulling data to fill a select list from Keyword documents This is used quite often on the web to fill select fields with values that come from keyword documents. Here we'll use a Domino view, get the results in JSON and filling the select field with them. Since the return value will depend upon whether the keyvalue is a text value or a text list, there are 2 samples show for getting keywords. For a view that returns multiple documents, each with a single value, the JSON value returned in an object called "text". There is one text object per entrydata. Results with a single value field
"entrydata": [
{        
     "@columnnumber": "0",
     "@name": "$1",
     "@category": "true",
     "text": {"0": "Dev_Members"}
}
]
For views returning ONE document that contains a textlist, the JSON value returned is a object called "textlist" that contains the values in an array called "text". Results with a multi-value field
"entrydata": [
{
     "@columnnumber": "1",
     "@name": "$4",
     "textlist": {
             "text": [
                     {"0": "Neale Wooten"},
                     {"0": "Bruce Lill"}
             ]
     }
]
Javascript to get data from a view with with single values
use this where there is ONE entry per document, multiple documents get pulled

this gets calls the server to get all values for the key and fill a select list
function getKeywords(selID, key) {
     alert("here: " + key);
    uses baseurl that is set on the form itself
     strUrl = baseurl +"/wKeyword?readviewentries&outputformat=json&restricttocategory="+ key;
     makeHttpRequest(strUrl, "fillKeywords('" + selID + "',", false);
}

function fillKeywords(selID, result){
used to post the contact on the ticket
     var Column = 1; column used to pull results
     var elSel = document.getElementById(selID);
     var data=eval("(" + result + ")");
     var top = parseInt(data["@toplevelentries"]);
     var opt = "";
     
     elSel.options.length=0;
     elSel.options[elSel.options.length]=new Option("<--Select-->","-1",true, true );
first selection
     
     for (i=0;i
            get the value from the text object in entrydata
             opt = data.viewentry[i].entrydata[Column].text[0];
             elSel.options[elSel.options.length]=new Option(opt, opt);
     }
}
Javascript to get data from a view with with multi-value fields
Use this where there is ONE document with a list of values
this gets calls the server to get all values for the key and fill a select list
function getKeywords(selID, key) {
     alert("here: " + key);
     
uses baseurl that is set on the form itself
     strUrl = baseurl +"/wKeyword?readviewentries&outputformat=json&restricttocategory="+ key;
     makeHttpRequest(strUrl, "fillKeyword('" + selID + "',", false);
}
function fillKeyword(selID, result){
used to fill a select list with the list in ONE keyword documents
     var elSel = document.getElementById(selID);
     var data=eval("(" + result + ")");
     var opt = "";
     
     elSel.options.length=0;  
clear current entries
     elSel.options[elSel.options.length]=new Option("<--Select-->","-1",true, true ); first selection
     
get the length of the textlist object in entrydata
     var top = data.viewentry[0].entrydata[0].textlist.text.length;

     for (i=0; i
                    get the value from the text object in textlist
             opt = data.viewentry[0].entrydata[0].textlist.text[i][0];
             elSel.options[elSel.options.length]=new Option(opt, opt);
     }
}
Getting JSON from Domino pages
You can use a Domino Page to provide data in JSON or any format. Build Domino pages with embedded views (set to HTML), or computed text ( using @dblookup or @dbcolumn), give it a name (data.json), and finally set the content type to application/json. With the computed-text objects, you can filter the data needed with URL parameters and easily change the data. Using an embedded Query view lets you quickly filter the data returned and add any additional formating needed if you aren't using the standard Domino Jason view format. This sample is used to pull values for a type-a-head field, where a list of entries is displayed that starts with the characters that the user has typed in. The following sample is based on a category type-a-head field where the user has entered "ad". The @dblookup uses the parameter passed in the URL to filter the result set. You can also use an embedded query view, where the URL parameters are passed to the view and used as part of the SQL query. See the Using query views section. Page name: AutoSug.json Content type: application/json The URL : /db.nsf/autosug.json?open&input=ad
{ results: [
] }
The computed text field has the following formula:
ClassCache := "Notes" : "NoCache";
LookupDb := "";
View := "(entry)";
Key := @UrlQueryString("input");
Column := 1;
Temp := @DbLookup(ClassCache; LookupDb; View; Key; Column;[PartialMatch]);

@If(@IsError(Temp); "{id : \"1\", value:\"No Match\", info:\"\"}"; @Implode("{ id: \""+@Unique(Temp);", "))
The following example shows the results:
{ results: [ { id: "Administration", value: "Administration", info: "all Administrationentries"},
     { id: "AdminP", value: "AdminP", info: "all AdminP entries"},
     { id: "Admin", value: "Admin", info: "all Admin entries"}
     ]
}
Getting JSON from Domino agents
Using agents allows you to do more complex data manipulation such as combining information from more than one database. You can use Java or LotusScript to build the agent. It does not have to reside in the same database as the data. You can have a central database that provides all JSON data. On the OpenNTF.org website, there are some libraries to read and write JSON data to help accelerate your development. Remember that Domino development is all about collaboration. The following example shows a sample agent that returns JSON (format like the view) of the first column in a view. In this case, it's a category. 
Sub Initialize
     Dim session As New notessession
     Dim db As notesdatabase
     Dim doc As notesdocument                 ' agent context
     Dim View As NotesView                         ' search view
     Dim vEntries As NotesViewEntryCollection
     Dim vEntry As NotesViewEntry
     Dim strCol As String
     Dim json As String

     Set db = session.currentdatabase
     Set doc = session.DocumentContext

     On Error Goto ErrorHandler
     ' use to force agent output to not include header info
     Print "Content-type: application/json"
     
     Set view=db.GetView("vCat")
     Set vEntries = view.allentries

     If vEntries.Count = 0 Then ' NO DOCS FOUND ERROR
             json =  {toplevel:[{"Status":"No Documents Found"}]}
             Print json
             Goto TheEnd
     End If

     json = {"@toplevelentries":"& vEntries.Count & ","viewentry":[
     Set vEntry = vEntries.GetFirstEntry

     While Not(vEntry Is Nothing)

             strCol = vEntry.Columnvalues(0)
             Set vEntry = vEntries.Getnextentry(vEntry)
             If vEntry Is Nothing Then
                     json = json + {"entrydata":[{"text":{"0":"+ strcol + "}}]}
             Else 'need the , at the end if not the last entry
                     json = json + {"entrydata":[{"text":{"0":"+ strcol + "}}]},
             End If
     Wend

     json = json +  ]}
     Print json
     Goto TheEnd

ErrorHandler:
     json =  {toplevel:[{"ERROR":Error$ & "    Line#: "   &  Erl &    Object: & Lsi_info(2)}]}
             Print json
     Resume TheEnd

TheEnd:

End Sub
posted @ 2010-12-27 17:31  hannover  阅读(1070)  评论(0编辑  收藏  举报