/* * Isomorphic SmartClient * Version SNAPSHOT_v8.3d_2012-05-02 (2012-05-02) * Copyright(c) 1998 and beyond Isomorphic Software, Inc. All rights reserved. * "SmartClient" is a trademark of Isomorphic Software, Inc. * * licensing@smartclient.com * * http://smartclient.com/license */ // Class will not work without the ListGrid if (isc.ListGrid) { //> @class DateRangeItem // Allows a user to select an absolute or relative range of dates via two // +link{RelativeDateItem}s (if +link{DateRangeItem.allowRelativeDates} is true) or two // +link{DateItems}. //

// DateRangeItem is just a convenience relative to using two +link{RelativeDateItem} or // +link{DateItem} controls in a form, then using +link{FormItem.operator} and // +link{FormItem.criteriaField} to cause them to produce a date range. If you need more // control over layout, validation, event handling or any other aspect of appearance or // behavior, stop using DateRangeItem and use two DateItem/RelativeDateItem controls directly // instead. // // @visibility external //< isc.defineClass("DateRangeItem", "CanvasItem"); isc.DateRangeItem.addProperties({ //> @attr dateRangeItem.shouldSaveValue (boolean : true : IR) // Allow dateRangeItems' values to show up in the form's values array, or if // +link{dynamicForm.getValuesAsCriteria()} is called, for the criterion to be included // in the returned AdvancedCriteria object // @visibility external //< shouldSaveValue:true, //> @object DateRange // A JavaScript object specifying a range of dates. Values are +link{dateRange.start, start} // and +link{dateRange.end, end}. If either value is omitted, the range is assumed to be // open-ended in that direction - so if dateRange.start is omitted, the range will include any // date earlier than the value specified in dateRange.end. // // @visibility external //< //> @attr dateRange.start (RelativeDate or Date : null : IR) // The start of this DateRange. // @visibility external //< //> @attr dateRange.end (RelativeDate or Date : null : IR) // The end of this DateRange. // @visibility external //< //> @attr dateRangeItem.fromTitle (string : "From" : IR) // The title for the +link{dateRangeItem.fromField, from} part of the range. // @visibility external // @group i18nMessages //< fromTitle: "From", //> @attr dateRangeItem.toTitle (string : "To" : IR) // The title for the +link{dateRangeItem.toField, to} part of the range. // @visibility external // @group i18nMessages //< toTitle: "To", //> @attr dateRangeItem.innerTitleOrientation (TitleOrientation : null : IR) // The title orientation for the to / from sub-items. If unset this will be derived from // +link{FormItem.titleOrientation,this.titleOrientation} or // +link{DynamicForm.titleOrientation,this.form.titleOrientation}. // @visibility external //< //innerTitleOrientation:null, //> @attr dateRangeItem.allowRelativeDates (boolean : false : IR) // Whether to allow the user to specify relative dates (via +link{RelativeDateItem}s) or whether // dates are absolute (via +link{DateItem}s). // @visibility external //< allowRelativeDates: false, //> @attr dateRangeItem.fromField (AutoChild FormItem : null : IR) // The field for the "from" date - a +link{RelativeDateItem} or +link{DateItem} according to // +link{allowRelativeDates}. // @visibility external //< //> @attr dateRangeItem.fromFieldProperties (FormItem Properties: null : IR) // Additional property-block to customize the +link{dateRangeItem.fromField, fromField} // AutoChild. // @visibility internal //< //> @attr dateRangeItem.toField (AutoChild FormItem : null : IR) // The field for the "to" date - a +link{RelativeDateItem} or +link{DateItem} according to // +link{allowRelativeDates}. // @visibility external //< //> @attr dateRangeItem.toFieldProperties (FormItem Properties: null : IR) // Additional property-block to customize the +link{dateRangeItem.toField, toField} // AutoChild. // @visibility internal //< //> @attr dateRangeItem.fromDate (Date or RelativeDateString or TimeUnit : today : IRW) // Initial value for the "from" date. // @setter setFromDate // @visibility external //< //fromDate: "$today", //> @method dateRangeItem.setFromDate() // Sets the +link{fromDate} for this DateRangeItem. // @param fromDate (Date) the date from which this item should start it's range // @visibility external //< setFromDate : function (fromDate) { this.fromDate = fromDate; if (this.fromField) this.fromField.setValue(this.fromDate); }, //> @attr dateRangeItem.toDate (Date or RelativeDateString or TimeUnit : today : IRW) // Initial value for the "to" date. // @setter setToDate // @visibility external //< //toDate: "$today", //> @method dateRangeItem.setToDate() // Sets the +link{toDate} for this DateRangeItem. // @param fromDate (Date) the date at which this item should end it's range // @visibility external //< setToDate : function (toDate) { this.toDate = toDate; if (this.toField) this.toField.setValue(this.toDate); }, //> @attr dateRangeItem.dateInputFormat (DateInputFormat : null : IR) // Format for direct user input of date values. //

