Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit

  • Loading branch information...
commit b17a92cd68eed7573cb4a5eb3563b391c2ab2243 1 parent 5565032
@timwis timwis authored
View
2  .c9revisions/css/styles.css.c9save
@@ -0,0 +1,2 @@
+{"ts":1354219251604,"silentsave":true,"restoring":false,"patch":[[]],"length":0}
+{"contributors":[],"silentsave":false,"ts":1354219251940,"patch":[[{"diffs":[[1,"[data-role=\"content\"] h1,\r\n[data-role=\"content\"] h2,\r\n[data-role=\"content\"] h3,\r\n[data-role=\"content\"] h4 {\r\n margin-top: 0;\r\n}\r\n\r\ndt {\r\n\tfont-weight: bold;\r\n\tbackground-color: #e6e6e6;\r\n}\r\n\r\ndd {\r\n\tmin-height: 15px;\r\n\tmargin-left: 20px;\r\n}\r\n\r\naddress {\r\n\tfont-style: normal;\r\n}\r\n\r\n[data-role=\"footer\"] {\r\n\tpadding: 5px;\r\n}\r\n\r\n.ui-collapsible-content {\r\n\tpadding: 0px 5px;\r\n}\r\n"]],"start1":0,"start2":0,"length1":0,"length2":380}]],"length":380,"saved":false}
View
2  .c9revisions/index.html.c9save
@@ -0,0 +1,2 @@
+{"ts":1354219139108,"silentsave":true,"restoring":false,"patch":[[]],"length":0}
+{"contributors":[],"silentsave":false,"ts":1354219139823,"patch":[[{"diffs":[[1,"<!DOCTYPE html>\r\n<html>\r\n<head>\r\n <title>L&I Property History</title>\r\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\r\n\t<meta charset=\"utf-8\">\r\n\t<link rel=\"stylesheet\" href=\"//code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css\" />\r\n\t<link rel=\"stylesheet\" href=\"css/styles.css\" />\r\n\r\n\t<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js\"></script>\r\n\t<script src=\"js/jquery.mobile.router.min.js\"></script>\r\n\t<script src=\"//code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js\"></script>\r\n\t<script src=\"//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js\"></script>\r\n\t<script src=\"js/phillyapi.js\"></script>\r\n\t<script src=\"js/script.js\"></script>\r\n\t<script type=\"text/javascript\">\r\n\tvar _gaq = _gaq || [];\r\n\t//_gaq.push(['_setAccount', 'UA-35850648-1']);\r\n\t//_gaq.push(['_trackPageview']);\r\n\t(function() {\r\n\tvar ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\r\n\tga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\r\n\tvar s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\r\n\t})();\r\n\t</script>\r\n</head>\r\n<body>\r\n\r\n\t<div data-role=\"page\" id=\"search\">\r\n\t\t<div data-role=\"content\">\r\n\t\t\t<h2>L&I Property History</h2>\r\n\t\t\t<form action=\"#summary\">\r\n\t\t\t\t<label for=\"address\" class=\"ui-hidden-accessible\">Address</label>\r\n\t\t\t\t<input type=\"text\" name=\"address\" placeholder=\"Address\">\r\n\t\t\t\t<button type=\"submit\" data-theme=\"b\">Search</button>\r\n\t\t\t</form>\r\n\t\t</div>\r\n\t</div>\r\n\r\n\t<div data-role=\"page\" id=\"summary\">\r\n\t\t<div data-role=\"content\"></div>\r\n\t\t<div data-role=\"footer\" data-theme=\"b\" data-position=\"fixed\" data-id=\"main-footer\">\r\n\t\t\t<a href=\"#\" data-icon=\"arrow-l\" data-rel=\"back\" data-inline=\"true\">Search</a>\r\n\t\t</div>\r\n\t</div>\r\n\t\r\n\t<div data-role=\"page\" id=\"details\">\r\n\t\t<div data-role=\"content\"></div>\r\n\t\t<div data-role=\"footer\" data-theme=\"b\" data-position=\"fixed\" data-id=\"main-footer\">\r\n\t\t\t<a href=\"#\" data-icon=\"arrow-l\" data-rel=\"back\" data-inline=\"true\">Search Results</a>\r\n\t\t</div>\r\n\t</div>\r\n\t\r\n\t<script type=\"text/template\" id=\"template-summary\">\r\n\t\t<h2><%= address %></h2>\r\n\t\t<ul data-role=\"listview\">\r\n\t\t<% if(data.permits !== undefined) { %>\r\n\t\t\t<li data-role=\"list-divider\">Permits <span class=\"ui-li-count\"><%= data.permits.length %></span></li>\r\n\t\t\t<% _.each(data.permits, function(permit) { %>\r\n\t\t\t<li><a href=\"#details?entity=<%= permit.entity %>&eid=<%= permit.permit_number%>\"><%= permit.permit_number %>: <%= permit.permit_type_name %></a></li>\r\n\t\t\t<% }); %>\r\n\t\t<% } %>\r\n\t\t\r\n\t\t<% if(data.licenses !== undefined) { %>\r\n\t\t\t<li data-role=\"list-divider\">Licenses <span class=\"ui-li-count\"><%= data.licenses.length %></span></li>\r\n\t\t\t<% _.each(data.licenses, function(license) { %>\r\n\t\t\t<li><a href=\"#details?entity=<%= license.entity %>&eid=<%= license.license_number%>\"><%= license.license_number %>: <%= license.license_type_name %></a></li>\r\n\t\t\t<% }); %>\r\n\t\t<% } %>\r\n\t\t\r\n\t\t<% if(data.cases !== undefined) { %>\r\n\t\t\t<li data-role=\"list-divider\">Violations <span class=\"ui-li-count\"><%= data.cases.length %></span></li>\r\n\t\t\t<% _.each(data.cases, function(_case) { %>\r\n\t\t\t<li><a href=\"#details?entity=<%= _case.entity %>&eid=<%= _case.case_number%>\"><%= _case.case_number %>: <%= _case.violations.length %> Violations</a></li>\r\n\t\t\t<% }); %>\r\n\t\t<% } %>\r\n\t\t\r\n\t\t<% if(data.appeals !== undefined) { %>\r\n\t\t\t<li data-role=\"list-divider\">Appeals <span class=\"ui-li-count\"><%= data.appeals.length %></span></li>\r\n\t\t\t<% _.each(data.appeals, function(appeal) { %>\r\n\t\t\t<li><a href=\"#details?entity=<%= appeal.entity %>&eid=<%= appeal.appeal_number%>\"><%= appeal.appeal_number %>: <%= appeal.appeal_type_name %></a></li>\r\n\t\t\t<% }); %>\r\n\t\t<% } %>\r\n\t\t</ul>\r\n\t</script>\r\n\t\r\n\t<script type=\"text/template\" id=\"template-details-permit\">\r\n\t\t<h2>Permit Details</h2>\r\n\t\t<dl title=\"Permit Details\">\r\n\t\t\t<dt>Permit Number</dt>\r\n\t\t\t<dd><%= data.permit_number %></dd>\r\n\t\t\t<dt>Application Type</dt>\r\n\t\t\t<dd><%= data.application_description %></dd>\r\n\t\t\t<dt>Permit Type</dt>\r\n\t\t\t<dd><%= data.permit_type_name %></dd>\r\n\t\t\t<dt>Status</dt>\r\n\t\t\t<dd><%= data.status %></dd>\r\n\t\t\t<dt>Date Issued</dt>\r\n\t\t\t<dd><%= display_date(data.issued_datetime) %></dd>\r\n\t\t\t<dt>Last Updated</dt>\r\n\t\t\t<dd><%= display_date(data.updated_datetime) %></dd>\r\n\t\t\t<dt>Work Description</dt>\r\n\t\t\t<dd><%= data.work_description %></dd>\r\n\t\t\t<% if(data.pri_contact_company_name || data.pri_contact_first_name || data.pri_contact_last_name || data.pri_contact_address1) { %>\r\n\t\t\t<dt>Contact Information</dt>\r\n\t\t\t<dd>\r\n\t\t\t\t<address>\r\n\t\t\t\t<%= data.pri_contact_company_name ? data.pri_contact_company_name + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_first_name ? data.pri_contact_first_name + \" \" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_last_name ? data.pri_contact_last_name + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_address1 ? data.pri_contact_address1 + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_address2 ? data.pri_contact_address2 + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_city ? data.pri_contact_city + \", \" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_state ? data.pri_contact_state + \" \" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_zip ? data.pri_contact_zip : \"\" %>\r\n\t\t\t\t</address>\r\n\t\t\t</dd>\r\n\t\t\t<dt>Contact Type</dt>\r\n\t\t\t<dd><%= data.pri_contact_type %></dd>\r\n\t\t\t<% } %>\r\n\t\t\t<% if(data.contractor_name || data.contractor_address1) { %>\r\n\t\t\t<dt>Contractor Information</dt>\r\n\t\t\t<dd>\r\n\t\t\t\t<address>\r\n\t\t\t\t<%= data.contractor_name ? data.contractor_name + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.contractor_address1 ? data.contractor_address1 + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.contractor_address2 ? data.contractor_address2 + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.contractor_city ? data.contractor_city + \", \" : \"\" %>\r\n\t\t\t\t<%= data.contractor_state ? data.contractor_state + \" \" : \"\" %>\r\n\t\t\t\t<%= data.contractor_zip ? data.contractor_zip : \"\" %>\r\n\t\t\t\t</address>\r\n\t\t\t</dd>\r\n\t\t\t<% } %>\r\n\t\t</dl>\r\n\t</script>\r\n\t\r\n\t<script type=\"text/template\" id=\"template-details-license\">\r\n\t\t<h2>License Details</h2>\r\n\t\t<dl title=\"License Details\">\r\n\t\t\t<dt>License Number</dt>\r\n\t\t\t<dd><%= data.license_number %></dd>\r\n\t\t\t<dt>License Type</dt>\r\n\t\t\t<dd><%= data.license_type_name %></dd>\r\n\t\t\t<dt>Status</dt>\r\n\t\t\t<dd><%= data.status %></dd>\r\n\t\t\t<dt>Date Issued</dt>\r\n\t\t\t<dd><%= display_date(data.issued_datetime) %></dd>\r\n\t\t\t<dt>Expiration Date</dt>\r\n\t\t\t<dd>Last Day of <%= data.expires_month %><%= data.expires_year %></dd>\r\n\t\t\t<% if(data.pri_contact_company_name || data.pri_contact_first_name || data.pri_contact_last_name || data.pri_contact_address1) { %>\r\n\t\t\t<dt>Contact Information</dt>\r\n\t\t\t<dd>\r\n\t\t\t\t<address>\r\n\t\t\t\t<%= data.pri_contact_company_name ? data.pri_contact_company_name + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_first_name ? data.pri_contact_first_name + \" \" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_last_name ? data.pri_contact_last_name + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_address1 ? data.pri_contact_address1 + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_address2 ? data.pri_contact_address2 + \"<br>\" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_city ? data.pri_contact_city + \", \" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_state ? data.pri_contact_state + \" \" : \"\" %>\r\n\t\t\t\t<%= data.pri_contact_zip ? data.pri_contact_zip : \"\" %>\r\n\t\t\t\t</address>\r\n\t\t\t</dd>\r\n\t\t\t<dt>Contact Type</dt>\r\n\t\t\t<dd><%= data.pri_contact_type %></dd>\r\n\t\t\t<% } %>\r\n\t\t</dl>\r\n\t</script>\r\n\t\r\n\t<script type=\"text/template\" id=\"template-details-case\">\r\n\t\t<h2>Case Details</h2>\r\n\t\t<dl title=\"Case Details\">\r\n\t\t\t<dt>Case Number</dt>\r\n\t\t\t<dd><%= data.case_number %></dd>\r\n\t\t\t<dt>Case Group</dt>\r\n\t\t\t<dd><%= data.case_type %></dd>\r\n\t\t\t<dt>Case Location</dt>\r\n\t\t\t<dd><%= data.case_location %></dd>\r\n\t\t\t<dt>Date Added</dt>\r\n\t\t\t<dd><%= display_date(data.added_datetime) %></dd>\r\n\t\t\t<dt>Date Updated</dt>\r\n\t\t\t<dd><%= display_date(data.updated_datetime) %></dd>\r\n\t\t\t<dt>Status</dt>\r\n\t\t\t<dd><%= data.resolution %></dd>\r\n\t\t\t<dt>Resolution Date</dt>\r\n\t\t\t<dd><%= display_date(data.resolution_datetime) %></dd>\r\n\t\t\t<dt>Priority</dt>\r\n\t\t\t<dd><%= data.priority %></dd>\t\t\t\r\n\t\t</dl>\r\n\t\t\r\n\t\t<% if( ! _.isEmpty(data.violationdetails)) { %>\r\n\t\t\t<h2>Violations</h2>\r\n\t\t\t<div data-role=\"collapsible-set\">\r\n\t\t\t<% _.each(data.violationdetails, function(violation) { %>\r\n\t\t\t\t<div data-role=\"collapsible\">\r\n\t\t\t\t\t<h3><%= violation.violation_code %></h3>\r\n\t\t\t\t\t<dl>\r\n\t\t\t\t\t\t<dt>Code</dt>\r\n\t\t\t\t\t\t<dd><%= violation.violation_code %></dd>\r\n\t\t\t\t\t\t<dt>Type</dt>\r\n\t\t\t\t\t\t<dd><%= violation.violation_code_description %></dd>\r\n\t\t\t\t\t\t<dt>Date</dt>\r\n\t\t\t\t\t\t<dd><%= display_date(violation.violation_datetime) %></dd>\r\n\t\t\t\t\t\t<dt>Status</dt>\r\n\t\t\t\t\t\t<dd><%= violation.violation_status %></dd>\r\n\t\t\t\t\t\t<dt>Location</dt>\r\n\t\t\t\t\t\t<dd><%= violation.violation_location %></dd>\r\n\t\t\t\t\t</dl>\r\n\t\t\t\t</div>\r\n\t\t\t<% }); %>\r\n\t\t\t</div>\r\n\t\t<% } %>\r\n\t</script>\r\n\t\r\n\t<script type=\"text/template\" id=\"template-details-appeal\">\r\n\t\t<h2>Appeal Details</h2>\r\n\t\t<dl title=\"Appeal Details\">\r\n\t\t\t<dt>Appeal Number</dt>\r\n\t\t\t<dd><%= data.appeal_number %></dd>\r\n\t\t\t<dt>Grounds</dt>\r\n\t\t\t<dd><%= data.grounds %></dd>\r\n\t\t\t<dt>Primary Applicant</dt>\r\n\t\t\t<dd><%= data.primary_applicant %></dd>\r\n\t\t\t<dt>Capacity</dt>\r\n\t\t\t<dd><%= data.capacity %></dd>\r\n\t\t\t<dt>Permit Number</dt>\r\n\t\t\t<dd><%= data.permit_number %></dd>\t\t\t\r\n\t\t</dl>\r\n\t\t\r\n\t\t<% if( ! _.isEmpty(data.hearingdecisions)) { %>\r\n\t\t\t<h2>Hearing Decisions History</h2>\r\n\t\t\t<div data-role=\"collapsible-set\">\r\n\t\t\t<% _.each(data.hearingdecisions, function(item) { %>\r\n\t\t\t\t<div data-role=\"collapsible\">\r\n\t\t\t\t\t<h3><%= display_date(item.decision_datetime) %></h3>\r\n\t\t\t\t\t<dl>\r\n\t\t\t\t\t\t<dt>Date</dt>\r\n\t\t\t\t\t\t<dd><%= display_date(item.decision_datetime) %></dd>\r\n\t\t\t\t\t\t<dt>Decision</dt>\r\n\t\t\t\t\t\t<dd><%= item.decision %></dd>\r\n\t\t\t\t\t\t<dt>Proviso</dt>\r\n\t\t\t\t\t\t<dd><%= item.proviso %></dd>\r\n\t\t\t\t\t</dl>\r\n\t\t\t\t</div>\r\n\t\t\t<% }); %>\r\n\t\t\t</div>\r\n\t\t\t<br>\r\n\t\t<% } %>\r\n\t\t\r\n\t\t<% if( ! _.isEmpty(data.courtdetails)) { %>\r\n\t\t\t<h2>Court History</h2>\r\n\t\t\t<div data-role=\"collapsible-set\">\r\n\t\t\t<% _.each(data.courtdetails, function(item) { %>\r\n\t\t\t\t<div data-role=\"collapsible\">\r\n\t\t\t\t\t<h3><%= display_date(item.court_action_datetime) %></h3>\r\n\t\t\t\t\t<dl>\r\n\t\t\t\t\t\t<dt>Court Case No</dt>\r\n\t\t\t\t\t\t<dd><%= item.court_case_number %></dd>\r\n\t\t\t\t\t\t<dt>Court Action</dt>\r\n\t\t\t\t\t\t<dd><%= item.court_action %></dd>\r\n\t\t\t\t\t\t<dt>Action Date</dt>\r\n\t\t\t\t\t\t<dd><%= display_date(item.court_action_datetime) %></dd>\r\n\t\t\t\t\t\t<dt>Court Result</dt>\r\n\t\t\t\t\t\t<dd><%= item.court_result %></dd>\r\n\t\t\t\t\t\t<dt>Proviso</dt>\r\n\t\t\t\t\t\t<dd><%= item.court_proviso %></dd>\r\n\t\t\t\t\t</dl>\r\n\t\t\t\t</div>\r\n\t\t\t<% }); %>\r\n\t\t\t</div>\r\n\t\t<% } %>\r\n\t</script>\r\n\t\r\n\t<script type=\"text/template\" id=\"template-details-error\">\r\n\t\t<h2>Error</h2>\r\n\t\t<%= errorMsg %>\r\n\t\t<br>\r\n\t\t<% if(xhr && xhr.status !== undefined && xhr.statusText !== undefined) { %>\r\n\t\t\t(<%= xhr.status %> <%= xhr.statusText %>)\r\n\t\t<% } %>\r\n\t</script>\r\n\t\r\n\t<script type=\"text/javascript\">\r\n\t// Google Analytics\r\n\t$('[data-role=page]').live('pageshow', function (event, ui) {\r\n\t\ttry {\r\n\t\t\t_gaq.push(['_setAccount', 'UA-35850648-1']);\r\n\t\t\thash = location.hash;\r\n\t\t\tif (hash) _gaq.push(['_trackPageview', hash.substr(1)]);\r\n\t\t\telse _gaq.push(['_trackPageview']);\r\n\t\t} catch(err) {\r\n\t\t}\r\n\t});\r\n\t// Muscula JS error logging\r\n\twindow.Muscula = { settings:{logId:\"jRrwCAC-QlhRab\", suppressErrors: false, branding: 'none'}};\r\n\t(function () {\r\n\t\tvar m = document.createElement('script'); m.type = 'text/javascript'; m.async = true;\r\n\t\tm.src = (window.location.protocol == 'https:' ? 'https:' : 'http:') +\r\n\t\t '//musculahq.appspot.com/Muscula.js';\r\n\t\tvar s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(m, s);\r\n\t\twindow.Muscula.run=function(c){eval(c);window.Muscula.run=function(){};};\r\n\t\twindow.Muscula.errors=[];window.onerror=function(){window.Muscula.errors.push(arguments);\r\n\t\treturn window.Muscula.settings.suppressErrors===undefined;}\r\n\t})();\r\n\t</script>\r\n</body>\r\n</html>"]],"start1":0,"start2":0,"length1":0,"length2":11827}]],"length":11827,"saved":false}
View
2  .c9revisions/js/jquery.mobile.router.min.js.c9save
@@ -0,0 +1,2 @@
+{"ts":1354219178507,"silentsave":true,"restoring":false,"patch":[[]],"length":0}
+{"contributors":[],"silentsave":false,"ts":1354219179414,"patch":[[{"diffs":[[1,"/*!\r\n * jQueryMobile-router v0.93\r\n * http://github.com/azicchetti/jquerymobile-router\r\n *\r\n * Copyright 2011 (c) Andrea Zicchetti\r\n * Dual licensed under the MIT or GPL Version 2 licenses.\r\n * http://github.com/azicchetti/jquerymobile-router/blob/master/MIT-LICENSE.txt\r\n * http://github.com/azicchetti/jquerymobile-router/blob/master/GPL-LICENSE.txt\r\n */\r\n(function(a,b){if(typeof define===\"function\"&&define.amd){define([\"jquery\"],b)}else{b(jQuery)}}(this,function(a){a(document).bind(\"mobileinit\",function(){var e=a.extend({fixFirstPageDataUrl:false,firstPageDataUrl:\"index.html\",ajaxApp:false,firstMatchOnly:false},a.mobile.jqmRouter||{});var c=true;function b(h){if(c){console.log(h)}}var f=null,g=null,d=false;a(document).bind(\"pagebeforechange\",function(l,k){var i=(typeof k.toPage===\"string\")?k.toPage:k.toPage.jqmData(\"url\")||\"\";if(k.options.hasOwnProperty(\"_jqmrouter_handled\")){return}k.options._jqmrouter_handled=true;if(k.options.data&&(k.options.type+\"\").toLowerCase()==\"get\"){i+=\"?\"+k.options.data}var h=a.mobile.path.parseUrl(i);f=g;g=h;if(h.hash.indexOf(\"?\")!==-1||(h.hash.length>0&&f!==null&&f.hash.indexOf(h.hash+\"?\")!==-1)){var j=h.hash.replace(/\\?.*$/,\"\");k.options.dataUrl=h.href;if(a.mobile.activePage&&j.replace(/^#/,\"\")==a.mobile.activePage.jqmData(\"url\")){k.options.allowSamePageTransition=true&&!d;a.mobile.changePage(a(j),k.options)}else{a.mobile.changePage(a(j),k.options)}l.preventDefault();a.mobile.urlHistory.ignoreNextHashChange=true}d=false;if(window.location.hash.indexOf(\"&ui-state=dialog\")!=-1){d=true}});if(e.fixFirstPageDataUrl){a(document).ready(function(){if(!window.location.pathname.match(\"/$\")){return}var i=a(\":jqmData(role='page')\").first();var j=i.jqmData(\"url\"),h=window.location.pathname+e.firstPageDataUrl+window.location.search+window.location.hash;if(j!=h){i.attr(\"data-url\",h).jqmData(\"url\",h)}})}a.mobile.Router=function(l,j,k){this.routes={pagebeforecreate:null,pagecreate:null,pagebeforeshow:null,pageshow:null,pagebeforehide:null,pagehide:null,pageinit:null,pageremove:null,pagebeforechange:null,pagebeforeload:null,pageload:null,popupbeforeposition:null,popupafteropen:null,popupafterclose:null};this.evtLookup={bC:\"pagebeforechange\",bl:\"pagebeforeload\",l:\"pageload\",bc:\"pagebeforecreate\",c:\"pagecreate\",bs:\"pagebeforeshow\",s:\"pageshow\",bh:\"pagebeforehide\",h:\"pagehide\",i:\"pageinit\",rm:\"pageremove\",pbp:\"popupbeforeposition\",pao:\"popupafteropen\",pac:\"popupafterclose\"};this.routesRex={};this.conf=a.extend({},e,k||{});this.defaultHandlerEvents={};if(this.conf.defaultHandlerEvents){var h=this.conf.defaultHandlerEvents.split(\",\");for(var m=0;m<h.length;m++){this.defaultHandlerEvents[this.evtLookup[h[m]]]=h[m]}}this.add(l,j)};a.extend(a.mobile.Router.prototype,{documentEvts:{pagebeforechange:1,pagebeforeload:1,pageload:1},add:function(k,j,m){if(!k){return}var h=this,i=[],n=[];if(k instanceof Array){a.each(k,a.proxy(function(p,o){this.add(o,j,true)},this))}else{a.each(k,function(t,q){if(typeof(q)==\"string\"||typeof(q)==\"function\"){if(h.routes.pagebeforeshow===null){h.routes.pagebeforeshow={}}h.routes.pagebeforeshow[t]=q;if(!h.routesRex.hasOwnProperty(t)){h.routesRex[t]=new RegExp(t)}}else{var p,s=q.events.split(\",\"),o;for(p=0;p<s.length;p++){o=h.evtLookup[s[p]];if(h.routes.hasOwnProperty(o)){if(h.routes[o]===null){h.routes[o]={}}h.routes[o][t]=q.handler;if(!h.routesRex.hasOwnProperty(t)){h.routesRex[t]=new RegExp(t)}}else{b(\"can't set unsupported route \"+s[p])}}}})}if(m===true){return}if(!this.userHandlers){this.userHandlers=j||{}}else{a.extend(this.userHandlers,j||{})}a.each(h.routes,function(o,p){if(p!==null){if(!h.documentEvts[o]){i.push(o)}else{n.push(o)}}});this._detachEvents();var l=function(p,o){h._processRoutes(p,o,this)};if(i.length>0){this._eventData={events:i.join(\" \"),selectors:\":jqmData(role='page'),:jqmData(role='dialog')\",handler:l};a(document).delegate(this._eventData.selectors,this._eventData.events,this._eventData.handler)}if(n.length>0){this._docEventData={events:n.join(\" \"),handler:l};a(document).bind(this._docEventData.events,this._docEventData.handler)}},_processRoutes:function(m,q,n){var o=this,p,i,l,h=0;if(m.type in {pagebeforehide:true,pagehide:true,pageremove:true}){p=f}else{p=g}do{if(!p){if(n){l=a(n);p=l.jqmData(\"url\");if(p){if(l.attr(\"id\")==p){p=\"#\"+p}p=a.mobile.path.parseUrl(p)}}}else{if(!this.documentEvts[m.type]&&n&&!a(n).jqmData(\"url\")){return}}if(!p){return}i=(!this.conf.ajaxApp?p.hash:p.pathname+p.search+p.hash);if(i.length==0){p=\"\"}h++}while(i.length==0&&h<=1);var k=false;a.each(this.routes[m.type],function(r,t){var s,v;if((s=i.match(o.routesRex[r]))){if(typeof(t)==\"function\"){v=t}else{if(typeof(o.userHandlers[t])==\"function\"){v=o.userHandlers[t]}}if(v){try{v.apply(o.userHandlers,[m.type,s,q,n,m]);k=true}catch(u){b(u)}}}if(k&&o.conf.firstMatchOnly){return false}});if(!k&&this.conf.defaultHandler&&this.defaultHandlerEvents[m.type]){if(typeof(this.conf.defaultHandler)==\"function\"){try{this.conf.defaultHandler.apply(o.userHandlers,[m.type,q,n,m])}catch(j){b(j)}}}},_detachEvents:function(){if(this._eventData){a(document).undelegate(this._eventData.selectors,this._eventData.events,this._eventData.handler)}if(this._docEventData){a(document).unbind(this._docEventData.events,this._docEventData.handler)}},destroy:function(){this._detachEvents();this.routes=this.routesRex=null},getParams:function(h){if(!h){return null}var k={},i;var j=h.slice(h.indexOf(\"?\")+1).split(\"&\");a.each(j,function(m,l){i=l.split(\"=\");i[0]=decodeURIComponent(i[0]);if(k[i[0]]){if(!(k[i[0]] instanceof Array)){k[i[0]]=[k[i[0]]]}k[i[0]].push(decodeURIComponent(i[1]))}else{k[i[0]]=decodeURIComponent(i[1])}});if(a.isEmptyObject(k)){return null}return k}})});return{}}));"]],"start1":0,"start2":0,"length1":0,"length2":5678}]],"length":5678,"saved":false}
View
2  .c9revisions/js/phillyapi.js.c9save
@@ -0,0 +1,2 @@
+{"ts":1354219191586,"silentsave":true,"restoring":false,"patch":[[]],"length":0}
+{"contributors":[],"silentsave":false,"ts":1354219193149,"patch":[[{"diffs":[[1,"var phillyapi = phillyapi || {};\r\nphillyapi = {\r\n options: {\r\n\t\tphillyapi: {\r\n\t\t\tbase: \"http://services.phila.gov/PhillyApi/Data/\"\r\n\t\t\t,summary: \"HelperService.svc/GetLocationHistory?$format=json&AddressKey=\"\r\n\t\t\t,permit: \"Service.svc/permits('%id%')?$format=json\"\r\n\t\t\t,license: \"Service.svc/licenses('%id%')?$format=json\"\r\n\t\t\t,_case: \"Service.svc/violationdetails?$filter=case_number%20eq%20'%id%'&$expand=cases&$format=json\"\r\n\t\t\t,zoningboardappeal: \"Service.svc/zoningboardappeals?$filter=appeal_number%20eq%20'%id%'&$format=json\"\r\n\t\t\t,zbahearingdecisions: \"Service.svc/zbahearingdecisions?$filter=appeal_id%20eq%20%id%&$format=json\"\r\n\t\t\t,zbacourtdetails: \"Service.svc/zbacourtdetails?$filter=appeal_id%20eq%20%id%&$format=json\"\r\n\t\t\t,buildingboardappeal: \"Service.svc/buildingboardappeals?$filter=appeal_number%20eq%20'%id%'&$format=json\"\r\n\t\t\t,bbshearingdecisions: \"Service.svc/bbshearingdecisions?$filter=appeal_id%20eq%20%id%&$format=json\"\r\n\t\t\t,bbscourtdetails: \"Service.svc/bbscourtdetails?$filter=appeal_id%20eq%20%id%&$format=json\"\r\n\t\t\t,lireviewboardappeal: \"Service.svc/lireviewboardappeals?$filter=appeal_number%20eq%20'%id%'&$format=json\"\r\n\t\t\t,lirbhearingdecisions: \"Service.svc/lirbhearingdecisions?$filter=appeal_id%20eq%20%id%&$format=json\"\r\n\t\t\t,lirbcourtdetails: \"Service.svc/lirbcourtdetails?$filter=appeal_id%20eq%20%id%&$format=json\"\r\n\t\t\t,timeout: 20000\r\n\t\t}\r\n\t\t,ulrs311: {\r\n\t\t\tbase: \"http://services.phila.gov/ULRS311/Data/\"\r\n\t\t\t,addressKey: \"LIAddressKey/\"\r\n\t\t\t,timeout: 20000\r\n\t\t}\r\n\t}\r\n\r\n\t,getAddressKey: function(input, successCallback, errorCallback) {\r\n\t\tvar url = phillyapi.options.ulrs311.base + phillyapi.options.ulrs311.addressKey + encodeURIComponent(input);\r\n\t\t$.ajax({\r\n\t\t\turl: url\r\n\t\t\t,dataType: \"jsonp\"\r\n\t\t\t,contentType: \"application/json; charset=utf-8\"\r\n\t\t\t,async: false\r\n\t\t\t,cache: true\r\n\t\t\t,crossDomain: true\r\n\t\t\t,timeout: phillyapi.options.ulrs311.timeout\r\n\t\t\t,type: \"GET\"\r\n\t\t\t,xhrFields: { withCredentials: false }\r\n\t\t\t,error: errorCallback\r\n\t\t\t,success: function(data) {\r\n\t\t\t\tif(\"TopicID\" in data) {\r\n\t\t\t\t\tvar addressKey = data.TopicID;\r\n \t\t\t\t// Clean up the address. Default format is something like \" 01234 MARKET ST\" - needs to be \"1234 MARKET ST\" - Anyone have a better regex for it?\r\n\t\t\t\t\tvar address = data.AddressRef ? $.trim(data.AddressRef.replace(/ +(?= )/g,\"\")).replace(/^0+/, \"\") : null;\r\n\t\t\t\t\tsuccessCallback(addressKey, address);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t,getSummary: function(addressKey, successCallback, errorCallback, sorted) {\r\n\t\tvar url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi.summary + addressKey;\r\n\t\tphillyapi.fetch(url, function(data) {\r\n\t\t\tsuccessCallback(sorted ? phillyapi.sortSummary(data) : data);\r\n\t\t}, errorCallback);\r\n\t}\r\n\t\r\n\t,getPermit: function(id, successCallback, errorCallback) {\r\n\t\tvar url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi.permit.replace(\"%id%\", id);\r\n\t\tphillyapi.fetch(url, successCallback, errorCallback);\r\n\t}\r\n\t\r\n\t,getLicense: function(id, successCallback, errorCallback) {\r\n\t\tvar url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi.license.replace(\"%id%\", id);\r\n\t\tphillyapi.fetch(url, successCallback, errorCallback);\r\n\t}\r\n\t\r\n\t,getCase: function(id, successCallback, errorCallback, sorted) {\r\n\t\tvar url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi._case.replace(\"%id%\", id);\r\n\t\tphillyapi.fetch(url, function(data) {\r\n\t\t\tsuccessCallback(sorted ? phillyapi.sortCase(data) : data);\r\n\t\t}, errorCallback);\r\n\t}\r\n\t\r\n\t/*\r\n\t\tDue to a known issue in the API, we have to do 3 calls here instead of 1. Also, since the Summary gives us the appeal\r\n\t\tnumber rather than appeal id, we have to wait for the first call to finish in order to get the appeal id for the second two\r\n\t*/\r\n\t,getAppeal: function(type, id, successCallback, errorCallback) {\r\n\t\tvar sortedData = {}, urlKeys = [];\r\n\t\tswitch(type) {\r\n\t\t\tcase \"zoningboardappeals\":\r\n\t\t\t\turlKeys = [\"zoningboardappeal\", \"zbahearingdecisions\", \"zbacourtdetails\"];\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"buildingboardappeals\":\r\n\t\t\t\turlKeys = [\"buildingboardappeal\", \"bbshearingdecisions\", \"bbscourtdetails\"];\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"lireviewboardappeals\":\r\n\t\t\t\turlKeys = [\"lireviewboardappeal\", \"lirbhearingdecisions\", \"lirbcourtdetails\"];\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\t// Appeal Details\r\n\t\tvar url1 = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi[urlKeys[0]].replace(\"%id%\", id);\r\n\t\tphillyapi.fetch(url1, function(data) {\r\n\t\t\tsortedData.d = data.d.results[0];\r\n\t\t\tvar requestsPending = 0;\r\n\t\t\t\r\n\t\t\t// Hearing Decisions\r\n\t\t\trequestsPending++;\r\n\t\t\tvar url2 = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi[urlKeys[1]].replace(\"%id%\", data.d.results[0].appeal_id);\r\n\t\t\tphillyapi.fetch(url2, function(data) {\r\n\t\t\t\tsortedData.d.hearingdecisions = data.d.results;\r\n\t\t\t\trequestsPending--;\r\n\t\t\t\tif(requestsPending < 1) successCallback(sortedData);\r\n\t\t\t}, errorCallback);\r\n\t\t\t// Court History\r\n\t\t\trequestsPending++;\r\n\t\t\tvar url3 = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi[urlKeys[2]].replace(\"%id%\", data.d.results[0].appeal_id);\r\n\t\t\tphillyapi.fetch(url3, function(data) {\r\n\t\t\t\tsortedData.d.courtdetails = data.d.results;\r\n\t\t\t\trequestsPending--;\r\n\t\t\t\tif(requestsPending < 1) successCallback(sortedData);\r\n\t\t\t}, errorCallback);\r\n\t\t}, errorCallback);\r\n\t}\r\n\r\n\t,fetch: function(url, successCallback, errorCallback) {\r\n\t\t$.ajax({\r\n\t\t\turl: url\r\n\t\t\t,dataType: \"jsonp\"\r\n\t\t\t,cache: true\r\n\t\t\t,timeout: phillyapi.options.phillyapi.timeout\r\n\t\t\t,jsonp: \"$callback\"\r\n\t\t\t,success: successCallback\r\n\t\t\t,error: errorCallback\r\n\t\t});\r\n\t}\r\n\t\r\n\t// Sort summary data into categories\r\n\t,sortSummary: function(data) {\r\n\t\tvar sortedData = {};\r\n\t\tfor(var i = 0; i < data.length; i++) {\r\n\t\t\tswitch(data[i].category) {\r\n\t\t\t\tcase \"Violation\":\r\n\t\t\t\t\tif(sortedData.cases === undefined) {\r\n\t\t\t\t\t\tsortedData.cases = {};\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif(sortedData.cases[data[i].id] === undefined) {\r\n\t\t\t\t\t\tsortedData.cases[data[i].id] = {\r\n\t\t\t\t\t\t\t\"case_number\": data[i].id\r\n\t\t\t\t\t\t\t,\"violations\": []\r\n\t\t\t\t\t\t\t,\"entity\": data[i].entity\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tsortedData.cases[data[i].id].violations.push(data[i].type);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"Permit\":\r\n\t\t\t\t\tif(sortedData.permits === undefined) {\r\n\t\t\t\t\t\tsortedData.permits = [];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tsortedData.permits.push({\r\n\t\t\t\t\t\t\"permit_number\": data[i].id\r\n\t\t\t\t\t\t,\"permit_type_name\": data[i].type\r\n\t\t\t\t\t\t,\"entity\": data[i].entity\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"Business\":\r\n\t\t\t\t\tif(sortedData.licenses === undefined) {\r\n\t\t\t\t\t\tsortedData.licenses = [];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tsortedData.licenses.push({\r\n\t\t\t\t\t\t\"license_number\": data[i].id\r\n\t\t\t\t\t\t,\"license_type_name\": data[i].type\r\n\t\t\t\t\t\t,\"entity\": data[i].entity\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"Appeal\":\r\n\t\t\t\t\tif(sortedData.appeals === undefined) {\r\n\t\t\t\t\t\tsortedData.appeals = [];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tsortedData.appeals.push({\r\n\t\t\t\t\t\t\"appeal_number\": data[i].id\r\n\t\t\t\t\t\t,\"appeal_type_name\": data[i].type\r\n\t\t\t\t\t\t,\"entity\": data[i].entity\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tif(sortedData.other === undefined) {\r\n\t\t\t\t\t\tsortedData.other = [];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tsortedData.other.push({\r\n\t\t\t\t\t\t\"number\": data[i].id\r\n\t\t\t\t\t\t,\"type_name\": data[i].type\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif(sortedData.cases !== undefined) sortedData.cases = phillyapi.objToArray(sortedData.cases);\r\n\t\treturn sortedData;\r\n\t}\r\n\t\r\n\t/*\r\n\t\tThis is a work-around for a known issue in the API. Ideally we'd do a call to the case and expand the violationdetails,\r\n\t\tbut since that gives an error, we do a call to the violation details of the case and expand the case.\r\n\t\tThat gives the case details multiple times, but at least it's only one ajax call. This function shuffles the data\r\n\t\taround to be the case with a violationdetails array.\r\n\t*/\r\n\t,sortCase: function(data) {\r\n\t\tvar sortedData = {};\r\n\t\tsortedData.d = data.d.results[0].cases;\r\n\t\tfor(var i = 0; i < data.d.results.length; i++) {\r\n\t\t\tif(data.d.results[i].cases !== undefined) delete data.d.results[i].cases;\r\n\t\t}\r\n\t\tsortedData.d.violationdetails = data.d.results;\r\n\t\treturn sortedData;\r\n\t}\r\n\t\r\n\t// Stock function\r\n\t,objToArray: function(obj) {\r\n\t\tvar arr = []\r\n\t\tfor(var key in obj) {\r\n\t\t\tarr.push(obj[key]);\r\n\t\t}\r\n\t\treturn arr;\r\n\t}\r\n};"]],"start1":0,"start2":0,"length1":0,"length2":8149}]],"length":8149,"saved":false}
View
2  .c9revisions/js/script.js.c9save
@@ -0,0 +1,2 @@
+{"ts":1354219214887,"silentsave":true,"restoring":false,"patch":[[]],"length":0}
+{"contributors":[],"silentsave":false,"ts":1354219215426,"patch":[[{"diffs":[[1,"var DEBUG = false;\r\nvar cache = {summary: null, details: null};\r\n\r\nvar controller = {\r\n search: function() {\r\n\t\t$(\"#search form input\").eq(0).focus();\r\n\t}\r\n\t,summary: function(eventType, matchObj, ui, page, evt) {\r\n\t\tvar input = decodeURIComponent(matchObj[1].replace(/\\+/g, \"%20\")).replace(/^\\s+|\\s+$/g, \"\");\r\n\t\tif(cache.summary != matchObj[0]) {\r\n\t\t\t$(\"[data-role=\\\"content\\\"]\", page).empty();\r\n\t\t\tsetLoading(true);\r\n\t\t\tphillyapi.getAddressKey(input, function(addressKey, address) {\r\n\t\t\t\tif(addressKey) {\r\n\t\t\t\t\tphillyapi.getSummary(addressKey, function(data) {\r\n\t\t\t\t\t\tif(DEBUG) console.log(data);\r\n\t\t\t\t\t\tif(_.isEmpty(data)) {\r\n\t\t\t\t\t\t\tcontroller.error(\"No history found for this address\", page);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t$(\"[data-role=\\\"content\\\"]\", page).html(_.template($(\"#template-summary\").html(), {address: address, data: data}));\r\n\t\t\t\t\t\t\t$(\"[data-role=\\\"listview\\\"]\", page).listview();\r\n\t\t\t\t\t\t\tcache.summary = matchObj[0];\r\n\t\t\t\t\t\t\tsetLoading(false);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, function(xhr, status, error) {\r\n\t\t\t\t\t\tcontroller.error(\"There was an issue fetching the summary data from the server\", page, xhr);\r\n\t\t\t\t\t}, true);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tcontroller.error(\"The address entered is not a valid L&I address\", page);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\t,permit: function(eventType, matchObj, ui, page, evt) {\r\n\t\tif(cache.details != matchObj[0]) {\r\n\t\t\t$(\"[data-role=\\\"content\\\"]\", page).empty();\r\n\t\t\tsetLoading(true);\r\n\t\t\tphillyapi.getPermit(matchObj[1], function(data) {\r\n\t\t\t\tif(DEBUG) console.log(data);\r\n\t\t\t\t$(\"[data-role=\\\"content\\\"]\", page).html(_.template($(\"#template-details-permit\").html(), {data: data.d}));\r\n\t\t\t\tcache.details = matchObj[0];\r\n\t\t\t\tsetLoading(false);\r\n\t\t\t}, function(xhr, status, error) {\r\n\t\t\t\tcontroller.error(\"There was an issue fetching the permit data from the server\", page, xhr);\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\t,license: function(eventType, matchObj, ui, page, evt) {\r\n\t\tif(cache.details != matchObj[0]) {\r\n\t\t\t$(\"[data-role=\\\"content\\\"]\", page).empty();\r\n\t\t\tsetLoading(true);\r\n\t\t\tphillyapi.getLicense(matchObj[1], function(data) {\r\n\t\t\t\tif(DEBUG) console.log(data);\r\n\t\t\t\t$(\"[data-role=\\\"content\\\"]\", page).html(_.template($(\"#template-details-license\").html(), {data: data.d}));\r\n\t\t\t\tcache.details = matchObj[0];\r\n\t\t\t\tsetLoading(false);\r\n\t\t\t}, function(xhr, status, error) {\r\n\t\t\t\tcontroller.error(\"There was an issue fetching the license data from the server\", page, xhr);\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\t,_case: function(eventType, matchObj, ui, page, evt) {\r\n\t\tif(cache.details != matchObj[0]) {\r\n\t\t\t$(\"[data-role=\\\"content\\\"]\", page).empty();\r\n\t\t\tsetLoading(true);\r\n\t\t\tphillyapi.getCase(matchObj[1], function(data) {\r\n\t\t\t\tif(DEBUG) console.log(data);\r\n\t\t\t\t$(\"[data-role=\\\"content\\\"]\", page).html(_.template($(\"#template-details-case\").html(), {data: data.d}));\r\n\t\t\t\t$(\"[data-role=\\\"collapsible-set\\\"]\", page).collapsibleset();\r\n\t\t\t\tcache.details = matchObj[0];\r\n\t\t\t\tsetLoading(false);\r\n\t\t\t}, function(xhr, status, error) {\r\n\t\t\t\tcontroller.error(\"There was an issue fetching the case data from the server\", page, xhr);\r\n\t\t\t}, true);\r\n\t\t}\r\n\t}\r\n\t,appeal: function(eventType, matchObj, ui, page, evt) {\r\n\t\tif(cache.details != matchObj[0]) {\r\n\t\t\t$(\"[data-role=\\\"content\\\"]\", page).empty();\r\n\t\t\tsetLoading(true);\r\n\t\t\tphillyapi.getAppeal(matchObj[1] + \"appeals\", matchObj[2], function(data) {\r\n\t\t\t\tif(DEBUG) console.log(data);\r\n\t\t\t\t$(\"[data-role=\\\"content\\\"]\", page).html(_.template($(\"#template-details-appeal\").html(), {data: data.d}));\r\n\t\t\t\t$(\"[data-role=\\\"collapsible-set\\\"]\", page).collapsibleset();\r\n\t\t\t\tcache.details = matchObj[0];\r\n\t\t\t\tsetLoading(false);\r\n\t\t\t}, function(xhr, status, error) {\r\n\t\t\t\tcontroller.error(\"There was an issue fetching the appeal data from the server\", page, xhr);\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\t,error: function(errorMsg, page, xhr) {\r\n\t\t$(\"[data-role=\\\"content\\\"]\", page).html(_.template($(\"#template-details-error\").html(), {errorMsg: errorMsg, xhr: xhr}));\r\n\t\tsetLoading(false);\r\n\t}\r\n};\r\nnew $.mobile.Router({\r\n\t\"#search\": { handler: \"search\", events: \"s\" }\r\n\t,\"#summary\\\\?address=(.*)\": { handler: \"summary\", events: \"bs\" }\r\n\t,\"#details\\\\?entity=permits&eid=(\\\\d*)\": { handler: \"permit\", events: \"bs\" }\r\n\t,\"#details\\\\?entity=licenses&eid=(\\\\d*)\": { handler: \"license\", events: \"bs\" }\r\n\t,\"#details\\\\?entity=violationdetails&eid=(\\\\d*)\": { handler: \"_case\", events: \"bs\" }\r\n\t,\"#details\\\\?entity=(.*)appeals&eid=(\\\\d*)\": { handler: \"appeal\", events: \"bs\" }\r\n}, controller);\r\n\r\n$(document).ready(function() {\r\n // Ensure user has input an address before pressing search\r\n\t$(\"#search form\").submit(function(e) {\r\n\t\tvar inputNode = $(\"input[name=\\\"address\\\"]\", $(this));\r\n\t\tif( ! $.trim(inputNode.val())) {\r\n\t\t\tinputNode.focus();\r\n\t\t\treturn false;\r\n\t\t}\r\n\t});\r\n});\r\n\r\n// Necessary because v1.1.0 of jQuery Mobile doesn't seem to let you show the loading message during pagebeforeshow\r\nfunction setLoading(on) {\r\n\tif(on) $(\"body\").addClass(\"ui-loading\");\r\n\telse $(\"body\").removeClass(\"ui-loading\");\r\n}\r\n\r\nfunction display_date(input, show_time){\r\n\tvar str;\r\n\tif(input) {\r\n\t\tvar UNIX_timestamp = input.replace(/\\D/g, \"\") / 1000;\r\n\t\tvar a = new Date(UNIX_timestamp*1000);\r\n\t\tvar months = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];\r\n\t\tvar year = a.getFullYear();\r\n\t\tvar month = a.getMonth()+1;\r\n\t\tvar date = a.getDate();\r\n\t\tstr = month+\"/\"+date+\"/\"+year;\r\n\t\tif(show_time) {\r\n\t\t\tvar hour = a.getHours();\r\n\t\t\tvar min = (\"0\" + a.getMinutes()).slice(-2);\r\n\t\t\tvar sec = (\"0\" + a.getSeconds()).slice(-2);\r\n\t\t\tstr += hour+\":\"+min+\":\"+sec;\r\n\t\t}\r\n\t}\r\n\treturn str;\r\n}"]],"start1":0,"start2":0,"length1":0,"length2":5499}]],"length":5499,"saved":false}
View
28 css/styles.css
@@ -0,0 +1,28 @@
+[data-role="content"] h1,
+[data-role="content"] h2,
+[data-role="content"] h3,
+[data-role="content"] h4 {
+ margin-top: 0;
+}
+
+dt {
+ font-weight: bold;
+ background-color: #e6e6e6;
+}
+
+dd {
+ min-height: 15px;
+ margin-left: 20px;
+}
+
+address {
+ font-style: normal;
+}
+
+[data-role="footer"] {
+ padding: 5px;
+}
+
+.ui-collapsible-content {
+ padding: 0px 5px;
+}
View
307 index.html
@@ -0,0 +1,307 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>L&I Property History</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="//code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
+ <link rel="stylesheet" href="css/styles.css" />
+
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
+ <script src="js/jquery.mobile.router.min.js"></script>
+ <script src="//code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
+ <script src="js/phillyapi.js"></script>
+ <script src="js/script.js"></script>
+ <script type="text/javascript">
+ var _gaq = _gaq || [];
+ //_gaq.push(['_setAccount', 'UA-35850648-1']);
+ //_gaq.push(['_trackPageview']);
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script>
+</head>
+<body>
+
+ <div data-role="page" id="search">
+ <div data-role="content">
+ <h2>L&I Property History</h2>
+ <form action="#summary">
+ <label for="address" class="ui-hidden-accessible">Address</label>
+ <input type="text" name="address" placeholder="Address">
+ <button type="submit" data-theme="b">Search</button>
+ </form>
+ </div>
+ </div>
+
+ <div data-role="page" id="summary">
+ <div data-role="content"></div>
+ <div data-role="footer" data-theme="b" data-position="fixed" data-id="main-footer">
+ <a href="#" data-icon="arrow-l" data-rel="back" data-inline="true">Search</a>
+ </div>
+ </div>
+
+ <div data-role="page" id="details">
+ <div data-role="content"></div>
+ <div data-role="footer" data-theme="b" data-position="fixed" data-id="main-footer">
+ <a href="#" data-icon="arrow-l" data-rel="back" data-inline="true">Search Results</a>
+ </div>
+ </div>
+
+ <script type="text/template" id="template-summary">
+ <h2><%= address %></h2>
+ <ul data-role="listview">
+ <% if(data.permits !== undefined) { %>
+ <li data-role="list-divider">Permits <span class="ui-li-count"><%= data.permits.length %></span></li>
+ <% _.each(data.permits, function(permit) { %>
+ <li><a href="#details?entity=<%= permit.entity %>&eid=<%= permit.permit_number%>"><%= permit.permit_number %>: <%= permit.permit_type_name %></a></li>
+ <% }); %>
+ <% } %>
+
+ <% if(data.licenses !== undefined) { %>
+ <li data-role="list-divider">Licenses <span class="ui-li-count"><%= data.licenses.length %></span></li>
+ <% _.each(data.licenses, function(license) { %>
+ <li><a href="#details?entity=<%= license.entity %>&eid=<%= license.license_number%>"><%= license.license_number %>: <%= license.license_type_name %></a></li>
+ <% }); %>
+ <% } %>
+
+ <% if(data.cases !== undefined) { %>
+ <li data-role="list-divider">Violations <span class="ui-li-count"><%= data.cases.length %></span></li>
+ <% _.each(data.cases, function(_case) { %>
+ <li><a href="#details?entity=<%= _case.entity %>&eid=<%= _case.case_number%>"><%= _case.case_number %>: <%= _case.violations.length %> Violations</a></li>
+ <% }); %>
+ <% } %>
+
+ <% if(data.appeals !== undefined) { %>
+ <li data-role="list-divider">Appeals <span class="ui-li-count"><%= data.appeals.length %></span></li>
+ <% _.each(data.appeals, function(appeal) { %>
+ <li><a href="#details?entity=<%= appeal.entity %>&eid=<%= appeal.appeal_number%>"><%= appeal.appeal_number %>: <%= appeal.appeal_type_name %></a></li>
+ <% }); %>
+ <% } %>
+ </ul>
+ </script>
+
+ <script type="text/template" id="template-details-permit">
+ <h2>Permit Details</h2>
+ <dl title="Permit Details">
+ <dt>Permit Number</dt>
+ <dd><%= data.permit_number %></dd>
+ <dt>Application Type</dt>
+ <dd><%= data.application_description %></dd>
+ <dt>Permit Type</dt>
+ <dd><%= data.permit_type_name %></dd>
+ <dt>Status</dt>
+ <dd><%= data.status %></dd>
+ <dt>Date Issued</dt>
+ <dd><%= display_date(data.issued_datetime) %></dd>
+ <dt>Last Updated</dt>
+ <dd><%= display_date(data.updated_datetime) %></dd>
+ <dt>Work Description</dt>
+ <dd><%= data.work_description %></dd>
+ <% if(data.pri_contact_company_name || data.pri_contact_first_name || data.pri_contact_last_name || data.pri_contact_address1) { %>
+ <dt>Contact Information</dt>
+ <dd>
+ <address>
+ <%= data.pri_contact_company_name ? data.pri_contact_company_name + "<br>" : "" %>
+ <%= data.pri_contact_first_name ? data.pri_contact_first_name + " " : "" %>
+ <%= data.pri_contact_last_name ? data.pri_contact_last_name + "<br>" : "" %>
+ <%= data.pri_contact_address1 ? data.pri_contact_address1 + "<br>" : "" %>
+ <%= data.pri_contact_address2 ? data.pri_contact_address2 + "<br>" : "" %>
+ <%= data.pri_contact_city ? data.pri_contact_city + ", " : "" %>
+ <%= data.pri_contact_state ? data.pri_contact_state + " " : "" %>
+ <%= data.pri_contact_zip ? data.pri_contact_zip : "" %>
+ </address>
+ </dd>
+ <dt>Contact Type</dt>
+ <dd><%= data.pri_contact_type %></dd>
+ <% } %>
+ <% if(data.contractor_name || data.contractor_address1) { %>
+ <dt>Contractor Information</dt>
+ <dd>
+ <address>
+ <%= data.contractor_name ? data.contractor_name + "<br>" : "" %>
+ <%= data.contractor_address1 ? data.contractor_address1 + "<br>" : "" %>
+ <%= data.contractor_address2 ? data.contractor_address2 + "<br>" : "" %>
+ <%= data.contractor_city ? data.contractor_city + ", " : "" %>
+ <%= data.contractor_state ? data.contractor_state + " " : "" %>
+ <%= data.contractor_zip ? data.contractor_zip : "" %>
+ </address>
+ </dd>
+ <% } %>
+ </dl>
+ </script>
+
+ <script type="text/template" id="template-details-license">
+ <h2>License Details</h2>
+ <dl title="License Details">
+ <dt>License Number</dt>
+ <dd><%= data.license_number %></dd>
+ <dt>License Type</dt>
+ <dd><%= data.license_type_name %></dd>
+ <dt>Status</dt>
+ <dd><%= data.status %></dd>
+ <dt>Date Issued</dt>
+ <dd><%= display_date(data.issued_datetime) %></dd>
+ <dt>Expiration Date</dt>
+ <dd>Last Day of <%= data.expires_month %><%= data.expires_year %></dd>
+ <% if(data.pri_contact_company_name || data.pri_contact_first_name || data.pri_contact_last_name || data.pri_contact_address1) { %>
+ <dt>Contact Information</dt>
+ <dd>
+ <address>
+ <%= data.pri_contact_company_name ? data.pri_contact_company_name + "<br>" : "" %>
+ <%= data.pri_contact_first_name ? data.pri_contact_first_name + " " : "" %>
+ <%= data.pri_contact_last_name ? data.pri_contact_last_name + "<br>" : "" %>
+ <%= data.pri_contact_address1 ? data.pri_contact_address1 + "<br>" : "" %>
+ <%= data.pri_contact_address2 ? data.pri_contact_address2 + "<br>" : "" %>
+ <%= data.pri_contact_city ? data.pri_contact_city + ", " : "" %>
+ <%= data.pri_contact_state ? data.pri_contact_state + " " : "" %>
+ <%= data.pri_contact_zip ? data.pri_contact_zip : "" %>
+ </address>
+ </dd>
+ <dt>Contact Type</dt>
+ <dd><%= data.pri_contact_type %></dd>
+ <% } %>
+ </dl>
+ </script>
+
+ <script type="text/template" id="template-details-case">
+ <h2>Case Details</h2>
+ <dl title="Case Details">
+ <dt>Case Number</dt>
+ <dd><%= data.case_number %></dd>
+ <dt>Case Group</dt>
+ <dd><%= data.case_type %></dd>
+ <dt>Case Location</dt>
+ <dd><%= data.case_location %></dd>
+ <dt>Date Added</dt>
+ <dd><%= display_date(data.added_datetime) %></dd>
+ <dt>Date Updated</dt>
+ <dd><%= display_date(data.updated_datetime) %></dd>
+ <dt>Status</dt>
+ <dd><%= data.resolution %></dd>
+ <dt>Resolution Date</dt>
+ <dd><%= display_date(data.resolution_datetime) %></dd>
+ <dt>Priority</dt>
+ <dd><%= data.priority %></dd>
+ </dl>
+
+ <% if( ! _.isEmpty(data.violationdetails)) { %>
+ <h2>Violations</h2>
+ <div data-role="collapsible-set">
+ <% _.each(data.violationdetails, function(violation) { %>
+ <div data-role="collapsible">
+ <h3><%= violation.violation_code %></h3>
+ <dl>
+ <dt>Code</dt>
+ <dd><%= violation.violation_code %></dd>
+ <dt>Type</dt>
+ <dd><%= violation.violation_code_description %></dd>
+ <dt>Date</dt>
+ <dd><%= display_date(violation.violation_datetime) %></dd>
+ <dt>Status</dt>
+ <dd><%= violation.violation_status %></dd>
+ <dt>Location</dt>
+ <dd><%= violation.violation_location %></dd>
+ </dl>
+ </div>
+ <% }); %>
+ </div>
+ <% } %>
+ </script>
+
+ <script type="text/template" id="template-details-appeal">
+ <h2>Appeal Details</h2>
+ <dl title="Appeal Details">
+ <dt>Appeal Number</dt>
+ <dd><%= data.appeal_number %></dd>
+ <dt>Grounds</dt>
+ <dd><%= data.grounds %></dd>
+ <dt>Primary Applicant</dt>
+ <dd><%= data.primary_applicant %></dd>
+ <dt>Capacity</dt>
+ <dd><%= data.capacity %></dd>
+ <dt>Permit Number</dt>
+ <dd><%= data.permit_number %></dd>
+ </dl>
+
+ <% if( ! _.isEmpty(data.hearingdecisions)) { %>
+ <h2>Hearing Decisions History</h2>
+ <div data-role="collapsible-set">
+ <% _.each(data.hearingdecisions, function(item) { %>
+ <div data-role="collapsible">
+ <h3><%= display_date(item.decision_datetime) %></h3>
+ <dl>
+ <dt>Date</dt>
+ <dd><%= display_date(item.decision_datetime) %></dd>
+ <dt>Decision</dt>
+ <dd><%= item.decision %></dd>
+ <dt>Proviso</dt>
+ <dd><%= item.proviso %></dd>
+ </dl>
+ </div>
+ <% }); %>
+ </div>
+ <br>
+ <% } %>
+
+ <% if( ! _.isEmpty(data.courtdetails)) { %>
+ <h2>Court History</h2>
+ <div data-role="collapsible-set">
+ <% _.each(data.courtdetails, function(item) { %>
+ <div data-role="collapsible">
+ <h3><%= display_date(item.court_action_datetime) %></h3>
+ <dl>
+ <dt>Court Case No</dt>
+ <dd><%= item.court_case_number %></dd>
+ <dt>Court Action</dt>
+ <dd><%= item.court_action %></dd>
+ <dt>Action Date</dt>
+ <dd><%= display_date(item.court_action_datetime) %></dd>
+ <dt>Court Result</dt>
+ <dd><%= item.court_result %></dd>
+ <dt>Proviso</dt>
+ <dd><%= item.court_proviso %></dd>
+ </dl>
+ </div>
+ <% }); %>
+ </div>
+ <% } %>
+ </script>
+
+ <script type="text/template" id="template-details-error">
+ <h2>Error</h2>
+ <%= errorMsg %>
+ <br>
+ <% if(xhr && xhr.status !== undefined && xhr.statusText !== undefined) { %>
+ (<%= xhr.status %> <%= xhr.statusText %>)
+ <% } %>
+ </script>
+
+ <script type="text/javascript">
+ // Google Analytics
+ $('[data-role=page]').live('pageshow', function (event, ui) {
+ try {
+ _gaq.push(['_setAccount', 'UA-35850648-1']);
+ hash = location.hash;
+ if (hash) _gaq.push(['_trackPageview', hash.substr(1)]);
+ else _gaq.push(['_trackPageview']);
+ } catch(err) {
+ }
+ });
+ // Muscula JS error logging
+ window.Muscula = { settings:{logId:"jRrwCAC-QlhRab", suppressErrors: false, branding: 'none'}};
+ (function () {
+ var m = document.createElement('script'); m.type = 'text/javascript'; m.async = true;
+ m.src = (window.location.protocol == 'https:' ? 'https:' : 'http:') +
+ '//musculahq.appspot.com/Muscula.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(m, s);
+ window.Muscula.run=function(c){eval(c);window.Muscula.run=function(){};};
+ window.Muscula.errors=[];window.onerror=function(){window.Muscula.errors.push(arguments);
+ return window.Muscula.settings.suppressErrors===undefined;}
+ })();
+ </script>
+</body>
+</html>
View
10 js/jquery.mobile.router.min.js
@@ -0,0 +1,10 @@
+/*!
+ * jQueryMobile-router v0.93
+ * http://github.com/azicchetti/jquerymobile-router
+ *
+ * Copyright 2011 (c) Andrea Zicchetti
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://github.com/azicchetti/jquerymobile-router/blob/master/MIT-LICENSE.txt
+ * http://github.com/azicchetti/jquerymobile-router/blob/master/GPL-LICENSE.txt
+ */
+(function(a,b){if(typeof define==="function"&&define.amd){define(["jquery"],b)}else{b(jQuery)}}(this,function(a){a(document).bind("mobileinit",function(){var e=a.extend({fixFirstPageDataUrl:false,firstPageDataUrl:"index.html",ajaxApp:false,firstMatchOnly:false},a.mobile.jqmRouter||{});var c=true;function b(h){if(c){console.log(h)}}var f=null,g=null,d=false;a(document).bind("pagebeforechange",function(l,k){var i=(typeof k.toPage==="string")?k.toPage:k.toPage.jqmData("url")||"";if(k.options.hasOwnProperty("_jqmrouter_handled")){return}k.options._jqmrouter_handled=true;if(k.options.data&&(k.options.type+"").toLowerCase()=="get"){i+="?"+k.options.data}var h=a.mobile.path.parseUrl(i);f=g;g=h;if(h.hash.indexOf("?")!==-1||(h.hash.length>0&&f!==null&&f.hash.indexOf(h.hash+"?")!==-1)){var j=h.hash.replace(/\?.*$/,"");k.options.dataUrl=h.href;if(a.mobile.activePage&&j.replace(/^#/,"")==a.mobile.activePage.jqmData("url")){k.options.allowSamePageTransition=true&&!d;a.mobile.changePage(a(j),k.options)}else{a.mobile.changePage(a(j),k.options)}l.preventDefault();a.mobile.urlHistory.ignoreNextHashChange=true}d=false;if(window.location.hash.indexOf("&ui-state=dialog")!=-1){d=true}});if(e.fixFirstPageDataUrl){a(document).ready(function(){if(!window.location.pathname.match("/$")){return}var i=a(":jqmData(role='page')").first();var j=i.jqmData("url"),h=window.location.pathname+e.firstPageDataUrl+window.location.search+window.location.hash;if(j!=h){i.attr("data-url",h).jqmData("url",h)}})}a.mobile.Router=function(l,j,k){this.routes={pagebeforecreate:null,pagecreate:null,pagebeforeshow:null,pageshow:null,pagebeforehide:null,pagehide:null,pageinit:null,pageremove:null,pagebeforechange:null,pagebeforeload:null,pageload:null,popupbeforeposition:null,popupafteropen:null,popupafterclose:null};this.evtLookup={bC:"pagebeforechange",bl:"pagebeforeload",l:"pageload",bc:"pagebeforecreate",c:"pagecreate",bs:"pagebeforeshow",s:"pageshow",bh:"pagebeforehide",h:"pagehide",i:"pageinit",rm:"pageremove",pbp:"popupbeforeposition",pao:"popupafteropen",pac:"popupafterclose"};this.routesRex={};this.conf=a.extend({},e,k||{});this.defaultHandlerEvents={};if(this.conf.defaultHandlerEvents){var h=this.conf.defaultHandlerEvents.split(",");for(var m=0;m<h.length;m++){this.defaultHandlerEvents[this.evtLookup[h[m]]]=h[m]}}this.add(l,j)};a.extend(a.mobile.Router.prototype,{documentEvts:{pagebeforechange:1,pagebeforeload:1,pageload:1},add:function(k,j,m){if(!k){return}var h=this,i=[],n=[];if(k instanceof Array){a.each(k,a.proxy(function(p,o){this.add(o,j,true)},this))}else{a.each(k,function(t,q){if(typeof(q)=="string"||typeof(q)=="function"){if(h.routes.pagebeforeshow===null){h.routes.pagebeforeshow={}}h.routes.pagebeforeshow[t]=q;if(!h.routesRex.hasOwnProperty(t)){h.routesRex[t]=new RegExp(t)}}else{var p,s=q.events.split(","),o;for(p=0;p<s.length;p++){o=h.evtLookup[s[p]];if(h.routes.hasOwnProperty(o)){if(h.routes[o]===null){h.routes[o]={}}h.routes[o][t]=q.handler;if(!h.routesRex.hasOwnProperty(t)){h.routesRex[t]=new RegExp(t)}}else{b("can't set unsupported route "+s[p])}}}})}if(m===true){return}if(!this.userHandlers){this.userHandlers=j||{}}else{a.extend(this.userHandlers,j||{})}a.each(h.routes,function(o,p){if(p!==null){if(!h.documentEvts[o]){i.push(o)}else{n.push(o)}}});this._detachEvents();var l=function(p,o){h._processRoutes(p,o,this)};if(i.length>0){this._eventData={events:i.join(" "),selectors:":jqmData(role='page'),:jqmData(role='dialog')",handler:l};a(document).delegate(this._eventData.selectors,this._eventData.events,this._eventData.handler)}if(n.length>0){this._docEventData={events:n.join(" "),handler:l};a(document).bind(this._docEventData.events,this._docEventData.handler)}},_processRoutes:function(m,q,n){var o=this,p,i,l,h=0;if(m.type in {pagebeforehide:true,pagehide:true,pageremove:true}){p=f}else{p=g}do{if(!p){if(n){l=a(n);p=l.jqmData("url");if(p){if(l.attr("id")==p){p="#"+p}p=a.mobile.path.parseUrl(p)}}}else{if(!this.documentEvts[m.type]&&n&&!a(n).jqmData("url")){return}}if(!p){return}i=(!this.conf.ajaxApp?p.hash:p.pathname+p.search+p.hash);if(i.length==0){p=""}h++}while(i.length==0&&h<=1);var k=false;a.each(this.routes[m.type],function(r,t){var s,v;if((s=i.match(o.routesRex[r]))){if(typeof(t)=="function"){v=t}else{if(typeof(o.userHandlers[t])=="function"){v=o.userHandlers[t]}}if(v){try{v.apply(o.userHandlers,[m.type,s,q,n,m]);k=true}catch(u){b(u)}}}if(k&&o.conf.firstMatchOnly){return false}});if(!k&&this.conf.defaultHandler&&this.defaultHandlerEvents[m.type]){if(typeof(this.conf.defaultHandler)=="function"){try{this.conf.defaultHandler.apply(o.userHandlers,[m.type,q,n,m])}catch(j){b(j)}}}},_detachEvents:function(){if(this._eventData){a(document).undelegate(this._eventData.selectors,this._eventData.events,this._eventData.handler)}if(this._docEventData){a(document).unbind(this._docEventData.events,this._docEventData.handler)}},destroy:function(){this._detachEvents();this.routes=this.routesRex=null},getParams:function(h){if(!h){return null}var k={},i;var j=h.slice(h.indexOf("?")+1).split("&");a.each(j,function(m,l){i=l.split("=");i[0]=decodeURIComponent(i[0]);if(k[i[0]]){if(!(k[i[0]] instanceof Array)){k[i[0]]=[k[i[0]]]}k[i[0]].push(decodeURIComponent(i[1]))}else{k[i[0]]=decodeURIComponent(i[1])}});if(a.isEmptyObject(k)){return null}return k}})});return{}}));
View
218 js/phillyapi.js
@@ -0,0 +1,218 @@
+var phillyapi = phillyapi || {};
+phillyapi = {
+ options: {
+ phillyapi: {
+ base: "http://services.phila.gov/PhillyApi/Data/"
+ ,summary: "HelperService.svc/GetLocationHistory?$format=json&AddressKey="
+ ,permit: "Service.svc/permits('%id%')?$format=json"
+ ,license: "Service.svc/licenses('%id%')?$format=json"
+ ,_case: "Service.svc/violationdetails?$filter=case_number%20eq%20'%id%'&$expand=cases&$format=json"
+ ,zoningboardappeal: "Service.svc/zoningboardappeals?$filter=appeal_number%20eq%20'%id%'&$format=json"
+ ,zbahearingdecisions: "Service.svc/zbahearingdecisions?$filter=appeal_id%20eq%20%id%&$format=json"
+ ,zbacourtdetails: "Service.svc/zbacourtdetails?$filter=appeal_id%20eq%20%id%&$format=json"
+ ,buildingboardappeal: "Service.svc/buildingboardappeals?$filter=appeal_number%20eq%20'%id%'&$format=json"
+ ,bbshearingdecisions: "Service.svc/bbshearingdecisions?$filter=appeal_id%20eq%20%id%&$format=json"
+ ,bbscourtdetails: "Service.svc/bbscourtdetails?$filter=appeal_id%20eq%20%id%&$format=json"
+ ,lireviewboardappeal: "Service.svc/lireviewboardappeals?$filter=appeal_number%20eq%20'%id%'&$format=json"
+ ,lirbhearingdecisions: "Service.svc/lirbhearingdecisions?$filter=appeal_id%20eq%20%id%&$format=json"
+ ,lirbcourtdetails: "Service.svc/lirbcourtdetails?$filter=appeal_id%20eq%20%id%&$format=json"
+ ,timeout: 20000
+ }
+ ,ulrs311: {
+ base: "http://services.phila.gov/ULRS311/Data/"
+ ,addressKey: "LIAddressKey/"
+ ,timeout: 20000
+ }
+ }
+
+ ,getAddressKey: function(input, successCallback, errorCallback) {
+ var url = phillyapi.options.ulrs311.base + phillyapi.options.ulrs311.addressKey + encodeURIComponent(input);
+ $.ajax({
+ url: url
+ ,dataType: "jsonp"
+ ,contentType: "application/json; charset=utf-8"
+ ,async: false
+ ,cache: true
+ ,crossDomain: true
+ ,timeout: phillyapi.options.ulrs311.timeout
+ ,type: "GET"
+ ,xhrFields: { withCredentials: false }
+ ,error: errorCallback
+ ,success: function(data) {
+ if("TopicID" in data) {
+ var addressKey = data.TopicID;
+ // Clean up the address. Default format is something like " 01234 MARKET ST" - needs to be "1234 MARKET ST" - Anyone have a better regex for it?
+ var address = data.AddressRef ? $.trim(data.AddressRef.replace(/ +(?= )/g,"")).replace(/^0+/, "") : null;
+ successCallback(addressKey, address);
+ }
+ }
+ });
+ }
+
+ ,getSummary: function(addressKey, successCallback, errorCallback, sorted) {
+ var url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi.summary + addressKey;
+ phillyapi.fetch(url, function(data) {
+ successCallback(sorted ? phillyapi.sortSummary(data) : data);
+ }, errorCallback);
+ }
+
+ ,getPermit: function(id, successCallback, errorCallback) {
+ var url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi.permit.replace("%id%", id);
+ phillyapi.fetch(url, successCallback, errorCallback);
+ }
+
+ ,getLicense: function(id, successCallback, errorCallback) {
+ var url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi.license.replace("%id%", id);
+ phillyapi.fetch(url, successCallback, errorCallback);
+ }
+
+ ,getCase: function(id, successCallback, errorCallback, sorted) {
+ var url = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi._case.replace("%id%", id);
+ phillyapi.fetch(url, function(data) {
+ successCallback(sorted ? phillyapi.sortCase(data) : data);
+ }, errorCallback);
+ }
+
+ /*
+ Due to a known issue in the API, we have to do 3 calls here instead of 1. Also, since the Summary gives us the appeal
+ number rather than appeal id, we have to wait for the first call to finish in order to get the appeal id for the second two
+ */
+ ,getAppeal: function(type, id, successCallback, errorCallback) {
+ var sortedData = {}, urlKeys = [];
+ switch(type) {
+ case "zoningboardappeals":
+ urlKeys = ["zoningboardappeal", "zbahearingdecisions", "zbacourtdetails"];
+ break;
+ case "buildingboardappeals":
+ urlKeys = ["buildingboardappeal", "bbshearingdecisions", "bbscourtdetails"];
+ break;
+ case "lireviewboardappeals":
+ urlKeys = ["lireviewboardappeal", "lirbhearingdecisions", "lirbcourtdetails"];
+ break;
+ }
+
+ // Appeal Details
+ var url1 = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi[urlKeys[0]].replace("%id%", id);
+ phillyapi.fetch(url1, function(data) {
+ sortedData.d = data.d.results[0];
+ var requestsPending = 0;
+
+ // Hearing Decisions
+ requestsPending++;
+ var url2 = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi[urlKeys[1]].replace("%id%", data.d.results[0].appeal_id);
+ phillyapi.fetch(url2, function(data) {
+ sortedData.d.hearingdecisions = data.d.results;
+ requestsPending--;
+ if(requestsPending < 1) successCallback(sortedData);
+ }, errorCallback);
+ // Court History
+ requestsPending++;
+ var url3 = phillyapi.options.phillyapi.base + phillyapi.options.phillyapi[urlKeys[2]].replace("%id%", data.d.results[0].appeal_id);
+ phillyapi.fetch(url3, function(data) {
+ sortedData.d.courtdetails = data.d.results;
+ requestsPending--;
+ if(requestsPending < 1) successCallback(sortedData);
+ }, errorCallback);
+ }, errorCallback);
+ }
+
+ ,fetch: function(url, successCallback, errorCallback) {
+ $.ajax({
+ url: url
+ ,dataType: "jsonp"
+ ,cache: true
+ ,timeout: phillyapi.options.phillyapi.timeout
+ ,jsonp: "$callback"
+ ,success: successCallback
+ ,error: errorCallback
+ });
+ }
+
+ // Sort summary data into categories
+ ,sortSummary: function(data) {
+ var sortedData = {};
+ for(var i = 0; i < data.length; i++) {
+ switch(data[i].category) {
+ case "Violation":
+ if(sortedData.cases === undefined) {
+ sortedData.cases = {};
+ }
+ if(sortedData.cases[data[i].id] === undefined) {
+ sortedData.cases[data[i].id] = {
+ "case_number": data[i].id
+ ,"violations": []
+ ,"entity": data[i].entity
+ }
+ }
+ sortedData.cases[data[i].id].violations.push(data[i].type);
+ break;
+ case "Permit":
+ if(sortedData.permits === undefined) {
+ sortedData.permits = [];
+ }
+ sortedData.permits.push({
+ "permit_number": data[i].id
+ ,"permit_type_name": data[i].type
+ ,"entity": data[i].entity
+ });
+ break;
+ case "Business":
+ if(sortedData.licenses === undefined) {
+ sortedData.licenses = [];
+ }
+ sortedData.licenses.push({
+ "license_number": data[i].id
+ ,"license_type_name": data[i].type
+ ,"entity": data[i].entity
+ });
+ break;
+ case "Appeal":
+ if(sortedData.appeals === undefined) {
+ sortedData.appeals = [];
+ }
+ sortedData.appeals.push({
+ "appeal_number": data[i].id
+ ,"appeal_type_name": data[i].type
+ ,"entity": data[i].entity
+ });
+ break;
+ default:
+ if(sortedData.other === undefined) {
+ sortedData.other = [];
+ }
+ sortedData.other.push({
+ "number": data[i].id
+ ,"type_name": data[i].type
+ });
+ break;
+ }
+ }
+ if(sortedData.cases !== undefined) sortedData.cases = phillyapi.objToArray(sortedData.cases);
+ return sortedData;
+ }
+
+ /*
+ This is a work-around for a known issue in the API. Ideally we'd do a call to the case and expand the violationdetails,
+ but since that gives an error, we do a call to the violation details of the case and expand the case.
+ That gives the case details multiple times, but at least it's only one ajax call. This function shuffles the data
+ around to be the case with a violationdetails array.
+ */
+ ,sortCase: function(data) {
+ var sortedData = {};
+ sortedData.d = data.d.results[0].cases;
+ for(var i = 0; i < data.d.results.length; i++) {
+ if(data.d.results[i].cases !== undefined) delete data.d.results[i].cases;
+ }
+ sortedData.d.violationdetails = data.d.results;
+ return sortedData;
+ }
+
+ // Stock function
+ ,objToArray: function(obj) {
+ var arr = []
+ for(var key in obj) {
+ arr.push(obj[key]);
+ }
+ return arr;
+ }
+};
View
141 js/script.js
@@ -0,0 +1,141 @@
+var DEBUG = false;
+var cache = {summary: null, details: null};
+
+var controller = {
+ search: function() {
+ $("#search form input").eq(0).focus();
+ }
+ ,summary: function(eventType, matchObj, ui, page, evt) {
+ var input = decodeURIComponent(matchObj[1].replace(/\+/g, "%20")).replace(/^\s+|\s+$/g, "");
+ if(cache.summary != matchObj[0]) {
+ $("[data-role=\"content\"]", page).empty();
+ setLoading(true);
+ phillyapi.getAddressKey(input, function(addressKey, address) {
+ if(addressKey) {
+ phillyapi.getSummary(addressKey, function(data) {
+ if(DEBUG) console.log(data);
+ if(_.isEmpty(data)) {
+ controller.error("No history found for this address", page);
+ } else {
+ $("[data-role=\"content\"]", page).html(_.template($("#template-summary").html(), {address: address, data: data}));
+ $("[data-role=\"listview\"]", page).listview();
+ cache.summary = matchObj[0];
+ setLoading(false);
+ }
+ }, function(xhr, status, error) {
+ controller.error("There was an issue fetching the summary data from the server", page, xhr);
+ }, true);
+ } else {
+ controller.error("The address entered is not a valid L&I address", page);
+ }
+ });
+ }
+ }
+ ,permit: function(eventType, matchObj, ui, page, evt) {
+ if(cache.details != matchObj[0]) {
+ $("[data-role=\"content\"]", page).empty();
+ setLoading(true);
+ phillyapi.getPermit(matchObj[1], function(data) {
+ if(DEBUG) console.log(data);
+ $("[data-role=\"content\"]", page).html(_.template($("#template-details-permit").html(), {data: data.d}));
+ cache.details = matchObj[0];
+ setLoading(false);
+ }, function(xhr, status, error) {
+ controller.error("There was an issue fetching the permit data from the server", page, xhr);
+ });
+ }
+ }
+ ,license: function(eventType, matchObj, ui, page, evt) {
+ if(cache.details != matchObj[0]) {
+ $("[data-role=\"content\"]", page).empty();
+ setLoading(true);
+ phillyapi.getLicense(matchObj[1], function(data) {
+ if(DEBUG) console.log(data);
+ $("[data-role=\"content\"]", page).html(_.template($("#template-details-license").html(), {data: data.d}));
+ cache.details = matchObj[0];
+ setLoading(false);
+ }, function(xhr, status, error) {
+ controller.error("There was an issue fetching the license data from the server", page, xhr);
+ });
+ }
+ }
+ ,_case: function(eventType, matchObj, ui, page, evt) {
+ if(cache.details != matchObj[0]) {
+ $("[data-role=\"content\"]", page).empty();
+ setLoading(true);
+ phillyapi.getCase(matchObj[1], function(data) {
+ if(DEBUG) console.log(data);
+ $("[data-role=\"content\"]", page).html(_.template($("#template-details-case").html(), {data: data.d}));
+ $("[data-role=\"collapsible-set\"]", page).collapsibleset();
+ cache.details = matchObj[0];
+ setLoading(false);
+ }, function(xhr, status, error) {
+ controller.error("There was an issue fetching the case data from the server", page, xhr);
+ }, true);
+ }
+ }
+ ,appeal: function(eventType, matchObj, ui, page, evt) {
+ if(cache.details != matchObj[0]) {
+ $("[data-role=\"content\"]", page).empty();
+ setLoading(true);
+ phillyapi.getAppeal(matchObj[1] + "appeals", matchObj[2], function(data) {
+ if(DEBUG) console.log(data);
+ $("[data-role=\"content\"]", page).html(_.template($("#template-details-appeal").html(), {data: data.d}));
+ $("[data-role=\"collapsible-set\"]", page).collapsibleset();
+ cache.details = matchObj[0];
+ setLoading(false);
+ }, function(xhr, status, error) {
+ controller.error("There was an issue fetching the appeal data from the server", page, xhr);
+ });
+ }
+ }
+ ,error: function(errorMsg, page, xhr) {
+ $("[data-role=\"content\"]", page).html(_.template($("#template-details-error").html(), {errorMsg: errorMsg, xhr: xhr}));
+ setLoading(false);
+ }
+};
+new $.mobile.Router({
+ "#search": { handler: "search", events: "s" }
+ ,"#summary\\?address=(.*)": { handler: "summary", events: "bs" }
+ ,"#details\\?entity=permits&eid=(\\d*)": { handler: "permit", events: "bs" }
+ ,"#details\\?entity=licenses&eid=(\\d*)": { handler: "license", events: "bs" }
+ ,"#details\\?entity=violationdetails&eid=(\\d*)": { handler: "_case", events: "bs" }
+ ,"#details\\?entity=(.*)appeals&eid=(\\d*)": { handler: "appeal", events: "bs" }
+}, controller);
+
+$(document).ready(function() {
+ // Ensure user has input an address before pressing search
+ $("#search form").submit(function(e) {
+ var inputNode = $("input[name=\"address\"]", $(this));
+ if( ! $.trim(inputNode.val())) {
+ inputNode.focus();
+ return false;
+ }
+ });
+});
+
+// Necessary because v1.1.0 of jQuery Mobile doesn't seem to let you show the loading message during pagebeforeshow
+function setLoading(on) {
+ if(on) $("body").addClass("ui-loading");
+ else $("body").removeClass("ui-loading");
+}
+
+function display_date(input, show_time){
+ var str;
+ if(input) {
+ var UNIX_timestamp = input.replace(/\D/g, "") / 1000;
+ var a = new Date(UNIX_timestamp*1000);
+ var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
+ var year = a.getFullYear();
+ var month = a.getMonth()+1;
+ var date = a.getDate();
+ str = month+"/"+date+"/"+year;
+ if(show_time) {
+ var hour = a.getHours();
+ var min = ("0" + a.getMinutes()).slice(-2);
+ var sec = ("0" + a.getSeconds()).slice(-2);
+ str += hour+":"+min+":"+sec;
+ }
+ }
+ return str;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.