HTML List to Outline

In the following scenario, “Omni-Interactive” code in a webpage extracts the contents of an HTML list and inserts the retrieved list items into an OmniOutliner outline document as individual rows.

U.S. Census Regions and Divisions (shown in video)

“Tap-able”|“Click-able” Lists

You can make an HTML list “tap-able” or “click-able” by adding an onclick() handler to the element’s opening tag. In the example HTML code below, the onclick() handler calls a function named addToOutline(elementID) and passes the element’s ID into the function:

Once the onclick() event handler has been assigned to an HTML list element, clicking or tapping any list item will cause the targeted JavaScript function to run.

Getting List Items

The first step in transferring the contents of an HTML list to an OmniOutliner document is to create a JavaScript array containing the text of the list items. This is accomplished using this JavaScript function placed in the host webpage.

function getListItemStrings(listID){ var ul = document.getElementById(listID); var items = ul.getElementsByTagName("li"); var listStrings = new Array(); for (var i = 0; i < items.length; ++i) { listStrings.push(items[i].textContent); }; return listStrings; }

When this function is called by the main function, it is passed the ID of the list whose contents are to be retrieved, and returns an JavaScript array of strings.

The Main Function

This is the main JavaScript function, embedded in the webpage, or linked from a file (see bottom of this page), that performs the following:

function addToOutline(listID){ var listItems = getListItemStrings(listID); var listItemsString = JSON.stringify(listItems); var encodedListItemsString = encodeURIComponent(listItemsString); var OmniOutlinerScript = 'omnioutliner:///omnijs-run?script=var%20itemArray%20%3D%20XXXXX%0Avar%20nodes%20%3D%20document%2Eeditors%5B0%5D%2EselectedNodes%0Aif%28nodes%2Elength%20%3D%3D%201%29%7B%0A%09var%20alert%20%3D%20new%20Alert%28%22Item%20Placement%22%2C%20%22Should%20the%20list%20items%20be%20added%20as%20children%20or%20siblings%20of%20the%20selected%20outline%20item%3F%22%29%0A%09alert%2EaddOption%28%22Children%22%29%0A%09alert%2EaddOption%28%22Siblings%22%29%0A%09alert%2EaddOption%28%22Cancel%22%29%0A%09alert%2Eshow%28function%28result%29%7B%0A%09%09var%20selectedItem%20%3D%20nodes%5B0%5D%2Eobject%0A%09%09if%20%28result%20%3D%3D%200%29%7B%0A%09%09%09for%28i%20%3D%200%3B%20i%20%3C%20itemArray%2Elength%3B%20i%2B%2B%29%7B%0A%09%09%09%09selectedItem%2EaddChild%28selectedItem%2Eend%2Cfunction%28item%29%7Bitem%2Etopic%20%3D%20itemArray%5Bi%5D%7D%29%0A%09%09%09%7D%0A%09%09%7D%20else%20if%20%28result%20%3D%3D%201%29%7B%0A%09%09%09parentItem%20%3D%20selectedItem%2Eparent%0A%09%09%09for%28i%20%3D%200%3B%20i%20%3C%20itemArray%2Elength%3B%20i%2B%2B%29%7B%0A%09%09%09%09parentItem%2EaddChild%28parentItem%2Eend%2Cfunction%28item%29%7Bitem%2Etopic%20%3D%20itemArray%5Bi%5D%7D%29%0A%09%09%09%7D%0A%09%09%7D%20else%20%7B%0A%09%09%09throw%20new%20Error%28%27script%20cancelled%27%29%0A%09%09%7D%0A%09%7D%29%0A%7D%20else%20%7B%0A%09var%20alert%20%3D%20new%20Alert%28%27SELECTION%20ERROR%27%2C%27Please%20select%20a%20single%20outline%20item%20at%20which%20you%20wish%20to%20add%20items%2E%27%29%0A%09alert%2Eshow%28function%28result%29%7B%7D%29%0A%7D'; OmniOutlinerScript = OmniOutlinerScript.replace('XXXXX',encodedListItemsString); window.location = OmniOutlinerScript; }

 01-08  The addToOutline(listID) function performs the task of extracting list data, inserting it into an Omni Automation script, and executed the script.

 02  Retrieve the list item strings using the getListItemStrings(listID) function, passing in the ID of the list to process.

 03  Convert the retrieved array of string into a string using the JSON.stringify() method.

 04  Encode the string using the standard JavaScript encodeURIComponent() method.

 05  An encoded version of the Omni Automation script URL for adding items to the outline document, is place within this function. The encoded script contains the placeholder DATAPLACEHOLDER that will be replaced with the encoded list data.

 06  Replace the placeholder with the encoded list content.

 07  Execute the Omni Automation script URL by assigning it to be the value of the window’s location property.

The Omni Automation Script

Here is the Omni Automation script that does the work of adding the retrieved list items into the currently open OmniOutliner document. In use, the script is encoded and the encoded script is placed within the main JavaScript function embedded in the webpage. Note the placeholder DATAPLACEHOLDER (line 1) that is replaced with an array of the list item strings before the script is executed by the main JavaScript function.

var itemArray = DATAPLACEHOLDER var nodes = document.editors[0].selectedNodes if(nodes.length == 1){ var alert = new Alert("Item Placement", "Should the list items be added as children or siblings of the selected outline item?") alert.addOption("Children") alert.addOption("Siblings") alert.addOption("Cancel"){ var selectedItem = nodes[0].object if (result == 0){ for(i = 0; i < itemArray.length; i++){ selectedItem.addChild(selectedItem.end,function(item){item.topic = itemArray[i]}) } } else if (result == 1){ parentItem = selectedItem.parent for(i = 0; i < itemArray.length; i++){ parentItem.addChild(parentItem.end,function(item){item.topic = itemArray[i]}) } } else { throw new Error('script cancelled') } }) } else { var alert = new Alert('SELECTION ERROR','Please select a single outline item at which you wish to add items.'){}) }