// If unset, the input format will be determined based on the specified // +link{dateDisplayFormat} if possible, otherwise picked up from the Date class (see // +link{Date.setInputFormat()}). // // @deprecated This property is supported but // the standard +link{dateFormatter} and +link{inputFormat} // may now be used to specify date formatting parsing behavior for dateRangeItems // // @visibility external //< //> @attr dateRangeItem.inputFormat (DateInputFormat : null : IR) // @include FormItem.inputFormat //< //> @attr dateRangeItem.dateDisplayFormat (DateDisplayFormat : null : IR) // Format for displaying dates in to the user. // Defaults to the system-wide default established by +link{Date.setDefaultDisplayFormat()}. // // @visibility external // // @deprecated This property is supported but // the standard +link{dateFormatter} and +link{inputFormat} // may now be used to specify date formatting parsing behavior for dateRangeItems // //< //> @method dateRangeItem.hasAdvancedCriteria() // Overridden to return true: dateRangeItems always generate AdvancedCriteria. // @return (boolean) true // @visibility external // @group criteriaEditing //< hasAdvancedCriteria : function () { return this.fromField && this.toField && (this.fromField.getValue() != null || this.toField.getValue() != null); }, //> @method dateRangeItem.getCriterion() // Returns the Criterion entered in the date field. //

// A Criterion with an "and" +link{type:OperatorId,operator} will be // returned with both a "greaterOrEqual" and "lessOrEqual" sub-criteria. If either date is // omitted, only the "greaterOrEqual" (from date) or "lessOrEqual" (to date) Criterion is // included. // // @return (Criterion) // // @group criteriaEditing // @visibility external //< getCriterion : function (absolute) { absolute = absolute || !this.allowRelativeDates; var fromValue = absolute ? this.fromField.getValue() : this.fromField.getRelativeDate() || this.fromField.getValue(), hasFromValue = fromValue != null, toValue = absolute ? this.toField.getValue() : this.toField.getRelativeDate() || this.toField.getValue(), hasToValue = toValue != null, result = null ; if (hasFromValue || hasToValue) { // return an AdvanvedCriteria with one or two subCriteria result = { _constructor: "AdvancedCriteria", operator: "and", criteria: [ ] }; if (hasFromValue) { if (isc.isA.RelativeDateItem(fromValue)) { fromValue.rangePosition = "start"; } result.criteria.add({ fieldName: this.getCriteriaFieldName(), operator: "greaterOrEqual", value: fromValue }); } if (hasToValue) { if (isc.isA.RelativeDateItem(toValue)) { toValue.rangePosition = "end"; } result.criteria.add({ fieldName: this.getCriteriaFieldName(), operator: "lessOrEqual", value: toValue }); } } return result; }, //> @method dateRangeItem.canEditCriterion() // Returns true if the specified criterion contains: //

