Integration of the ICD-11 Coding Tool into a Ninox database
Hi,
I use a Ninox database to keep electronic medical records of my patients. I am writing here looking for help to integrate the ICD-11 Coding Tool into my Ninox database.
You can see live the kind of functionality that I would like to implement here:
The World Health Organization (WHO) provides detailed instructions here:
I have tried the following code (full example) within an HTML function, but it doesn't work.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://icdcdn.who.int/embeddedct/icd11ect-1.6.1.css">
<title>Embedded Coding Tool v1.6</title>
</head>
<body>
Type for starting search:
<!-- input element used for typing the search -->
<input type="text" class="ctw-input" autocomplete="off" data-ctw-ino="1">
<!-- div element used for showing the search results -->
<div class="ctw-window" data-ctw-ino="1"></div>
<!-- example of an extra input element for testing the Embedded Coding Tool select entity function -->
The selected code: <input type="text" id="paste-selectedEntity" value="">
<script src="https://icdcdn.who.int/embeddedct/icd11ect-1.6.1.js"></script>
<script>
// Embedded Coding Tool settings object
// please note that only the property "apiServerUrl" is required
// the other properties are optional
const mySettings = {
// The API located at the URL below should be used only for software
// development and testing. ICD content at this location might not
// be up to date or complete. For production, use the API located at
// id.who.int with proper OAUTH authentication
apiServerUrl: "https://icd11restapi-developer-test.azurewebsites.net" };
// example of an Embedded Coding Tool using the callback selectedEntityFunction
// for copying the code selected in an <input> element and clear the search results
const myCallbacks = {
selectedEntityFunction: (selectedEntity) => {
// paste the code into the <input>
document.getElementById('paste-selectedEntity').value = selectedEntity.code;
// clear the searchbox and delete the search results
ECT.Handler.clear("1") } }; // configure the ECT Handler with mySettings and myCallbacks ECT.Handler.configure(mySettings, myCallbacks);
</script>
</body>
Integrating this tool could benefit all users who keep medical records in Ninox.
Any help is welcome.
24 replies
-
Seems like it works on codepen and in my Visual Studio but not in Ninox, seems like the input field is blocked...
Any specialists around?
-
I do not do much with embedding HTML in Ninox.. tho it seems like something really good to learn.
That said.. See the ninox documentation on using the HTTP function.
https://docs.ninox.com/en/api/http-function
Provided it is simple RestAPI.. it "should" work. If you need to do something tricky with the response object.. then your mileage may vary.
This seems to discuss the RestAPI.. I will see what I can find out.
https://icd.who.int/docs/icd-api/APIDoc-Version2/ -
OK.. so the basic API works.. But I do not know what the embedded tool kit is doing.. This screen shot shows the basic call to an ICD entity. Open "Table1" .. drill into a row.. and then manipulate the "API Endpoint" to the way you want it.. Click 'Call API' and GOOD LUCK! ;)
-
... Using the above provided ninox database.. put this into the API Endpoint.. It will return a json block items that have 'hypertension' in it.. You will have to write some Ninox code to parse the response.result .. which will be in a json string.
https://icd11restapi-developer-test.azurewebsites.net/icd/entity/search?q=hypertension&useFlexisearch=false&flatResults=true&highlightingEnabled=true -
.. OK.. I am NOT an ICD-xx expert.. but it looks like you will want this API
/icd/release/11/{releaseId}/{linearizationname}/search
In the above supplied ninox db.. put this in the API Endpoint
https://icd11restapi-developer-test.azurewebsites.net/icd/release/11/2023-01/mms/search?q=hypertension%25&subtreeFilterUsesFoundationDescendants=false&includeKeywordResult=false&useFlexisearch=false&flatResults=true&highlightingEnabled=true&medicalCodingMode=true
Again.. you will have to write some code to parse the information .. So.. like the embedded tool kit example, you will want to pull the destinationEntities[x].title and .theCode
"title": "Essential <em class='found'>hypertension</em><em class='nonwbe'></em>, unspecified"
"theCode": "BA00.Z",
To use the "production" API.. you will have to register at https://icd.who.int/icdapi which will generate you a client id / secret .. You use these to first request your OAuth / Bearer token which is then put in the header of all the API requests.
Happy Coding! -
Hi, Thanks for all your reflections!
The International Classification of Diseases (ICD) is the predominant classification of human diseases, syndromes, and conditions worldwide. The ICD-11 database is the latest taxonomy comprising about 85,000 entities, called classes or nodes. An entity can be anything relevant to health care. It usually represents a disease or a pathogen, but it can also be an isolated symptom or (developmental) body anomaly.
In practice, no one can remember all these codes, so the WHO developed the ICD-11 Coding Tool software. A very advanced search engine written in javascript. It has features such as word completion and word suggestion and an intuitive way to help someone find the correct entity.
When I want to assign a new diagnosis to a patient, I go to the above online version of the ICD-11 Coding tool, type in one or more keywords (e.g., hypertension), select and copy to the clipboard the desired code. Finally, paste the selected code back into my Ninox database.
you got the point! It seems that yours last API endpoint suggestion search the ICD database and give back relevant results according to the keyword (e.g. hypertension). Now, what I need is to be able to select only one of the suggested entities. Do you think that it is feasible to pull only one of the "destinationEntities[x].title and .theCode" using ninox scripting?
So, what I understand from your replies untill now is that one approach is to directly make calls to ICD-11 API and then try to manage the results local in Ninox. The alternative is to use the Embedded Coding Tool that allows the integration of a complete ICD-11 Coding Tool into your web application by loading the external javascript library. do you believe that the latter is feasible without breaking down Ninox security?
In summary, which of the above approaches is the more efficient and feasible?
-
.. Yes.. it is possible.. I started looking at a way to do a dynamic choice selection .. Then it took me over two hours to remember that https posts only seem to work from the Ninox Cloud .. at least that has been my experience... I was playing around with the logic to POST / request an OAuth token.
So.. Yes.. it should be possible to do from your Ninox Database.. Assuming that database is hosted within a Team on the Ninox Cloud.
The others will have to comment about how to pull it into an HTML window within Ninox.. That would be really interesting to see the code behind that and if it would continue to work as Ninox upgrades. -
said:
Jacques TUR do you believe that the latter is feasible without breaking down Ninox security?What do you mean by "challenging Ninox's security"?
I believe you should be able to do this without much difficulty. You simply need to include the JS code directly instead of using <script> tags. To do this, open the link "https://icdcdn.who.int/embeddedct/icd11ect-1.6.1.js" in a browser, then copy the JavaScript code that appears and paste it into your code. The same applies to the .CSS files.
It's a good idea to start with a trial on CodePen as it's easier for debugging.
For retrieving data from your code, you can either use Ninox's REST API or utilize Ninext, which enables you to directly modify the value of a field.
Note : that while Ninext is recognized by Ninox, there isn't an official agreement in place yet to guarantee that Ninox updates won't disrupt the proper functioning of Ninext. Therefore, relying solely on Ninext for a commercial application is not recommended.
-
said:
For retrieving data from your code, you can either use Ninox's REST API or utilize Ninext, which enables you to directly modify the value of a field.I will have to go back and check out you Ninext again.. I don't follow the bit about retrieving data from your code using Ninox REST API.. Would the REST API access the html code block or are you referring to the base IDC API?
-
said:
I just meant that once the value is selected in the HTML/JavaScript code, you still need to retrieve it to place it in a field of a Ninox table. And for this purpose, you can use either the Ninox REST API or Ninext... I think it is I that does not understand.. In the above quote, are you saying that once the HTML/JavaScript has selected a value, the Ninox REST API can reach into that HTML code block and pull the selected value?
Or.. that you can use the Ninox REST API to call out to the ICD API and list the values?
Sorry if I am confused. -
Hello,
although the option of integrating the ICD coding tool into Ninox in the way suggests seems the most functional option, it is far from my capabilities and furthermore makes me worry about the possibility that in the future the Ninext project will not be compatible with Ninox.
I decided to follow 's advice and tried to customize his database based on my needs.
- I modified the endpoint API to accept a different keyword each time from the 'Type in a keyword' field.
- I created a table "TempResults" to store the 'theCode' and 'title' from the API response results each time.
- I added a dynamic choice field 'Select a code' which takes its values from the "TempResults" table.
See the code below:
'Select a code' := null; delete (select TempResults); let urlAPI := "https://icd11restapi-developer-test.azurewebsites.net/icd/release/11/2023-01/mms/search?q=" + 'Type in a keyword' + "%25&subtreeFilterUsesFoundationDescendants=false&includeKeywordResult=false&useFlexisearch=false&flatResults=true&highlightingEnabled=false&medicalCodingMode=true"; let headers := { Accept: "application/json", 'API-Version': "v2", 'Accept-Language': "en" }; let response := do as server http("GET", urlAPI, headers, null) end; if response.error then 'API Error Response' := text(response.error) else do as server for item in response.result.destinationEntities do let newRec := (create TempResults); newRec.(Code := text(item.theCode)); newRec.(Title := text(item.title)) end end end
This way I can select the desired ICD code+title which is then copied to the corresponding patient fields.
It works (see the screenshot) but the whole process is a bit slow.Do you have any suggestions for something more efficient and fast?
In other words, is there a better way to select the desired ICD code+title and copy it to the corresponding database fields?
Best wishes
-
.. I also have a framework for accessing the "production" API version.. If I get time, I will roll the above into that DB and then share..
-
I managed to make the embedded code work by loading the CSS and JS, and then integrating it within an html() function:
var _style := http("GET", "https://icdcdn.who.int/embeddedct/icd11ect-1.4.1.css"); var _code := http("GET", "https://icdcdn.who.int/embeddedct/icd11ect-1.4.1.js"); var _localScript := " // configure the ECT Handler ECT.Handler.configure({ // The API located at the URL below should be used only // for software development and testing. // ICD content at this location might not // be up to date or complete. // For production, use the API located at // id.who.int with proper OAUTH authentication apiServerUrl: 'https://icd11restapi-developer-test.azurewebsites.net', language: '" + 'Country code' + "' // set the language to Spanish }); ECT.Handler.bindEmbeddedBrowser(1) "; var _html := --- <style>{ _style.result } </style> <script>{ _code.result } { _localScript } </script> <!-- div element used for building the Embedded Browser --> <div class="ctw-eb-window" style="width:100%; height:100%" data-ctw-ino="1"></div> ---; html(_html)
I also had to call the bindEmbeddedBrowser function (line 17) to refresh the page upon display.
And there you have the result :
-
Hi,
I spent the past two days studying OAUTH2 authentication and how to use Ninox to request a token from the ICD server.
After dozens of failed attempts, I found a way that worked (see screenshot).
See the code below:let token_endpoint := "https://icdaccessmanagement.who.int/connect/token"; let header := { 'Content-Type': "application/x-www-form-urlencoded" }; let data := "client_id=*******&client_secret=********&scope=icdapi_access&grant_type=client_credentials"; let response := do as server http("POST", token_endpoint, header, data) end; if response.error then 'API Response' := text(response.error) else 'API Response' := text(response.result) end
is the above code optimal? Have you use a different 'Content-Type' in your database?
Have a good time
Sotirios
-
Sorry.. I have been crazy busy. Here is a WORK IN PROGRESS. See the "HowTo" table for some help. It only works to get the access token for now. Have not had time to roll it into the rest of calling the API. I have used this framework on many other OAuth APIs with great success.
If I get more time.. I will clean it up.. but for now.. Have fun.
-
Content aside
- Status Answered
- 1 yr agoLast active
- 24Replies
- 495Views
-
4
Following