JSON
- Introduction
- Getting JSON from Domino views
- Getting JSON from Domino pages
- Getting JSON from Domino agents
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
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.
"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": ""} }] }] } |
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. |
var text = xhr.responseText; var data=eval("(" + text + ")"); var top = parseInt(data["@toplevelentries"]); |
"entrydata": [ { "@columnnumber": "0", "@name": "$1", "@category": "true", "text": {"0": "Dev_Members"} } ] |
"entrydata": [ { "@columnnumber": "1", "@name": "$4", "textlist": { "text": [ {"0": "Neale Wooten"}, {"0": "Bruce Lill"} ] } ] |
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); } } |
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: [ |
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);", ")) |
{ 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 |