// @param criterion (Criterion) criterion to test // @return (boolean) returns true if this criterion can be edited by this item // @group criteriaEditing // @visibility external //< canEditCriterion : function (criterion) { if (criterion == null) return false; var dateField = this.getCriteriaFieldName(); if (criterion.operator == "and") { var innerCriteria = criterion.criteria; // we always produce one or 2 criteria only (to and from date range) - note, however, // that we can also edit an "equals" criterion, by first converting it into a range if (innerCriteria.length == 0 || innerCriteria.length > 2) { return false; } else if (innerCriteria.length == 1) { var crit = innerCriteria[0]; if (crit.fieldName != dateField) return false; if (crit.operator == "equals") { this.logWarn("DynamicForm editing Advanced criteria. Includes criterion for " + "field " + dateField + ". A dateRange editor is showing for this field and " + "the existing criteria has operator: " + crit.operator + ". DateRange " + "items can only edit criteria greaterThan/greaterOrEqual or lessThan/lessOrEqual. "+ "However, for the 'equals' operator, a dateRange will be constructed for you, " + "as greaterOrEqual to [value] and lessOrEqual to [value], ie, one day."); return true; } } for (var i = 0; i < innerCriteria.length; i++) { var innerCriterion = innerCriteria[i]; // other field - just bail if (innerCriterion.fieldName != dateField) return false; // wrong operator - bail, but with a warning since this could confuse a // developer if (innerCriterion.operator != "greaterThan" && innerCriterion.operator != "greaterOrEqual" && innerCriterion.operator != "lessThan" && innerCriterion.operator != "lessOrEqual") { this.logWarn("DynamicForm editing Advanced criteria. Includes criterion for " + "field " + dateField + ". A dateRange editor is showing for this field but " + "the existing criteria has operator:" + innerCriterion.operator + ". DateRange " + "items can only edit criteria greaterThan/greaterOrEqual or lessThan/lessOrEqual " + "so leaving this unaltered."); return false; } } // Only contains a range, with one or 2 values, so we'll allow editing of that. return true; // single criterion matching to or from of range.. We support that.. } else if (criterion.fieldName == dateField) { var message = "DynamicForm editing Advanced criteria. Includes criterion for " + "field " + dateField + ". A dateRange editor is showing for this field and " + "the existing criteria has operator:" + criterion.operator + ". DateRange " + "items can only edit criteria greaterThan/greaterOrEqual or lessThan/lessOrEqual"; if (criterion.operator == "equals") { this.logWarn(message + ". However, for the 'equals' operator, a dateRange will be " + "constructed for you, as greaterOrEqual to [value] and lessOrEqual to [value], " + "ie, one day."); return true; } if (criterion.operator != "greaterThan" && criterion.operator != "greaterOrEqual" && criterion.operator != "lessThan" && criterion.operator != "lessOrEqual") { this.logWarn(message + " so leaving this unaltered."); return false; } return true; } // in this case it's not on our field at all return false; }, //> @method dateRangeItem.setCriterion() // Applies the specified criterion to this item for editing. Applies any specified // "greaterOrEqual" operator criterion or sub-criterion to our +link{fromField} and any // specified "lessOrEqual" operator criterion or sub-criterion to our +link{toField}. //

// Note that a single "equals" criterion can also be passed. See // +link{dateRangeItem.canEditCriterion, canEditCriterion()} for more detail. // @param criterion (Criterion) criterion to edit // @group criteriaEditing // @visibility external //< setCriterion : function (criterion) { if (!criterion) return; if (criterion.operator == "equals") { // handle "equals" criterion by constructing an AdvancedCriteria that represents a // genuine range var newCrit = { _constructor: "AdvancedCriteria", operator: "and", criteria: [ { fieldName: criterion.fieldName, operator: "greaterOrEqual", value: criterion.value }, { fieldName: criterion.fieldName, operator: "lessOrEqual", value: criterion.value } ]}; criterion = newCrit; } var fromCrit, toCrit; if (criterion.operator == "and") { fromCrit = criterion.criteria.find("operator", "greaterThan"); if (!fromCrit) fromCrit = criterion.criteria.find("operator", "greaterOrEqual"); toCrit = criterion.criteria.find("operator", "lessThan"); if (!toCrit) toCrit = criterion.criteria.find("operator", "lessOrEqual"); } else { if (criterion.operator == "greaterThan") fromCrit = criterion; else if (criterion.operator == "greaterOrEqual") fromCrit = criterion; else if (criterion.operator == "lessThan") toCrit = criterion; else if (criterion.operator == "lessOrEqual") toCrit = criterion; } // just call setValue on the relevant items. // If we're showing relative date items they should handle being passed an absolute // date value if (fromCrit != null) { this.fromField.setValue(fromCrit.value); } if (toCrit != null) { this.toField.setValue(toCrit.value); } }, //> @attr dateRangeItem.dateRangeForm (AutoChild : null : R) // +link{DynamicForm} +link{AutoChild} automatically created by the dateRangeItem and applied // to the item as +link{canvasItem.canvas,this.canvas}.

