Sending/Receiving XML Data
This section explains the working of an embedded webpage solution that uses XML source data (a book list). The book list is sent from the webpage (screenshot below) to an embedded IFrame (framed in blue). Here, the list can be edited using a MobileTogether solution. On saving the changes in the IFrame, the edited book list is sent to the webpage.
The embedded webpage solution consists of the HTML webpage (xmlBooks.html) and a MobileTogether design (xmlBooks.mtd). Both files are located in your (My) Documents MobileTogether folder: MobileTogetherDesignerExamples\Tutorials\EmbeddedWebpageSolutions. To try out the files, deploy the MTD file to your server and enable it to be accessed anonymously. If needed, modify the HTML code so that the IFrame correctly targets the workflow on the server. Open the webpage in a browser and click the Load button to start.
The description below contains the complete HTML code listing of the webpage, followed by a color-coded explanation of how the HTML code interacts with the solution.
HTML code listing
The HTML code listing of the file xmlBooks.html. An explanation of the code is given in the next section below. Please note that some JavaScript functionality used in this example might not be available in all browsers. In this case, please modify the JavaScript to suit your browser.
<!DOCTYPE html> <html> <head> <style> * { font-family: Segoe UI, Tahoma, Arial, Helvetica, sans-serif; } iframe { width: 100%; height: 400px; border: 2px solid blue; border-radius: 5px; margin: 10px 0px; } code { font-size: small; } </style> <script> // The book list in XML format var books = ' <books> <item> <author>Mary Shelley</author> <title>Frankenstein; or, The Modern Prometheus</title> <year>1818</year> <pages>280</pages> </item> <item> <author>Bram Stoker</author> <title>Dracula</title> <year>1897</year> <pages>302</pages> </item> </books> ';
// This is the XML DOM tree (initialized in showbooks) var books;
function sendbooks() { document.querySelector('iframe').contentWindow.postMessage({ "books": books.childNodes[0].outerHTML }, '*'); }
// This is the function that receives the updated books function receivebooks(m) { books = m.data.json.books; showbooks(); }
// Contents of variable 'books' converted to string and displayed inside HTML element CODE function showbooks() { // Create a DOM tree from the XML books = new DOMParser().parseFromString(books, 'text/xml'); // Manipulate the DOM and show the result document.querySelector('code').innerText = books.childNodes[0].outerHTML; }
// Handler to receive messages from server via solution in IFrame window.addEventListener('message', receivebooks);
// Handler to show initial list of books on page load document.addEventListener('DOMContentLoaded', showbooks); </script> </head> <body> <h4>Example showing how to interact with an XML source</h4> <h5>The books we want to edit:</h5> <button onclick="sendbooks()">Load</button> <pre><code></code></pre> <h5> Click LOAD to load the book list into the IFrame. In the IFrame, edit the list. You can add, delete, and/or modify entries. Click SAVE to save changes. Notice that changes are propagated to the list in the webpage. </h5> <iframe src="http://localhost:8083/run?d=/public/xmlBooks" frameborder="0"></iframe> </body> </html>
|
How it works
In this explanatory part, different background colors are used to indicate what's happening in the individual parts of the mechanism (webpage–solution–workflow):
Webpage: user actions and how the HTML/JavaScript code works | |
Solution: actions carried out by the solution in the IFrame | |
Workflow: processing on the server (based on the MT design) |
On loading the HTML page:
A JavaScript variable named books is read. It contains a string containing an XML structure:
var books = ' <books> <item> <author>Mary Shelley</author> <title>Frankenstein; or, The Modern Prometheus</title> <year>1818</year> <pages>280</pages> </item> <item> <author>Bram Stoker</author> <title>Dracula</title> <year>1897</year> <pages>302</pages> </item> </books> ';
The content of the books variable is displayed inside the HTML code element by using an event listener (that listens for a DOMContentLoaded event) and a JavaScript function (showbooks):
document.addEventListener('DOMContentLoaded', showbooks);
The showbooks function: (i) creates a DOM tree from the XML structure in the books variable, and (ii) places the desired XML structure inside the HTML code element.
function showbooks() { books = new DOMParser().parseFromString(books, 'text/xml'); document.querySelector('code').innerText = books.childNodes[0].outerHTML; }
<pre><code></code></pre>
This enables us to see the contents of the books variable when the HTML document is loaded. (Later, we will use the showbooks function to check whether the books variable has been updated.)
|
The IFrame loads the solution xmlBooks (targeted in the src attribute of the iframe element):
<iframe src="http://localhost:8083/run?d=/public/xmlBooks" frameborder="0"></iframe>
|
On clicking the Load button:
<button onclick="sendbooks()">Load</button>
A JavaScript function (sendbooks) uses postMessage() to send the contents of the books variable to the IFrame. Note that the XML content is placed inside a JSON object. (This is because the workflow expects to receive JSON.)
function sendbooks() { document.querySelector('iframe').contentWindow.postMessage({ "books": books.childNodes[0].outerHTML }, '*'); }
|
{books} is automatically sent to the workflow on the server (in serialized JSON form). |
The page event OnEmbeddedMessage is enabled since an action has been defined for it (see screenshot below). As a result, the page source $MT_EMBEDDEDMESSAGE is automatically loaded with {books} data. The Load from String action (screenshot above) creates the content of $MT_EMBEDDEDMESSAGE/json/books as the XML page source $books. The structures of both these page sources have been created beforehand (see screenshot below). The XML page source has been created so that the XML data can be linked to design components, thereby enabling the XML data to be edited. The design contains a repeating table of item nodes of the $books page source (see screenshot below). Cells of the table are linked, respectively, to the author, title, year, and pages page source nodes. Because the page source has been loaded, the repeating table is populated with the data in the workflow's $MT_EMBEDDEDMESSAGE page source. |
This data update is shown in the solution in the IFrame. |
On editing the books data in the solution, the $books page source is continually updated. On clicking Save, an OnButtonClick event handler is triggered. |
The OnButtonClick event specifies two actions: (i) a Save to String action, which saves the $books page source (containing the edited book list) to $MT_EMBEDDEDMESSAGE/json/books; (ii) an Embedded Message Back action, which sends the contents of $MT_EMBEDDEDMESSAGE as a message event to the IFrame. (Note that $MT_EMBEDDEDMESSAGE/json/books contains the edited book list.) |
An event listener has been registered to listen for the message event. On picking up a message event, a JavaScript function (receivebooks) is called:
window.addEventListener('message', receivebooks);
The receivebooks function (see below) takes the message event (m) as its parameter (data is the data of the message event), and assigns the content of the json/books object in the received message to the books variable. The books variable now contains the updated book list from the server.
function receivebooks(m) { books = m.data.json.books; showbooks(); }
The showbooks function: (i) creates a DOM tree from the XML structure in the books variable, and (ii) places the desired XML structure inside the HTML code element.
function showbooks() { books = new DOMParser().parseFromString(books, 'text/xml'); document.querySelector('code').innerText = books.childNodes[0].outerHTML; }
<pre><code></code></pre>
The updated book list is shown in the webpage.
|