728 lines
24 KiB
JavaScript
728 lines
24 KiB
JavaScript
/// <reference path="jquery-1.3.2-vsdoc.js">
|
|
var needRegisterH5Exts = true;
|
|
var isAlreadyInitialized = false;
|
|
|
|
// Only register the placeholder attachment code once, regardless of include count.
|
|
// File shouldn't be included more than once, but it could happen.
|
|
if (needRegisterH5Exts) {
|
|
$(document).ready(function () {
|
|
// Register placeholder shims, if needed.
|
|
if (needPlaceHoldersShim() && !isAlreadyInitialized) {
|
|
isAlreadyInitialized = true;
|
|
|
|
// Not all INPUTs/TEXTAREAs are automatically hooked into this,
|
|
// since we have older implementations of placeholders and
|
|
// overridding them would cause wierd behavior. Plus, it
|
|
// would not make sense to hook to image/checkbox/radio/etc.
|
|
|
|
// The attribute cp5ph (CivicPlus HTML5 PlaceHolder) is automatically placed on inputs
|
|
// with placeholders through the CPHtml5TextInput() HTML extension.
|
|
registerPlaceHoldersShim($('input[cp5ph]'));
|
|
registerPlaceHoldersShim($('textarea[cp5ph]'));
|
|
}
|
|
});
|
|
|
|
needRegisterH5Exts = false;
|
|
}
|
|
|
|
// Registers placeholders on fields inside a specific context.
|
|
function registerPlaceHoldersShimOnContainer($container) {
|
|
registerPlaceHoldersShim($('input[cp5ph]', $container));
|
|
registerPlaceHoldersShim($('textarea[cp5ph]', $container));
|
|
}
|
|
|
|
// Unregisters placeholders on fields inside a specific context.
|
|
function unregisterPlaceHoldersShimOnContainer($container) {
|
|
unregisterPlaceHolderShim($('input[cp5ph]', $container));
|
|
unregisterPlaceHolderShim($('textarea[cp5ph]', $container));
|
|
}
|
|
|
|
// Determines if placeholder shim is necessary.
|
|
function needPlaceHoldersShim() {
|
|
var tmpElem = document.createElement('input');
|
|
return !('placeholder' in tmpElem);
|
|
}
|
|
|
|
// Added due to a bug with IE 10's IE 7 document standards mode. The elem.getAttribute('placeholder')
|
|
// always returns NULL if IE 10 in IE 7 document standards mode, but elem.attributes['placeholder']
|
|
// works.
|
|
function getPlaceholder(elem) {
|
|
var placeholder = elem.getAttribute('placeholder')
|
|
if (placeholder == null) {
|
|
placeholder = elem.attributes['placeholder'];
|
|
if (placeholder == null)
|
|
return '';
|
|
else
|
|
return placeholder.value;
|
|
}
|
|
return placeholder;
|
|
}
|
|
|
|
// Unregisters placeholder shim hooks. Destroys event hooks and spawned placeholder element.
|
|
function unregisterPlaceHolderShim($elemsToHack) {
|
|
// Get hooks.
|
|
var hookData = $elemsToHack.data('cp5ph_hooks');
|
|
|
|
if (hookData) {
|
|
// Destroy all the hooks present.
|
|
var attachedMSIE = hookData.ie == null ? [] : hookData.ie;
|
|
var attachedSTD = hookData.std == null ? [] : hookData.std;
|
|
var attachedJQR = hookData.jqr == null ? [] : hookData.jqr;
|
|
var spawnedPHs = hookData.spawns == null ? [] : hookData.spawns;
|
|
|
|
// Remove MSIE style events.
|
|
for (var i = 0, len = attachedMSIE.length; i < len; i++) {
|
|
if (attachedMSIE[i].element)
|
|
attachedMSIE[i].element.detachEvent(attachedMSIE[i].event, attachedMSIE[i].method);
|
|
}
|
|
|
|
// Remove DOM standard (STD) events.
|
|
for (var i = 0, len = attachedSTD.length; i < len; i++) {
|
|
if (attachedSTD[i].element)
|
|
attachedSTD[i].element.removeEventListener(attachedSTD[i].event, attachedSTD[i].method, false);
|
|
}
|
|
|
|
// Remove jQuery bindings.
|
|
for (var i = 0, len = attachedJQR.length; i < len; i++) {
|
|
if (attachedJQR[i].instance)
|
|
attachedJQR[i].instance.unbind(attachedJQR[i].event, attachedJQR[i].method);
|
|
}
|
|
|
|
// Destroy placeholder spawned elements.
|
|
for (var i = 0, len = spawnedPHs.length; i < len; i++) {
|
|
if (spawnedPHs[i]) {
|
|
spawnedPHs[i].innerHTML = "";
|
|
spawnedPHs[i].style.display = "none";
|
|
|
|
if (spawnedPHs[i].parentNode)
|
|
spawnedPHs[i].parentNode.removeChild(spawnedPHs[i]);
|
|
}
|
|
}
|
|
|
|
// Destroy hook data now that hooks have been cleaned.
|
|
$elemsToHack.removeData('cp5ph_hooks');
|
|
}
|
|
}
|
|
|
|
// Registers placeholder shims for jQuery element group specified.
|
|
// The shim is by no means perfect (won't catch things like attribute selectors causing changes).
|
|
|
|
function registerPlaceHoldersShim($elemsToHack) {
|
|
// Track standard, MSIE, and jQuery event assignments so they can be cancelled/destroyed.
|
|
// Also track any spawned placeholder elements since they too need to be cleaned up.
|
|
var attachedMSIE = [];
|
|
var attachedSTD = [];
|
|
var attachedJQR = [];
|
|
var spawnedPHs = [];
|
|
|
|
// Hooks programmatic changes to the value property for browsers without
|
|
// placeholder support. jQuery did not seem to have a way to do this.
|
|
var hookProgrammaticValueChange = function(elem, callback) {
|
|
// Note: Browsers are buggy at this time with DOMControlValueChanged.
|
|
|
|
// Handle Firefox Prior to 4 (which has built-in placeholder support).
|
|
if (elem.__defineSetter__) {
|
|
var oldSetter = elem.__lookupSetter__('value');
|
|
|
|
if (oldSetter) {
|
|
elem.__defineSetter__('value', function(v) {
|
|
oldSetter.call(elem, v);
|
|
callback();
|
|
});
|
|
}
|
|
}
|
|
|
|
// Handle IE, even up to IE 9.
|
|
if (elem.attachEvent) {
|
|
attachedMSIE.push({ element: elem, event: 'onpropertychange', method: callback });
|
|
elem.attachEvent('onpropertychange', callback);
|
|
}
|
|
};
|
|
|
|
var displayAttrMatch = new RegExp('^(class|value|className|placeholder|id|style|style\\..*)$');
|
|
|
|
// Hooks display changes for an element (placeholder may need to update itself).
|
|
var hookDisplayUpdates = function(elem, callback) {
|
|
if (elem.addEventListener) {
|
|
var domAttrModifiedHook = function(event) {
|
|
// Prevents an infinite loop due to bubbling.
|
|
event.stopPropagation();
|
|
|
|
// Another necessary escape hatch.
|
|
if (event.target.className == '_ph_shim')
|
|
return;
|
|
|
|
if (displayAttrMatch.test(event.attrName))
|
|
callback(event.attrName);
|
|
};
|
|
|
|
attachedSTD.push({ element: elem, event: 'DOMAttrModified', method: domAttrModifiedHook });
|
|
elem.addEventListener('DOMAttrModified', domAttrModifiedHook, false);
|
|
} else if (elem.attachEvent) {
|
|
var propertyChangeHook = function(event) {
|
|
if (displayAttrMatch.test(event.propertyName))
|
|
callback(event.propertyName);
|
|
};
|
|
|
|
attachedMSIE.push({ element: elem, event: 'onpropertychange', method: propertyChangeHook });
|
|
elem.attachEvent('onpropertychange', propertyChangeHook);
|
|
}
|
|
};
|
|
|
|
// Hooks display changes for an element or its parents.
|
|
var hookDisplayUpdatesAndParents = function(elem, callback) {
|
|
var node = elem;
|
|
|
|
while (node && node != document.body) {
|
|
hookDisplayUpdates(node, callback);
|
|
|
|
node = node.parentNode;
|
|
}
|
|
};
|
|
|
|
// Debouncer used to prevent the same placeholder updates from ocuring over and over again within a short time (30 ms).
|
|
var debouncer = [];
|
|
var isBouncy = function(element) {
|
|
var now = function() {
|
|
return new Date().getTime();
|
|
};
|
|
var getIndexOf = function(elem) {
|
|
for (var i = 0; i < debouncer.length; i++) {
|
|
if (debouncer[i].object === element) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
var index = getIndexOf(element);
|
|
if (index === -1) {
|
|
var obj = { object: element, recentlyOccured: true };
|
|
debouncer.push(obj);
|
|
setTimeout(function () {
|
|
obj.recentlyOccured = false;
|
|
}
|
|
,30);
|
|
return false;
|
|
} else if (debouncer[index].recentlyOccured) {
|
|
return true;
|
|
} else {
|
|
debouncer[index].recentlyOccured = true;
|
|
setTimeout(function () {
|
|
debouncer[index].recentlyOccured = false;
|
|
}
|
|
, 30);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Updates position/style of pseudo-element that acts as placeholder message.
|
|
// Called when necessary to ensure placeholder looks right (e.g. styles changed).
|
|
var updatePlaceHolderMessageElement = function (phElem, elem) {
|
|
var $elem = $(elem);
|
|
if (isBouncy(elem)) {
|
|
return;
|
|
}
|
|
|
|
// TODO: Does $elem.is() not work if the element is not in the document?
|
|
if (elem.parentNode != null && !elem._focus && $elem.is(':visible'))
|
|
phElem.style.display = (elem.value == '' || elem.value == null ? 'block' : 'none');
|
|
else {
|
|
phElem.style.display = 'none';
|
|
return;
|
|
}
|
|
|
|
// Determine where placeholder element should go.
|
|
var shouldParent = $elem.offsetParent().get(0);
|
|
|
|
// Placeholder element cannot go inside table rows, use cell instead.
|
|
if (shouldParent.tagName == 'TR') {
|
|
shouldParent = elem;
|
|
|
|
while (shouldParent.tagName != 'TD')
|
|
shouldParent = shouldParent.parentNode;
|
|
}
|
|
|
|
var phChanged = (phElem.getAttribute('_ph_val') != getPlaceholder(elem));
|
|
|
|
if ((shouldParent != phElem.parentNode) || phChanged) {
|
|
// Remove from old parent (or existing, if phChanged).
|
|
// Necessary for phChanged since element may be inside a table,
|
|
// and trying to set innerHTML in a table with IE causes trouble.
|
|
phElem.parentNode.removeChild(phElem);
|
|
|
|
// If placeholder changed, update innerHTML.
|
|
if (phChanged)
|
|
phElem.innerHTML = getPlaceholder(elem);
|
|
|
|
// Ensure pseudo-placeholder is placed in same offsetParent
|
|
// that element resides within (positioning), and add it to
|
|
// the end (resolves some possible z-index issues).
|
|
shouldParent.appendChild(phElem);
|
|
}
|
|
|
|
phElem.style.width = elem.clientWidth + 'px';
|
|
phElem.style.height = elem.clientHeight + 'px';
|
|
phElem.style.verticalAlign = elem.style.verticalAlign;
|
|
phElem.style.lineHeight = elem.style.lineHeight;
|
|
phElem.style.textAlign = elem.style.textAlign;
|
|
phElem.style.fontSize = elem.style.fontSize;
|
|
phElem.style.fontFamily = elem.style.fontFamily;
|
|
|
|
var compStyle = (window.getComputedStyle ? window.getComputedStyle(elem, null) : elem.currentStyle);
|
|
var elemPaddingLeft = parseInt(compStyle.paddingLeft.replace(/px$/g, ''), 10);
|
|
var elemPaddingTop = parseInt(compStyle.paddingTop.replace(/px$/g, ''), 10);
|
|
var pos = $elem.position();
|
|
|
|
phElem.style.top = (pos.top + elem.clientTop + elemPaddingTop - 2) + 'px';
|
|
phElem.style.left = (pos.left + elem.clientLeft + elemPaddingLeft) + 'px';
|
|
}
|
|
|
|
// Creates pseudo-element that acts as placeholder message.
|
|
var createPlaceHolderMessageElement = function(elem) {
|
|
// Create pseudo-placeholder that will appear over the top of the control.
|
|
var phElem = document.createElement('div');
|
|
|
|
// Attach to element for reference.
|
|
elem._ph_shim = phElem;
|
|
|
|
// Ensure pseudo-placeholder is placed in same offsetParent
|
|
// that element resides within (positioning), and add it to
|
|
// the end (resolves some possible z-index issues).
|
|
var phValue = getPlaceholder(elem);
|
|
phElem.innerHTML = (phValue == null ? '' : phValue);
|
|
phElem.setAttribute('_ph_val', 'phValue');
|
|
|
|
phElem.setAttribute('id', 'ph_' + elem.id);
|
|
phElem.setAttribute('name', 'ph_' + elem.id);
|
|
|
|
var shouldParent = $(elem).offsetParent().get(0);
|
|
shouldParent.appendChild(phElem);
|
|
|
|
// Configure the pseudo-placeholder.
|
|
phElem.className = '_ph_shim';
|
|
phElem.style.position = 'absolute';
|
|
phElem.style.color = '#aaa'; // Placeholder Text Color.
|
|
phElem.style.backgroundColor = 'transparent';
|
|
phElem.style.cssFloat = 'none';
|
|
|
|
// Update appearance.
|
|
updatePlaceHolderMessageElement(phElem, elem);
|
|
|
|
// Set up events for pseudo-placeholder and element.
|
|
var $phElem = $(phElem);
|
|
|
|
var mouseDownHook = function(event) {
|
|
phElem.style.display = 'none';
|
|
|
|
// Mouse down is passed to the input control
|
|
// the placeholder is shown on top of.
|
|
$(elem).trigger('mousedown', event);
|
|
|
|
// Hack: IE needs setTimeout to actually do this properly for TEXTAREA.
|
|
setTimeout(function() {
|
|
try {
|
|
elem.focus()
|
|
} catch(err) {
|
|
//When the text box is readonly then the above focus code would throw error
|
|
//so that error is only handled only for Center, if u happen to get this error please do ur implemntation below
|
|
//NOTE: here we have checked only for /formcenter and so if there is any other place which uses readonly textbox and trys to focus also will get the same alert - This is known bug
|
|
//for DEtails talk to Akila or Robin - AK
|
|
|
|
//**Please note the use of lowercase here**
|
|
var url = (location.href).toLowerCase();
|
|
|
|
if (url.indexOf("/admin/formcenter") > -1) {
|
|
alert('You have selected the field input. Please select the field label or instructions.');
|
|
}
|
|
}
|
|
}, 15);
|
|
};
|
|
|
|
$phElem.mousedown(mouseDownHook);
|
|
|
|
attachedJQR.push({ instance: $phElem, event: 'mousedown', method: mouseDownHook });
|
|
|
|
return phElem;
|
|
};
|
|
|
|
// Registers a shim placeholder for an element (private helper method).
|
|
var registerPlaceHolder = function (elem) {
|
|
// Create jQuery wrapper.
|
|
var $elem = $(elem);
|
|
|
|
// Create placeholder.
|
|
var phElem = createPlaceHolderMessageElement(elem);
|
|
|
|
// Track creation.
|
|
spawnedPHs.push(phElem);
|
|
|
|
var focusHook = function () {
|
|
// Older firefox does not support document.activeElement.
|
|
elem._focus = true;
|
|
|
|
phElem.style.display = 'none';
|
|
};
|
|
|
|
var blurHook = function () {
|
|
// Older firefox does not support document.activeElement.
|
|
elem._focus = false;
|
|
|
|
if ((elem.value == '' || elem.value == null) && $(elem).is(':visible'))
|
|
phElem.style.display = 'block';
|
|
};
|
|
|
|
$elem.focus(focusHook);
|
|
$elem.blur(blurHook);
|
|
|
|
attachedJQR.push({ instance: $elem, event: 'focus', method: focusHook });
|
|
attachedJQR.push({ instance: $elem, event: 'blur', method: blurHook });
|
|
|
|
// Ensure placeholder state is updated when the value
|
|
// is changed programmatically.
|
|
hookProgrammaticValueChange(elem, function () {
|
|
if (elem._focus)
|
|
phElem.style.display = 'none';
|
|
else {
|
|
if ((elem.value == '' || elem.value == null) && $(elem).is(':visible'))
|
|
phElem.style.display = 'block';
|
|
else
|
|
phElem.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Ensure placeholder UI updates correctly when display changes are made.
|
|
hookDisplayUpdatesAndParents(elem, function () {
|
|
updatePlaceHolderMessageElement(phElem, elem);
|
|
});
|
|
};
|
|
|
|
// Attach shim to each wrapped element passed to the method.
|
|
$elemsToHack.each(function () {
|
|
registerPlaceHolder(this);
|
|
});
|
|
|
|
// Keep track of hooks so they can be destroyed.
|
|
$elemsToHack.data('cp5ph_hooks', {
|
|
ie: attachedMSIE,
|
|
std: attachedSTD,
|
|
jqr: attachedJQR,
|
|
spawns: spawnedPHs
|
|
});
|
|
}
|
|
|
|
|
|
// Unregisters placeholder shim hooks. Destroys event hooks and spawned placeholder element.
|
|
function unregisterPlaceHoldersShimForEach($elemsToHack) {
|
|
// Get hooks.
|
|
$elemsToHack.each(function () {
|
|
var hookData = $(this).data('cp5ph_hooks');
|
|
|
|
if (hookData) {
|
|
// Destroy all the hooks present.
|
|
var attachedMSIE = hookData.ie == null ? [] : hookData.ie;
|
|
var attachedSTD = hookData.std == null ? [] : hookData.std;
|
|
var attachedJQR = hookData.jqr == null ? [] : hookData.jqr;
|
|
var spawnedPHs = hookData.spawns == null ? [] : hookData.spawns;
|
|
|
|
// Remove MSIE style events.
|
|
for (var i = 0, len = attachedMSIE.length; i < len; i++) {
|
|
if (attachedMSIE[i].element)
|
|
attachedMSIE[i].element.detachEvent(attachedMSIE[i].event, attachedMSIE[i].method);
|
|
}
|
|
|
|
// Remove DOM standard (STD) events.
|
|
for (var i = 0, len = attachedSTD.length; i < len; i++) {
|
|
if (attachedSTD[i].element)
|
|
attachedSTD[i].element.removeEventListener(attachedSTD[i].event, attachedSTD[i].method, false);
|
|
}
|
|
|
|
// Remove jQuery bindings.
|
|
for (var i = 0, len = attachedJQR.length; i < len; i++) {
|
|
if (attachedJQR[i].instance)
|
|
attachedJQR[i].instance.unbind(attachedJQR[i].event, attachedJQR[i].method);
|
|
}
|
|
|
|
// Destroy placeholder spawned elements.
|
|
for (var i = 0, len = spawnedPHs.length; i < len; i++) {
|
|
if (spawnedPHs[i]) {
|
|
spawnedPHs[i].innerHTML = "";
|
|
spawnedPHs[i].style.display = "none";
|
|
|
|
if (spawnedPHs[i].parentNode)
|
|
spawnedPHs[i].parentNode.removeChild(spawnedPHs[i]);
|
|
}
|
|
}
|
|
|
|
// Destroy hook data now that hooks have been cleaned.
|
|
$(this).removeData('cp5ph_hooks');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Registers placeholder shims for jQuery element group specified.
|
|
// The shim is by no means perfect (won't catch things like attribute selectors causing changes).
|
|
function registerPlaceHoldersShimForEach($elemsToHack) {
|
|
// Track standard, MSIE, and jQuery event assignments so they can be cancelled/destroyed.
|
|
// Also track any spawned placeholder elements since they too need to be cleaned up.
|
|
var attachedMSIE = [];
|
|
var attachedSTD = [];
|
|
var attachedJQR = [];
|
|
var spawnedPHs = [];
|
|
|
|
// Hooks programmatic changes to the value property for browsers without
|
|
// placeholder support. jQuery did not seem to have a way to do this.
|
|
var hookProgrammaticValueChange = function (elem, callback) {
|
|
// Note: Browsers are buggy at this time with DOMControlValueChanged.
|
|
|
|
// Handle Firefox Prior to 4 (which has built-in placeholder support).
|
|
if (elem.__defineSetter__) {
|
|
var oldSetter = elem.__lookupSetter__('value');
|
|
|
|
if (oldSetter) {
|
|
elem.__defineSetter__('value', function (v) {
|
|
oldSetter.call(elem, v);
|
|
callback();
|
|
});
|
|
}
|
|
}
|
|
|
|
// Handle IE, even up to IE 9.
|
|
if (elem.attachEvent) {
|
|
attachedMSIE.push({ element: elem, event: 'onpropertychange', method: callback });
|
|
elem.attachEvent('onpropertychange', callback);
|
|
}
|
|
};
|
|
|
|
var displayAttrMatch = new RegExp('^(class|value|className|placeholder|id|style|style\\..*)$');
|
|
|
|
// Hooks display changes for an element (placeholder may need to update itself).
|
|
var hookDisplayUpdates = function (elem, callback) {
|
|
if (elem.addEventListener) {
|
|
var domAttrModifiedHook = function (event) {
|
|
// Prevents an infinite loop due to bubbling.
|
|
event.stopPropagation();
|
|
|
|
// Another necessary escape hatch.
|
|
if (event.target.className == '_ph_shim')
|
|
return;
|
|
|
|
if (displayAttrMatch.test(event.attrName))
|
|
callback(event.attrName);
|
|
};
|
|
|
|
attachedSTD.push({ element: elem, event: 'DOMAttrModified', method: domAttrModifiedHook });
|
|
elem.addEventListener('DOMAttrModified', domAttrModifiedHook, false);
|
|
}
|
|
else if (elem.attachEvent) {
|
|
var propertyChangeHook = function (event) {
|
|
if (displayAttrMatch.test(event.propertyName))
|
|
callback(event.propertyName);
|
|
};
|
|
|
|
attachedMSIE.push({ element: elem, event: 'onpropertychange', method: propertyChangeHook });
|
|
elem.attachEvent('onpropertychange', propertyChangeHook);
|
|
}
|
|
};
|
|
|
|
// Hooks display changes for an element or its parents.
|
|
var hookDisplayUpdatesAndParents = function (elem, callback) {
|
|
var node = elem;
|
|
|
|
while (node && node != document.body) {
|
|
hookDisplayUpdates(node, callback);
|
|
|
|
node = node.parentNode;
|
|
}
|
|
};
|
|
|
|
// Updates position/style of pseudo-element that acts as placeholder message.
|
|
// Called when necessary to ensure placeholder looks right (e.g. styles changed).
|
|
var updatePlaceHolderMessageElement = function (phElem, elem) {
|
|
var $elem = $(elem);
|
|
|
|
// TODO: Does $elem.is() not work if the element is not in the document?
|
|
if (elem.parentNode != null && !elem._focus && $elem.is(':visible'))
|
|
phElem.style.display = (elem.value == '' || elem.value == null ? 'block' : 'none');
|
|
else {
|
|
phElem.style.display = 'none';
|
|
return;
|
|
}
|
|
|
|
// Determine where placeholder element should go.
|
|
var shouldParent = $elem.offsetParent().get(0);
|
|
|
|
// Placeholder element cannot go inside table rows, use cell instead.
|
|
if (shouldParent.tagName == 'TR') {
|
|
shouldParent = elem;
|
|
|
|
while (shouldParent.tagName != 'TD')
|
|
shouldParent = shouldParent.parentNode;
|
|
}
|
|
|
|
var phChanged = (phElem.getAttribute('_ph_val') != getPlaceholder(elem));
|
|
|
|
if ((shouldParent != phElem.parentNode) || phChanged) {
|
|
// Remove from old parent (or existing, if phChanged).
|
|
// Necessary for phChanged since element may be inside a table,
|
|
// and trying to set innerHTML in a table with IE causes trouble.
|
|
phElem.parentNode.removeChild(phElem);
|
|
|
|
// If placeholder changed, update innerHTML.
|
|
if (phChanged)
|
|
phElem.innerHTML = getPlaceholder(elem);
|
|
|
|
// Ensure pseudo-placeholder is placed in same offsetParent
|
|
// that element resides within (positioning), and add it to
|
|
// the end (resolves some possible z-index issues).
|
|
shouldParent.appendChild(phElem);
|
|
}
|
|
|
|
phElem.style.width = elem.clientWidth + 'px';
|
|
phElem.style.height = elem.clientHeight + 'px';
|
|
phElem.style.verticalAlign = elem.style.verticalAlign;
|
|
phElem.style.lineHeight = elem.style.lineHeight;
|
|
phElem.style.textAlign = elem.style.textAlign;
|
|
phElem.style.fontSize = elem.style.fontSize;
|
|
phElem.style.fontFamily = elem.style.fontFamily;
|
|
|
|
var compStyle = (window.getComputedStyle ? window.getComputedStyle(elem, null) : elem.currentStyle);
|
|
var elemPaddingLeft = parseInt(compStyle.paddingLeft.replace(/px$/g, ''), 10);
|
|
var elemPaddingTop = parseInt(compStyle.paddingTop.replace(/px$/g, ''), 10);
|
|
var pos = $elem.position();
|
|
|
|
phElem.style.top = (pos.top + elem.clientTop + elemPaddingTop - 2) + 'px';
|
|
phElem.style.left = (pos.left + elem.clientLeft + elemPaddingLeft) + 'px';
|
|
}
|
|
|
|
// Creates pseudo-element that acts as placeholder message.
|
|
var createPlaceHolderMessageElement = function (elem) {
|
|
// Create pseudo-placeholder that will appear over the top of the control.
|
|
var phElem = document.createElement('div');
|
|
|
|
// Attach to element for reference.
|
|
elem._ph_shim = phElem;
|
|
|
|
// Ensure pseudo-placeholder is placed in same offsetParent
|
|
// that element resides within (positioning), and add it to
|
|
// the end (resolves some possible z-index issues).
|
|
var phValue = getPlaceholder(elem);
|
|
phElem.innerHTML = (phValue == null ? '' : phValue);
|
|
phElem.setAttribute('_ph_val', 'phValue');
|
|
|
|
phElem.setAttribute('id', 'ph_' + elem.id);
|
|
phElem.setAttribute('name', 'ph_' + elem.id);
|
|
|
|
var shouldParent = $(elem).offsetParent().get(0);
|
|
shouldParent.appendChild(phElem);
|
|
|
|
// Configure the pseudo-placeholder.
|
|
phElem.className = '_ph_shim';
|
|
phElem.style.position = 'absolute';
|
|
phElem.style.color = '#aaa'; // Placeholder Text Color.
|
|
phElem.style.backgroundColor = 'transparent';
|
|
phElem.style.cssFloat = 'none';
|
|
|
|
// Update appearance.
|
|
updatePlaceHolderMessageElement(phElem, elem);
|
|
|
|
// Set up events for pseudo-placeholder and element.
|
|
var $phElem = $(phElem);
|
|
|
|
var mouseDownHook = function (event) {
|
|
phElem.style.display = 'none';
|
|
|
|
// Mouse down is passed to the input control
|
|
// the placeholder is shown on top of.
|
|
$(elem).trigger('mousedown', event);
|
|
|
|
// Hack: IE needs setTimeout to actually do this properly for TEXTAREA.
|
|
setTimeout(function () {
|
|
try { elem.focus() } catch (err) {
|
|
//When the text box is readonly then the above focus code would throw error
|
|
//so that error is only handled only for Center, if u happen to get this error please do ur implemntation below
|
|
//NOTE: here we have checked only for /formcenter and so if there is any other place which uses readonly textbox and trys to focus also will get the same alert - This is known bug
|
|
//for DEtails talk to Akila or Robin - AK
|
|
|
|
//**Please note the use of lowercase here**
|
|
var url = (location.href).toLowerCase();
|
|
|
|
if (url.indexOf("/admin/formcenter") > -1) {
|
|
alert('You have selected the field input. Please select the field label or instructions.');
|
|
}
|
|
}
|
|
}, 15);
|
|
};
|
|
|
|
$phElem.mousedown(mouseDownHook);
|
|
|
|
attachedJQR.push({ instance: $phElem, event: 'mousedown', method: mouseDownHook });
|
|
|
|
return phElem;
|
|
}
|
|
|
|
// Registers a shim placeholder for an element (private helper method).
|
|
var registerPlaceHolder = function (elem) {
|
|
// Create jQuery wrapper.
|
|
var $elem = $(elem);
|
|
|
|
// Create placeholder.
|
|
var phElem = createPlaceHolderMessageElement(elem);
|
|
|
|
// Track creation.
|
|
spawnedPHs.push(phElem);
|
|
|
|
var focusHook = function () {
|
|
// Older firefox does not support document.activeElement.
|
|
elem._focus = true;
|
|
|
|
phElem.style.display = 'none';
|
|
};
|
|
|
|
var blurHook = function () {
|
|
// Older firefox does not support document.activeElement.
|
|
elem._focus = false;
|
|
|
|
if ((elem.value == '' || elem.value == null) && $(elem).is(':visible'))
|
|
phElem.style.display = 'block';
|
|
};
|
|
|
|
$elem.focus(focusHook);
|
|
$elem.blur(blurHook);
|
|
|
|
attachedJQR.push({ instance: $elem, event: 'focus', method: focusHook });
|
|
attachedJQR.push({ instance: $elem, event: 'blur', method: blurHook });
|
|
|
|
// Ensure placeholder state is updated when the value
|
|
// is changed programmatically.
|
|
hookProgrammaticValueChange(elem, function () {
|
|
if (elem._focus)
|
|
phElem.style.display = 'none';
|
|
else {
|
|
if ((elem.value == '' || elem.value == null) && $(elem).is(':visible'))
|
|
phElem.style.display = 'block';
|
|
else
|
|
phElem.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Ensure placeholder UI updates correctly when display changes are made.
|
|
hookDisplayUpdatesAndParents(elem, function () {
|
|
updatePlaceHolderMessageElement(phElem, elem);
|
|
});
|
|
};
|
|
|
|
// Attach shim to each wrapped element passed to the method.
|
|
$elemsToHack.each(function () {
|
|
registerPlaceHolder(this);
|
|
});
|
|
|
|
// Keep track of hooks so they can be destroyed.
|
|
$elemsToHack.each(function() {
|
|
$(this).data('cp5ph_hooks', {
|
|
ie: attachedMSIE,
|
|
std: attachedSTD,
|
|
jqr: attachedJQR,
|
|
spawns: spawnedPHs
|
|
});
|
|
});
|
|
} |