CINXE.COM
Custom report - Nomis - Official Census and Labour Market Statistics
<!DOCTYPE html> <html lang="en"> <head> <!--[if lt IE 9]> <script> document.createElement('header'); document.createElement('nav'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('footer'); </script> <![endif]--> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>Custom report - Nomis - Official Census and Labour Market Statistics</title> <meta name="description" content="nomis - official labour market statistics" /> <meta name="keywords" content="annual business inquiry" /> <meta name="viewport" content="initial-scale=1" /> <meta charset="UTF-8" /> <link title="Easy Access version" rel="alternate" href="/home/accesskeys.htm" media="aural, braille, tty"> <link rel="alternate" type="application/rss+xml" title="Nomis RSS News Feed" href="/articles/rssArticles.asp" /> <link rel="alternate" type="application/rss+xml" title="Nomis RSS Release Dates Feed" href="/home/rssRelease_dates.asp" /> <link rel="stylesheet" href="/libs/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="/libs/jqueryui/jquery-ui.min.css" /> <link rel="stylesheet" href="/libs/jquery-simplePagination/simplePagination.min.css" /> <link rel="stylesheet" href="/libs/leaflet/leaflet.css" type="text/css" /> <link rel="stylesheet" href="/css/nomis.css" type="text/css" /> <link rel="stylesheet" href="/css/standard.css" type="text/css" /> <link rel="stylesheet" href="/css/nomis-ui.css" type="text/css" /> <link rel="stylesheet" href="/css/menubar.css" type="text/css" /> <link rel="stylesheet" href="/css/responsive.css" type="text/css" /> <link rel="stylesheet" href="/css/print.css" type="text/css" media="print" /> <!--[if Safari]> <link rel="stylesheet" href="/css/safari-nomis.css" type="text/css" /> <![endif]--> <script type="text/javascript" src="/libs/modernizr/modernizr.min.js"></script> <script type="text/javascript" src="/libs/jquery/jquery.min.js"></script> <script type="text/javascript" src="/libs/jquery-cookie/jquery.cookie.min.js"></script> <script type="text/javascript" src="/libs/jquery-simplePagination/jquery.simplePagination.min.js"></script> <script type="text/javascript" src="/libs/jqueryui/jquery-ui.min.js"></script> <script type="text/javascript" src="/libs/jqueryui-touch-punch/jquery.ui.touch-punch.min.js"></script> <script type="text/javascript" src="/libs/leaflet/leaflet.min.js"></script> <style> .prefFntCtrl:hover, .prefFntCtrl:visited { color: #00B; } .prefFntCtrl { border: 1px solid transparent; padding: 1px; } .activeFntSz { border-color: #00b; font-weight: normal; } #nomisweb-organisation-name-title:hover { text-decoration: underline; } .fa-search { border: 0; padding: 0.7em; background: #5f7d41; font-size: 13px; color: #fff; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } .fa-search:hover { cursor: pointer; } </style> <script type="text/javascript"> // Include D3 for browsers that support it if (Modernizr.inlinesvg) { document.write ('<script type="text\/javascript" src="\/libs\/d3\/d3.min.js"><\/script>'); } </script> <script type="text/javascript" src="/js/PageScripts.js"></script> <script type="text/javascript" src="/js/nomis-core.js"></script> <script type="text/javascript" src="/js/nomis-geography.js"></script> <script type="text/javascript" src="/js/nomis-api.js"></script> <script type="text/javascript" src="/js/nomis-ui.js"></script> <script type="text/javascript" src="/js/nomis-stat.js"></script> <script type="text/javascript"> (function (i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () { (i[r].q = i[r].q || []).push(arguments) }, i[r].l = 1 * new Date(); a = s.createElement(o), m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m) })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); ga('create', 'UA-3628896-1', 'auto'); ga('send', 'pageview'); </script> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-LMNEJ7PM1T"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-LMNEJ7PM1T'); </script> <!-- Google Tag Manager --> <script> (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-NJWJX69'); </script> <!-- End Google Tag Manager --> </head> <body onload="javascript:try { pageLoaded(); } catch(er) { }" onunload="javascript:try { pageUnloaded(); } catch(er) { }"> <!-- Google Tag Manager (noscript) --> <noscript> <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWJX69" height="0" width="0" style="display:none;visibility:hidden"></iframe> </noscript> <!-- End Google Tag Manager (noscript) --> <div role="status" id="titleStatusDiv" class="visually-hidden"></div> <div id="nomis-webpage"> <div id="cookie-consent-wrapper" aria-labelledby="cookie-consent-heading" style="display: none;" role="alert"> <h1 id="cookie-consent-heading">Cookie Consent</h1> <p id="cookie-consent-info">We use cookies to ensure you get the best experience on our website. By using this site, you agree to our <a href="/home/cookies.asp" title="Read about how cookies are used on the Nomis web site">cookie policy</a>.</p> <input id="cookie-consent-dismiss-button" aria-labelledby="cookie-consent-terms" onclick="cookieConsentDismiss();" title="Hide this message about cookies" type="button" value="Hide" /> </div> <script type="text/javascript"> function shouldDisplayCookieConsent() { return ($.cookie('cookie-consent') != 'yes'); } function cookieConsentDismiss() { $('#cookie-consent-wrapper').slideUp(800); $.cookie('cookie-consent', 'yes', { expires: 900, secure: true, path: '/' }); } if (shouldDisplayCookieConsent()) { $('#cookie-consent-wrapper').css('display', 'block'); } </script> <div id="org-name-and-logo-wrapper" role="banner" aria-labelledby="nomisweb-organisation-name-title nomisweb-organisation-name-subtitle" style="overflow: hidden;"> <div class="hidden-until-focus"> <a href="#content-anchor" accesskey="s" class="skiptocontent">Skip to content</a> <a href="/home/accessibility.asp" title="navigation link to Nomis website accessibility guide page">Skip to accessibility help</a> </div> <div id="nomisweb-organisation-name"> <div id="nomisweb-main-title-container"> <div id="nomisweb-organisation-name-title"><a href="/" accesskey="1">nomis</a></div> </div> <div id="nomisweb-subtitle-container"> <div id="nomisweb-organisation-name-subtitle">official census and labour market statistics</div> </div> </div> <div class="nomisweb-ons-logo" style="float: none; text-align: right; margin-right: 0;"> <a href="https://www.ons.gov.uk"> <img alt="National Statistics Logo" src="/images/ons-logo.svg" style="margin-top: 0; float: none; width: 19.7em;"> </a> <div class="page-heading-tools" style="padding-left: 0 !important; background-color: #fff; margin-right: -5px; margin-top: 0; padding: 0 !important; clear: none;"> <form id="site-search" onsubmit="if(document.getElementById('site-search-term').value == 'Search Nomis...') return false; else return true;" action="/home/Search" method="GET"> <input type="hidden" id="site-search-context" name="context" value="" /> <label class="obscure" for="site-search-term" id="lblsite-search-term">Search term</label> <input type="search" id="site-search-term" name="term" maxlength="75" aria-labelledby="lblsite-search-term" style="border: 1px solid #ddd; margin-right: 0; padding: 0.2em;" value="" /> <button type="submit" style="padding: 0; border: 0;" title="Search" accesskey="4"><i class="fa fa-search"></i></button> <script type="text/javascript"> NomisCore.setPlaceholder('site-search-term', 'Search...'); </script> </form> </div> </div> </div> <!-- PRE-SITE-NAV-BANNER-HOOK --> <div id="site-nav-banner"> <div id="menu-control"> <a title="Show/Hide site navigation menu" href="javascript: $('#nomis-top-main-nav-wrapper').slideToggle(); event.preventDefault();"><img src="/images/menu.gif" alt="Picture of three horizontal lines representing a menu" /> Menu</a> <a title="Set site preferences" href="javascript: showSitePrefs();"><img src="/images/cog.gif" alt="Picture of a cog representing settings for the web site" /></a> </div> <!-- Begin site navigation banner section --> <div id="nomis-top-main-nav-wrapper" role="navigation" aria-label="Site Navigation"> <nav> <ul class="nav-menu"> <li class="nav-item"> <a href="/" accesskey="1">Home</a> </li> <li class="nav-item"> <a href="/home/profiles.asp">Reports</a> <div class="sub-nav"> <h1>Area reports</h1> <ul> <li><a href="/reports/localarea">Local Area Report (district/county and smaller areas)</a></li> <li><a href="/reports/lmp/la/contents.aspx">Local Authority Profile (district/county areas)</a></li> <li><a href="/reports/lmp/lep/contents.aspx">Local Enterprise Partnerships Profile</a></li> <li><a href="/reports/lmp/gor/contents.aspx">Regional and National Profile</a></li> <li><a href="/reports/lmp/comb/contents.aspx">Combined Authority Profile</a></li> <li><a href="/reports/lmp/wpca/contents.aspx">2010 Parliamentary Constituencies Profile</a></li> <li><a href="/reports/lmp/ward2011/contents.aspx">2011 Ward Profile</a></li> </ul> <h1>Topic reports</h1> <ul> <li><a href="/datasets/aps218/reports/employment-by-occupation">Employment by occupation (SOC2020) by sex</a></li> <li><a href="/datasets/aps218/reports/employment-by-status-and-occupation">Occupation (SOC2020) by sex, employment status and full/part-time</a></li> <li><a href="/datasets/aps218/reports/employment-by-temp-workers">Temporary and permanent employees by sex and broad occupation (SOC2020)</a></li> <li><a href="/datasets/aps218/reports/employment-by-part-time-workers">Employment by broad occupation (SOC2020) for part-time workers</a></li> <li><a href="/datasets/aps218/reports/employment-by-sex-by-ftpt-by-emp-self">Broad occupation (SOC2020) by sex, employment status and full/part-time time-series</a></li> </ul> </div> </li> <li class="nav-item"> <a id="A5" href="/sources">Data Sources</a> <div class="sub-nav"> <ul> <li><a href="/sources/acses">Annual Civil Service Employment Survey</a></li> <li><a href="/sources/aps">Annual Population Survey/Labour Force Survey</a></li> <li><a href="/sources/ashe">Annual Survey of Hours and Earnings</a></li> <li><a href="/sources/bres">Business Register and Employment Survey</a></li> <li><a href="/sources/census">Census</a></li> <li><a href="/sources/cc">Claimant Count</a></li> <li><a href="/sources/dwp">DWP Benefits</a></li> <li><a href="/sources/housing">Housing</a></li> <li><a href="/sources/eop">Economic output and productivity</a></li> <li><a href="/sources/jd">Jobs Density</a></li> <li><a href="/sources/jsa">Jobseekers Allowance</a></li> <li><a href="/sources/life">Life Events</a></li> <li><a href="/sources/pest">Population Estimates/Projections</a></li> <li><a href="/sources/ra">Regional Accounts</a></li> <li><a href="/sources/ukbc">UK Business Counts</a></li> <li><a href="/sources/wfj">Workforce Jobs</a></li> </ul> </div> </li> <li class="nav-item"> <a id="A6" href="/sources/census">Census</a> <div class="sub-nav"> <ul> <li><a href="/sources/census_2021">2021 Census</a></li> <li><a href="/sources/census_2011">2011 Census</a></li> <li><a href="/sources/census_2001">2001 Census</a></li> <li><a href="/sources/census_1991">1991 Census</a></li> <li><a href="/sources/census_1981">1981 Census</a></li> <li><a href="/sources/census_1961">1961 Census</a></li> <li><a href="/sources/census_1951">1951 Census</a></li> <li><a href="/sources/census_1931">1931 Census</a></li> <li><a href="/sources/census_1921">1921 Census</a></li> </ul> </div> </li> <li class="nav-item"> <a id="A8" href="/home/contacts.asp">Contact us</a> </li> <li class="nav-item nav-my-account"> <a id="A7" href="/myaccount/overview.asp" title="My account overview">Sign-in</a> <div class="sub-nav"> <div style="display: none;"> <ul> <li><a href="/myaccount/overview.asp">My account</a></li> </ul> </div> <div id="menu-my-account-not-signed-in"> <h1>You're not signed in</h1> <ul> <li><a id="signin_link" href="/login/login.asp" title="Sign-in and return to the current page">Sign-in</a></li> </ul> <h1>New to Nomis?</h1> <p>You can use most parts of this site without registering.</p> <ul> <li><a href="/myaccount/userjoin.asp">Register</a></li> <li><a href="/home/register.asp">Benefits of registering</a></li> </ul> </div> </div> </li> </ul> </nav> <a id="nomisweb-prefs-link" title="Site settings" href="javascript: showSitePrefs();"><img src="/images/cog.gif" alt="Picture of a cog representing settings for the web site" /><span>Settings</span></a> <!-- initialize a selector as an accessibleMegaMenu --> <script type="text/javascript"> var mmansi = document.getElementById('menu-my-account-not-signed-in'); // Only change sign-in urls if the user is not logged in if (mmansi != null && mmansi != undefined && mmansi.style != undefined && mmansi.style.display != 'none') { var signina = document.getElementById('signin_link'); var a7a = document.getElementById('A7'); var signin_tgt = window.location.pathname var signin_par = window.location.search; if (signin_par.length > 0) signin_par = signin_par.substring(1); // Remove ? signin_par = encodeURIComponent(signin_par); var signin_hrefp = '?target=' + signin_tgt + '¶ms=' + signin_par; if (signina != null && signina != undefined) signina.href = signina.href + signin_hrefp; // Make sub-menu sign-in link target go to same page if (a7a != null && a7a != undefined) a7a.href = '/login/login.asp' + signin_hrefp; // Initially make my account link target go to same page } </script> <script src="/libs/jquery-accessibleMegaMenu.js"></script> <script type="text/javascript"> $("nav:first").accessibleMegaMenu({ uuidPrefix: "accessible-megamenu", menuClass: "nav-menu", topNavItemClass: "nav-item", panelClass: "sub-nav", panelGroupClass: "sub-nav-group", hoverClass: "hover", focusClass: "focus", openClass: "open" }); </script> </div> <!-- End site navigation banner section --> <!-- Begin breadcrumbs --> <div id="breadcrumbs-wrapper"> <div id="BCBox" class="breadcrumbs" role="navigation" aria-label="Breadcrumbs"></div> </div> <!-- End breadcrumbs --> <script type="text/javascript"> var BaseBreadCrumbs = new Array('/default.asp', 'home'); SetBreadCrumbs(null); </script> <div id="skip-to-content"><a id="content-anchor"></a></div> <div id="page-heading-and-sub-nav"></div> </div> <!-- End site navigation banner section --> <div id="page-wrap" role="main"> <!-- Begin page content --> <style> #uimodes label, #uimodes label:hover { text-decoration: none; color: #b7c6d0; cursor: default; } #loading { background: #fff; color: #58798f; border: 3px solid #58798f; margin: 3em auto; max-width: 1024px; } #loading h1 { border-bottom: none !important; padding: 3em !important; padding-bottom: 0.3em !important; color: #58798f !important; padding-top: 1.5em !important; } #loading div { color: #58798f; padding: 0 0 2em 4.8em; } thead th div { color: #666; font-size: 0.85em; } table.plain td { text-align: left; } button.actual-search-hit:disabled { border: none !important; background: none !important; color: #333 !important; } #site-search input[type="submit"] { font-size: 0.8em; background: #fff; } #site-search input[type="submit"]:hover { color: #333; } select { background-color: #dde9f3; } #matches aside { margin-top: 2em; } #matches aside h1 { margin-left: 0; font-size: 1em; margin-bottom: 1em; } #matches aside span { padding-left: 0; } .search-result { padding: 0.1em; } .search-result:hover { } .search-result .maplink { display: none; padding-left: 1em; position: relative; top: 0.2em; cursor: pointer; } .search-result:hover .maplink { display: inline; } .descriptive-content-section h1 { text-transform: none; } #selectbox button { margin-left: 0.5em; } </style> <link rel="Stylesheet" href="/css/profile.css?1" /> <link rel="Stylesheet" href="/css/ui.css?1" /> <div id="report" class="descriptive-content-section"> <div id="err" style="display: none;"></div> <div id="loading"><h1>Please wait...</h1><div id="loading-message"></div></div> <div id="areacompdiv" style="display: none;"> <h1><span id="dsname">Custom report</span><span id="uimodes"></span></h1> <h2>Search for your area <span id="coverage"></span></h2> <div id="comparisonareas"></div> <div id="searchbox"></div> <div id="matches" role="status"></div> <div id="selectbox"></div> </div> <div id="template-wrapper" style="display: none;"> </div> </div> <script type="text/javascript" src="/libs/json-stat.js?1"></script> <script type="text/javascript" src="/libs/function-queue.js?1"></script> <script type="text/javascript" src="/js/profile.js?1"></script> <script type="text/javascript" src="/js/ui.js?1"></script> <script> var params = null; var kv = 0; var maxcomparisons = 5; var mode = 0; var modes = [ { name: 'Single area', autoCompleteSearch: true, displaySelectedAreas: false, destroyReportOnSearch: true, searchResultViewStyle: 'list' }, { name: 'Related areas', autoCompleteSearch: true, autoAddParentsOnSelectArea: true, displaySelectedAreas: false, destroyReportOnSearch: true, searchResultViewStyle: 'list' }, { name: 'Customised', alpha: true, autoAddParentsOnSelectArea: false, autoCompleteSearch: true, hidden: true, displaySelectedAreas: true, destroyReportOnSearch: false, searchResultViewStyle: 'list', showAddParentsButtonForSelectedAreas: false, showShuffleButtonsForSelectedAreas: true, retainComparisonOnModeSwitch: true, keepResults: false }, { name: 'Tree Search', autoAddParentsOnSelectArea: false, autoCompleteSearch: true, hidden: true, displaySelectedAreas: true, destroyReportOnSearch: false, searchResultViewStyle: 'tree', showAddParentsButtonForSelectedAreas: true, showShuffleButtonsForSelectedAreas: true } ]; var supportedgeogtypes = [ { type: 1, name: "Wards (as of 1991)", singular: "Ward (as of 1991)", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 7, name: "1991 Enumeration Districts", singular: "1991 Enumeration District", meta: "Smallest area for which data are available", forPostcode: false, forName: true, hasAreaLookup: true }, { type: 121, name: "Counties", singular: "County", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 142, name: "Counties", singular: "County", forPostcode: false, forName: true, hasAreaLookup: true }, { type: 141, name: "Regions", singular: "Region", forPostcode: false, forName: true, hasAreaLookup: true }, { type: 368, name: "Parishes", singular: "Parish", forPostcode: true, forName: true, hasAreaLookup: true, noMatchMessage: "Not in a parish" }, { type: 279, name: "Parishes", singular: "Parish", forPostcode: true, forName: true, hasAreaLookup: true, noMatchMessage: "Not in a parish" }, { type: 312, name: "Wards (as of 2003)", singular: "Ward (as of 2003)", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 295, name: "Wards (as of 2011)", singular: "Ward (as of 2011)", forPostcode: true, fofrName: true, hasAreaLookup: true }, { type: 153, name: "Wards (as of 2022)", singular: "Ward (as of 2022)", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 463, name: "Counties", singular: "County", forPostcode: true, forName: false, hasAreaLookup: true }, { type: 155, name: "Counties", singular: "County", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 464, name: "Local Authorities", singular: "Local Authority", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 432, name: "Local Authorities", singular: "Local Authority", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 154, name: "Local Authorities", singular: "Local Authority", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 480, name: "Regions", singular: "Region", forPostcode: false, forName: true, obvious: false, hasAreaLookup: true }, { type: 156, name: "Regions", singular: "Region", forPostcode: false, forName: true, hasAreaLookup: true }, { type: 269, name: "Built-up areas", singular: "Built-up area", meta: "villages, towns or cities", forPostcode: true, forName: true, hasAreaLookup: true, noMatchMessage: "Not in a built-up area" }, { type: 267, name: "Built-up area sub divisions", singular: "Built-up area sub division", meta: "town or city sub divisions", forPostcode: true, forName: true, hasAreaLookup: true, noMatchMessage: "Not in a built-up area sub division" }, { type: 152, name: "Mid-layer Super Output Areas", singular: "Mid-layer SOA", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 297, name: "Mid-layer Super Output Areas", singular: "Mid-layer SOA", forPostcode: true, forName: true, hasAreaLookup: true }, { type: 304, name: "Lower-layer Super Output Areas", singular: "Lower-layer SOA", forPostcode: true, forName: true, hasAreaLookup: true, labelWithGSS: true }, { type: 151, name: "Lower-layer Super Output Areas", singular: "Lower-layer SOA", forPostcode: true, forName: true, hasAreaLookup: true, labelWithGSS: true }, { type: 298, name: "Lower-layer Super Output Areas", singular: "Lower-layer SOA", forPostcode: true, forName: true, hasAreaLookup: true, labelWithGSS: true }, { type: 150, name: "Output Areas", singular: "Output Area", meta: "Smallest area for which data are available", forPostcode: true, forName: false, hasAreaLookup: false, resolveParent: 154 }, { type: 299, name: "Output Areas", singular: "Output Area", meta: "Smallest area for which data are available", forPostcode: true, forName: false, hasAreaLookup: false, resolveParent: 464 }, { type: 310, name: "Output Areas", singular: "Output Area", meta: "Smallest area for which data are available", forPostcode: true, forName: false, hasAreaLookup: false, resolveParent: 464 }, { type: 499, name: "Countries", singular: "Country", forPostcode: false, forName: true, obvious: false, hasAreaLookup: true } ]; var pcSearchContext = 604; var countryCoverage = [ 3, 4 ]; function loadingMsg(msg) { document.getElementById('loading-message').innerHTML = msg; } var namegeogtypes = [ ]; // List of geogtypes for name searching. var gssgeogtypes = [ ]; // List of geogtypes for GSS searching. var pcgeogtypes = [ ]; // List of geogtypes for postcode searching. var validgeogtypes = []; // List of geography types that are valid for this dataset. var hits = []; // Results from most recent search // Patterns of text substitution for various customisation options, these are configurable by defining this entire object in pageinfo.patterns in template. var patterns = { geogNameInReport: '$label $typename in $parent (GSS code $gss)', geogNameInTable: '$label <div>$typename</div>', geogNameInTableAmbiguous: '$label in $parent', geogNameInCompleteList: '$label $typename' }; var p = null; var compared = []; var complookups = 0; // During initialisation, number of area lookups ongoing. var initialSearch = null; function createRemoveFunction(item) { var itm = item; return function() { compared = compared.filter(function(el) { return el.value !== itm.value; }); go(); }; } function createMoveComparsionFunc(index, direction) { var _i = index; var _d = direction; return function() { var tmp = compared[_i]; compared[_i] = compared[_i + _d]; compared[_i + _d] = tmp; updatecomparedlist(); updateGeogConfig(); p.redraw(); }; }; function getGeogType(tp) { if(tp > 10000) tp = tp >> 22; for(var i = 0; i < validgeogtypes.length; i++) { var f = validgeogtypes[i]; if(f.type == tp) return f; } return null; } function createParentCompareFunction(area) { var a = area; return function() { if(a.parents && a.parents.length > 0) { var added = []; for(var i = 0; i < a.parents.length; i++) { // Add first and last parent. if(i == 0 || i == a.parents.length - 1) { if(!hasComparison(a.parents[i])) { var par = lookup(a.parents[i]); if(par) added.push(par); } } } if(compared.length + added.length > 5) window.alert('Maximum of 5 comparison areas allowed, please remove some before adding parent areas of ' + a.label + '.'); else if(added.length > 0) { added.map(function(par) { addComparison(par, true); }); updatecomparedlist(); go(); } else window.alert('Parent areas of ' + a.label + ' are not available in this report.'); } } } function updatecomparedlist() { var div = document.getElementById('comparisonareas'); if(modes[mode].alpha) div.innerHTML = '<span style="display: block;" class="note">Please note, area selection is in early stages of development and may change significantly in the future.</span>'; else div.innerHTML = ''; var c = ''; for(var i = 0; i < compared.length; i++) { var n = document.createElement('div'); var ca = compared[i]; var lbl = ca.label; if((lbl.indexOf('(') == -1 || lbl.indexOf('(no data)') != -1) && ca.parents && ca.parents.length > 0) { var par = lookup(ca.parents[0]); if(par) { lbl += ' (' + par.label + ')'; } } n.appendChild(document.createTextNode(lbl)); var btnCf = ui.button({ label: '+Parents', classname: 'positive', onclick: createParentCompareFunction(ca) }); btnCf.innerHTML = '⑂'; btnCf.title = 'Compare with parent areas'; var btnUp = ui.button( { label: 'Move Up', classname: 'positive', onclick: createMoveComparsionFunc(i, -1) } ); var btnDn = ui.button( { label: 'Move Down', classname: 'positive', onclick: createMoveComparsionFunc(i, 1) } ); btnUp.innerHTML = '⇧'; btnUp.title = 'Move this area up the list'; btnDn.innerHTML = '⇩'; btnDn.title = 'Move this area down the list'; if(i == 0) btnUp.disabled = true; if(i == compared.length - 1) btnDn.disabled = true; var ctrl = document.createElement('div'); if(!ca.parents || (ca.parents.length == 0)) { btnCf.disabled = true; } else { var hasall = true; var cft = []; for(var j = 0; j < ca.parents.length; j++) { // Add first and last parent. if(j == 0 || j == ca.parents.length - 1) { if(!hasComparison(ca.parents[j])) { hasall = false; cft.push(ca.parents[j]); } } } if(hasall) btnCf.disabled = true; else if(modes[mode].showAddParentsButtonForSelectedAreas) { btnCflbl = 'Add comparison with '; for(var k = 0; k < cft.length; k++) { if(cft.length > 1 && k == cft.length - 1) btnCflbl += ' and '; else if(k > 0) btnCflbl += ', '; btnCflbl += lookup(cft[k]).label; } btnCf.title = btnCflbl; } } var btnRm = ui.button( { label: 'Remove', classname: 'negative', onclick: createRemoveFunction(ca) } ) btnRm.innerHTML = '✕ Remove'; btnRm.title = 'Remove ' + ca.label; // Shuffle button if(modes[mode].showShuffleButtonsForSelectedAreas) { ctrl.appendChild(btnDn); ctrl.appendChild(btnUp); } // Comparison with parents button if(modes[mode].showAddParentsButtonForSelectedAreas) ctrl.appendChild(btnCf); ctrl.appendChild(btnRm); n.appendChild(ctrl); div.appendChild(n); if(c.length > 0) c += ','; c += compared[i].gss; } // Delete all button if(compared.length > 1) { var btnDa = ui.button( { label: 'Remove all areas', classname: 'negative', onclick: function() { compared = []; go(); } }); div.appendChild(btnDa); } // URL update if (history.pushState) { if(c.length > 0) { var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?compare=' + c; if(mode > 0) newurl += '&mode=' + mode; if(document.location.href != newurl) window.history.pushState({path:newurl},'',newurl); } } } function updateGeogConfig() { params.config.geography = []; params.config.geognames = ''; params.config.geognamelist = []; params.config.substitute = { geography: [ ] }; for(var i = 0; i < compared.length; i++) { var entry = { value: compared[i].value, label: compared[i].label }; var ambig = false; var gt = getGeogType(entry.value); if(entry.value >> 22 == 267) ambig = true; // Force Built-up area names through to data else { // Check ambiguous name? for(var j = 0; j < compared.length; j++) { // Check the others if(i != j && compared[i].label == compared[j].label) { ambig = true; break; } } } var parlab = ''; var par = null; if(compared[i].parents && compared[i].parents.length > 0) par = lookup(compared[i].parents[0]); params.config.geography.push(compared[i].value); var gnlname = patterns.geogNameInReport; gnlname = gnlname.replace('$label', entry.label); gnlname = gnlname.replace('$typename', gt.singular); gnlname = gnlname.replace('$parent', (par)? par.label : 'unknown'); gnlname = gnlname.replace('$gss', (compared[i].gss)? compared[i].gss : 'unknown'); params.config.geognamelist.push(gnlname); // Make the data display the names the way we refer to them in the application. var gntname = (ambig)? patterns.geogNameInTableAmbiguous : patterns.geogNameInTable; gntname = gntname.replace('$label', entry.label); gntname = gntname.replace('$typename', gt.singular); gntname = gntname.replace('$parent', (par)? par.label : 'unknown'); gntname = gntname.replace('$gss', (compared[i].gss)? compared[i].gss : 'unknown'); params.config.substitute.geography.push({ value: entry.value, label: gntname }); // Complete list of geography names in play var gnname = patterns.geogNameInCompleteList; gnname = gnname.replace('$label', entry.label); gnname = gnname.replace('$typename', gt.singular); gnname = gnname.replace('$parent', (par)? par.label : 'unknown'); gnname = gnname.replace('$gss', (compared[i].gss)? compared[i].gss : 'unknown'); if(params.config.geognames.length > 0) params.config.geognames += (i == compared.length-1)? ' and ' : ', '; params.config.geognames += gnname; } } function isNullOrUndefined(value){ return value === undefined || value === null; } function setTitle(){ const headingDiv = document.getElementById('template-wrapper'); const pageHeadStatusDiv = document.getElementById('titleStatusDiv'); if(!isNullOrUndefined(headingDiv)){ const heading = headingDiv.querySelector('h1'); const subheading = headingDiv.querySelector('h2'); if(!isNullOrUndefined(heading) && !isNullOrUndefined(subheading)){ const headingText = heading.textContent; const subheadingText = subheading.textContent; const newTitle = `Nomis - ${subheadingText} - ${headingText}`; document.title = newTitle; pageHeadStatusDiv.textContent = newTitle; } } } function go() { updatecomparedlist(); updateGeogConfig(); document.getElementById('template-wrapper').innerHTML = ''; if(params.config.geography.length > 0) { if (p == null) p = NomisProfile.create(params); else p.refresh(); ga('send', 'event', 'Report sources/census_2011_ks', 'View', params.config.geography[0]); ga('send', 'event', 'Report sources/census_2011_ks', 'View (area type)', getGeogType(params.config.geography[0]).singular); $('#template-wrapper').show(); setTitle(); } else { if(p != null) p.remove(); $('#template-wrapper').hide(); } } function setSearchingEnabled(enabled) { if(enabled) refreshSearchResults(); document.getElementById('searchtxt').disabled = !enabled; document.getElementById('searchbtn').disabled = !enabled; } var areatypelist = { }; function setAreaType(typenum, callback) { if(!areatypelist['type' + typenum]) { loadingMsg('Loading areas'); $.getJSON("/json/geography/type" + typenum + ".json?1", function (data) { areatypelist['type' + typenum] = data; data.map(function(area) { // Fix gss code not present in object, but given in label. var s = area.label.split(' : '); if((s.length) > 1 && !area.gss) { area.gss = s[0]; area.label = s[1]; } }); if(callback) callback(data); }); } else { if(callback) callback(areatypelist['type' + typenum]); } } function getAreas(tp) { return areatypelist['type' + tp]; } function hasComparison(kv) { for(var i = 0; i < compared.length; i++) { if(compared[i] != undefined && compared[i] != null && compared[i].label != undefined && compared[i].value.toString() == kv.toString()) return true; } return false; } function addComparison(match, noRefresh, index) { kv = match.value; if(!hasComparison(match.value)) { if(index != undefined && index != null) compared[index] = match; else compared.push(match); if(modes[mode].autoAddParentsOnSelectArea && compared.length == 1) { // Auto add comparison parents for first area searched? if(match.parents && match.parents.length > 0) { for(var i = 0; i < match.parents.length; i++) { // Add first and last parent. if(i == 0 || i == match.parents.length - 1) { var par = lookup(match.parents[i]); if(par) addComparison(par, true); } } } } if(!noRefresh) go(); } } function nomatch() { var matchbox = document.getElementById('matches'); matchbox.innerHTML = '<span>No matching areas found.</span>'; } function clearResults() { var matchbox = document.getElementById('matches'); matchbox.innerHTML = ''; hits = []; } function findHitIn(value, o) { var hit = o[value]; if(!hit) { // Look through everything in o for (var property in o) { if (o.hasOwnProperty(property)) { var op = o[property]; if(op) { if(op.hit.value == value) { hit = op; break; } else { hit = findHitIn(value, op.children); if(hit) break; } } } } } return hit; } function addChildrenToHitEntry(entry) { validgeogtypes.map(function(t) { if(t.type != (entry.value >> 22)) { getAreas(t.type).map(function(a) { if(a.parents && a.parents.length > 0) { var fc = a.parents[0]; if(fc == entry.hit.value) { entry.children.push({ hit: a, children: [] }); } } }); } }); } function organiseHits(h) { var o = {}; h.map(function(a) { var entry = findHitIn(a.value, o); if(!entry) { // create entry entry = { hit: a, children: [] }; addChildrenToHitEntry(entry); o[a.value] = entry; } entry.autoExpand = false; entry.realHit = true; if(a.parents) { var lastp = null; for(var i = a.parents.length - 1; i >= 0; i--) { var p = a.parents[i]; var pentry = findHitIn(p, o); if(!pentry) { // create entry var par = lookup(p); if(par) { // valid parent pentry = { hit: par, children: [] }; o[p] = pentry; } } if(pentry) { if(lastp != null) { o[p] = null; // This is now a child if(lastp.children.indexOf(pentry) == -1) lastp.children.push(pentry); } lastp = pentry; } } if(lastp != null) { o[a.value] = null; if(lastp.children.indexOf(entry) == -1) lastp.children.push(entry); //o[lastp.hit.value] = lastp; } } }); return o; } function addSearchNodeProperties(node) { var m = node.hit; var div = ui.element({ tagname: 'span', classname: 'search-result' }); div.appendChild(ui.button({ label: m.label, classname: node.realHit? 'actual-search-hit' : '', onclick: function() { if(hasComparison(m.value)) window.alert('You have already selected ' + m.label + '.'); else if(compared.length == maxcomparisons) window.alert('Maximum of ' + maxcomparisons + ' areas can be compared, please remove one before trying to add more.'); else { addComparison(m); clearResults(); } } })); div.appendChild(ui.element({ tagname: 'span', classname: 'areatype-name', content: getGeogType(node.hit.value).name })); node.content = div; if(node.children && node.children.length > 0) { // Sort children node.children.sort(function (a, b) { if (a.hit.label < b.hit.label) return -1; if (a.hit.label > b.hit.label) return 1; return 0; }); node.children.map(function(c) { addSearchNodeProperties(c); }); } else node.children = null; } function createSearchTreeNodes(h) { var t = []; for (var property in h) { if (h.hasOwnProperty(property)) { var op = h[property]; if(op) { addSearchNodeProperties(op); t.push(op); } } } return t; } function createSearchTree(nodes) { return ui.tree({ classname: 'tree', children: nodes }) } function refreshSearchResults() { if(hits.length > 0) { var matchbox = document.getElementById('matches'); if(modes[mode].searchResultViewStyle == 'tree') { // Hierarchical tree view of results var h = organiseHits(hits); var nodes = createSearchTreeNodes(h); var tree = createSearchTree(nodes); matchbox.appendChild(tree); } else { // List view hits.map(function(h) { addListSearchResults(h.matches, h.geogtype, matchbox); }); var opts = document.createElement('aside'); opts.appendChild(ui.element({ tagname: 'h3', content: 'Options' })); opts.appendChild(ui.element({ tagname: 'div', classname: 'divider' })); opts.appendChild(ui.checkbox({ id: 'chkpar', value: 'yes', label: 'When I choose an area, include its parent areas (for example the local authority and country that it is within).', checked: modes[mode].autoAddParentsOnSelectArea, onclick: function() { modes[mode].autoAddParentsOnSelectArea = document.getElementById('chkpar').checked; return true; } })); matchbox.appendChild(opts); } } } function setSearchResults(matches, geogtype) { if(modes[mode].searchResultViewStyle == 'tree') { matches.map(function(m) { hits.push(m); }); } else { // List view hits.push({ matches: matches, geogtype: geogtype }); } } function addListSearchResults(matches, geogtype, matchbox) { matchbox.appendChild(ui.element({ tagname: 'h3', content: ((matches.length <= 1)? geogtype.singular : geogtype.name) + ((geogtype.meta)? ' (' + geogtype.meta + ')' : '') })); if(matches.length > 0) { matches.sort(function (a, b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; }); matches.map(function(m) { var lbl = m.label; var lbl2 = 'Compare ' + m.label; var others = []; if(geogtype.labelWithGSS && m.gss && (m.label.indexOf(m.gss) == -1)) { lbl = m.gss + ' - ' + lbl; } if((lbl.indexOf('(') == -1 || lbl.indexOf('(no data)') != -1) && m.parents && m.parents.length > 0) { for(var i = 0; i < m.parents.length; i++) { var par = lookup(m.parents[i]); if(par) { if(i == 0) { var tmpptp = isSupported({ type: par.value >> 22 }); lbl += ' (in ' + par.label; if(tmpptp) lbl += ' ' + tmpptp.singular; lbl += ')'; } if(i == 0 || i == m.parents.length - 1) { if(others.length == 0) lbl2 += ' with '; else if(i == m.parents.length - 1) lbl2 += ' and '; else lbl2 += ','; lbl2 += par.label; others.push(par); } } } } var nodata = (lbl.indexOf('(no data)') != -1); var div = document.createElement('div'); div.className = 'search-result'; var btn = ui.button({ label: lbl, classname: 'actual-search-hit', onclick: function() { if(hasComparison(m.value)) window.alert('You have already selected ' + lbl + '.'); else if(compared.length == maxcomparisons) window.alert('Maximum of ' + maxcomparisons + ' areas can be compared, please remove one before trying to add more.'); else { ga('send', 'event', 'Report sources/census_2011_ks', 'Select area', 'Result list'); addComparison(m); if(!modes[mode].keepResults) clearResults(); } } }); var maplink = document.createElement('a'); maplink.onclick = function() { modalMap(m.value, lbl, false, event.shiftKey); } maplink.setAttribute('class', 'maplink'); maplink.setAttribute('title', 'Preview a map of ' + lbl); var mapicon = document.createElement('img'); mapicon.setAttribute('src', '/images/map.gif'); maplink.appendChild(mapicon); div.appendChild(btn); div.appendChild(maplink); if(nodata) { btn.disabled = nodata; div.appendChild(ui.alink({ href: '#', classname: 'whynodata', label: 'Why no data?', onclick: function() { window.alert('2011 Census data are not available for this Parish.'); ga('send', 'event', 'Report sources/census_2011_ks', 'Select area', 'Why no data'); return false; } })); } matchbox.appendChild(div); }); } else { matchbox.appendChild(ui.element({ tagname: 'span', content: (geogtype.noMatchMessage)? geogtype.noMatchMessage : 'No matches found' }));; } } function isInCoverage(a) { if(countryCoverage == null || (!a.cov)) return true; for(var i = 0; i < countryCoverage.length; i++) { if(countryCoverage[i] == a.cov) return true; } return false; } function isGSSPattern(pattern) { var regex = /[EWSNLMKewsnlmk][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/; var found = pattern.match(regex); if(found != null && found.length > 0) return true; else return false;l } function search(pattern) { var suppliedpattern = pattern; pattern = pattern.toLowerCase(); pattern = pattern.replace(/ /g, ''); pattern = pattern.replace(/-/g, ''); pattern = pattern.replace(/[\W_]+/g," "); // Strip out funny characters if(pattern.length < 2) return; document.getElementById('searchbtn').focus(); document.getElementById('searchtxt').focus(); setSearchingEnabled(false); clearResults(); if(modes[mode].destroyReportOnSearch) { compared = []; go(); } var matchcount = 0; if(isGSSPattern(pattern)) { for(var t = 0; t < gssgeogtypes.length; t++) { var a = getAreas(gssgeogtypes[t].type); var matches = []; for(var i = 0; i < a.length; i++) { if(isInCoverage(a[i]) && (a[i].gss != undefined && a[i].gss.toLowerCase() == pattern)) { matches.push(a[i]); break; // Stop after first hit } } matchcount += matches.length; if(matches.length > 0) { setSearchResults(matches, gssgeogtypes[t]); // Stop after first hit break; } } if(matchcount == 0) { ga('send', 'event', 'Report sources/census_2011_ks', 'Search area - no hits', suppliedpattern); nomatch(); setSearchingEnabled(true); } else { ga('send', 'event', 'Report sources/census_2011_ks', 'Search area - hits', suppliedpattern); setSearchingEnabled(true); } } else { // Name search for(var t = 0; t < namegeogtypes.length; t++) { var a = getAreas(namegeogtypes[t].type); var matches = []; for(var i = 0; i < a.length; i++) { if(isInCoverage(a[i]) && (a[i].label.toLowerCase().replace(/ /g, '').replace(/-/g, '').indexOf(pattern) !== -1)) matches.push(a[i]); } if(matches.length > 0) setSearchResults(matches, namegeogtypes[t]); matchcount += matches.length; } // If no area matches then try a postcode search if(matchcount == 0) { if(pattern.length >= 5) { containsnum = /\d/.test(pattern); if(containsnum) { // No number then it can't be a postcode. var queue = FuncQueue.create({ ignoreErrors: false, timeout: 30000, onError: function(message) { console.log(message); }, onTimeout: function() { console.log('failed'); } }); // Add some function calls to the queue pcgeogtypes.map(function(t) { queue.add(createPCfunc(pattern, t)); }); queue.run(function(data) { data.map(function(d) { // Process results to try and resolve parents for areas that don't have their own list if(d.geogtype.resolveParents = true && d.matches.length == 1) { data.map(function(d2) { if(d2.geogtype.type == d.geogtype.resolveParent && d2.matches.length == 1) { var a = d2.matches[0]; // Take this area and its last parent too. d.matches[0].parents.push(a.value); d.matches[0].parents.push(a.parents[a.parents.length - 1]); } }); } setSearchResults(d.matches, d.geogtype); matchcount += d.matches.length; }); if(matchcount == 0) ga('send', 'event', 'Report sources/census_2011_ks', 'Search postcode - no hits', suppliedpattern); else ga('send', 'event', 'Report sources/census_2011_ks', 'Search postcode', suppliedpattern); setSearchingEnabled(true); }); } else { ga('send', 'event', 'Report sources/census_2011_ks', 'Search area - no hits', suppliedpattern); nomatch(); setSearchingEnabled(true); } } else { ga('send', 'event', 'Report sources/census_2011_ks', 'Search area - no hits', suppliedpattern); nomatch(); setSearchingEnabled(true); } } else { ga('send', 'event', 'Report sources/census_2011_ks', 'Search area - hits', suppliedpattern); setSearchingEnabled(true); } } } function createPCfunc(pattern, t) { var pat = pattern; var tp = t; var matches = []; return function(complete) { $.getJSON('/api/v01/dataset/NM_' + pcSearchContext + '_1/geography/POSTCODE|' + pat + ';' + tp.type + '.def.sdmx.json', function(data) { try { data.structure.codelists.codelist[0].code.map(function(obj, idx, arr) { if(typeof obj.value === 'number') { var a = lookup(obj.value); if(a) this.push(a); else if(!tp.hasAreaLookup) { // Capture this as a new area var at = getAreas(tp.type); if(at) { a = { value: obj.value, label: obj.description.value, gss: obj.description.value, parents: [] }; at.push(a); this.push(a); } } } }, matches); } catch(err) { ; } complete({ matches: matches, geogtype: t }); }); }; } function addqueue(queue, type) { queue.add(function(complete) { setAreaType(type, complete); }); } function isSupported(t) { for(var i = 0; i < supportedgeogtypes.length; i++) { var suppt = supportedgeogtypes[i]; if(t.type == suppt.type) return suppt; } return null; } function shouldAddToNameSearch(t) { for(var i = 0; i < supportedgeogtypes.length; i++) { var suppt = supportedgeogtypes[i]; if(suppt.forName == true && t.type == suppt.type) return suppt; } return null; } function shouldAddToPostcodeSearch(t) { for(var i = 0; i < supportedgeogtypes.length; i++) { var suppt = supportedgeogtypes[i]; if(suppt.forPostcode == true && t.type == suppt.type) return suppt; } return null; } function resolveType(kvOrGss) { var kv = parseInt(kvOrGss); if(!isNaN(kv)) { return kv >> 22; } else { // Get the Nomis type by checking 3 characters of the GSS of the first geography in each of the type lists // taking the value and right-shifting the keyval var part = kvOrGss.substring(0,3); for (var prop in areatypelist) { var atp = areatypelist[prop]; if(atp.length > 0 && atp[0].gss.substring(0,3) == part) return atp[0].value >> 22; } return 0; } } function lookup(kv) { var tp = resolveType(kv); if(tp != 0) { // Found the type, look in the list var list = areatypelist['type' + tp]; if(list) { for(var i = 0; i < list.length; i++) { if(list[i].value == kv || list[i].gss == kv) return list[i]; } } } else { // Look through all lists for (var prop in areatypelist) { var list = areatypelist[prop]; for(var i = 0; i < list.length; i++) { if(list[i].value == kv || list[i].gss == kv) return list[i]; } } } return null; } function numGeogsAvailable() { var tot = 0; namegeogtypes.map(function(t) { var a = getAreas(t.type); if(a) tot += a.length; }); return tot; } function initGeogPulldown() { var selectbox = document.getElementById('selectbox'); var optgrplist = []; namegeogtypes.map(function(t) { var list = getAreas(t.type); if(list) { if(compared.length == 0) compared.push(list[0]); optgrplist.push({ label: t.name, list: list }); } }); var currgeog = null; if(compared && (compared.length >= 1)) currgeog = compared[0].value; var selctrl = ui.select({ label: (modes[mode].displaySelectedAreas)? 'Choose an area for comparison' : 'Choose an area', id: 'areaselector', list: optgrplist, selected: currgeog }); var selbtn = ui.button({ label: (modes[mode].displaySelectedAreas)? 'Add' : 'View', classname: 'positive', onclick: function() { selbtn.disabled = true; var a = lookup(document.getElementById('areaselector').value); if(modes[mode].destroyReportOnSearch) { compared = []; } if(hasComparison(a.value)) window.alert('You have already seleted ' + a.label + '.'); else if(compared.length >= maxcomparisons) window.alert('Maximum of ' + maxcomparisons + ' areas can be compared, please remove an area before adding more.'); else addComparison(a); }}); selbtn.disabled = true; selctrl.onchange = function() { selbtn.disabled = false; } selectbox.appendChild(selctrl); selectbox.appendChild(selbtn); } function hideSearch() { document.getElementById('searchbox').style.display = 'none'; // Hide the search box } function hidePulldown() { document.getElementById('selectbox').style.display = 'none'; // Hide the select box } function uimodeCtrl() { var c = document.getElementById('uimodes'); c.style.display = 'none'; // hidden for now var optlist = []; modes.map(function(m, i) { if(m.name != undefined && m.hidden != true) { optlist.push({ label: m.name, value: i }); } }); c.appendChild(ui.select({ label: 'Report type', id: 'uimode', list: optlist, onchange: function() { var loc = document.location.href; ga('send', 'event', 'Report sources/census_2011_ks', 'Change mode', modes[this.value].name); if(!modes[this.value].retainComparisonOnModeSwitch) { // Dump the entire querystring if(loc.indexOf('?') != -1) loc = loc.substring(0, loc.indexOf('?')); if(this.value != 0) { loc += '?mode=' + this.value; // Don't need mode for mode 0 as this is default } } else if(loc.indexOf('mode=' + mode) != -1) { // Tweak URL loc = loc.replace('mode=' + mode, 'mode=' + this.value); } else { // Add mode to URL if(loc.indexOf('?') != -1) loc = loc.replace('?', '?mode=' + this.value + '&'); else if(loc.indexOf('&') != -1) loc = loc.replace('&', '&mode=' + this.value + '&'); else loc += '?mode=' + this.value; } document.location.href = loc; } })); document.getElementById('uimode').value = mode; } function findAnnot(annots, title, defaultval) { if(annots != null) { for(var i = 0; i < annots.length; i++) { if(annots[i].annotationtitle === title) return annots[i].annotationtext; } } return defaultval; } function addreinsqueue(queue, str) { var searchstr = str; queue.add(function(complete) { $.getJSON('/api/v01/dataset/NM_' + pcSearchContext + '_1/geography/' + searchstr + '.def.sdmx.json', function(data) { try { var code = data.structure.codelists.codelist[0].code[0]; var annots = (code.annotations && code.annotations.annotation)? code.annotations.annotation : null; var a = { value: findAnnot(annots,"NomisKey", code.value), label: code.description.value, gss: findAnnot(annots, "GeogCode", code.value) }; var tp = getGeogType(a.value >> 22); if(tp != null) { var at = getAreas(tp.type); if(at) { at.push(a); compared.push(a); } } } catch(e) { } complete(); }); }); } $(document).ready(function () { if(window.history) window.history.replaceState({path:document.location.href},'',document.location.href); // Initial state push window.onpopstate = function() { if(event && (event.state !== null)) { compared = []; reinstate(); } } var sections = document.getElementById('template-wrapper'); var searchbox = document.getElementById('searchbox'); var inputsearch = ui.inputsearch({ id: 'searchtxt', placeholder: 'Postcode or area name', onkeyup: function(event) { keycode = event.keyCode || event.which; if(keycode == 13) search(this.value); } }); // Set the aria-label attribute for better accessibility inputsearch.setAttribute('aria-label', 'Search for your area: Postcode or area name'); searchbox.appendChild(inputsearch); searchbox.appendChild(ui.button({ id: 'searchbtn', label: 'Search', classname: 'positive', onclick: function() { search(inputsearch.value); } })); function err(msg) { var errbox = document.getElementById('err'); errbox.innerHTML = msg; errbox.style.display = 'block'; } var firstReinstate = true; function reinstate() { // Interface mode var qmode = ui.getQueryString('mode'); if(qmode) { try { mode = parseInt(qmode); } catch(e) { mode = 0; } } if(firstReinstate) { uimodeCtrl(); } if(!modes[mode].displaySelectedAreas) document.getElementById('comparisonareas').style.display = 'none'; initialSearch = ui.getQueryString('search'); if(initialSearch != null && initialSearch.length > 0) initialSearch = decodeURIComponent(initialSearch); var qcomp = ui.getQueryString('compare'); var unresolvedqueue = null; if(qcomp) { var qcomplist = qcomp.split(','); for(var i = 0; i < qcomplist.length; i++) { try { var kvstr = qcomplist[i]; if(!hasComparison(kvstr)) { var c = lookup(kvstr); if(c != null) compared.push(c); else { if(!unresolvedqueue) unresolvedqueue = FuncQueue.create({ ignoreErrors: false, timeout: 30000, onError: function(message) { console.log(message); }, onTimeout: function() { console.log('failed'); } }); addreinsqueue(unresolvedqueue, kvstr); } } } catch(e) { } } } // There are some unknown keyvals, go look these up before reinstate can finish. if(unresolvedqueue) { loadingMsg('Resolving selected area(s)'); unresolvedqueue.run(function() { completeReinstate(); }); } else completeReinstate(); // Nothing is unresolved, complete the reinstate immediately. } function completeReinstate() { if(firstReinstate) { var totgeogs = numGeogsAvailable(); if(totgeogs < 50) { initGeogPulldown(); hideSearch(); } else { hidePulldown(); // Too many areas for pulldown if(modes[mode].autoCompleteSearch) { $("#searchtxt").autocomplete({ minLength: 3, source: function (request, response) { var results = []; var pattern = request.term.toLowerCase().replace(/ /g, '').replace(/-/g, ''); for(var i = 0; i < namegeogtypes.length; i++) { var a = getAreas(namegeogtypes[i].type); for(var j = 0; j < a.length; j++) { var area = a[j]; if(area.label.indexOf('(no data)') == -1) { if(isInCoverage(area) && (area.label.toLowerCase().replace(/ /g, '').replace(/-/g, '').indexOf(pattern) !== -1)) results.push(area); } } } response(results.slice(0, 200)); }, focus: function (event, ui) { return false; }, select: function (event, ui) { if(modes[mode].destroyReportOnSearch) compared = []; clearResults(); if(compared.length < maxcomparisons) { ga('send', 'event', 'Report sources/census_2011_ks', 'Select area', 'Autocomplete'); addComparison(ui.item, false); } else window.alert('Maximum of ' + maxcomparisons + ' areas can be compared, please remove one before adding more'); document.getElementById('searchtxt').value = ''; document.getElementById('searchbtn').focus(); document.getElementById('searchtxt').focus(); return false; } }).data('ui-autocomplete')._renderItem = function(ul, item) { var lbl = item.label; if((lbl.indexOf('(') == -1) && item.parents && item.parents.length > 0) { var par = lookup(item.parents[0]); if(par) lbl += ' (' + par.label + ')'; } var meta = getGeogType(item.value).singular; return $( '<li></li>' ).data('item.autocomplete', item) .append( '<a>' + lbl + '<div style="color: #999">' + meta + '</div></a>') .appendTo( ul ); }; } } } setSearchingEnabled(true); document.getElementById('loading').style.display = 'none'; document.getElementById('areacompdiv').style.display = 'block'; go(); var stxt = document.getElementById('searchtxt'); stxt.focus(); if(initialSearch != null && initialSearch.length > 0) { stxt.value = initialSearch; var sbtn = document.getElementById('searchbtn'); sbtn.click(); } firstReinstate = false; } // Load template loadingMsg('Loading report'); $.getJSON('/json/templates/sources/census_2011_ks.json?1', function(template) { params = { config: { geography: [] }, profile: template, target: sections, lazyload: false, onRenderComplete: function () { } }; if(template.pageinfo) { if(template.pageinfo.title) { document.getElementById('dsname').innerHTML = template.pageinfo.title; document.title = template.pageinfo.title + ' - Nomis'; } if(template.pageinfo.breadcrumbs) SetBreadCrumbs(template.pageinfo.breadcrumbs); if(template.pageinfo.patterns) patterns = template.pageinfo.patterns; } var queue = FuncQueue.create({ ignoreErrors: false, timeout: 30000, onError: function(message) { console.log(message); }, onTimeout: function() { console.log('failed'); } }); if(template.postcodeSearchDataset) pcSearchContext = template.postcodeSearchDataset; if(template.countryCoverage) countryCoverage = template.countryCoverage; // For each of the valid geography types for this dataset. if(template.validity && template.validity.geography) template.validity.geography.map(function(t) { // Which ones are for name search? var ns = shouldAddToNameSearch(t); if(ns) namegeogtypes.push(ns); // Which ones are for postcode search? var ps = shouldAddToPostcodeSearch(t); if(ps) pcgeogtypes.push(ps); // Which ones are valid var st = isSupported(t); if(st) { validgeogtypes.push(st); // Add to GSS search always. gssgeogtypes.push(st); // Add geography type name search lookup calls to pre-load lists. if(st.hasAreaLookup) addqueue(queue, t.type); else { // Create an empty list to hold captured areas. areatypelist['type' + st.type] = []; } } }); if(validgeogtypes.length > 0) { queue.run(function(data) { // Reinstate areas reinstate(); }); } else console.log('No geography types supported'); }); }); </script> </div> <!-- Begin footer --> <footer style="clear:both;"> <div id="nomis-footer-wrapper" role="contentinfo"> <ul> <li><a href="/api">API</a></li> <li><a href="/home/sitemap.asp" accesskey="3" id="Site-map">Site map</a></li> <li><a href="/home/news.asp" id="News">News</a></li> <li><a href="/home/accessibility.asp">Accessibility</a></li> <li><a href="/home/accesskeys.asp" id="access-keys" accesskey="0">Access keys</a></li> <li><a href="/home/privacy.asp" id="Privacy-and-Cookies">Privacy and Cookies</a></li> <li><a href="/home/terms.asp" id="Terms-and-Conditions" accesskey="8">Terms and Conditions</a></li> <li><a href="/home/copyright.asp" id="Crown-Copyright">© Crown Copyright</a></li> </ul> <div id="durham-uni-logo-container"> <a href="http://www.dur.ac.uk"><img border="0" src="/images/du_logo.png" alt="Durham University Logo" /></a> </div> </div> </footer> <!-- End footer --> <!-- Begin Site-wide Information Popup Box --> <div id="modalBack" role="alert" aria-labelledby="modalDivTitle" style="display: none;"> <div id="modalDiv" tabindex="-1"> <div id="modalDivHead"> <h2 id="modalDivTitle"></h2> <div id="modalDivTools"><input type="button" title="Close this pop-up (esc)" id="modalCloseButton" value="Close" onclick="modalClose();" class="modalDivTool" /></div> </div> <div id="modalBusy"><p>Please wait...</p></div> <div id="modalDivBody"></div> </div> </div> <!-- End Site-wide Information Popup Box --> <!-- PRE-END-NOMISWEB-PAGE-DIV-HOOK --> </div> <script type="text/javascript" src="/js/tips.js"></script> <!-- End Nomisweb Page div --> </body> </html>