// This DynamicForm contains the "from" and "to" fields the user will interact with to actually // select a date-range. Note that as a standard autoChild, developers may customize this form // by modifying dateRangeProperties. // // @visibility external //< dateRangeFormDefaults: { _constructor: "DynamicForm", margin: 0, padding: 0, itemChanged : function (item, newValue) { var values = this.getValues(), dateRange = {_constructor:"DateRange"}; if (values.fromField != null) dateRange.start = values.fromField; if (values.toField != null) dateRange.end = values.toField; this.creator._updateValue(dateRange); } } }); isc.DateRangeItem.addMethods({ init : function () { this._createEditor(); this.Super("init", arguments); }, isEditable : function () { return true; }, // If we get destroyed also wipe out our canvas autoDestroy:true, _createEditor: function () { var ds; var dynProps = { _suppressColWidthWarnings: true }; if (this.form.dataSource) { // Should be, otherwise how have we ended up with a complex field? ds = isc.DataSource.getDataSource(this.form.dataSource); var field = ds.getField(this.name); if (field) { dynProps.dataSource = ds.getFieldDataSource(field); } } if (this.form && this.form.showComplexFieldsRecursively) { dynProps.showComplexFields = true; dynProps.showComplexFieldsRecursively = true; } else { dynProps.showComplexFields = false; } dynProps.height = 22; var titleOrientation = this.innerTitleOrientation || this.titleOrientation || this.form.titleOrientation || "left"; dynProps.titleOrientation = titleOrientation; if (titleOrientation == "left" || titleOrientation == "right") { dynProps.numCols = 2; dynProps.colWidths = [50, "*"]; } else { dynProps.numCols = 1; dynProps.colWidths = ["*"]; } this.addAutoChild("dateRangeForm", dynProps); this.canvas = this.dateRangeForm; // set a default baseDate is one wasn't provided var type = this.getType(), isLogicalDate = false; if (isc.SimpleType.inheritsFrom(type, "date") && !isc.SimpleType.inheritsFrom(type, "datetime")) { isLogicalDate = true; } this.baseDate = this.baseDate || (isLogicalDate ? isc.Date.createLogicalDate() : new Date()); var _this = this, _constructor = this.allowRelativeDates ? "RelativeDateItem" : "DateItem", items = [] ; items[0] = isc.addProperties({}, this.fromFieldDefaults, this.fromFieldProperties, { name: "fromField", _constructor: _constructor, baseDate: this.baseDate, // dateDisplayFormat and dateInputFormat are basically there for back-compat only dateFormatter:(this.dateDisplayFormat || this.dateFormatter), type:this.getType(), inputFormat: (this.dateInputFormat || this.inputFormat), rangePosition: "start", title: this.fromTitle, defaultValue: this.fromValue, useTextField: (_constructor == "DateItem" ? true : null) } ); items[1] = isc.addProperties({}, this.toFieldDefaults, this.toFieldProperties, { name: "toField", _constructor: _constructor, baseDate: this.baseDate, dateFormatter:(this.dateDisplayFormat || this.dateFormatter), type:this.getType(), inputFormat: (this.dateInputFormat || this.inputFormat), rangePosition: "end", title: this.toTitle, defaultValue: this.toValue, useTextField: (_constructor == "DateItem" ? true : null) } ); this.canvas.setFields(items); this.toField = this.canvas.getField("toField"); this.fromField = this.canvas.getField("fromField"); if (this.allowRelativeDates) { this.fromField.canvas._nextTabWidget = this.toField.canvas; this.toField.canvas._previousTabWidget = this.fromField.canvas; } if (this.defaultValue) { this.setValue(this.defaultValue); } else { if (this.fromDate) this.setFromDate(this.fromDate); if (this.toDate) this.setToDate(this.toDate); } }, fieldChanged : function () { }, //> @method dateRangeItem.setValue() // Sets the value for this dateRangeItem. The value parameter is a // +link{object:DateRange} object that optionally includes both start and end values. If // passed null, both start- and end-range values are cleared. // @param value (DateRange) the new value for this item // @visibility external //< setValue : function (value) { var start = value ? value.start : null, end = value ? value.end : null, RDI = isc.RelativeDateItem; if (!this.allowRelativeDates && RDI.isRelativeDate(start)) this.setFromDate(null); else this.setFromDate(start); if (!this.allowRelativeDates && RDI.isRelativeDate(end)) this.setToDate(null); else this.setToDate(end); this.Super("setValue", arguments); }, //> @method dateRangeItem.getValue() // Retrieves the current value of this dateRangeItem. The return value is a // +link{object:DateRange} object that excludes start and end values if they aren't // set. // @return (DateRange) the current value of this item // @visibility external //< getValue : function () { if (!this.fromField || !this.toField) return; var isRelative = this.allowRelativeDates, fromValue = isRelative && this.fromField.getRelativeDate() ? this.fromField.getRelativeDate() : this.fromField.getValue(), toValue = isRelative && this.toField.getRelativeDate() ? this.toField.getRelativeDate() : this.toField.getValue(), result = {_constructor:"DateRange"}; if (fromValue == null && toValue == null) return null; if (fromValue != null) result.start = fromValue; if (toValue != null) result.end = toValue; return result; }, destroy : function () { if (this.dateRangeForm) this.dateRangeForm.destroy(); this.Super("destroy", arguments); } }); if (isc.Window) { // dateRangeDialog and miniDateRangeItem require isc.Window //> @class DateRangeDialog // Simple modal dialog for collecting a date range from the end user. // // @visibility external //< isc.defineClass("DateRangeDialog", "Window"); isc.DateRangeDialog.addClassMethods({ //> @classMethod DateRangeDialog.askForRange() // Helper method to launch a DateRangeDialog to have a date range input by the user. // @param allowRelativeDates (boolean) whether to allow relative date entry via // +link{RelativeDateItem}s, default true // @param rangeItemProperties (DateRangeItem Properties) properties for the DateRangeItem // @param windowProperties (DateRangeDialog Properties) properties for the Window // @param callback (Callback) method to fire once user has input values, with a single parameter // "criterion" of type +link{Criterion} // // @visibility external //< askForRange : function (allowRelativeDates, rangeItemProperties, windowProperties, callback) { var drd = isc.DateRangeDialog.create({ allowRelativeDates: allowRelativeDates != null ? allowRelativeDates : true, rangeItemProperties: rangeItemProperties, callback: callback }, windowProperties); drd.show(); } }); isc.DateRangeDialog.addProperties({ isModal: true, showModalMask: true, dismissOnEscape: true, autoCenter: true, width: 380, height: 140, vertical: "true", showMinimizeButton: false, headerIconProperties: { src: "[SKIN]/DynamicForm/DatePicker_icon.gif" }, returnCriterion: false, //> @attr dateRangeDialog.headerTitle (String : "Select Date Range" : IR) // The title to display in the header-bar of this Dialog. // // @visibility external // @group i18nMessages //< headerTitle: "Select Date Range", mainLayoutDefaults: { _constructor: "VLayout", width: "100%", height: "100%", layoutMargin: 5 }, rangeFormDefaults: { _constructor: "DynamicForm", numCols: 1, width: "100%", height: "100%", autoParent: "mainLayout" }, //> @attr dateRangeDialog.rangeItem (AutoChild DateRangeItem : null : IR) // // @visibility external //< rangeItemDefaults: { _constructor: "DateRangeItem", allowRelativeDates: true, showTitle: false }, buttonLayoutDefaults: { _constructor: "HLayout", width: "100%", height: 22, align: "right", membersMargin: 5, autoParent: "mainLayout" }, //> @attr dateRangeDialog.clearButtonTitle (string : "Clear" : IR) // The title for the "Clear" button on this dialog. // @visibility external // @group i18nMessages //< clearButtonTitle: "Clear", //> @attr dateRangeDialog.clearButton (AutoChild : null : IR) // Button used for clearing the dialog's values. Note that, since this is an +link{AutoChild}, // it can be configured using clearButtonDefaults and clearButtonProperties. // @visibility external //< clearButtonDefaults: { _constructor: "IButton", height: 22, width: 80, canFocus:true, autoParent: "buttonLayout", click : function () { this.creator.clearValues(); } }, //> @attr dateRangeDialog.okButtonTitle (string : "OK" : IR) // The title for the "OK" button on this dialog. // @visibility external // @group i18nMessages //< okButtonTitle: "OK", //> @attr dateRangeDialog.okButton (AutoChild : null : IR) // Button used for accepting the values entered into the dialog. Note that, since this is an // +link{AutoChild}, it can be configured using okButtonDefaults and okButtonProperties. // @visibility external //< okButtonDefaults: { _constructor: "IButton", height: 22, width: 80, canFocus:true, autoParent: "buttonLayout", click : function () { this.creator.accept(); } }, //> @attr dateRangeDialog.cancelButtonTitle (string : "Cancel" : IR) // The title for the "Cancel" button on this dialog. // @visibility external // @group i18nMessages //< cancelButtonTitle: "Cancel", //> @attr dateRangeDialog.cancelButton (AutoChild : null : IR) // Button used for cancelling the dialog. Note that, since this is an +link{AutoChild}, it can // be configured using cancelButtonDefaults and cancelButtonProperties. // @visibility external //< cancelButtonDefaults: { _constructor: "IButton", height: 22, width: 80, canFocus:true, autoParent: "buttonLayout", click : function () { this.creator.cancel(); } }, destroyOnClose: true, destroy : function () { if (this.rangeForm) { this.rangeForm.markForDestroy(); } this.Super("destroy", arguments); } }); isc.DateRangeDialog.addMethods({ initWidget : function () { this.title = this.headerTitle; this.Super("initWidget", arguments); this.addAutoChild("mainLayout"); this.addAutoChild("rangeForm", { _suppressColWidthWarnings: true, items: [ isc.addProperties({}, this.rangeItemDefaults, this.rangeItemProperties, { name: "rangeItem", fromDate: this.fromDate, toDate: this.toDate, dateDisplayFormat: this.dateDisplayFormat } ) ] } ); var rangeItem = this.rangeItem = this.rangeForm.getField("rangeItem"); var titleOrientation = rangeItem.innerTitleOrientation || rangeItem.titleOrientation || "left"; if (rangeItem.canvas) { rangeItem.canvas.titleOrientation = titleOrientation; if (titleOrientation == "left" || titleOrientation == "right") { rangeItem.canvas.numCols = 2; rangeItem.canvas.colWidths = [50, "*"]; } else { rangeItem.canvas.numCols = 1; rangeItem.canvas.colWidths = ["*"]; } } this.addAutoChild("buttonLayout"); this.addAutoChild("clearButton", { canFocus:true, title: this.clearButtonTitle}); this.addAutoChild("okButton", { canFocus:true, title: this.okButtonTitle}); this.addAutoChild("cancelButton", { canFocus:true, title: this.cancelButtonTitle}); this.addItem(this.mainLayout); }, clearValues : function () { if (this.rangeItem) this.rangeItem.setValue(null); }, accept : function () { this.finished( this.rangeItem.returnCriterion ? this.rangeItem.getCriterion() : this.rangeItem.getValue() ); }, cancel : function () { this.hide(); if (this.destroyOnClose) this.markForDestroy(); }, finished : function (value) { if (this.callback) this.fireCallback(this.callback, "value", [value]); this.hide(); if (this.destroyOnClose) this.markForDestroy(); } }); //> @class MiniDateRangeItem // Provides a compact interface for editing a date range, by providing a formatted, read-only // display of the current selected date range with an icon to launch a +link{DateRangeDialog} // to edit the range. // // @visibility external //< isc.defineClass("MiniDateRangeItem", "StaticTextItem"); isc.MiniDateRangeItem.addProperties({ //> @attr miniDateRangeItem.textBoxStyle (FormItemBaseStyle : "textItem" : IRW) // @include formItem.textBoxStyle //< textBoxStyle:"textItem", clipValue: true, wrap: false, iconVAlign: "top", height: 20, width: 100, //> @attr miniDateRangeItem.shouldSaveValue (boolean : true : IR) // Allow miniDateRangeItems' values to show up in the form's values array, or if // +link{dynamicForm.getValuesAsCriteria()} is called, for the criterion to be included // in the returned AdvancedCriteria object // @visibility external //< shouldSaveValue:true, //> @attr miniDateRangeItem.rangeDialog (AutoChild DateRangeDialog : null : IR) // Pop-up +link{DateRangeDialog} for entering a date range. // // @visibility external //< rangeDialogDefaults: { _constructor: "DateRangeDialog", autoDraw: false, destroyOnClose: false }, //> @attr miniDateRangeItem.canFocus (boolean : true : IR) // MiniDateRangeItems are marked as canFocus:true, and set up with properties such that focus // will always go to the icon to launch the dateRange dialog. Set canFocus to false to // suppress this behavior. // @visibility external //< canFocus:true, // these overrides ensure focus goes to the picker icon (actually this.icons[0]) rather than // us writing tab-order properties into the static div. getFocusElement : function () { return this._getIconLinkElement(this.icons[0]); }, _canFocusInTextBox : function () { return false; }, canTabToIcons:true, //> @attr miniDateRangeItem.fromDateOnlyPrefix (string : "Since" : IR) // The text to prepend to the formatted date when only a +link{fromDate, fromDate} is supplied. // @visibility external // @group i18nMessages //< fromDateOnlyPrefix: "Since", //> @attr miniDateRangeItem.toDateOnlyPrefix (string : "Before" : IR) // The text to prepend to the formatted date when only a +link{toDate, toDate} is supplied. // @visibility external // @group i18nMessages //< toDateOnlyPrefix: "Before", //> @attr miniDateRangeItem.pickerIconPrompt (String : "Show Date Chooser" : IR) // The prompt to show when the mouse is hovered over the +link{pickerIcon}. // // @visibility external // @group i18nMessages //< pickerIconPrompt: "Show Date Chooser", //> @attr miniDateRangeItem.pickerIcon (FormItemIcon Properties : null : IR) // Icon that launches a +link{DateChooser} for choosing an absolute date. // // @visibility external //< pickerIconDefaults: { name: "showDateRange", src: "[SKIN]/DynamicForm/DatePicker_icon.gif", width: 16, height: 16, showOver: false, showFocused: false, showFocusedWithItem: false, hspace: 0, click : function (form, item, icon) { if (!item.disabled) item.showRangeDialog(); } }, iconVAlign: "center", //> @method miniDateRangeItem.allowRelativeDates() // Whether the +link{DateRangeDialog} opened when the // +link{miniDateRangeItem.pickerIcon, pickerIcon} is clicked should display // +link{RelativeDateItem}s or +link{DateItem}s. // @return (boolean) true // @visibility external //< allowRelativeDates: true, //> @attr miniDateRangeItem.dateDisplayFormat (DateDisplayFormat : null : IR) // Format for displaying dates to the user. //

