/SPUtility.js
http://sputility.codeplex.com · JavaScript · 1235 lines · 879 code · 167 blank · 189 comment · 146 complexity · b121bff26cb367d30a057136ce4b14cb MD5 · raw file
- /*
- Name: SPUtility.js
- Version: 0.8.1
- Description:
- A JavaScript library that is used to alter SharePoint's user interface
- (mostly NewForm and EditForm). It can be used to populate fields, make
- fields read only, or hide a field from view.
- Author: Kit Menke
- http://SPUtility.codeplex.com/
- License: Microsoft Public License (see http://sputility.codeplex.com/license)
- Changelog: http://sputility.codeplex.com/wikipage?title=Changelog
- */
-
- /*jslint white: true, browser: true, devel: true, onevar: true, undef: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, indent: 3 */
- /*global Element: false, Class: false, $: false, $$: false, $A: false, Hash: false, Event: false, Prototype: false, $break: false, $H: false, RTE_GetIFrameContents: false, RTE_TransferTextAreaContentsToIFrame: false, RTE_GetEditorIFrame: false */
-
-
- // getTextContent credit to Dan Dean
- // http://dandean.com/category/code/2009/hatin-on-textcontent-and-innertext/
- Element.addMethods({
- /**
- * Element#getTextContent(@element) -> String
- * Cross-browser means of getting Element#textContent or Element#innerText
- **/
- getTextContent: function (element) {
- if (!Object.isUndefined(element.textContent)) {
- return element.textContent;
- }
- return element.innerText;
- },
-
- setTextContent: function (element, value) {
- if (!Object.isUndefined(element.textContent)) {
- element.textContent = value;
- }
- element.innerText = value;
- }
- });
-
- //+ Jonas Raoni Soares Silva
- //@ http://jsfromhell.com/number/fmt-money [rev. #2]
- // Modified to pass JSLint
- // c = # of floating point decimal places
- // d = decimal separator
- // t = thousands separator
- Number.prototype.formatMoney = function (c, d, t) {
- c = (isNaN(c = Math.abs(c)) ? 2 : c);
- d = (d === undefined ? "." : d);
- t = (t === undefined ? "," : t);
- var n = this,
- s = (n < 0 ? "-" : ""),
- i = parseInt(n = Math.abs(+n || 0).toFixed(c), 10) + "",
- j = (j = i.length) > 3 ? j % 3 : 0;
- return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
- };
-
- /*
- * SPUtility namespace
- */
- var SPUtility = (function () {
- "use strict";
-
- /*
- * SPUtility Private Variables
- **/
-
- var SPField, SPTextField, SPUserField, SPURLField, SPChoiceField,
- SPDateTimeField, SPDateTimeFieldValue, SPFileField, SPCurrencyField,
- SPNumberField, SPBooleanField, SPNoteField, SPLookupField, SPLookupMultiField,
- _fieldsHashtable = null,
- _debugMode = false,
- _isSurveyForm = false,
- _numErrors = 0;
-
- /*
- * SPUtility Private Methods
- **/
-
- function log(message, exception) {
- var property;
- try {
- if (!_debugMode) {
- return;
- }
- if (exception) {
- message += '\r\n';
- for (property in exception) {
- if (exception.hasOwnProperty(property)) {
- message += property + ': ' + exception[property] + '\r\n';
- }
- }
- }
- if (Prototype.Browser.IE || Object.isUndefined(console)) {
- _numErrors += 1;
- if (_numErrors === 3) {
- message = "More than 3 errors (additional errors will not be shown):\r\n" + message;
- }
- if (_numErrors <= 3) {
- alert(message);
- }
- } else {
- console.error(message);
- }
- } catch (ex) { }
- }
-
- function convertStringToNumber(val) {
- if (typeof val === "string") {
- var match = val.match(/[0-9,.]+/g);
- if (null !== match) {
- val = match[0].replace(/,/g, ''); // commas to delimit thousands need to be removed
- val = parseFloat(val);
- }
- }
- return val;
- }
-
- // Gets the input controls for a field (used for Textboxes)
- function getInputControl(spField) {
- var controls = spField.Controls.select('input');
- if (null !== controls && 1 === controls.length) {
- return controls[0];
- }
-
- throw 'Unable to retrieve the input control for ' + spField.Name;
- }
-
- function getHashFromInputControls(spField, selector) {
- var oHash = null, inputTags = spField.Controls.select(selector), inputLabel, key;
- if (null !== inputTags && inputTags.length > 0) {
- oHash = new Hash();
-
- inputTags.each(function (elem) {
- inputLabel = elem.next(0);
- if (!Object.isUndefined(inputLabel)) {
- key = inputLabel.getTextContent();
- oHash.set(key, elem);
- }
- });
- }
- return oHash;
- }
-
- function getSPFieldType(element) {
- var matches, comment, n;
- try {
- // find the HTML comment and get the field's type
- for (n = 0; n < element.childNodes.length; n += 1) {
- if (8 === element.childNodes[n].nodeType) {
- comment = element.childNodes[n].data;
- matches = comment.match(/SPField\w+/);
- if (null !== matches) {
- return matches[0];
- }
- break;
- }
- }
- } catch (ex) {
- log('getSPFieldType: Error getting field type', ex);
- }
- return null;
- }
-
- function getSPFieldFromType(spFieldParams) {
- var field = null;
-
- switch (spFieldParams.type) {
- case 'SPFieldText':
- field = new SPTextField(spFieldParams);
- break;
- case 'SPFieldNote':
- field = new SPNoteField(spFieldParams);
- break;
- case 'SPFieldBoolean':
- field = new SPBooleanField(spFieldParams);
- break;
- case 'SPFieldNumber':
- field = new SPNumberField(spFieldParams);
- break;
- case 'SPFieldCurrency':
- field = new SPCurrencyField(spFieldParams);
- break;
- case 'SPFieldFile':
- field = new SPFileField(spFieldParams);
- break;
- case 'SPFieldDateTime':
- field = new SPDateTimeField(spFieldParams);
- break;
- case 'SPFieldChoice':
- case 'SPFieldMultiChoice':
- field = new SPChoiceField(spFieldParams);
- break;
- case 'SPFieldURL':
- field = new SPURLField(spFieldParams);
- break;
- case 'SPFieldUser':
- case 'SPFieldUserMulti':
- field = new SPUserField(spFieldParams);
- break;
- case 'SPFieldLookup':
- field = new SPLookupField(spFieldParams);
- break;
- case 'SPFieldLookupMulti':
- field = new SPLookupMultiField(spFieldParams);
- break;
- default:
- field = new SPField(spFieldParams);
- break;
- }
- return field;
- }
-
- function createSPField(spFieldParams) {
- var field = null;
- try {
- if (null === spFieldParams.controlsCell) {
- // the only time this property will NOT be null is in survey forms
- spFieldParams.controlsCell = spFieldParams.labelCell.next();
- // use nextSibling?
- }
- spFieldParams.type = getSPFieldType(spFieldParams.controlsCell);
-
- // if we can't get the type then we can't create the field
- if (null === spFieldParams.type) {
- return null;
- }
-
- field = getSPFieldFromType(spFieldParams);
- } catch (e) {
- log('createSPField: Error creating field for ' + spFieldParams.name, e);
- }
- return field;
- }
-
- function getFieldParams(elemTD, surveyElemTD, isSurveyForm) {
- var fieldParams = null, fieldName = 'Unknown field', elemLabel, isRequired;
- try {
- if (isSurveyForm) {
- elemLabel = elemTD;
- } else {
- // navigate TD -> ??
- elemLabel = elemTD.firstDescendant();
- if (null === elemLabel || elemLabel.nodeName === 'NOBR') {
- return null; // attachments row not currently supported
- }
- }
-
- fieldName = (elemLabel.getTextContent()).strip();
- isRequired = fieldName.endsWith(' *');
-
- if (true === isRequired) {
- fieldName = fieldName.substring(0, fieldName.length - 2);
- }
-
- fieldParams = {
- 'name': fieldName,
- 'label': $(elemLabel),
- 'labelRow': $(elemTD.parentNode),
- 'labelCell': elemTD,
- 'isRequired': isRequired,
- 'controlsRow': Object.isUndefined(surveyElemTD) ? null : $(surveyElemTD.parentNode),
- 'controlsCell': Object.isUndefined(surveyElemTD) ? null : surveyElemTD,
- 'type': null,
- 'spField': null
- };
- } catch (e) {
- log('getFieldParams: Error getting field parameters ' + fieldName, e);
- }
- return fieldParams;
- }
-
- function lazyLoadSPFields() {
- if (null === _fieldsHashtable) {
- var i, fieldParams,
- fieldElements = $$('table.ms-formtable td.ms-formlabel'),
- surveyElements = $$('table.ms-formtable td.ms-formbodysurvey'),
- len = fieldElements.length;
-
- _isSurveyForm = (surveyElements.length > 0);
- _fieldsHashtable = new Hash();
-
- for (i = 0; i < len; i += 1) {
- fieldParams = getFieldParams(fieldElements[i], surveyElements[i], _isSurveyForm);
- if (null !== fieldParams) {
- _fieldsHashtable.set(fieldParams.name, fieldParams);
- }
- }
- }
- }
-
- function toggleSPFieldRows(labelRow, controlsRow, bShowField) {
- // controlsRow is populated on survey forms (null otherwise)
- if (bShowField) {
- labelRow.show();
- if (null !== controlsRow) {
- controlsRow.show();
- }
- } else {
- labelRow.hide();
- if (null !== controlsRow) {
- controlsRow.hide();
- }
- }
- }
-
- function toggleSPField(strFieldName, bShowField) {
- lazyLoadSPFields();
-
- var fieldParams = _fieldsHashtable.get(strFieldName);
-
- if (Object.isUndefined(fieldParams)) {
- log('toggleSPField: Unable to find a SPField named ' + strFieldName + ' - ' + bShowField);
- return;
- }
-
- toggleSPFieldRows(fieldParams.labelRow, fieldParams.controlsRow, bShowField);
- }
-
- function updateReadOnlyLabel(spField, value) {
- if (spField.ReadOnlyLabel) {
- spField.ReadOnlyLabel.update(spField.GetValue());
- }
- }
-
- function makeReadOnly(spField, htmlToInsert) {
- try {
- Element.hide(spField.Controls);
- if (null === spField.ReadOnlyLabel) {
- spField.ReadOnlyLabel = new Element('div');
- spField.ReadOnlyLabel.addClassName('sputility-readonly');
- Element.insert(spField.Controls, { after: spField.ReadOnlyLabel });
- }
- spField.ReadOnlyLabel.update(htmlToInsert);
- spField.ReadOnlyLabel.show();
- } catch (ex) {
- alert('Error making ' + spField.Name + ' read only. ' + ex.toString());
- }
- return spField;
- }
-
- function arrayToSemicolonList(arr) {
- var text = '';
-
- arr.each(function (value) {
- text += value + '; ';
- });
-
- if (text.length > 2) {
- text = text.substring(0, text.length - 2);
- }
-
- return text;
- }
-
- /*
- * SPUtility Classes
- **/
-
- /*
- * SPField class
- * Contains all of the common properties and functions used by the specialized
- * sub-classes. Typically, this should not be intantiated directly.
- */
- SPField = Class.create({
- initialize: function (fieldParams) {
- // Public Properties
- this.Label = fieldParams.label;
- this.LabelRow = fieldParams.labelRow;
- this.Name = fieldParams.name;
- this.IsRequired = fieldParams.isRequired;
- this.Type = fieldParams.type;
- this.Controls = fieldParams.controlsCell.firstDescendant();
- this.ControlsRow = fieldParams.controlsRow;
- this.ReadOnlyLabel = null;
- },
-
- /*
- * Public SPField Methods
- */
- Show: function () {
- toggleSPFieldRows(this.LabelRow, this.ControlsRow, true);
- return this;
- },
-
- Hide: function () {
- toggleSPFieldRows(this.LabelRow, this.ControlsRow, false);
- return this;
- },
-
- MakeReadOnly: function () {
- return makeReadOnly(this, this.GetValue().toString());
- },
-
- MakeEditable: function () {
- try {
- Element.show(this.Controls);
- if (null !== this.ReadOnlyLabel) {
- this.ReadOnlyLabel.hide();
- }
- } catch (ex) {
- alert('Error making ' + this.Name + ' editable. ' + ex.toString());
- }
- return this;
- },
-
- toString: function () {
- return this.Name;
- },
-
- /*
- * Public SPField Override Methods
- * All of the below methods need to be implemented in each sub-class
- */
- GetValue: function () {
- throw 'GetValue not yet implemented for ' + this.Type + ' in ' + this.Name;
- },
-
- SetValue: function (value) {
- throw 'SetValue not yet implemented for ' + this.Type + ' in ' + this.Name;
- }
- });
-
- /*
- * SPTextField class
- * Supports Single line of text and Currency fields (base class for number fields)
- */
- SPTextField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- this.Textbox = getInputControl(this);
- },
-
- /*
- * SPTextField Public Methods
- * Overrides SPField class methods.
- */
- GetValue: function () {
- return this.Textbox.getValue();
- },
-
- SetValue: function (value) {
- this.Textbox.setValue(value);
- updateReadOnlyLabel(this);
- return this;
- }
- });
-
- /*
- * SPLookupField class
- * Supports single select lookup fields
- */
- SPLookupField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- var controls = this.Controls.select('input');
- if (1 === controls.length) {
- // autocomplete lookup
- this.Textbox = controls[0];
-
- this.GetValue = function () {
- return this.Textbox.getValue();
- };
-
- this.SetValue = function (value) {
- var choices, hash;
-
- if (Object.isNumber(value)) {
- // a list item ID was passed to the function so attempt to lookup the text value
- choices = this.Textbox.readAttribute('choices');
- hash = new Hash();
- // JSLint error here but not much I can do...
- choices.scan(/(([^\|]|\|\|)+)\|(\d+)/, function (match) {
- hash.set(match[3], match[1].replace(/\|\|/g, '|'));
- });
-
- this.Textbox.setValue(hash.get(value.toString()));
- } else {
- this.Textbox.setValue(value);
- }
-
- updateReadOnlyLabel(this);
- return this;
- };
-
- } else {
- controls = this.Controls.select('select');
- if (1 === controls.length) {
- // regular dropdown lookup
- this.Dropdown = controls[0];
-
- this.GetValue = function () {
- return this.Dropdown.options[this.Dropdown.selectedIndex].text;
- };
-
- this.SetValue = function (value) {
- if (Object.isNumber(value)) {
- this.Dropdown.setValue(value);
- } else {
- var i, numOptions;
- // need to set the dropdown based on text
- numOptions = this.Dropdown.options.length;
- for (i = 0; i < numOptions; i += 1) {
- if (this.Dropdown.options[i].text === value) {
- this.Dropdown.selectedIndex = i;
- break;
- }
- }
- }
- updateReadOnlyLabel(this);
- return this;
- };
- }
- }
- }
- });
-
- /*
- * SPLookupMultiField class
- * Supports multi select lookup fields
- */
- SPLookupMultiField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- var controls = this.Controls.select('select');
- if (2 === controls.length) {
- // multi-select lookup
- this.ListChoices = controls[0];
- this.ListSelections = controls[1];
- controls = this.Controls.select('button');
- this.ButtonAdd = controls[0];
- this.ButtonRemove = controls[1];
-
- this.GetValue = function () {
- var values = [], i, numOptions;
-
- numOptions = this.ListSelections.options.length;
- for (i = 0; i < numOptions; i += 1) {
- values.push(this.ListSelections.options[i].text);
- }
-
- return values;
- };
-
- // display as semicolon delimited list
- this.MakeReadOnly = function (options) {
- return makeReadOnly(this, arrayToSemicolonList(this.GetValue()));
- };
-
- this.SetValue = function (value, addValue) {
- if (Object.isUndefined(addValue)) {
- addValue = true;
- }
-
- var i, option, options, numOptions, funcAction;
-
- if (addValue) {
- options = this.ListChoices.options;
- funcAction = this.ButtonAdd.onclick;
- } else {
- options = this.ListSelections.options;
- funcAction = this.ButtonRemove.onclick;
- }
-
- numOptions = options.length;
-
- // select the value
- if (Object.isNumber(value)) {
- value = value.toString();
- for (i = 0; i < numOptions; i += 1) {
- option = options[i];
-
- // deliberate fuzzy comparison
- if (option.value === value) {
- option.selected = true;
- } else {
- option.selected = false;
- }
- }
- } else {
- for (i = 0; i < numOptions; i += 1) {
- option = options[i];
-
- // deliberate fuzzy comparison
- if (option.text === value) {
- option.selected = true;
- } else {
- option.selected = false;
- }
- }
- }
-
- funcAction(); // add or remove the value
-
- updateReadOnlyLabel(this);
- return this;
- };
- }
- }
- });
-
- /*
- * SPNoteField class
- * Supports rich text fields (SPFieldNote)
- */
- SPNoteField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- this.Textbox = null;
- var controls = this.Controls.select('textarea');
- if (1 === controls.length) {
- this.Textbox = controls[0];
- }
-
- this.IsRichText = (RTE_GetEditorIFrame(this.Textbox.id) !== null);
-
- if (this.IsRichText) {
- // RTE functions are defined in layouts/1033/form.js
- this.GetValue = function () {
- return RTE_GetIFrameContents(this.Textbox.id);
- };
-
- this.SetValue = function (value) {
- this.Textbox.setValue(value);
- RTE_TransferTextAreaContentsToIFrame(this.Textbox.id);
- updateReadOnlyLabel(this);
- return this;
- };
- } else {
- this.GetValue = function () {
- return this.Textbox.getValue();
- };
-
- this.SetValue = function (value) {
- this.Textbox.setValue(value);
- updateReadOnlyLabel(this);
- return this;
- };
- }
- }
-
- });
-
- /*
- * SPBooleanField class
- * Supports yes/no fields (SPFieldBoolean)
- */
- SPBooleanField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- this.Checkbox = getInputControl(this);
- },
-
- /*
- * SPBooleanField Public Methods
- * Overrides SPField class methods.
- */
- GetValue: function () {
- // double negative to return a boolean value
- return !!this.Checkbox.getValue();
- },
-
- SetValue: function (value) {
- this.Checkbox.setValue(value);
- updateReadOnlyLabel(this);
- return this;
- }
- });
-
-
- /*
- * SPNumberField class
- * Supports Number fields
- */
- SPNumberField = Class.create(SPTextField, {
- initialize: function ($super, spParams) {
- $super(spParams);
- },
-
- /*
- * SPNumberField Public Methods
- * Overrides SPTextField class methods.
- */
- GetValue: function () {
- return convertStringToNumber(this.Textbox.getValue());
- }
- });
-
- /*
- * SPCurrencyField class
- * Supports currency fields (SPCurrencyField)
- */
- SPCurrencyField = Class.create(SPNumberField, {
- initialize: function ($super, spParams) {
- $super(spParams);
- this.FormatOptions = {
- eventHandler: null,
- autoCorrect: false,
- decimalPlaces: 2
- };
- },
-
- Format: function () {
- if (this.FormatOptions.autoCorrect) {
- this.FormatOptions.eventHandler = function () {
- this.SetValue(this.GetFormattedValue());
- }.bindAsEventListener(this);
- Event.observe(this.Textbox, 'change', this.FormatOptions.eventHandler);
- this.FormatOptions.eventHandler(); // run once
- } else {
- if (this.FormatOptions.eventHandler) {
- Event.stopObserving(this.Textbox, 'change', this.FormatOptions.eventHandler);
- this.FormatOptions.eventHandler = null;
- }
- }
- },
-
- GetFormattedValue: function () {
- var text = this.GetValue();
- if (typeof text === "number") {
- text = '$' + text.formatMoney(this.FormatOptions.decimalPlaces);
- }
- return text;
- },
-
- // Override the default MakeReadOnly function to allow displaying
- // the value with currency symbols
- MakeReadOnly: function (options) {
- return makeReadOnly(this, this.GetFormattedValue());
- }
- });
-
- /*
- * SPUserField class
- * Supports people fields (SPFieldUser)
- */
- SPUserField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- this.spanUserField = null;
- this.upLevelDiv = null;
- this.textareaDownLevelTextBox = null;
- this.linkCheckNames = null;
- this.txtHiddenSpanData = null;
-
- var controls = this.Controls.select('span.ms-usereditor');
- if (null !== controls && 1 === controls.length) {
- this.spanUserField = controls[0];
- this.upLevelDiv = $(this.spanUserField.id + '_upLevelDiv');
- this.textareaDownLevelTextBox = $(this.spanUserField.id + '_downlevelTextBox');
- this.linkCheckNames = $(this.spanUserField.id + '_checkNames');
- this.txtHiddenSpanData = $(this.spanUserField.id + '_hiddenSpanData');
- }
- },
-
- /*
- * SPUserField Public Methods
- * Overrides SPField class methods.
- */
- GetValue: function () {
- //this.textareaDownLevelTextBox.getValue()
- return this.upLevelDiv.getTextContent();
- },
-
- SetValue: function (value) {
- if (Prototype.Browser.IE) {
- this.upLevelDiv.innerHTML = value;
- this.txtHiddenSpanData.setValue(value);
- this.linkCheckNames.click();
- } else { // FireFox (maybe others?)
- this.textareaDownLevelTextBox.setValue(value);
- this.linkCheckNames.onclick();
- }
- updateReadOnlyLabel(this);
- return this;
- }
- });
-
- /*
- * SPURLField class
- * Supports hyperlink fields (SPFieldURL)
- */
- SPURLField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- this.TextboxURL = null;
- this.TextboxDescription = null;
-
- var controls = this.Controls.select('input');
- if (null !== controls && 2 === controls.length) {
- this.TextboxURL = controls[0];
- this.TextboxDescription = controls[1];
- }
- },
-
- /*
- * SPURLField Public Methods
- * Overrides SPField class methods.
- */
- GetValue: function () {
- return [this.TextboxURL.getValue(), this.TextboxDescription.getValue()];
- },
-
- SetValue: function (url, description) {
- this.TextboxURL.setValue(url);
- this.TextboxDescription.setValue(description);
- updateReadOnlyLabel(this);
- return this;
- },
-
- // overriding the default MakeReadOnly function because we have multiple values returned
- // and we want to have the hyperlink field show up as a URL
- MakeReadOnly: function (options) {
- var text, values = this.GetValue();
-
- if (options && true === options.TextOnly) {
- text = values[0] + ', ' + values[1];
- } else {
- text = '<a href="' + values[0] + '">' + values[1] + '</a>';
- }
-
- return makeReadOnly(this, text);
- }
- });
-
- /*
- * SPFileField class
- * Supports the name field of a Document Library
- */
- SPFileField = Class.create(SPTextField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- this.FileExtension = this.Textbox.up(0).getTextContent();
- },
-
- /*
- * SPFileField Public Methods
- * Overrides SPField class methods.
- */
- GetValue: function () {
- return this.Textbox.getValue() + this.FileExtension;
- }
- });
-
- /*
- * SPChoiceField class
- * Supports single select choice fields that show as either a dropdown or radio buttons
- */
- SPChoiceField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- var FILL_IN_VALUE = 'Specify your own value:',
- CHECKBOX_SELECTOR = 'input[type="checkbox"]',
- RADIO_SELECTOR = 'input[type="radio"]',
- controls = null;
-
- $super(spParams);
-
- this.FillInTextbox = this.Controls.select('input[type="text"]');
- if (this.FillInTextbox.length === 1) {
- this.FillInTextbox = this.FillInTextbox[0];
- this.FillInAllowed = true;
- this.FillInElement = null;
- } else {
- this.FillInAllowed = false;
- this.FillInTextbox = null;
- this.FillInElement = null;
- }
-
- // is this a single select or multi-select?
- if (this.Type === 'SPFieldChoice') {
- // single select choice field using a dropdown
- controls = this.Controls.select('select');
- if (1 === controls.length) {
- this.Dropdown = controls[0];
-
- if (!this.FillInAllowed) {
- // dynamically set our getter/setter functions
- this.GetValue = function () {
- return this.Dropdown.getValue();
- };
- this.SetValue = function (value) {
- this.Dropdown.setValue(value);
- updateReadOnlyLabel(this);
- return this;
- };
- } else {
- // dropdown with a fill-in value
- controls = getHashFromInputControls(this, RADIO_SELECTOR);
- this.FillInElement = controls.get(FILL_IN_VALUE);
- controls.unset(FILL_IN_VALUE);
-
- this.GetValue = function () {
- if (this.FillInElement.checked === true) {
- return this.FillInTextbox.getValue();
- }
- return this.Dropdown.getValue();
- };
-
- this.SetValue = function (value) {
- var found = false;
- found = !Object.isUndefined($A(this.Dropdown.options).find(function (option) { return option.value === value; }));
- if (found) {
- this.Dropdown.setValue(value);
- this.FillInElement.checked = false;
- // fires the function to select the radio button
- this.Dropdown.onclick();
- } else {
- this.FillInElement.checked = true;
- this.FillInTextbox.setValue(value);
- }
- updateReadOnlyLabel(this);
- return this;
- };
- }
- }
- }
-
- // if the field is single select, then we will have already found
- // a dropdown control and everything is setup. otherwise we have setup to do
- if (Object.isUndefined(this.Dropdown)) {
- if (this.Type === 'SPFieldMultiChoice') {
- // multi-choice fields use checkboxes
- this.Checkboxes = getHashFromInputControls(this, CHECKBOX_SELECTOR);
-
- // remove the fill-in checkbox because we will check it separately
- if (this.FillInAllowed) {
- this.FillInElement = this.Checkboxes.get(FILL_IN_VALUE);
- this.Checkboxes.unset(FILL_IN_VALUE);
- }
-
- this.GetValue = function () {
- var values = [];
-
- this.Checkboxes.each(function (pair) {
- var checkbox = pair.value;
- if (checkbox.checked === true) {
- values.push(pair.key);
- }
- });
-
- if (this.FillInAllowed && this.FillInElement.checked === true) {
- values.push(this.FillInTextbox.getValue());
- }
-
- return values;
- };
-
- this.SetValue = function (value, checked) {
- // find the radio button we need to set in our hashtable
- var checkBox = this.Checkboxes.get(value);
-
- // if couldn't find the element in the hashtable
- // and fill-in is allowed, assume they meant the fill-in value
- if (Object.isUndefined(checkBox) && this.FillInAllowed) {
- checkBox = this.FillInElement;
- this.FillInTextbox.setValue(value);
- }
-
- if (!Object.isUndefined(checkBox)) {
- if (!Object.isUndefined(checked)) {
- checkBox.checked = (true === checked);
- } else {
- checkBox.checked = true;
- }
- }
- updateReadOnlyLabel(this);
- return this;
- };
-
- // display as semicolon delimited list
- this.MakeReadOnly = function (options) {
- return makeReadOnly(this, arrayToSemicolonList(this.GetValue()));
- };
- } else {
- this.RadioButtons = getHashFromInputControls(this, RADIO_SELECTOR);
-
- // remove the fill-in radio button because we will check it separately
- if (this.FillInAllowed) {
- this.FillInElement = this.RadioButtons.get(FILL_IN_VALUE);
- this.RadioButtons.unset(FILL_IN_VALUE);
- }
-
- this.GetValue = function () {
- var value = null;
- // find the radio button we need to get in our hashtable
- this.RadioButtons.each(function (pair) {
- var radioButton = pair.value;
- if (true === radioButton.checked) {
- value = pair.key;
- throw $break;
- }
- });
-
- if (this.FillInAllowed && value === null && this.FillInElement.checked === true) {
- value = this.FillInTextbox.getValue();
- }
-
- return value;
- };
-
- this.SetValue = function (value) {
- // find the radio button we need to set in our hashtable
- var radioButton = this.RadioButtons.get(value);
-
- // if couldn't find the element in the hashtable and fill-in
- // is allowed, assume they want to set the fill-in value
- if (Object.isUndefined(radioButton) && this.FillInAllowed) {
- radioButton = this.FillInElement;
- this.FillInTextbox.setValue(value);
- }
-
- if (!Object.isUndefined(radioButton)) {
- radioButton.checked = true;
- }
- updateReadOnlyLabel(this);
- return this;
- };
- }
- }
- }
- });
-
- /*
- * SPDateTimeFieldValue class
- * Used to set/get values for SPDateTimeField fields
- */
- SPDateTimeFieldValue = Class.create({
- initialize: function (year, month, day, strHour, strMinute) {
- this.Year = year;
- this.Month = month;
- this.Day = day;
- this.Hour = strHour;
- this.Minute = strMinute;
- this.IsTimeIncluded = !Object.isUndefined(this.Hour) && !Object.isUndefined(this.Minute);
-
- if (this.IsTimeIncluded) {
- if (!this.IsValidHour(this.Hour)) {
- throw 'Hour parameter is not in the correct format. Needs to be formatted like "1 PM" or "12 AM".';
- }
- if (!this.IsValidMinute(this.Minute)) {
- throw 'Minute parameter is not in the correct format. Needs to be formatted like "00", "05" or "35".';
- }
- }
- },
-
- /*
- * SPDateTimeFieldValue Public Methods
- */
-
- IsValidDate: function () {
- return !Object.isUndefined(this.Year) && !Object.isUndefined(this.Month) && !Object.isUndefined(this.Day);
- },
-
- IsValidHour: function (h) {
- return !Object.isUndefined(h) && (/^([1-9]|10|11|12) (AM|PM)$/).test(h);
- },
-
- IsValidMinute: function (m) {
- return !Object.isUndefined(m) && (/^([0-5](0|5))$/).test(m);
- },
-
- // returns the part of a date as a string and pads with a 0 if necessary
- PadWithZero: function (d) {
- if (Object.isUndefined(d) || null === d) {
- return '';
- }
- if (typeof d === 'string') {
- d = parseInt(d, 10);
- if (isNaN(d)) {
- return '';
- }
- }
- if (typeof d === 'number' && d < 10) {
- return '0' + d.toString();
- }
- return d.toString();
- },
-
- // transforms a date object into a string
- GetShortDateString: function () {
- if (!this.IsValidDate()) {
- return '';
- }
- var strDate = this.PadWithZero(this.Month) + "/" +
- this.PadWithZero(this.Day) + "/" +
- this.PadWithZero(this.Year);
- return strDate;
- },
-
- toString: function () {
- var str = this.GetShortDateString(), arrHour;
- if (this.IsValidHour(this.Hour) && this.IsValidMinute(this.Minute)) {
- arrHour = this.Hour.split(' ');
- str += ' ' + arrHour[0] + ':' + this.Minute + arrHour[1];
- }
- return str;
- }
- });
-
- /*
- * SPDateTimeField class
- * Date and DateTime fields
- */
- SPDateTimeField = Class.create(SPField, {
- initialize: function ($super, spParams) {
- $super(spParams);
-
- this.DateTextbox = getInputControl(this);
-
- this.HourDropdown = null;
- this.MinuteDropdown = null;
- var timeControls = this.Controls.select('select');
- if (null !== timeControls && 2 === timeControls.length) {
- this.HourDropdown = $(timeControls[0]);
- this.MinuteDropdown = $(timeControls[1]);
- }
- },
-
- /*
- * SPDateTimeField Public Methods
- * Overrides SPField class methods.
- */
- GetValue: function () {
- var strHour, strMinute, arrShortDate,
- strShortDate = this.DateTextbox.getValue();
-
- if (null !== this.HourDropdown && null !== this.MinuteDropdown) {
- strHour = this.HourDropdown.getValue();
- strMinute = this.MinuteDropdown.getValue();
- }
-
- arrShortDate = strShortDate.split('/');
-
- if (arrShortDate.length === 3) {
- return new SPDateTimeFieldValue(arrShortDate[2], arrShortDate[0], arrShortDate[1], strHour, strMinute);
- }
-
- // empty or invalid date
- return '';
- },
-
- SetValue: function (year, month, day, strHour, strMinute) {
- if (Object.isString(year) && Object.isUndefined(month)) {
- // one string param passed to SetValue
- // assume they know what they are doing
- this.DateTextbox.setValue(year);
- } else {
- var value = new SPDateTimeFieldValue(year, month, day, strHour, strMinute);
- this.DateTextbox.setValue(value.GetShortDateString());
- if (null !== this.HourDropdown && null !== this.MinuteDropdown) {
- this.HourDropdown.setValue(value.Hour);
- this.MinuteDropdown.setValue(value.Minute);
- }
- }
- updateReadOnlyLabel(this);
- return this;
- }
-
- });
-
- /*
- * SPUtility Public Methods
- */
-
- return {
- // Creates a soap envelope for use with an AJAX call to SharePoint web services
- CreateSoapEnvelope: function (action, namespace, parameters) {
- var soap = '<?xml version="1.0" encoding="utf-8"?>';
- soap += '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
- soap += ' <soap:Body>';
-
- // creat body of the soap envelope
- if (typeof parameters === 'object' && $H(parameters).keys().length > 0) {
- soap += ' <' + action + ' xmlns="' + namespace + '">';
- $H(parameters).each(function (pair) {
- soap += "<" + pair.key + ">" + pair.value + "</" + pair.key + ">";
- });
- soap += ' </' + action + '>';
- } else {
- soap += ' <' + action + ' xmlns="' + namespace + '" />';
- }
-
- soap += ' </soap:Body>';
- soap += '</soap:Envelope>';
- return soap;
- },
-
- Debug: function (isDebug) {
- if ('boolean' === typeof isDebug) {
- _debugMode = isDebug;
- }
- return _debugMode;
- },
-
- // Gets all of the SPFields on the page
- GetSPFields: function () {
- lazyLoadSPFields();
- return _fieldsHashtable;
- },
-
- // Searches the page for a specific field by name
- GetSPField: function (strFieldName) {
- lazyLoadSPFields();
-
- var fieldParams = _fieldsHashtable.get(strFieldName);
-
- if (Object.isUndefined(fieldParams)) {
- log('GetSPField: Unable to find a SPField named ' + strFieldName);
- return null;
- }
-
- if (fieldParams.spField === null) {
- // field hasn't been initialized yet
- fieldParams.spField = createSPField(fieldParams);
- }
-
- return fieldParams.spField;
- },
-
- HideSPField: function (strFieldName) {
- toggleSPField(strFieldName, false);
- },
-
- ShowSPField: function (strFieldName) {
- toggleSPField(strFieldName, true);
- }
- };
- }());