Working with Titled Lists

In the Grocery Shopping List example (plugin), each the source lists are titled, and the added row is to be a parent (List Title) with children (List Items). Therefore, a title attribute is added to the list element so that it can be retrieved and used as the topic for the added parent row.

Grocery Shopping List

Here is the HTML for one of the lists from the example shown in the video above. Note that the “title” and “id” attributes are added to the standard ul (unordered list) element, with the of the title attribute being the name of the list as it is to appear in the outline document. The value of the id attribute can be whatever unique value you want to use. In this case, we use a lowercase version of the title.

Also added to the ul opening statement is the onclick handler that calls the embedded JavaScript function described on this page: addToOutline('dairy')

<ul id="dairy" title="Dairy" onclick="addToOutline('dairy')"> <p class="list-head">Dairy</p> <li>Butter / Margarine</li> <li>Cottage cheese</li> <li>Half & half</li> <li>Milk</li> <li>Sour cream </li> <li>Whipped cream</li> <li>Yogurt</li> <li style="border-bottom:1px solid #000;"></li> <li style="border-bottom:1px solid #000;"></li> </ul>

Because the list element includes the title attribute, the processing function includes statements for extracting and passing the value of list’s title attribute:

function addToOutline(listID){ var ul = document.getElementById(listID); var listTitle = ul.getAttribute('title'); var encodedListTitle = encodeURIComponent(listTitle); var listItems = getListItemStrings(listID); var listItemsString = JSON.stringify(listItems); var encodedListItems = encodeURIComponent(listItemsString); var OmniOutlinerScript = 'omnioutliner://localhost/omnijs-run?script=var%20itemTitle%20%3D%20%27LISTTITLEPLACEHOLDER%27%0Avar%20itemArray%20%3D%20LISTITEMSPLACEHOLDER%0Avar%20newItem%20%3D%20rootItem%2EaddChild%28rootItem%2Ebeginning%2Cfunction%28item%29%7Bitem%2Etopic%20%3D%20itemTitle%7D%29%0Afor%28i%20%3D%200%3B%20i%20%3C%20itemArray%2Elength%3B%20i%2B%2B%29%7B%0A%09newItem%2EaddChild%28newItem%2Eend%2Cfunction%28item%29%7Bitem%2Etopic%20%3D%20itemArray%5Bi%5D%7D%29%0A%7D%0AstatusCol%20%3D%20document%2Eoutline%2EstatusColumn%0Adocument%2Eeditors%5B0%5D%2EsetVisibilityOfColumn%28statusCol%2Ctrue%29'; OmniOutlinerScript = OmniOutlinerScript.replace('LISTITEMSPLACEHOLDER',encodedListItems); OmniOutlinerScript = OmniOutlinerScript.replace('LISTTITLEPLACEHOLDER',encodedListTitle); window.location = OmniOutlinerScript; }

Since the grocery list example adds a row (List Title) with children (List Items), the Omni Automation script does not query the user as to where to insert the new item, and instead places it at the beginning of the top-level items. Here is the unencoded Omni Automation script:

var itemTitle = 'LISTTITLEPLACEHOLDER' var itemArray = LISTITEMSPLACEHOLDER var newItem = rootItem.addChild( rootItem.beginning, function(item){item.topic = itemTitle} ) for(i = 0; i < itemArray.length; i++){ newItem.addChild(newItem.end,function(item){item.topic = itemArray[i]}) } statusCol = document.outline.statusColumn document.editors[0].setVisibilityOfColumn(statusCol,true)

Working with Checked Lists

In the Grocery List example, items were added from webpage to an OmniOutliner document with status checkboxes displayed. Here are two OmniOutliner actions for working with status-type lists:

macOS_deviceTo install on macOS, download and unpack the ZIP archive files from the links above. Choose “Plug-Ins…” from the OmniOutliner automation menu, and place the files in the PlugIns folder now opened on the desktop. The actions will now be available from the OmniOutliner automation menu.

macOS_deviceTo install on iOS, tap each link, choosing the “Open” option in forthcoming dialog. Then tap “More…” and choose the “Copy to OmniOutliner” option. The installed action will appear in the Plug-Ins view on your device, and will be available from the OmniOutliner automation menu:

Adding Functions from File

You can incude the functionality shown on this webpage in your webpages by downloading the addListToOutline.js file and including this link in the HEAD section of your webpages. Add the TAP|CLICK triggers to your lists as shown above.

Image Maps and Omni Automation

OmniGraffle Pro for macOS has the awesome ability to export the graphics on a canvas as an HTML image map. The image map shown in the example video was created in OmniGraffle Pro and was exported as an HTML image map, with the ability to trigger embedded JavaScript functions that run “Omni-Interactive” scripts.


When the OmniGraffle document used to generate the image is exported as an image map, URLs assigned as actions to graphics are automatically exported as URLs integrated into the generated HTML for the image map.

To make the URLs able to trigger the JavaScript functions embedded in the webpage, simply make the value of the action URL assigned to the graphic (see illustration below) a call to the target JavaScript function, instead a standard URL.



Once you’ve assigned all of the graphics an action URL, export the canvas as an image map, by choosing “Export…” from the “File” menu, and then select the “HTML Image Map” export option in the forthcoming drop-down sheet. An archive of the example document shown in the video is available for download.


This webpage is in the process of being developed. Any content may change and may not be accurate or complete at this time.