// If this attribute is unset, the display value is formatted intelligently according to the // dates involved. For example, if both dates appear in the same month, the value will be // formatted as //

Month date1 - date2, Year //

and, if in different months of the same year, //

Month1 date1 - Month2 date2, Year. //

If either date-value is unset, the display-value is formatted according to // +link{miniDateRangeItem.fromDateOnlyPrefix, fromDateOnlyPrefix} and // +link{miniDateRangeItem.toDateOnlyPrefix, toDateOnlyPrefix}. // // @visibility external //< //> @attr miniDateRangeItem.fromDate (Date or RelativeDateString or TimeUnit : today : IRW) // Initial value for the "from" date. // @setter setFromDate // @visibility external //< //fromDate: "$today", //> @attr miniDateRangeItem.toDate (Date or RelativeDateString or TimeUnit : today : IRW) // Initial value for the "to" date. // @setter setFromDate // @visibility external //< //toDate: "$today", handleClick : function () { if (!this.disabled) this.showRangeDialog(); } }); isc.MiniDateRangeItem.addMethods({ init : function () { this.addAutoChild("rangeDialog", { fromDate: this.fromDate, toDate: this.toDate, rangeItemProperties: { allowRelativeDates: this.allowRelativeDates, type:this.getType() }, dateDisplayFormat: this.dateDisplayFormat, callback: this.getID()+".rangeDialogCallback(value)" } ); this.icons = [ isc.addProperties({ prompt: this.pickerIconPrompt }, this.pickerIconDefaults, this.pickerIconProperties ) ]; this.canTabToIcons = true; this.rangeItem = this.rangeDialog.rangeItem; this.rangeItem.name = this.name; if (this.defaultValue) { this.setValue(this.defaultValue); } }, showRangeDialog : function () { this.rangeDialog.rangeItem.setFromDate(this.fromDate); this.rangeDialog.rangeItem.setToDate(this.toDate); this.rangeDialog.show(); }, rangeDialogCallback : function (value) { if (!this._updateValue(value)) return; this.displayValue(value); }, //> @method miniDateRangeItem.hasAdvancedCriteria() // @include dateRangeItem.hasAdvancedCriteria() // @group criteriaEditing //< hasAdvancedCriteria : function () { return this.rangeItem != null && this.rangeItem.hasAdvancedCriteria(); }, //> @method miniDateRangeItem.getCriterion() // Returns the Criterion entered in the fields shown in the // +link{miniDateRangeItem.rangeDialog}. //

