/* Copyright 2006 Vantageous, LLC. All rights reserved. */ var p3 = {}; p3.globals = {}; p3.globals.head = getElementsByTagAndClassName('head')[0]; p3.globals.cookieName = 'p3_live_search'; /* load safari css */ if (navigator.userAgent.toLowerCase().indexOf('safari') != -1) { var script = createDOM('link', { 'rel': 'stylesheet', 'href': '/media/css/safari.css', 'type': 'text/css' }); appendChildNodes(p3.globals.head, script); } /* keep google/urchin from slowing page loads */ connect(window, 'onload', function() { setTimeout(function() { var script = createDOM('script', { 'charset': 'utf-8', 'src': 'https://ssl.google-analytics.com/urchin.js', 'type': 'text/javascript' }); appendChildNodes(p3.globals.head, script); var interval = setInterval(function() { if ('urchinTracker' in window) { _uacct = 'UA-1298944-3'; urchinTracker(); // will throw if doesn't exist clearInterval(interval); } }, 500); }, 1); }); p3.formHandling = { addHighlight: function(e) { var elem = e.src().parentNode.parentNode; //should be container class addElementClass(elem, 'highlight'); }, removeAllHighlight: function(e) { forEach(p3.formHandling.elems, function(elem) { removeElementClass(elem.parentNode.parentNode, 'highlight'); }); }, clearDefaultText: function(e) { var elem = e.src(); if (getNodeAttribute(elem, 'defaulttext') == elem.value) { elem.value = ''; } }, toggleEnabled: function(e) { var src = e.src(); var elem = getElementsByTagAndClassName('input', 'input_text', e.src().parentNode.parentNode)[0]; if (src.checked === true) { elem.readOnly = true; addElementClass(elem, 'grayed_out'); if (getNodeAttribute(elem, 'readonlytext') !== null) { elem.value = getNodeAttribute(elem, 'readonlytext'); } else { elem.value = src.parentNode.getElementsByTagName('label')[0].innerHTML; } } else { elem.readOnly = false; removeElementClass(elem, 'grayed_out'); elem.value = ''; } }, showBillingForm: function(e) { p3.util.makeInvisible('billing_info_read_only'); p3.util.makeVisible('billing_info_read_write'); }, init: function() { p3.formHandling.elems = getElementsByTagAndClassName('input', 'input_text'); var textareas = getElementsByTagAndClassName('textarea', null); forEach(textareas, function(textarea) { p3.formHandling.elems.push(textarea); }); forEach(p3.formHandling.elems, function(elem) { connect(elem, 'onfocus', p3.formHandling.addHighlight); if (elem.value !== '' && getNodeAttribute(elem, 'defaulttext') !== '') { connect(elem, 'onfocus', p3.formHandling.clearDefaultText); } connect(elem, 'onblur', p3.formHandling.removeAllHighlight); }); try { connect('search_email', 'onfocus', p3.formHandling.clearDefaultText); } catch(e) { /* pass */ } var checkboxes = getElementsByTagAndClassName('input', 'input_check'); forEach(checkboxes, function(checkbox) { connect(checkbox, 'onchange', p3.formHandling.toggleEnabled); connect(checkbox, 'onclick', p3.formHandling.toggleEnabled); //connect this as well for IE }); } }; p3.search = { lastQuery: '', page: 1, locationID: '', sectorID: '', typeID: '', inputFocus: function() { var self = p3.search; if (self.SEARCH_INPUT.value === self.DEFAULT) { self.SEARCH_INPUT.value = ''; } }, inputBlur: function() { var self = p3.search; if (self.SEARCH_INPUT.value === '') { self.SEARCH_INPUT.value = self.DEFAULT; } }, updateSearchEmailLink: function(e) { //var elem = getElement('email_form_note'); //var query = strip(getElement('p3_search').value); //p3.util.makeInvisible('email_form_confirm'); //if (query.length >= 3) { //elem.innerHTML = 'Email me jobs for "' + query + '"'; //} else { //elem.innerHTML = ''; //} }, repage: function(url) { var self = p3.search; var arr = url.split('/'); self.page = arr[arr.length - 2]; window.location.hash = 'sizer'; self.refresh(); }, rekeyword: function(url) { var self = p3.search; var arr = url.split('/'); self.page = 1; self.lastQuery = arr[arr.length - 2]; getElement('p3_search').value = self.lastQuery; window.location.hash = 'sizer'; self.refresh(); }, updateSearchResults: function() { var change = 0; var self = p3.search; var src = getElement('p3_search'); var query = strip(src.value); if (query != self.lastQuery || self.lastQuery == '') { self.lastQuery = query; change = 1; } var loc_src = getElement('location_id'); var loc_query = loc_src.value; if (loc_query != self.locationID) { self.locationID = loc_query; change = 1; } var sec_src = getElement('sector_id'); var sec_query = sec_src.value; if (sec_query != self.sectorID) { self.sectorID = sec_query; change = 1; } var typ_src = getElement('type_id'); var typ_query = typ_src.value; if (typ_query != self.typeID) { self.typeID = typ_query; change = 1; } if (change == 0) { return; } p3.util.makeInvisible('email_form_container'); p3.util.makeVisible('email_form_note'); self.page = 1; self.refresh(); }, refresh: function() { var self = p3.search; var elem = getElement('searchcontent'); addElementClass('p3_search_form', 'searching'); var cookie = new p3.cookie(p3.globals.cookieName); cookie.query = self.lastQuery; cookie.page = self.page; cookie.store(); var d = doSimpleXMLHttpRequest( 'search_engine.php?string=' + self.lastQuery + '&page=' + self.page + '&locid=' + self.locationID + '&secid=' + self.sectorID + '&typid=' + self.typeID); d.addCallback(function(text) { elem.innerHTML = ''; elem.innerHTML = text.responseText; removeElementClass('p3_search_form', 'searching'); d = null; }); }, init: function() { var cookie = new p3.cookie(p3.globals.cookieName); if ('query' in cookie && 'page' in cookie) { getElement('p3_search').value = cookie['query']; p3.search.lastQuery = cookie['query']; p3.search.updateSearchEmailLink(); p3.search.page = cookie['page']; p3.search.refresh(); if (p3.search.lastQuery === '') { getElement('p3_search').value = getNodeAttribute('p3_search', 'defaulttext'); } } connect('p3_search_form', 'onsubmit', function(e) { e.stop(); }); connect('p3_search', 'onkeyup', p3.search.updateSearchEmailLink); connect('p3_search', 'onkeyup', p3.search.updateSearchResults); connect('location_id', 'onchange', p3.search.updateSearchResults); connect('sector_id', 'onchange', p3.search.updateSearchResults); connect('type_id', 'onchange', p3.search.updateSearchResults); connect('email_subscribe_form', 'onsubmit', function(e) { e.stop(); MochiKit.Async.doSimplePostXMLHttpRequest('/services/rest/email/subscribe/', { 'search_email': getElement('search_email').value, 'query': getElement('p3_search').value }); p3.util.makeInvisible('email_form_container'); p3.util.makeVisible('email_form_confirm'); }); connect('email_subscribe_form', 'onclick', function(e) { e.stop(); var id = e.target().id; if (id == 'search_email_text') { p3.util.makeVisible('email_form_container'); p3.util.makeInvisible('email_form_note'); } else if (id == 'email_subscribe_submit') { MochiKit.Async.doSimplePostXMLHttpRequest('/services/rest/email/subscribe/', { 'search_email': getElement('search_email').value, 'query': getElement('p3_search').value }); p3.util.makeInvisible('email_form_container'); p3.util.makeVisible('email_form_confirm'); } }); var preload = new Image(600, 100).src = '/media/css/cssimg/search_input_text_candy.gif'; } }; p3.jobs = {}; p3.jobs.textarea = { jobForm: {}, characterMax: 0, init: function() { var self = p3.jobs.textarea; /* self.characterMax = scrapeText('charactersRemaining'); self.updateCount(); connect('job_description', 'onkeyup', self.updateCount); */ cache = new Image(); cache.src = "/media/css/cssimg/html_editor/bold_down.gif"; connect('bold', 'onmousedown', function(e) { e.stop(); elem = getElement('bold'); elem.src = elem.src.replace(/up/, 'down'); }); connect('bold', 'onmouseup', function(e) { e.stop(); elem = getElement('bold'); elem.src = elem.src.replace(/down/, 'up'); }); connect('bold', 'onclick', function(e) { e.stop(); self.insertTags('**', '**', 'bold'); /*self.updateCount();*/ }); connect('list', 'onmousedown', function(e) { e.stop(); elem = getElement('list'); elem.src = elem.src.replace(/up/, 'down'); }); connect('list', 'onmouseup', function(e) { e.stop(); elem = getElement('list'); elem.src = elem.src.replace(/down/, 'up'); }); connect('list', 'onclick', function(e) { e.stop(); self.insertTags('\n* ', '', 'list item'); /*self.updateCount();*/ }); }, updateCount: function() { var self = p3.jobs.textarea; var text = getElement('job_description').value text = text.replace(/\s/gmi, ''); var count = text.length; replaceChildNodes('charactersRemaining', self.characterMax - count); if (count > self.characterMax) { addElementClass('charactersRemaining', 'warning'); } else if (count <= self.characterMax) { removeElementClass('charactersRemaining', 'warning'); } }, insertTags: function(openTag, closeTag, sampleText) { var area = getElement('job_description'); var ds = document.selection; if (ds) { var theSelection = ds.createRange().text; if (!theSelection) { theSelection = sampleText; } area.focus(); if (theSelection.charAt(theSelection.length - 1) == ' ') { theSelection = theSelection.substring(0, theSelection.length - 1); ds.createRange().text = openTag + theSelection + closeTag + ' '; } else { ds.createRange().text = openTag + theSelection + closeTag; } } else if (typeof(area.selectionStart) == 'number') { var replaced = false; var startPos = area.selectionStart; var endPos = area.selectionEnd; var scrollTop = area.scrollTop; var text = (area.value).substring(startPos, endPos); if (endPos - startPos) { replaced = true; } if (!text) { text = sampleText; } if (text.charAt(text.length - 1) == ' ') { replaceWith = openTag + text.substring(0, (text.length - 1)) + closeTag + ' '; } else { replaceWith = openTag + text + closeTag; } area.value = area.value.substring(0, startPos) + replaceWith + area.value.substring(endPos, area.value.length); area.focus(); if (replaced) { var cPos = startPos + (openTag.length + text.length + closeTag.length); area.selectionStart = cPos; area.selectionEnd = cPos; } else { area.selectionStart = startPos + openTag.length; area.selectionEnd = startPos + openTag.length + text.length; } area.scrollTop = scrollTop; } if (area.createTextRange) { area.caretPos = ds.createRange().duplicate(); } } }; p3.accounts = {}; p3.accounts.billing = { init: function() { var self = p3.account.card.billing; connect('cardNumber', 'onkeyup', self.updateCardInfo); }, updateCardInfo: function() { var number = getElement('cardNumber').value; var type = p3.card.getType(number); if (type === null) { replaceChildNodes('cardType', 'Invalid'); } else { replaceChildNodes('cardType', type.name); } if (p3.card.isValid(number)) { replaceChildNodes('isValid', 'Yes'); } else { replaceChildNodes('isValid', 'No'); } } }; /* p3.cookie from JavaScript: The Definitive Guide, by David Flanagan. Copyright 2006 O'Reilly Media, Inc., 978-0-596-10199-2. */ p3.cookie = function(name) { this.$name = name; var allcookies = document.cookie; if (allcookies == "") return; var cookies = allcookies.split(';'); var cookie = null; var cookieName = null; for(var i = 0; i < cookies.length; i++) { cookieName = cookies[i].replace(/^\s+/, ''); if (cookieName.substring(0, name.length+1) == (name + "=")) { cookie = cookies[i]; break; } } if (cookie == null) return; var cookieval = cookie.substring(name.length+1); var a = cookieval.split('&'); for(var i=0; i < a.length; i++) { a[i] = a[i].split(':'); } for(var i = 0; i < a.length; i++) { this[a[i][0]] = decodeURIComponent(a[i][1]); } }; p3.cookie.prototype.store = function(daysToLive, path, domain, secure) { var cookieval = ""; for(var prop in this) { if ((prop.charAt(0) == '$') || ((typeof this[prop]) == 'function')) continue; if (cookieval != "") cookieval += '&'; cookieval += prop + ':' + encodeURIComponent(this[prop]); } var cookie = this.$name + '=' + cookieval; if (daysToLive || daysToLive == 0) { cookie += "; max-age=" + (daysToLive*24*60*60); } if (path) cookie += "; path=" + path; if (domain) cookie += "; domain=" + domain; if (secure) cookie += "; secure"; document.cookie = cookie; }; p3.cookie.prototype.remove = function(path, domain, secure) { for(var prop in this) { if (prop.charAt(0) != '$' && typeof this[prop] != 'function') delete this[prop]; } this.store(0, path, domain, secure); }; p3.util = { toggleVisible: function(elem) { if (getElement(elem) !== null) { toggleElementClass('invisible', elem); } }, makeVisible: function(elem) { if (getElement(elem) !== null) { removeElementClass(elem, 'invisible'); } }, makeInvisible: function(elem) { if (getElement(elem) !== null) { addElementClass(elem, 'invisible'); } }, isVisible: function(elem) { if (getElement(elem) !== null) { return !hasElementClass(elem, 'invisible'); } return false; }, write_email: function(cipher, key) { var clear = ''; var shift = cipher.length; for (var i=0; i'+clear+''); }, passkeyword: function(keyword) { var cookie = new p3.cookie(p3.globals.cookieName); cookie.query = keyword; cookie.page = 1; cookie.store(); } }; p3.util.creditCard = { types: [ {'name': 'amex', 'len': [15], 'prefix': new RegExp('^3[4|7]')}, {'name': 'discover', 'len': [16], 'prefix': new RegExp('^6011')}, {'name': 'mastercard', 'len': [16], 'prefix': new RegExp('^5[1-5]')}, {'name': 'visa', 'len': [16,13], 'prefix': new RegExp('^4')} ], getType: function(number) { /* see: http://www.beachnet.com/~hstiles/cardtype.html */ number = '' + number; number = number.replace(new RegExp('[^\\d]', 'gi'), ''); var self = p3.util.creditCard; for (var i = 0; i < self.types.length; i++) { if (number.match(self.types[i].prefix)) { return self.types[i]; } } return null; }, isValid: function(number) { var self = p3.card; var type = self.getType(number); if (type === null) { return false; } number = '' + number; number = number.replace(new RegExp('[^\\d]', 'gi'), ''); var lenOK = false; for (var i = 0; i < type.len.length; i++) { if (type.len[i] == number.length) { lenOK = true; break; } } if (lenOK === false) { return false; } return self.checkLuhn(number); }, checkLuhn: function(number) { /* see: http://en.wikipedia.org/wiki/Luhn */ number = '' + number; number = number.replace(new RegExp('[^\\d]', 'gi'), ''); var sum = 0; var parity = number.length % 2; var digit = 0; for (var i = 0; i < number.length; i++) { digit = parseInt(number.charAt(i)); if (i % 2 == parity) { digit = digit * 2; } if (digit > 9) { digit = digit - 9; } sum = sum + digit; } return (sum % 10) === 0; } }; /* TODO: something like doSimplePostXMLHttpRequest will be in MochiKit soon. Replace this with that function when it's there. */ /* from: http://groups.google.com/group/mochikit/msg/e3bd7456ee21bef7 */ MochiKit.Async.doSimplePostXMLHttpRequest = function (url/*, ...*/) { var self = MochiKit.Async; var req = self.getXMLHttpRequest(); if (arguments.length > 1) { var m = MochiKit.Base; var qs = m.queryString.apply(null, m.extend(null, arguments, 1)); } req.open("POST", url, true); /* taken from prototype, pretty much verbatim */ var requestHeaders = ['X-Requested-With', 'XMLHttpRequest', 'X-MochiKit-Version', MochiKit.Async.VERSION, 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*', 'Content-type', 'application/x-www-form-urlencoded']; /* Force "Connection: close" for Mozilla browsers to work around a bug where XMLHttpReqeuest sends an incorrect Content-length header. See Mozilla Bugzilla #246651. */ if (req.overrideMimeType) { requestHeaders.push('Connection', 'close'); } for (var i = 0; i < requestHeaders.length; i += 2) { req.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); } return self.sendXMLHttpRequest(req, qs); };