/* * ER Wait Times RSS Reader for the ICU and JavaScript compatible implementations * -- This new version was created to go around the XML cross-domain limitation * -- and the replication issues being experienced by the EHC servers in Cincinnati * Date: 04/19/2010 * Version: * 3.0 - * 2.0 - Includes auto contingency plan detection * Files: * - ERWaitTimes_CSS.css * - ERWaitTimes_RSSReader.js * - ERWaitTimes_SampleImplementation.html * Author: Gabriel O. Perez * HCA East Florida Division Inc. * (954) 767-5767 */ function ErWaitTimesRssReader(divisionRssFeedFile) { setRequestType('p'); setRssFeedFile(divisionRssFeedFile); GetErWaitTimes(); /************************************** Global Variables ************************************/ /********************************* DO NOT MODIFY - DO NOT MODIFY ****************************/ /* * feedFile will be instantiated at class construct, it will contain the file_name for * the division's RSS feed. Possible values to follow. */ /* * containerName will hold the ID value/name of the container where * the results of this script will be sent to. * Default value is ErWaitTimes_Container * this can be changed to accommodate your already present container name. * It is recommended you use the default container name below for support reasons. * * This value is only to be changed by the function BuildWidget(string filterType, * string filterValue, * string containerID) */ var containerID = 'ErWaitTimes_Container'; /* * filterType will contain the type of filter to be applied * possible values are: * facility * market * division * city * state * * The default value is an empty string so the behaviour would be to return all * available facilities within the RSS feed. No filters * * This value is only to be changed by the function BuildWidget(string filterType, * string filterValue, * string containerID) */ var filterType = ''; /* * filterValue will contain the value to be looked for within the feed. * filterValue must match the actual value contained within the feed. * if filterType = market, then filterValue = NameOfTheMarketDesired element * if filterType = facility, then filterValue = NameOfTheFacilityDesired element * if filterType = division, then filterValue = NameOfTheDivision <division> element * if filterType = city, then filterValue = NameOfCity <address> element * if filterType = state, then filterValue = StateAbbreviation <address> element * * The default value is an empty string so the behaviour would be to return all * available facilities within the RSS feed. No filters * * This value is only to be changed by the function BuildWidget(string filterType, * string filterValue, * string containerID) */ var filterValue = ''; /* * contingencyMessage will contain the message as approved by HCA's Internal audit to be * displayed in case the wait time is no longer in compliance. Compliance for an RSS Reading * system is defined as the time being accurate as of no more than 90 minutes from the time * the reading system reads the feed. */ var contingencyMessage = 'updating'; var gObjFeed; var dataAvailable = false; var rssFeedFile = ''; /* * requestType will define whether this request will be through a proxy or local file. * default would be l for local. p will make this a proxy request. */ var requestType = 'l'; /*******************************************************************************************/ /************************************* Private Functions ********************************************/ this.BuildWidget = function(objFeed, filterType, filterValue, containerID, requestType) { setRequestType(requestType); setFilterAndContainer(filterType, filterValue, containerID); switch (getRequestType()) { case 'p': setObjFeed(objFeed); ParseERWaitTimes(); break; default: setRssFeedFile(objFeed); GetErWaitTimes(); break; } return true; } /* * function setContainerID overrides the default container id of ErWaitTimes_Container to * the desired container name.Useful when wanting to put different result sets in different containers. */ function setContainerID(newContainerID) { containerID = newContainerID ? newContainerID : 'ErWaitTimes_Container'; } function getContainerID() { return containerID; } /* * function set/get FilterType And FilterValue overrides the default filter values set by the global variables * which currently are empty strings. This function is useful if you are going to call the script * multiple times but want to use different filters each time or if you want to give the user the * option of choosing what they want to see from what is available. */ function setFilterType(newFilterType) { filterType = newFilterType ? newFilterType : ''; } function getFilterType() { return filterType; } function setFilterValue(newFilterValue) { filterValue = newFilterValue ? newFilterValue : ''; } function getFilterValue() { return filterValue; } function setFilterTypeAndValue(newFilterType, newFilterValue) { setFilterType(newFilterType); setFilterValue(newFilterValue); } /* * function setFilterAndContainer overrides the default filter and container ID values in one shot */ function setFilterAndContainer(newFilterType, newFilterValue, newContainerID) { setContainerID(newContainerID); setFilterTypeAndValue(newFilterType, newFilterValue); } function setRssFeedFile(newRssFeedFile){ rssFeedFile = newRssFeedFile; } function getRssFeedFile(){ return rssFeedFile; } function setRequestType(newRequestType){ requestType = newRequestType ? newRequestType : 'l'; } function getRequestType(){ return requestType; } function setDataAvailable(available) { dataAvailable = available; } function isDataAvailable() { return dataAvailable; } function setObjFeed(newObjFeed) { var tempObjFeed; try{tempObjFeed = newObjFeed.query.results.item;}catch(e){tempObjFeed = newObjFeed;} gObjFeed = tempObjFeed; setDataAvailable(true); } function getObjFeed() { return gObjFeed; } function setContingencyMessage(newMessage){ contingencyMessage = newMessage ? newMessage : 'updating'; } function getContingencyMessage(){ return contingencyMessage; } function getFullDate(dateString) { return new Date(dateString).toLocaleDateString(); } function getTime(dateString) { return new Date(dateString).toLocaleTimeString(); } function getFullDateTime(dateString) { return getFullDate(dateString) + ' ' + getTime(dateString); } function getAbbrDate(dateString) { return new Date(dateString).toDateString(); } function getAbbrDateTime(dateString) { return getAbbrDate(dateString) + ' ' + getTime(dateString); } function isStaleWaitTime(dateString) { var currLocalDate = new Date(); return ((currLocalDate.getTime()-Date.parse(dateString)) >=5400000) ? true : false; } function contingencyWaitTimeCheck(erWaitTime,dateString) { return (erWaitTime == '---' || isStaleWaitTime(dateString)) ? getContingencyMessage() : erWaitTime; } String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }; String.prototype.ltrim = function() { return this.replace(/^\s+/, ""); }; String.prototype.rtrim = function() { return this.replace(/\s+$/, ""); }; function GetErWaitTimes() { switch(getRequestType()){ case 'p': GetProxyFeed(getRssFeedFile()); break; default: GetLocalFeed(getRssFeedFile()); break; } } function getCacheBuster() { var currentDateTime = new Date(); return (currentDateTime.getFullYear() + '' + (currentDateTime.getMonth() + 1) + '' + currentDateTime.getDate() + '' + currentDateTime.getHours() + '' + (currentDateTime.getMinutes() / 10).toString().substring(0, 1)); } function GetProxyFeed(divisionFeedFile) { setDataAvailable(false); var currentDateTime = new Date(); var source = 'http://query.yahooapis.com/v1/public/yql?q=' + 'select%20*%20from%20rss%20where%20url%3D%22http%3A%2F%2F' + 'eastflamkt.two.icu.ehc.com%2Fcpm%2Frss%2F' + divisionFeedFile + '%22&rnd=_' + getCacheBuster() + '&format=json&callback=loadWidgets'; var s = document.createElement('script'); s.setAttribute('src', source); document.getElementsByTagName('head')[0].appendChild(s); } /* * function ParseERWaitTimesFeed will take an object and parse through it's * values, assign all available feed fields into variables and then append * to the output variable the chosen fields for the particular filter when * a filter match is found. */ function ParseERWaitTimes() { ParseJSONERWaitTimesFeed(getObjFeed()); } function ParseJSONERWaitTimesFeed(objFeed) { /* facilities will contain all the items (facilities) and elements(facility data) of the object */ var facility = objFeed; /* lets clean our output here */ var output = ''; /* retrieving the number of items within the items object */ var noOfItems = facility.length; /* iterate through each item and grab all available elements */ for (var i = 0; i < noOfItems; i++) { var facilityName = facility[i].title; //facility name var asOfDateTime = getAbbrDateTime(facility[i].pubDate); //facility's wait time accuracy date/time //for non-abbreviated version, use //getFullDateTime(facility[i].pubDate); var facilityURL = facility[i].link; //facility's web site URL var erWaitTime = contingencyWaitTimeCheck(facility[i].description,facility[i].pubDate); //facility's ER wait time var facilityPhoneNumber = facility[i].phone; //facility's phone number var facilityAddres = facility[i].address; //facility's full address var division = facility[i].division; //facility's division var market = facility[i].category; //facility's market var title = facility[i].comments; //description of feed data var address = facility[i].address.split(','); //facility's address array var street = address[0]; //facility's street var city = address[1]; //facility's city var state = address[2].substring(1, 3); //facility's state /* * The following statement will only concatenate the data for those items * that match the filter selected. If errors or no filters are defined, the default would be * to include the entire content of the RSS feed. * * Each filterType contains it's own independent "output" format so you are free to use * whichever elements from above within your output and use any HTML formatting/elements * per filterType. */ switch (getFilterType()) { case 'city': if (city.toLowerCase().trim() == getFilterValue().toLowerCase().trim()) { output += "<h3><a href='" + facilityURL + "'>" + facilityName + "</a></h3>" + erWaitTime + "As of: " + asOfDateTime + "<hr/>"; }; break; case 'state': if (state.toLowerCase().trim() == getFilterValue().toLowerCase().trim()) { output += "<h3><a href='" + facilityURL + "'>" + facilityName + "</a></h3>" + erWaitTime + "As of: " + asOfDateTime + "<hr/>"; }; break; case 'facility': if (facilityName.toLowerCase().trim() == getFilterValue().toLowerCase().trim()) { output += "<FONT color=#ffffff><I><A style='CURSOR: help' href='/CustomPage.asp?guidCustomContentID={CBCA4FB3-9367-4BC9-9827-28FC10ED88B7}'><DIV id=info-link></DIV></A><DIV id=pubdate>" + asOfDateTime + "</DIV></I><DIV style='OVERFLOW: auto; WIDTH: 163px; HEIGHT: 30px'><DIV id=facility>" + facilityName + "</DIV><DIV id=wait-time>"+erWaitTime+"</DIV></DIV></FONT>"; }; break; case 'market': if (market.toLowerCase().trim() == getFilterValue().toLowerCase().trim()) { output += "<h3><a href='" + facilityURL + "'>" + facilityName + "</a></h3>" + erWaitTime + "As of: " + asOfDateTime + "<hr/>"; }; break; case 'division': if (division.toLowerCase().trim() == getFilterValue().toLowerCase().trim()) { output += "<h3><a href='" + facilityURL + "'>" + facilityName + "</a></h3>" + erWaitTime + "As of: " + asOfDateTime + "<hr/>"; }; break; default: output += "<h3><a href='" + facilityURL + "'>" + facilityName + "</a></h3>" + erWaitTime + "As of: " + asOfDateTime + "<hr/>"; } } /* Places the results within the container defined within the Global Variables at the beginning of this file tag */ document.getElementById(getContainerID()).innerHTML = output; } function GetLocalFeed(feedFile) { var mygetrequest = new getSupportedXMLAPI(); if (mygetrequest.overrideMimeType) { mygetrequest.overrideMimeType('text/xml'); } mygetrequest.onreadystatechange = function() { if (mygetrequest.readyState == 4) { if (mygetrequest.status == 200 || window.location.href.indexOf("http") == -1) { var xmldata = mygetrequest.responseXML; //retrieve result as an XML object processFeedDocument(xmldata); } else { alert("An error has occured making the request"); } } }; mygetrequest.open("GET", feedFile, true); mygetrequest.send(null); } function getSupportedXMLAPI() { var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]; if (window.ActiveXObject) { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken) for (var i = 0; i < activexmodes.length; i++) { try { return new ActiveXObject(activexmodes[i]); } catch (e) { //suppress error }//end Catch }//end For Loop } //end-if else if (window.XMLHttpRequest) {return new XMLHttpRequest();} else {return false;} } //end getSupportedXMLAPI(); function processFeedDocument(doc) { if (doc) {setObjFeed(parseXMLRSSFeed2JSON(doc));} ParseERWaitTimes(); } function findChild(element, nodeName) { return element.getElementsByTagName(nodeName)[0].firstChild.nodeValue; } function parseXMLRSSFeed2JSON(rss) { var results = new Array; var items = rss.getElementsByTagName("item"); for (var i = 0; i < items.length; i++) { var item = items[i]; if (item.nodeName == "item") { var title = findChild(item, "title"); // we have to have the title to include the item in the list if (title != null) { // get the link var link = findChild(item, "link"); // get the date var dateEl = findChild(item, "pubDate"); // get the description var description = findChild(item, "description"); // get phone number var phone = findChild(item, "phone"); // get address var address = findChild(item, "address"); var division = findChild(item, "division"); var category = findChild(item, "category"); var comments = findChild(item, "comments"); // save the result results[results.length] = { title: title, link: link, pubDate: dateEl, description: description, phone: phone, address: address, division: division, category: category, comments: comments }; } } } return results; } } /*******************************************************************************************/