// If both dates are entered, a Criterion with an "and" +link{type:OperatorId,operator} // and both "greaterOrEqual" and "lessOrEqual" sub-criteria will be returned. If either // date is omitted, only the "greaterOrEqual" (from date) or "lessOrEqual" (to date) // Criterion is returned. // // @return (Criterion) // // @group criteriaEditing // @visibility external //< getCriterion : function () { var criteria = this.rangeItem ? this.rangeItem.getCriterion() : null; return criteria; }, //> @method miniDateRangeItem.setCriterion() // @include dateRangeItem.setCriterion() // @visibility external //< setCriterion : function (criterion) { if (this.rangeItem) { this.rangeItem.setCriterion(criterion); var value = this.rangeItem.getValue(); // call superclass 'setValue()' to update display and store // the new DateRange value derived from the criterion passed in // Pass flag to suppress updating the dateRangeItem again this.setValue(value, null, true); } }, //> @method miniDateRangeItem.canEditCriterion() // @include dateRangeItem.canEditCriterion() // @visibility external //< canEditCriterion : function (criterion) { return this.rangeItem ? this.rangeItem.canEditCriterion(criterion) : false; }, //> @method miniDateRangeItem.setValue() // Sets the value for this miniDateRangeItem. The value parameter is a // +link{object:DateRange} object that optionally includes both start and end values. // @param value (DateRange) the new value for this item // @visibility external //< setValue : function (value, allowNull, fromRangeItem) { // update this.fromDate / this.toDate this.updateStoredDates(value); // update the rangeItem if (!fromRangeItem && this.rangeItem.setFromDate && this.rangeItem.setToDate) { this.rangeItem.setFromDate(this.fromDate); this.rangeItem.setToDate(this.toDate); } // this will store the value in the DynamicForm values object, and // refresh to display the value var newArgs = [this.getValue()]; this.Super("setValue", newArgs, arguments); }, updateStoredDates : function (value) { if (value != null) { if (isc.DataSource.isAdvancedCriteria(value)) { // value has come back as an AdvancedCriteria! var newValue = {}; for (var i=0; i @method miniDateRangeItem.getValue() // Retrieves the current value of this dateRangeItem. The return value is a // +link{object:DateRange} object that excludes start and end values if they aren't // set. // @return (DateRange) the current value of this item // @visibility external //< getValue : function () { if (!this.rangeItem) return; return this.rangeItem.getValue(); }, // formatDate() - given a live date object, returns the formatted date string to display formatDate : function (date) { if (!isc.isA.Date(date)) return date; var type = this.getType(), isLogicalDate = isc.SimpleType.inheritsFrom(type, "date") && !isc.SimpleType.inheritsFrom(type, "datetime"); return date.toShortDate(this._getDateFormatter(), !isLogicalDate); }, getCriteriaValue : function () { return this.getCriterion(); }, destroy : function () { if (this.rangeDialog) this.rangeDialog.markForDestroy(); this.Super("destroy", arguments); } }); } }