![JAR search and dependency download from the Maven repository](/logo.png)
com.smartclient.debug.public.sc.client.widgets.DetailViewer.js Maven / Gradle / Ivy
Show all versions of smartgwt Show documentation
/*
* Isomorphic SmartClient
* Version SC_SNAPSHOT-2011-08-08 (2011-08-08)
* Copyright(c) 1998 and beyond Isomorphic Software, Inc. All rights reserved.
* "SmartClient" is a trademark of Isomorphic Software, Inc.
*
* [email protected]
*
* http://smartclient.com/license
*/
//> @class DetailViewer
//
// Displays one or more records "horizontally" with one property per line.
//
// @implements DataBoundComponent
// @treeLocation Client Reference/Grids
// @visibility external
//<
isc.ClassFactory.defineClass("DetailViewer", "Canvas", "DataBoundComponent");
// add default properties
isc.DetailViewer.addProperties({
// Data
// --------------------------------------------------------------------------------------------
//> @attr detailViewer.data (Array of DetailViewerRecord : null : IRW)
// A single record object or an array of them, specifying data. Note that DetailViewers do
// not observe changes to the data array (in other words they will not automatically
// re-draw when the data provided via this property is altered).
//
// @group basics
// @visibility external
//<
//> @attr detailViewer.dataFetchMode (FetchMode : "basic" : IRW)
// DetailViewers do not yet support paging, and will fetch and render all available
// records.
//
// @group databinding
// @visibility external
//<
dataFetchMode:"basic",
// dataArity:"either" - DetailViewers support viewing single, or multiple records
dataArity:"either",
//> @object DetailViewerRecord
//
// A DetailViewerRecord is an object literal with properties that define the values for the
// various fields of a +link{DetailViewer}.
//
// For example a DetailViewer that defines the following fields:
//
// fields : [
// {name: "field1"},
// {name: "field2"}
// ],
//
// Might have the following data:
//
// data : [
// {field1: "foo", field2: "bar"},
// {field1: "field1 value", field2: "field2 value"}
// ]
//
// Each element in the data array above is an instance of DetailViewerRecord - notice that
// these are specified simply as object literals with properties.
//
// @treeLocation Client Reference/Grids/DetailViewer
// @visibility external
//<
// Fields
// ---------------------------------------------------------------------------------------
//> @attr detailViewer.fields (List of DetailViewerField : null : IRW)
//
// An array of field objects, specifying the order and type of fields to display in this
// DetailViewer. In DetailViewers, the fields specify rows.
//
// @visibility external
//<
//> @object DetailViewerField
//
// An object literal with a particular set of properties used to configure the display of
// and interaction with the rows of a +link{DetailViewer}.
//
// @treeLocation Client Reference/Grids/DetailViewer
// @visibility external
//<
//> @attr DetailViewerField.name (String : null : IR)
// Name property used to identify the field, and determines which attribute from
// records will be displayed in this field.
// @visibility external
//<
//> @attr DetailViewerField.dataPath (String : null : IRA)
// dataPath property allows this field to display detail from nested data structures
// @visibility external
//<
//> @method DetailViewerField.formatCellValue()
// Optional method to format the value to display for this field's cells. Takes precedence over
// +link{DetailViewer.formatCellValue()} for cells in this field.
// @param value (string) the raw value of the cell
// @param record (detailViewerRecord) the record being displayed
// @param field (detailViewerField) the field being displayed
// @param viewer (detailViewer) the detailViewer containing this field
// @group i18nMessages
// @visibility external
//<
//> @attr detailViewerField.dateFormatter (DateDisplayFormat : null : [IRW])
// Display format to use for date type values within this field.
//
// The +link{detailViewerField.timeFormatter} may also be used to format underlying Date values as
// times (ommitting the date part entirely). If both dateFormatter
and
// timeFormatter
are specified on a field, for
// fields specified as +link{detailViewerField.type,type "time"} the
// timeFormatter
will be used, otherwise the dateFormatter
//
// If field.dateFormatter
and field.timeFormatter
is unspecified,
// date display format may be defined at the component level via
// +link{detailViewer.dateFormatter}, or for fields of type "datetime"
// +link{detailViewer.datetimeFormatter}. Otherwise the
// default is to use the system-wide default normal date format, configured via
// +link{Date.setNormalDisplayFormat()}. Specify any valid +link{type:DateDisplayFormat} to
// change the format used by this item.
//
// @see listGrid.dateFormatter
// @see listGrid.datetimeFormatter
// @see listGridField.timeFormatter
// @visibility external
//<
//> @attr detailViewerField.timeFormatter (TimeDisplayFormat : null : [IRWA])
// Time-format to apply to date type values within this field. If specified, any
// dates displayed in this field will be formatted as times using the appropriate format.
// This is most commonly only applied to fields specified as type "time"
though
// if no explicit +link{detailViewerField.dateFormatter} is specified it will be respected for other
// fields as well.
//
// If unspecified, a timeFormatter may be defined
// +link{detailViewer.timeFormatter,at the component level} and will be respected by fields
// of type "time"
.
//
// @group appearance
// @visibility external
//<
//timeFormatter:null
//> @attr detailViewerField.imageSize (number : null : IRW)
// Size of images shown for fieldTypes image in this field.
//
// If set to a String, assumed to be a property on each record that specifies the image
// height. For example, if field.imageSize
is "logoSize",
// record.logoSize
will control the size of the image.
//
// @see attr:detailViewerField.imageWidth
// @see attr:detailViewerField.imageHeight
//
// @group imageColumns
// @visibility external
//<
//> @attr detailViewerField.imageWidth (number : null : IRW)
// Width of images shown for fieldTypes image in this field.
//
// If set to a String, assumed to be a property on each record that specifies the image
// width. For example, if field.imageWidth
is "logoWidth",
// record.logoWidth
will control the width of the image.
//
// @see attr:detailViewerField.imageSize
// @see attr:detailViewerField.imageHeight
//
// @group imageColumns
// @visibility external
//<
//> @attr detailViewerField.imageHeight (number : null : IRW)
// Height of image shown for fieldTypes image in this field.
//
// If set to a String, assumed to be a property on each record that specifies the image
// height. For example, if field.imageHeight
is "logoHeight",
// record.logoHeight
will control the height of the image.
//
// @see attr:detailViewerField.imageSize
// @see attr:detailViewerField.imageWidth
//
// @group imageColumns
// @visibility external
//<
//> @attr detailViewerField.imageURLPrefix (string : null : IRWA)
// If this field has type set to "image"
// and the URL for the image displayed is not absolute, the path of the URL will be relative
// to this string
//
// @group imageColumns
// @visibility external
//<
//> @method detailViewerField.showIf
//
// If specified on a field, this method is evaluated at draw time to determine whether or
// not to show this particular field.
//
// This method can be specified either as a function or a string that will be
// auto-converted to a function.
//
// @param viewer (DetailViewer) The DetailViewer
// @param valueList (List of DetailViewerRecord)
//
// @return (boolean) true to show the field, false to not show it.
//
// @visibility external
//<
//> @attr detailViewerField.type (String : null : IR)
//
// Specifies the type of this DetailViewerField. By default (value is null
)
// the field shows a field title on the left and the field value on the right. There are
// two special values for this attribute:
//
// - "header" - If you specify type "header", the field spans both the field name and
// field value columns and contains text defined in the +link{DetailViewerField.value}
// attribute with the style specified by +link{DetailViewer.headerStyle}. You can use this
// field type as a titled separator.
//
- "separator" - If you specify type "separator", the field spans both the field name
// and the field value columns with no text, and is styled using the style specified via
// +link{DetailViewer.separatorStyle}. The height of the separator field can be controlled
// via +link{DetailViewerField.height}.
//
- "image" For viewing, a thumbnail image is rendered in the field. The URL of the
// image is the value of the field, and should be absolute. The size of the image is
// controlled by +link{attr:DetailViewerField.imageSize},
// +link{attr:DetailViewerField.imageWidth}, +link{attr:DetailViewerField.imageHeight}
//
//
// @visibility external
//<
//> @attr detailViewerField.title (HTMLString : null : IR)
//
// The title of the field as displayed on the left-hand side. If left unspecified, the
// title of the field is derived by looking up the value of
// +link{DetailViewer.fieldIdProperty} on this field. So, by default, the title of a field
// is the value of its "name" property.
//
// @see DetailViewer.fieldIdProperty
// @visibility external
//<
//> @attr detailViewerField.valueMap (object : null : IR)
//
// A property list (or an expression that evaluates to a property list)
// specifying a mapping of internal values to display values for the field (row).
//
// @visibility external
//<
//> @attr detailViewerField.escapeHTML (boolean : null : IR)
// By default HTML values in DetailViewer cells will be interpreted by the browser.
// Setting this flag to true will causes HTML characters to be escaped, meaning the
// raw value of the field (for example "<b>AAA</b>"
) is displayed
// to the user rather than the interpreted HTML (for example "AAA"
)
//
// @visibility external
//<
//> @attr detailViewerField.value (HTMLString : "undefined" : IR)
//
// When a field specifies its +link{detailViewerField.type} to be "header", the value of
// this attribute specifies the header text.
//
// @visibility external
//<
//> @attr detailViewerField.width (Number : null : IR)
//
// @visibility internal
//<
//> @attr detailViewerField.height (Number : null : IR)
//
// For +link{DetailViewerField.type}: "separator"
, this attribute specifies
// the height of the separator.
//
// @visibility external
//<
//> @method detailViewerField.getCellStyle()
// Optional method to return the CSS class for cells in this field. If specified, this method
// will be called from +link{detailViewer.getCellStyle()}, and should return a css class name.
//
// @param value (string) actual value of this cell
// @param field (object) field object for this cell
// @param record (object) record object for this cell
// @param viewer (DetailViewer) the viewer instance to which this cell belongs
//
// @return (CSSStyleName) CSS style for this cell
// @group appearance
// @visibility external
//<
//> @attr detailViewerField.cellStyle (CSSClassName : null : IRW)
// If specified, cells in this field will be rendered using this css className rather than
// +link{detailViewer.cellStyle}
// @visibility external
//<
//> @attr detailViewerField.printCellStyle (CSSClassName : null : IRW)
// If specified, when generating print HTML for this detailViewer,
// cells in this field will be rendered using this css className rather than
// +link{detailViewer.printCellStyle}
// @visibility external
//<
//> @attr detailViewerField.showFileInline (boolean : null : [IR])
// For a field of type:"imageFile", indicates whether to stream the image and display it
// inline or to display the View and Download icons.
//
// @visibility external
//<
//> @attr detailViewerField.canExport (Boolean : null : IR)
// Dictates whether the data in this field be exported. Explicitly set this
// to false to prevent exporting. Has no effect if the underlying
// +link{dataSourceField.canExport, dataSourceField} is explicitly set to
// canExport: false.
//
// @visibility external
//<
//> @attr detailViewer.fieldIdProperty (string : "name" : IRWA)
// Name of the field in the DetailViewerRecord which specifies the data property for that record.
// @visibility external
//<
fieldIdProperty:"name",
//> @attr detailViewerField.includeFrom (string : null : [IR])
// Indicates this field's values come from another, related DataSource.
// The individual field will inherit settings such as +link{DetailViewerField.type,field.type}
// and +link{DetailViewerField.title,field.title} from the related DataSource just like
// fields from the primary DataSource.
//
// @visibility crossDS
//<
// Multi-record display
// --------------------------------------------------------------------------------------------
//> @attr detailViewer.recordsPerBlock (number : 1 : [IRW])
// The number of records to display in a block. A block is a horizontal row on a page
// containing one or more records, as specified by the value of recordsPerBlock. The
// height of a block is equal to the height of a single record. The default setting of
// 1 causes each record to appear by itself in a vertical row. Setting recordsPerBlock
// to 2 would cause records to appear side by side in groups of two.
// Use a value of "*" to indicate all records.
// @group appearance
// @visibility external
//<
recordsPerBlock:1,
//> @attr detailViewer.blockSeparator (HTMLString : "
" : [IRW])
// A string (HTML acceptable) that will be written to a page to separate blocks.
// @group appearance
// @visibility external
//<
blockSeparator:"
",
// Empty values
// --------------------------------------------------------------------------------------------
//> @attr detailViewer.showEmptyField (boolean : true : IRWA)
// Whether to show the field when the value is null
// @group appearance
// @visibility external
//<
showEmptyField:true,
//> @attr detailViewer.emptyCellValue (HTMLString : " " : IRWA)
// Text to show for an empty cell
// @group appearance
// @visibility external
//<
emptyCellValue:" ",
// Labels
// --------------------------------------------------------------------------------------------
//> @attr detailViewer.labelPrefix (HTMLString : "" : IRW)
// text to put before a label
// @group labels
// @visibility external
//<
labelPrefix:"",
//> @attr detailViewer.labelSuffix (HTMLString : ":" : IRW)
// text to put after a label
// @group labels
// @visibility external
//<
labelSuffix:":",
//> @attr detailViewer.valueAlign (alignEnum : "left" : IRW)
// horizontal alignment of values
// @group values
//<
valueAlign:"left",
//> @attr detailViewer.wrapLabel (boolean : false : IRW)
// Should the label be allowed to wrap, or be fixed to one line no matter how long
// @group labels
// @visibility external
//<
//> @attr detailViewer.wrapValues (boolean : true : IR)
// Whether values should be allowed to wrap by default, or should be shown on one line
// regardless of length.
//
// @group labels
// @visibility external
//<
wrapValues: true,
// internal property used by tileGrid to force table size to be width 100%
useInnerWidth: true,
// internal property to clip cell values
clipValues: false,
// CSS styles
// --------------------------------------------------------------------------------------------
//> @attr detailViewer.styleName (CSSStyleName : "detailViewer" : IRW)
// CSS style for the component as a whole.
// @group appearance
// @visibility external
//<
styleName:"detailViewer",
//> @attr detailViewer.blockStyle (CSSStyleName : "detailBlock" : IRW)
// CSS style for each block (one record's worth of data).
// @group appearance
// @visibility external
//<
blockStyle:"detailBlock",
//> @attr detailViewer.labelStyle (CSSStyleName : "detailLabel" : IRW)
// CSS style for a normal detail label
// @group appearance
// @visibility external
//<
labelStyle:"detailLabel",
//> @attr detailViewer.cellStyle (CSSStyleName : "detail" : IRW)
// CSS style for a normal value
// @group appearance
// @visibility external
//<
cellStyle:"detail",
//> @attr detailViewer.headerStyle (CSSStyleName : "detailHeader" : IRW)
// CSS style for a header
// @group appearance
// @visibility external
//<
headerStyle:"detailHeader",
//> @attr detailViewer.printCellStyle (CSSStyleName : null : IRW)
// Optional CSS style for a cell in printable HTML for this component. If unset
// +link{detailViewer.cellStyle} will be used for printing as well as normal presentation.
// @group printing
// @visibility external
//<
//> @attr detailViewer.printLabelStyle (CSSStyleName : null : IRW)
// Optional CSS style for a label cell in printable HTML for this component. If unset
// +link{detailViewer.labelStyle} will be used for printing as well as normal presentation.
// @group printing
// @visibility external
//<
//> @attr detailViewer.printHeaderStyle (CSSStyleName : null : IRW)
// Optional CSS style for a header in printable HTML for this component. If unset
// +link{detailViewer.headerStyle} will be used for printing as well as normal presentation.
// @group printing
// @visibility external
//<
//> @attr detailViewer.separatorStyle (CSSStyleName : "detail" : IRW)
// CSS style for a separator
// @group appearance
// @visibility external
//<
separatorStyle:"detail",
//> @attr detailViewer.cellPadding (number : 3 : [IRW])
// The amount of empty space, in pixels, surrounding each detailViewer value in its
// cell.
//<
cellPadding:3,
//> @attr detailViewer.dateFormatter (DateDisplayFormat : null : [IRW])
// How should Date type values be displayed in this DetailViewer by default?
//
// This property specifies the default DateDisplayFormat to apply to Date values
// displayed in this grid for all fields except those of +link{detailViewerField.type,type "time"}
// (See also +link{detailViewer.timeFormatter}).
// If +link{detailViewer.datetimeFormatter} is specified, that will be applied by default
// to fields of type "datetime"
.
//
// Note that if +link{detailViewerField.dateFormatter} or +link{detailViewerField.timeFormatter} are
// specified those properties will take precedence over the component level settings.
//
// If unset, date values will be formatted according to the system wide
// +link{Date.setNormalDisplayFormat(),normal display format}.
//
// @visibility external
//<
//dateFormatter:null,
//> @attr detailViewer.datetimeFormatter (DateDisplayFormat : null : [IRW])
// Display format to use for fields specified as type 'datetime'. Default is to use the
// system-wide default long ("normal") date time format, configured via
// +link{Date.setNormalDatetimeDisplayFormat()}. Specify any
// valid +link{type:DateDisplayFormat} to change the display format for datetimes used by this
// viewer.
//
// May be specified as a function. If specified as a function, this function will
// be executed in the scope of the Date
// and should return the formatted string.
//
//
// May also be specified at the field level via
// +link{detailViewerField.dateFormatter}
//
// @see listGridField.dateFormatter
// @group appearance
// @visibility external
//<
//> @attr detailViewer.timeFormatter (TimeDisplayFormat : null : [IRW])
// Display format to use for fields specified as type 'time'. May also be specified at
// the field level via +link{detailViewerField.timeFormatter}.
// If unset, time fields will be formatted based on the system wide
// +link{Time.setNormalDisplayFormat()}
// @group appearance
// @visibility external
//<
// Empty Message
// --------------------------------------------------------------------------------------------
//> @attr detailViewer.showEmptyMessage (boolean : true : IRWA)
// Show +link{attr:detailViewer.emptyMessage} when there is no data to display?
// @see emptyMessage
// @group emptyMessage
// @visibility external
//<
showEmptyMessage:true,
//> @attr detailViewer.emptyMessage (HTMLString : "No items to display." : IRW)
// The string to display in the body of a detailViewer with no records.
// @group emptyMessage
// @visibility external
//<
emptyMessage:"No items to display.",
//> @attr detailViewer.emptyMessageStyle (CSSStyleName : "normal" : IRWA)
// CSS style to display this message in
// @group emptyMessage
// @visibility external
//<
emptyMessageStyle:"normal",
//> @attr detailViewer.loadingMessage (HTMLString : " \${loadingImage}" : IRW)
// The string to display in the body of a detailViewer which is loading records.
// Use "\${loadingImage}"
to include +link{Canvas.loadingImageSrc,a loading image}.
// @group emptyMessage
// @visibility external
//<
loadingMessage:" ${loadingImage}",
//> @attr detailViewer.loadingMessageStyle (CSSStyleName : "normal" : IRWA)
// CSS style to use for the +link{loadingMessage}.
// @group emptyMessage
// @visibility external
//<
loadingMessageStyle:"normal",
// ---------------------------------------------------------------------------------------
// About two values worth of data. Keeps the DV from taking up the 100px default height
// without being unexpectedly small when it has no data.
defaultHeight:35 ,
showLabel: true
});
// add methods
isc.DetailViewer.addMethods({
//> @method detailViewer.initWidget() (A)
// initializes the list of fields
// sets up the data (if specified)
//
// @param [all arguments] (object) objects with properties to override from default
//<
initWidget : function () {
// call the superclass function
this.Super("initWidget",arguments);
// set field state if necessary, call setFields() otherwise
if (this.fieldState != null) this.setFieldState(this.fieldState);
else this.setFields(this.fields);
},
//> @method detailViewer.setData() ([])
// Sets the data displayed by this detail viewer.
//
// @visibility external
// @param newData (object or array) new data to be displayed
//<
setData : function (newData) {
// clear old observation
if (this.data) this.ignore(this.data, "dataChanged");
// remember the new data
this.data = newData;
if (this.data && this.data.dataChanged) {
this.observe(this.data, "dataChanged", "observer.dataChanged()");
}
// and mark the viewer as dirty so it'll be redrawn
this.markForRedraw("new data");
},
dataChanged : function () {
this.applyHilites();
this.markForRedraw();
},
//> @method detailViewer.getData() (A)
// return the data to be displayed
//
// @return (Object) data for this widget - either Object or Array
//<
getData : function () { return this.data; },
//> @method detailViewer.getFields() (A)
// return the list of fields to display
//
// @return (List of DetailViewerField) array of objects to display
//<
getFields : function () { return this.fields; },
//> @method detailViewer.getInnerHTML() (A)
// return the HTML for this widget
// @return (string) HTML to display
//<
getInnerHTML : function () {
// get the data to display
var valueList = this.getData();
//>DEBUG
if (this.fields == null || this.fields.length == 0) {
return "Note: you must define detailViewer.fields to specify what to display!";
}
// @method detailViewer.getBlockHTML() (A)
// Return the HTML for either a single object or a set of objects where each object gets one
// column.
// @return (string) HTML to display
//<
getBlockHTML : function (valueList) {
// how many separate value objects are we dealing with ?
var numValues = valueList.getLength();
// start the table to display the output
var output = "
";
// output the data
// get the list of fields to output
var fields = this.fields;
// iterate through each of the keys in detailFields and output the info for each field
for (var fieldNum = 0, fieldLength = fields.length; fieldNum < fieldLength; fieldNum++) {
var field = fields[fieldNum];
if (!field || field.hidden || field.visible == false) continue;
// if the field has a showIf property
if (field.showIf) {
// CALLBACK API: available variables: "viewer,valueList"
// Convert a string callback to a function
if (!isc.isA.Function(field.showIf)) {
isc.Func.replaceWithMethod(field, "showIf", "viewer,valueList");
}
// skip this if the showIf returns false
if (field.showIf(this, valueList) == false) continue;
}
// MAE: if we don't want to show fields that have empty/null values
// check the appropriate values and skip if they are all empty/null
// This does not apply to headers and separators
var type = field.type ? field.type : "";
if (type != "separator" && type != "header" && !this.showEmptyField) {
var valuesAreEmpty = true;
for (var i = 0; i < valueList.getLength(); i++) {
var value = valueList.get(i)[field[this.fieldIdProperty]]
if (!(value == null || value == "")) {
valuesAreEmpty = false;
break;
}
}
// if no values were found, continue to the next field
if (valuesAreEmpty) continue;
}
// if there is a specific output function for this field, call that
if (field.output) {
// CALLBACK API: available variables: "fieldNum,field,valueList"
// Convert a string callback to a function
if (!isc.isA.Function(field.output)) {
isc.Func.replaceWithMethod(field, "output", "fieldNum,field,valueList");
}
output += field.output(fieldNum, field, valueList);
} else {
// output this particular field
output += this.outputItem(fieldNum, field, valueList);
}
}
// end the table
output += "
";
// and return the output
return output;
},
//> @method detailViewer.outputItem() (A)
// Output one row of the data as HTML
// @param fieldNum (number) number of the field to output
// @param field (object) pointer to the field to output
// @param valueList (array) list of values to output
//
// @return (string) HTML output
//<
outputItem : function (fieldNum, field, valueList) {
var type = (field.type ? field.type : "value"),
// functionName == name of a function to call to ouput this particular type of object
functionName = "output_"+type,
output = ""
;
// if a function by that name cannot be found, default to output_value
if (!this[functionName]) functionName = "output_value";
// start the table row
output += "";
// output
output += this[functionName](fieldNum, field, valueList);
// end the row
output += " \r";
// return the output
return output;
},
//
// OUTPUT HTML FOR DIFFERENT TYPES OF OBJECTS
//
//> @method detailViewer.output_value() (A)
// output a normal value for each field in valueList
// @param fieldNum (number) number of the field to output
// @param field (object) pointer to the field to output
// @param valueList (array) list of values to output
//
// @return (string) HTML output
//<
output_blob : function (fieldNum, field, valueList) {
return this.output_binary(fieldNum, field, valueList);
},
output_upload : function (fieldNum, field, valueList) {
return this.output_binary(fieldNum, field, valueList);
},
output_binary : function (fieldNum, field, valueList) {
// output the label
var output = "" : " NOWRAP>")
+ this.labelPrefix + (field.title ? field.title : field[this.fieldIdProperty]) + this.labelSuffix
+ "<\/NOBR><\/TD>"
;
// iterate for each object in valueList, outputing the object[field[this.fieldIdProperty]]
for (var i = 0; i < valueList.getLength(); i++) {
var record = valueList.get(i),
index = this.getData().indexOf(record),
nativeName = field.nativeName || field.name,
name = record[nativeName+"_filename"],
viewIconHTML = isc.Canvas.imgHTML("[SKIN]actions/view.png", 16, 16, null,
"style='cursor:"+isc.Canvas.HAND+"' onclick='"+this.getID()+".viewRow("+index+")'"),
downloadIconHTML = isc.Canvas.imgHTML("[SKIN]actions/download.png", 16, 16, null,
"style='cursor:"+isc.Canvas.HAND+"' onclick='"+this.getID()+".downloadRow("+index+")'"),
value = viewIconHTML + " " + downloadIconHTML + " " + name;
// output the value as a cell
output += ""
+ value + "<\/TD>";
}
return output;
},
viewRow : function (index) {
isc.DS.get(this.dataSource).viewFile(this.getData().get(index));
},
downloadRow : function (index) {
isc.DS.get(this.dataSource).downloadFile(this.getData().get(index));
},
// given an Array of records (valueList) output one complete DetailViewer row, which will have
// multiple data columns if recordsPerBlock > 1
output_value : function (fieldNum, field, valueList) {
// output the label
var output;
if (this.showLabel) {
output = " " : " NOWRAP>")
+ this.labelPrefix + (field.title ? field.title : field[this.fieldIdProperty]) + this.labelSuffix
+ "<\/NOBR><\/TD>"
;
} else {
output = "";
}
// resolve field level valueMap reference strings to objects before going into the for loop
if (field.valueMap && isc.isA.String(field.valueMap))
field.valueMap = this.getGlobalReference(field.valueMap);
// iterate for each object in valueList, outputing the object[field.name]
for (var i = 0; i < valueList.getLength(); i++) {
var record = valueList.get(i),
formattedValue;
if (field.type == "image") {
// if any of field.imageWidth/Height/Size are set as strings, assume they are property
// names on the record
var dimensions = isc.Canvas.getFieldImageDimensions(field, record);
var src = this.getCellValue(record, field), prefix =
field.imageURLPrefix || field.baseURL || field.imgDir;
formattedValue = this.imgHTML(src, dimensions.width, dimensions.height, null,
field.extraStuff, prefix, field.activeAreaHTML);
} else {
// NOTE: calls formatCellValue()
formattedValue = this.getCellValue(record, field);
}
// determine the cell style
var rawValue = this.getRawValue(record,field);
var cellStyle;
if (field.getCellStyle) {
cellStyle = field.getCellStyle(rawValue, field, record, this);
} else {
cellStyle = (this.getCellStyle(rawValue, field, record, this) || this.cellStyle);
}
// put together a STYLE attribute
var styleStr = " style='";
if (this.clipValues) styleStr += "overflow:hidden;";
styleStr += "text-align:" + this.valueAlign;
// allow custom CSS text per field
if (this.getCellCSSText) {
var cssText = this.getCellCSSText(rawValue, field, record, this);
if (cssText != null) styleStr += isc.semi + cssText;
}
// output the value as a cell
styleStr += "'";
output += "" : " NOWRAP>") +
formattedValue +
(this.wrapValues ? "<\/NOBR>" : "") +
"<\/TD>";
}
return output;
},
getRawValue : function (record, field) {
if (!record || !field) return null;
if (field.dataPath) return isc.Canvas._getFieldValue(field.dataPath, record);
return record[field.name];
},
//> @method detailViewer.getCellCSSText()
// Return CSS text for styling this cell, which will be applied in addition to the CSS class
// for the cell, as overrides.
//
// "CSS text" means semicolon-separated style settings, suitable for inclusion in a CSS
// stylesheet or in a STYLE attribute of an HTML element.
//
// @param value (any) actual value of this cell
// @param field (DetailViewerField) field object for this cell
// @param record (Record) record object for this cell
// @param viewer (DetailViewer) the viewer instance to which this cell belongs
// @return (CSSText) CSS text to add to this cell
//
// @group appearance
// @visibility external
//<
getCellCSSText : function (value, field, record, viewer) {
return this.getRecordHiliteCSSText(record, "", field);
},
//> @method detailViewer.getCellStyle()
// Return the CSS class for a cell. Default implementation calls
// +link{detailViewerField.getCellStyle(), getCellStyle()} on the field if defined, otherwise
// returns +link{detailViewer.cellStyle,this.cellStyle}
// @param value (any) actual value of this cell
// @param field (DetailViewerField) field object for this cell
// @param record (Record) record object for this cell
// @param viewer (DetailViewer) the viewer instance to which this cell belongs
// @return (CSSStyleName) CSS style for this cell
// @group appearance
// @visibility external
//<
//
// Note: if +link{detailViewer.printCellStyle} is specified this will be used as the default
// styling for cells instead of this.cellStyle
when generating printable HTML for
// this component.
getCellStyle : function (value, field, record, viewer) {
if (field) {
if (field.getCellStyle) return field.getCellStyle(value,field,record,viewer);
if (this.isPrinting && field.printCellStyle) {
return field.printCellStyle;
}
if (field.cellStyle) {
return field.cellStyle;
}
}
return (this.isPrinting && this.printCellStyle != null) ? this.printCellStyle
: this.cellStyle;
},
//> @method DetailViewer.formatCellValue()
// Optional method to format the value to display for cells in this DetailViewer.
// Note that if +link{detailViewerField.formatCellValue()} is specified this method will not
// be called for cells within that field.
// @param value (string) the raw value of the cell (may be formatted by
// +link{detailViewerField.formatCellValue()}
// @param record (detailViewerRecord) the record being displayed
// @param field (detailViewerField) the field being displayed
// @group i18nMessages
// @visibility external
//<
getSelectedRecord : function() {
return this.data.get(0);
},
// getCellValue - method to actually get the value for a record.
// Called from 'output_value', which handles writing the
tags around the value and
// outputting a whole block of records.
// Can be overridden by a user.
// Also if 'getCellValue()' is specified at a field level, will apply it to this cell.
getCellValue : function (record, field) {
// get the value of this key for that field
var value = this.getRawValue(record,field);
if (isc.isA.String(field.formatCellValue)) {
field.formatCellValue = isc.Func.expressionToFunction("value,record,field,viewer",
field.formatCellValue);
}
if (field.getCellValue != null) {
if (isc.isA.String(field.getCellValue)) {
field.getCellValue = isc.Func.expressionToFunction("value,record,field,viewer",
field.getCellValue);
}
// note the 'value' passed into field.getCellValue() is the raw value, not valueMapped, etc.
// This matches the ListGrid's field-level getCellValue behavior.
value = field.getCellValue(value, record, field, this);
if (field.formatCellValue) value = field.formatCellValue(value, record, field, this);
} else {
// if the col has an 'valueMap' parameter, treat the value as a key in the valueMap
if (field.valueMap != null) value = isc.getValueForKey(value, field.valueMap);
if (field.formatCellValue) value = field.formatCellValue(value, record, field, this);
// if no value was specified, output the emptyCellValue
if (value == null || isc.is.emptyString(value)) value = this.emptyCellValue;
}
// Support formatCellValue if specified.
// - to match ListGrid behavior, don't run both field.formatCellValue and DV.formatCellValue()
if (field.formatCellValue == null && this.formatCellValue) {
value = this.formatCellValue(value, record, field);
} else {
// _formatDataType ensures that non string values get formatted as strings as appropriately
value = this._formatDataType(record, field, value);
// field.escapeHTML is a boolean - if true, escape HTML chars in the value such as "<".
var escapeHTML = field.escapeHTML;
// asHTML was old name
if (escapeHTML == null) escapeHTML = field.asHTML;
if (escapeHTML) value = value.asHTML();
}
// handle formula and summary fields
if (field) {
if (field.userFormula) value = this.getFormulaFieldValue(field, record);
else if (field.userSummary) value = this.getSummaryFieldValue(field, record);
else if (field.type=="imageFile") {
if (field.showFileInline != false) {
if (!record[field[this.fieldIdProperty] + "_imgURL"]) {
var dimensions = isc.Canvas.getFieldImageDimensions(field, record),
image = this.getDataSource().streamFile(record);
value = record[field[this.fieldIdProperty] + "_imgURL"] =
this.imgHTML(image, dimensions.width, dimensions.height);
} else
value = record[field[this.fieldIdProperty] + "_imgURL"];
} else {
value = this.getViewDownloadHTML(field, record);
}
} else if (field.showFileInline == true) { // non-imageFile field
this.logWarn("getCellValue(): Unsupported field-type for showFileInline: "+field.type);
}
}
// apply hilites to capture htmlBefore/after
var hilites = this.getFieldHilites(record, field);
if (hilites != null) value = this.applyHiliteHTML(hilites, value);
return value;
},
getViewDownloadHTML : function (field, record) {
if (record == null) return null;
var nativeName = field.nativeName || field.name,
name = record[nativeName + "_filename"];
if (name == null || isc.isA.emptyString(name)) return " ";
var viewIconHTML = isc.Canvas.imgHTML("[SKIN]actions/view.png", 16, 16, null,
"style='cursor:"+isc.Canvas.HAND+
"' onclick='"+this.getID()+".viewFile("+record+","+field+")'");
var downloadIconHTML = isc.Canvas.imgHTML("[SKIN]actions/download.png", 16, 16, null,
"style='cursor:"+isc.Canvas.HAND+
"' onclick='alert('running');"+this.getID()+".downloadFile("+record+","+field+")'");
return "" + viewIconHTML + " " + downloadIconHTML + " " + name + " ";
},
viewFile : function (record, field) {
isc.DS.get(this.dataSource).viewFile(record, field.name);
},
downloadFile : function (record, field) {
isc.DS.get(this.dataSource).downloadFile(record, field.name);
},
// _formatDataType, format a cell value based on data type.
// At this point we've checked for field.formatValue etc. Current implementation:
// - if a formatter is defined on the SimpleType make use of it
// - otherwise format dates according to standard DBC rules:
// - use field.dateFormatter or field.timeFormatter if specified
// - otherwise use component.dataFormatter, component.timeFormatter, component.datetimeFormatter
// depending on field type.
_$date:"date",
_formatDataType : function (record, field, value) {
// Format date values, according to standard DBC rules
// Respect field level dateFormatter/timeFormatter if specified
// Otherwise respect component level dateFormatter/datetimeFormatter/timeFormatter depending
// on specified field-type.
if (isc.isA.Date(value)) {
if (this._formatAsTime(field)) {
var isLogicalTime = isc.SimpleType.inheritsFrom(field.type, "time");
value = isc.Time.toTime(value, this._getTimeFormatter(field), isLogicalTime);
} else {
// If the field is a logical date field
// use short formatter, since the "time" part of
// the date has no real meaning (and no long formatters suppress time).
// Otherwise use the long format by default for DetailViewers.
if (isc.SimpleType.inheritsFrom(field.type, "date") &&
!isc.SimpleType.inheritsFrom(field.type, "datetime"))
{
value = value.toShortDate(this._getDateFormatter(field), false);
} else {
value = value.toNormalDate(this._getDateFormatter(field));
}
}
}
// If normalDisplayFormatter is specified on the simpleType make use of it
if (field._normalDisplayFormatter != null) {
value = field._simpleType.normalDisplayFormatter(value, field, this, record);
}
return isc.iscToLocaleString(value);
},
_formatAsTime : function (field) {
if (field == null) return false;
if (field.dateFormatter == null && field.timeFormatter != null) return true;
if (field.timeFormatter == null && field.dateFormatter != null) return false;
return isc.SimpleType.inheritsFrom(field.type, "time");
},
_getDateFormatter : function (field) {
if (field.dateFormatter) return field.dateFormatter;
if (field.displayFormat != null && isc.SimpleType.inheritsFrom(field.type, "date")) {
return field.displayFormat;
}
if (this.datetimeFormatter != null && isc.SimpleType.inheritsFrom(field.type, "datetime")) {
return this.datetimeFormatter;
}
return this.dateFormatter;
},
_getTimeFormatter : function (field) {
if (field.timeFormatter) return field.timeFormatter;
if (field.displayFormat != null && isc.SimpleType.inheritsFrom(field.type, "time")) {
return field.displayFormat;
}
return this.timeFormatter;
},
//> @method detailViewer.getRecordIndex()
// @param record (Record) the record whose index is to be retrieved
// @return index (Number) index of the record, or -1 if not found
// @include dataBoundComponent.getRecordIndex
// @visibility external
//<
getRecordIndex : function (record) {
var result = this.Super('getRecordIndex', arguments);
if (result==-1) result = 0;
return result;
},
//> @method detailViewer.output_header() (A)
// output a header field
// @param fieldNum (number) number of the field to output
// @param field (object) pointer to the field to output
// @param valueList (array) list of values to output
//
// @return (string) HTML output
//<
output_header : function (fieldNum, field, valueList) {
return " "+field.value+" ";
},
//> @method detailViewer.output_separator() (A)
// output a separator field
// @param fieldNum (number) number of the field to output
// @param field (object) pointer to the field to output
// @param valueList (array) list of values to output
//
// @return (string) HTML output
//<
output_separator : function (fieldNum, field, valueList) {
var width = (field.width == null ? field.defaultSeparatorWidth : field.width),
height = (field.height == null ? field.defaultSeparatorHeight : field.height)
;
return ""
+ isc.Canvas.spacerHTML(width, height)
+ " ";
},
//> @method detailViewer.getEmptyMessage() (A)
// return the empty message to display when no data was specified
// this is a function so you can override it in complex cases
// in simple cases, just returns this.emptyMessage
//
// @return (string) HTML output
//<
getEmptyMessage : function () {
return this.emptyMessage;
},
getLoadingMessage : function () {
return this.loadingMessage == null ? " " : this.loadingMessage.evalDynamicString(this, {
loadingImage: this.imgHTML(isc.Canvas.loadingImageSrc,
isc.Canvas.loadingImageSize,
isc.Canvas.loadingImageSize)
});
},
//> @method detailViewer.emptyMessageHTML() (A)
// Return the message to show if the component has no data. Default implementation returns a
// centered +link{detailViewer.emptyMessage} or " " if showEmptyMessage is false. If
// the component has no data because the browser is offline, we instead display the
// +link{dataBoundComponent.offlineMessage} or " " if showOfflineMessage is false
// @return (string) HTML output
// @visibility external
//<
emptyMessageHTML : function () {
if (this.isOffline()) {
if (!this.showOfflineMessage) return " ";
} else {
if (!this.showEmptyMessage) return " ";
}
return ""
+ "
"
+ (this.isOffline() ? this.offlineMessage : this.getEmptyMessage())
+ "<\/TD><\/TR><\/TABLE>";
},
//> @method detailViewer.loadingMessageHTML() (A)
// return the message to display while the data is loading
//
// @return (string) HTML output
//<
loadingMessageHTML : function () {
return ""
+ "
"
+ this.getLoadingMessage()
+ "<\/TD><\/TR><\/TABLE>";
},
setFieldState : function (fieldState) {
if (fieldState == null && this.fieldState != null) {
if (isc.isA.String(this.fieldState)) {
fieldState = this.evalViewState(this.fieldState, "fieldState")
}
} else fieldState = this.evalViewState(fieldState, "fieldState");
this.completeFields = this._setFieldState(fieldState, true);
this.setFields(this.completeFields);
this.markForRedraw();
this.fieldStateChanged();
},
// minimal implementation of setFields()
setFields : function (newFields) {
if (this.completeFields == null || this.fields == null) this.fields = [];
// bind the passed-in fields to the DataSource and store
this.completeFields = this.bindToDataSource(newFields);
if (this.completeFields == null) this.completeFields = [];
this.deriveVisibleFields();
},
// determine which fields should be shown, and add them to the visible fields array.
// (Used as an internal helper - developers should call 'refreshFields' instead)
deriveVisibleFields : function () {
// NOTE: we use setArray() so that this.fields remains the same array instance.
this.fields.setArray(this.getVisibleFields(this.completeFields));
},
getVisibleFields : function (fields) {
var returnFields = fields.duplicate();
for (var i=0; i @method detailViewer.getField() (A)
// Return a field by fieldName
//
// @return (DetailViewerField) requested field or null
//<
getField : function (fieldName) {
var allFields = this.getAllFields(),
fields = this.fields,
field;
if (isc.isAn.Object(fieldName) && fieldName[this.fieldIdProperty] != null) {
// passed a field-object, check it's real by finding it by name
field = allFields.find(this.fieldIdProperty, fieldName[this.fieldIdProperty]) ||
fields.find(this.fieldIdProperty, fieldName[this.fieldIdProperty]);
} else if (isc.isA.Number(fieldName)) {
field = allFields[fieldName] || fields[fieldName];
} else {
field = allFields.find(this.fieldIdProperty, fieldName) ||
fields.find(this.fieldIdProperty, fieldName)
}
return field;
},
getFormattedValue : function (record, fieldName, value) {
return this.getCellValue(record, this.getSpecifiedField(fieldName));
},
//> @method detailViewer.getPivotedExportData()
// Export visual description of DetailViewer data into a form suitable for external
// processing.
// @param settings (Object) contains configuration settings for the export, including:
// includeHiddenFields (Boolean) - controls if hidden fields should be exported
// allowedProperties (Array) optional array of CSS property names (camelCaps format)
// constraining the allowed properties to be returned
// @return value (String) exported data
//<
// * Data is exported as an array of objects, with one object per visual row of the
// DetailViewer grid - meaning one row per field.
// * The title of each visible field is mapped to the property "title" for each object.
// * Each record's value for the corresponding field is mapped to the properties
// "value1", "value2", ..., up to the number of records specified in this.recordsPerBlock.
// Records extending beyond this.recordsPerBlock are not exported.
// * Additionally, if CSS hilighting styles are present on a record's field, the CSS text is
// converted into an object mapping CSS properties in camelCaps format to CSS values, and the
// object is stored in $style.
// * Null record values are converted to empty strings.
//
// Example object:
// [
// { title: "Foo Fighter", value1: "1", "value1$style": { backgroundColor: "#f00000" } },
// { title: "bar", value1: "baz" },
// { title: "xyzzy", value1: "" },
// { title: "Summary Field", value1: "1 --- baz", "value1$style": { font-weight: "bold" } }
// ]
getPivotedExportData : function (settings) {
var exportOutput = [],
fields = this.getAllFields(),
data = this.data,
includeHiddenFields,
allowedProperties,
alwaysExportExpandedStyles
;
if (isc.isA.Object(settings)) {
includeHiddenFields = settings.includeHiddenFields;
allowedProperties = settings.allowedProperties;
alwaysExportExpandedStyles = settings.alwaysExportExpandedStyles;
}
if (isc.isA.ResultSet(data)) data = data.getAllLoadedRows();
if (!isc.isA.Array(data)) data = [data];
for (var fieldIndex = 0; fieldIndex < fields.length; fieldIndex++) {
var field = fields[fieldIndex],
exportObject = {},
recordsPerBlock = this.recordsPerBlock;
exportObject.title = field.title || field.name;
if (isc.isA.String(exportObject.title)) exportObject.title = this.htmlUnescapeExportFieldTitle(exportObject.title);
// Implement default value of 1 and "*" -> unbounded
if (recordsPerBlock == null) recordsPerBlock = 1;
if (recordsPerBlock == "*") recordsPerBlock = 100000;
if ((!this.fields.contains(field)) && !includeHiddenFields) continue;
for (var rowIndex = 0;
rowIndex < recordsPerBlock && rowIndex < data.getLength();
rowIndex++)
{
var record = data[rowIndex],
fieldNum = this.getFieldNum(field.name),
exportProp = "value" + (rowIndex+1),
styleProp = exportProp + "$style";
var value = this.getExportFieldValue(record, field.name, fieldNum);
if (!(value == null || value == " ")) exportObject[exportProp] = value;
this.addDetailedExportFieldValue(exportObject, styleProp, record, field, fieldNum,
allowedProperties, alwaysExportExpandedStyles);
if (exportObject[styleProp] == null || exportObject[styleProp] == " ")
delete exportObject[styleProp];
}
exportOutput.push(exportObject);
}
return exportOutput;
}
}); // END isc.DetailViewer.addMethods()
// Register stringMethods for this class - instance methods that can be defined as strings using
// specified keywords (replaced by arguments in the function created)
isc.DetailViewer.registerStringMethods({
getCellValue:"record,field",
getCellStyle:"value,field,record,viewer",
getCellCSSText:"value,field,record,viewer",
formatCellValue:"value,record,field,viewer",
fieldStateChanged:""
});
© 2015 - 2025 Weber Informatics LLC | Privacy Policy