Class: SC.View
Extends
SC.DelegateSupport, SC.Responder.
Base class for managing a view. Views provide two functions:
- They display – translating your application's state into drawing instructions for the web browser, and
They react – acting as responders for incoming keyboard, mouse, and touch events.
View Basics
SproutCore's view layer is made up of a tree of
SC.View
instances, nested using thechildViews
list – usually an array of local property names. You position each view by specifying a set of layout keys, like 'left', 'right', 'width', or 'centerX', in a hash on the layout property. (See the 'layout' documentation for more.)Other than positioning, SproutCore relies on CSS for all your styling needs. Set an array of CSS classes on the
classNames
property, then style them with standard CSS. (SproutCore's build tools come with Sass support built in, too.) If you have a class that you want automatically added and removed as another property changes, take a look atclassNameBindings
.Different view classes do different things. The so-called "Big Five" view classes are
SC.LabelView
, for displaying (optionally editable, optionally localizable) text;SC.ButtonView
, for the user to poke;SC.CollectionView
(most often as its subclassSC.ListView)
for displaying an array of content;SC.ContainerView
, for easily swapping child views in and out; andSC.ScrollView
, for containing larger views and allowing them to be scrolled.All views live in panes (subclasses of
SC.Pane
, likeSC.MainPane
andSC.PanelPane)
, which are parentless views that know how to append themselves directly to the document. Panes also serve as routers for events, like mouse, touch and keyboard events, that are bound for their views. (See "View Events" below for more.)For best performance, you should define your view and pane instances with
extend()
inside anSC.Page
instance, getting them as needed withget
. As its name suggests,SC.Page's
only job is to instantiate views once when first requested, deferring the expensive view creation process until each view is needed. Correctly usingSC.Page
is considered an important best practice for high-performance applications.View Initialization
When a view is setup, there are several methods you can override that will be called at different times depending on how your view is created. Here is a guide to which method you want to override and when:
init
-- override this method for any general object setup (such as observers, starting timers and animations, etc) that you need to happen every time the view is created, regardless of whether or not its layer exists yet.render
-- override this method to generate or update your HTML to reflect the current state of your view. This method is called both when your view is first created and later anytime it needs to be updated.update
-- Normally, when a view needs to update its content, it will re-render the view using the render() method. If you would like to override this behavior with your own custom updating code, you can replace update() with your own implementation instead.didCreateLayer
-- the render() method is used to generate new HTML. Override this method to perform any additional setup on the DOM you might need to do after creating the view. For example, if you need to listen for events.willDestroyLayer
-- if you implementdidCreateLayer
() to setup event listeners, you should implement this method as well to remove the same just before the DOM for your view is destroyed.didAppendToDocument
-- in theory all DOM setup could be done indidCreateLayer
() as you already have a DOM element instantiated. However there is cases where the element has to be first appended to the Document because there is either a bug on the browser or you are using plugins which objects are not instantiated until you actually append the element to the DOM. This will allow you to do things like registering DOM events on flash or quicktime objects.willRemoveFromDocument
-- This method is called on the view immediately before its layer is removed from the DOM. You can use this to reverse any setup that is performed indidAppendToDocument
.View Events
One of SproutCore's optimizations is application-wide event delegation: SproutCore handles and standardizes events for you before sending them through your view layer's chain of responding views. You should never need to attach event listeners to elements; instead, just implement methods like
click
,doubleClick
,mouseEntered
anddataDragHover
on your views.Note that events generally bubble up an event's responder chain, which is made up of the targeted view (i.e. the view whose DOM element received the event), and its chain of
parentViews
up to its pane. (In certain rare cases, you may wish to manipulate the responder chain to bypass certain views; you can do so by overriding a view'snextResponder
property.)Simple mouse click events
In many situations, all you need are clicks - in which case, just implement click
or
doubleClick
on your views. Note that these events bubble up the responder chain until
they encounter a view which implements the event method. For example, if a view and its
parent both implement click
, the parent will not be notified of the click. (If you want a
view to handle the event AND allow the event to keep bubbling to its parent views, no
problem: just be sure to return NO
from the event method.)
- click
-- Called on a view when the user clicks the mouse on a view. (Note that the view
on which the user lifts the mouse button will receive the click
event, regardless of
whether the user depressed the mouse button elsewhere. If you need finer-grained control
than this, see "Granular mouse click events" below.)
- doubleClick
-- Called on a view when a user has double-clicked it. Double-clicks are
triggered when two clicks of the same button happen within eight pixels and 250ms of each
other. (If you need finer-grained control than this, see "Granular mouse click events"
below.) The same view may receive both click
and doubleClick
events.
Note that defining application behavior directly in event handlers is usually a bad idea; you
should follow the target/action pattern when possible. See SC.ButtonView
and SC.ActionSupport.
Also note that you will not need to implement event handling yourself on most built-in
SproutCore controls.
Note that click
and doubleClick
event handlers on your views will not be notified of touch
events; you must also implement touch handling. See "Touch events" below.
Mouse movement events
SproutCore normalizes (and brings sanity to) mouse movement events by calculating when
the mouse has entered and exited views, and sending the correct event to each view in
the responder chain. For example, if a mouse moves within a parent view but crosses from
one child view to another, the parent view will receive a mouseMoved
event while the child
views will receive mouseEntered
and mouseExit
events.
In contrast to mouse click events, mouse movement events are called on the entire responder chain regardless of how you handle it along the way - a view and its parent, both implementing event methods, will both be notified of the event.
mouseEntered
-- Called when the cursor first enters a view. Called on every view that has just entered the responder chain.mouseMoved
-- Called when the cursor moves over a view.mouseExited
-- Called when the cursor leaves a view. Called on every view that has just exited the responder chain.Granular mouse click events
If you need more granular handling of mouse click events than what is provided by click
and doubleClick
, you can handle their atomic components mouseDown
, mouseDrag
and
mouseUp
. Like the compound events, these events bubble up their responder chain towards
the pane until they find an event which implements the event handler method. (Again, to
handle an event but allow it to continue bubbling, just return NO.)
It bears emphasizing that mouseDrag
and mouseUp
events for a given mouse click sequence
are only ever called on the view which successfully responded to the mouseDown
event. This
gives mouseDown
control over which view responder-chain is allowed to handle the entire
click sequence.
(Note that because of how events bubble up the responder chain, if a child view implements
mouseDown
but not mouseDrag
or mouseUp
, those events will bubble to its parent. This
may cause unexpected behavior if similar events are handled at different parts of your view
hierarchy, for example if you handle mouseDown
in a child and a parent, and only handle
mouseUp
in the parent.)
mouseDown
-- Called on the target view and responder chain when the user depresses a button. A view must implementmouseDown
(and not return NO) in order to be notified of the subsequent drag and up events.mouseDrag
-- Called on the target view if it handledmouseDown
. A view must implementmouseDown
(and not return NO) in order to receivemouseDrag
; only the view which handled a given click sequence'smouseDown
will receivemouseDrag
events (and will continue to receive them even if the user drags the mouse off of it).mouseUp
-- Called on the target view when the user lifts a mouse button. A view must implementmouseDown
(and not return NO) in order to receivemouseUp
.SproutCore implements a higher-level API for handling in-application dragging and dropping. See
SC.Drag
,SC.DragSourceProtocol
,SC.DragDataSourceProtocol
, andSC.DropTargetProtocol
for more.Data-drag events
Browsers implement a parallel system of events for drags which bring something with them: for example, dragging text, an image, a URL or (in modern browsers) a file. They behave differently, and require different responses from the developer, so SproutCore implements them as a separate set of "data drag" events. These behave much like mouse events; the data-drag movement events bubble indiscriminately, and the data-drag drop event bubbles until it finds a view which handles it (and doesn't return NO).
By default, SproutCore cancels the default behavior of any data drag event which carries URLs
or files, as by default these would quit the app and open the dragged item in the browser. If
you wish to implement data drag-and-drop support in your application, you should set the event's
dataTransfer
.dropEffect property to 'copy' in a dataDragHovered
event handler.
dataDragEntered
-- Triggered when a data drag enters a view. You can use this handler to update the view to visually signal that a drop is possible.dataDragHovered
-- Triggered when the browser sends a dragover event to a view. If you want to support dropping data on your view, you must set the event'sdataTransfer.dropEffect
property to 'copy' (or related). Note thatdataDragHovered
is given access to dragenter events as well, so you do not need to worry about this in yourdataDragEntered
methods.dataDragDropped
-- If the last hover event'sdropEffect
was set correctly, this event will give the view access to the data that was dropped. This event bubbles up the responder chain until it finds a view which handles it (and doesn't return NO).dataDragExited
-- Triggered when a data drag leaves a view. You can use this handler to update the view to remove the visual drop signal. This event is fired regardless of whether a drop occurred.Touch events
Touch events can be much more complicated than mouse events: multiple touches may be in flight at once, and views may wish to handle average touches rather than individual touches.
Basic support for touch events is required to make your application touch-aware. (You will not
need to implement touch support for built-in SproutCore controls, which are touch-aware out of
the box.) The basic touch event handlers are touchStart
and touchEnd
; if all you need is
basic support then you can simply proxy these events to their mouse counterparts.
The counterpart to mouseDragged
is touchesDragged
, which is passed two arguments: a special
multitouch event object which includes methods for accessing information about all currently
in-flight touches, and a list of touches active on the current view. If you need to check the
status of touches currently being handled by other views, the special multitouch event object
exposes the touchesForView
method. It also exposes the convenient averagedTouchesForView
method, which gives you easy access to an average touch center and distance. Unlike mouseDragged
,
touchesDragged
does not bubble, being only called on views whic handled touchStart
for touches
which have moved.
To facilitate intuitive behavior in situations like scroll views with touch handlers inside them,
you may capture a touch from part way up its responder chain before it has a chance to bubble
up from the target. To capture a touch, expose a method on your view called captureTouch
which
accepts the touch as its only argument, and which returns YES
if you would like to capture that
touch. A captured touch will not bubble as normal, instead bubbling up from the capture point. Any
child views will not have the opportunity to handle the captured event unless you implement custom
responder swapping yourself.
Touch events bubble differently than mouse and keyboard events. The initial reverse captureTouch
bubbling is followed by regular touchStart
bubbling; however, once this process has found a view
that's willing to respond to the touch, further events are applied only to that view. If a view
wishes to assign respondership for a touch to a different view, it can call one of several methods
on the touch object. For a fuller discussion of touch events, touch responder behavior, and the touch
object itself, see the documentation for SC.Touch.
Keyboard events
The basic key events are keyDown
and keyUp
. In order to be notified of keyboard events,
a view must set acceptsFirstResponder
to YES
, and be on an active pane with
acceptsKeyPane
set to YES
. (You may also need to call becomeFirstResponder
on your view
on a mouseDown
, for example, to focus it. You can verify whether your view has successfully
received first responder status by checking isFirstResponder
.)
Note that key events bubble similarly to mouse click events: they will stop bubbling if they
encounter a view which handles the event and does not return NO
.
SproutCore implements a set of very convenient, higher-level keyboard events for action keys
such as tab, enter, and the arrow keys. These are not triggered automatically, but you
can gain access to them by proxying the keyboard event of your choice to interpretKeyEvent
.
For example:
// Proxy the keyboard event to SC's built-in interpreter.
keyDown: function(evt) {
return this.interpretKeyEvents(evt);
},
// The interpreter will trigger the view's `cancel` event if the escape key was pressed.
cancel: function(evt) {
console.log('The escape key was pressed.'');
}
This will analyze the key press and fire an appropriate event. These events include, but are not limited to:
moveUp
,moveDown
,moveLeft
,moveRight
-- The arrow keysinsertNewline
-- The enter key (note the lower-case 'line')cancel
-- The escape keyinsertTab
-- The tab keyinsertBacktab
-- Shift + the tab keymoveToBeginningOfDocument
-- The home keymoveToEndOfDocument
-- The end keypageUp
andpageDown
moveLeftAndModifySelection
-- Shift + the left arrowselectAll
-- Ctrl + A / Cmd + AFor a full list of available methods, see the key values on
SC.BASE_KEY_BINDINGS
andSC.MODIFIED_KEY_BINDINGS.
Defined in: view.js
- Since:
- SproutCore 1.0
Field Summary
- acceptsFirstResponder
- acceptsMultitouch
- ariaHidden Deprecated
- ariaRole
- attributeBindings
- autoMixins
- backgroundColor
- childViewLayout
- childViewLayoutOptions
- childViews
- childViewsNeedLayout
- classNameBindings
- classNames
- concatenatedProperties
- createdByParent
- designMode
- displayProperties
- enabledState
- firstKeyView
- hasLayout
- hasTouch
- hasVisibility Deprecated
- SC.View.HORIZONTAL_STACK
- isBuildingIn Deprecated
- isBuildingOut Deprecated
- isChildViewLayoutLive
- isEnabled
- isFixedHeight
- isFixedPosition
- isFixedSize
- isFixedWidth
- isKeyResponder
- isTextSelectable
- isView
- isVisible
- lastKeyView
- layerLocationNeedsUpdate Deprecated
- layerNeedsUpdate Deprecated
- layout
- modeAdjust
- nextKeyView
- page
- pane
- parentView
- previousKeyView
- renderDelegateName
- shouldInheritCursor
- shouldInheritEnabled
- tagName
- themeName
- toolTip
- touchBoundary
- transitionAdjust
- transitionAdjustOptions
- transitionHide
- transitionHideOptions
- transitionIn
- transitionInOptions
- transitionOut
- transitionOutOptions
- transitionShow
- transitionShowOptions
- useStaticLayout
- SC.View.VERTICAL_STACK
- Fields borrowed from SC.Responder:
- hasFirstResponder, isFirstResponder, responderContext
- Fields borrowed from SC.Object:
- isDestroyed, isObject, nextProperty, object, property, target, toInvalidate
- Fields borrowed from SC.Observable:
- isObservable
Class Methods
- convertLayoutToAnchoredLayout(layout, parentFrame)
- convertLayoutToCustomLayout(layout, layoutParams, parentFrame)
Instance Methods
- $(sel)
- adjust(key, value)
- animate(properties, value, Duration, target, method)
- appendChild(view)
- applyAttributesToContext(context)
- beginLiveResize()
- borderFrame()
- buildIn() Deprecated
- buildInChild(view) Deprecated
- buildInDidCancel() Deprecated
- buildInDidFinish() Deprecated
- buildInDidFinishFor(child) Deprecated
- buildOut() Deprecated
- buildOutChild(view) Deprecated
- buildOutDidCancel() Deprecated
- buildOutDidFinish() Deprecated
- cancelAnimation(layoutState)
- clippingFrame()
- computeFrameWithParentFrame()
- computeParentDimensions(frame)
- containerLayer()
- contextMenu(evt)
- convertFrameFromView(frame, targetView)
- convertFrameToView(frame, targetView)
- createChildView(view, attrs)
- createChildViews()
- createLayer()
- cursor(key, value)
- destroy()
- destroyLayer()
- didBecomeKeyResponderFrom(responder)
- didLoseKeyResponderTo(responder)
- displayDidChange()
- displayToolTip()
- emitDesign()
- encodeDesign(coder)
- endLiveResize()
- findLayerInParentLayer(parentLayer)
- frame()
- init()
- insertBefore(view, beforeView)
- insertText(event)
- interpretKeyEvents(event)
- invokeRenderDelegateMethod(method, arg)
- isContextMenuEnabled()
- isDescendantOf(view)
- isEnabledInPane()
- isFixedLayout()
- layer(key, value)
- layerId(key, value)
- layerIdDidChange()
- layoutChildViews(force)
- layoutChildViewsIfNeeded(force)
- layoutDidChange()
- layoutDidChangeFor(childView)
- layoutStyle()
- layoutView()
- nextResponder()
- nextValidKeyView()
- owner() Deprecated
- parentViewDidChange()
- parentViewDidResize(parentFrame)
- performKeyEquivalent(keystring, evt)
- previousValidKeyView()
- propertyDidChange(key, value, _keepCache)
- recomputeIsVisibleInWindow() Deprecated
- removeAllChildren(immediately)
- removeChild(view, immediately)
- removeChildAndDestroy(view, immediately)
- removeFromParent()
- render(context, firstTime)
- renderChildViews(context)
- renderContext(tagNameOrElement)
- renderDelegate(key, value)
- renderDelegateProxy()
- renderLayout(the)
- replaceAllChildren(newChildViews)
- replaceChild(view, view)
- replaceLayer()
- resetAnimation() Deprecated
- resetBuild() Deprecated
- resetBuildState() Deprecated
- respondsTo(methodName)
- scrollToVisible()
- selectStart(evt)
- theme()
- touchIsInBoundary(touch)
- tryToPerform(methodName, arg1, arg2)
- updateDesignMode(lastDesignMode, designMode)
- updateLayer()
- updateLayerIfNeeded(skipIsVisibleInWindowCheck)
- updateLayerLocation() Deprecated
- updateLayerLocationIfNeeded() Deprecated
- updateLayout(force)
- viewDidResize()
- willBecomeKeyResponderFrom(responder)
- willLoseKeyResponderTo(responder)
Field Detail
acceptsFirstResponderSet to YES
if you want to receive touch events for each distinct touch
(rather than only the first touch start and last touch end).
Defined in: touch.js.
The aria-hidden role is managed appropriately by the internal view's statechart. When the view is not currently displayed the aria-hidden attribute will be set to true.
- Default value:
- null
The WAI-ARIA role of the control represented by this view. For example, a button may have a role of type 'button', or a pane may have a role of type 'alertdialog'. This property is used by assistive software to help visually challenged users navigate rich web applications.
The full list of valid WAI-ARIA roles is available at: http://www.w3.org/TR/wai-aria/roles#roles_categorization
- Default value:
- null
A list of properties on the view to translate dynamically into attributes on the view's layer (element).
When the view is rendered, the value of each property listed in
attributeBindings
will be inserted in the element. If the value is a
Boolean, the attribute name itself will be inserted. As well, as the
value of any of these properties changes, the layer will update itself
automatically.
This is an easy way to set custom attributes on the View without implementing it through a render or update function.
For example,
// ... MyApp.MyView
attributeBindings: ['aria-valuenow', 'disabled'],
'aria-valuenow': function () {
return this.get('value');
}.property('value').cacheable(), // adds 'aria-valuenow="{value}"' attribute
disabled: YES, // adds 'disabled="disabled"' attribute
// ...
- Default value:
- null
Use this property to automatically mix in a collection of mixins into all
child views created by the view. This collection is applied during createChildView
- Default value:
- null
The view's background color. Only recommended for use during prototyping and in views
where the background color may change arbitrarily, for example in connection with an
instance of SC.Color
. Otherwise you should use CSS and classNames
or
classNameBindings
.
If set at create time, will be added to the view's layer. For dynamic background colors,
you must add backgroundColor
to the view's displayProperties
.
Defined in: layout.js.
- Default value:
- null
The child view layout plugin to use when laying out child views.
You can set this property to a child layout plugin object to
automatically set and adjust the layouts of this view's child views
according to some specific layout style. For instance, SproutCore includes
two such plugins, SC.View.VERTICAL_STACK
and SC.View.HORIZONTAL_STACK.
SC.View.VERTICAL_STACK
will arrange child views in order in a vertical
stack, which only requires that the height of each child view be specified.
Likewise, SC.View.HORIZONTAL_STACK
does the same in the horizontal
direction, which requires that the width of each child view be specified.
Where child layout plugins are extremely useful, besides simplifying
the amount of layout code you need to write, is that they can update the
layouts automatically as things change. For more details and examples,
please see the documentation for SC.View.VERTICAL_STACK
and
SC.View.HORIZONTAL_STACK.
To define your own child view layout plugin, simply create an object that
conforms to the SC.ChildViewLayoutProtocol
protocol.
Note* This should only be set once and is not bindable.
Defined in: layout.js.
- Default value:
- null
The options for the given child view layout plugin.
These options are specific to the current child layout plugin being used and
are used to modify the applied layouts. For example, SC.View.VERTICAL_STACK
accepts options like:
childViewLayoutOptions: {
paddingAfter: 20,
paddingBefore: 20,
spacing: 10
}
To determine what options may be used for a given plugin and to see what the default options are, please refer to the documentation for the child layout plugin being used.
Defined in: layout.js.
- Default value:
- null
Array of child views. You should never edit this array directly unless
you are implementing createChildViews
(). Most of the time, you should
use the accessor methods such as appendChild
(), insertBefore
() and
removeChild
().
- Default value:
- []
Set this property to YES
whenever the view needs to layout its child
views. Normally this property is set automatically whenever the layout
property for a child view changes.
Defined in: layout.js.
A list of local property names to translate dynamically into standard CSS class names on your view's layer (element).
Each entry in the array should take the form "propertyName:css-class". For example, "isRed:my-red-view" will cause the class "my-red-view" to be appended if the property "isRed" is (or becomes) true, and removed if it later becomes false (or null/undefined).
Optionally, you may provide just the property name, in which case it will
be dasherized and used as the class name. For example, including
"isUpsideDown" will cause the view's isUpsideDown
property to mediate the
class "is-upside-down".
Instead of a boolean value, your property may return a string, which will be used as the class name for that entry. Use caution when returning other values; numbers will be appended verbatim and objects will be stringified, leading to unintended results such as class="4" or class="Object object".
Class names mediated by these bindings are used in addition to any that
you've listed in the classNames
property.
Standard CSS class names to apply to the view's outer element. These class names are used in addition to any defined on the view's superclass.
- Default value:
- []
An array of the properties of this class that will be concatenated when also present on subclasses.
- Default value:
- ['outlets', 'displayProperties', 'classNames', 'renderMixin', 'didCreateLayerMixin', 'willDestroyLayerMixin', 'classNameBindings', 'attributeBindings']
Whether this view was created by its parent view or not.
Several views are given child view classes or instances to automatically append and remove. In the case that the view was provided an instance, when it removes the instance and no longer needs it, it should not destroy the instance because it was created by someone else.
On the other hand if the view was given a class that it creates internal instances from, then it should destroy those instances properly to avoid memory leaks.
This property should be set by any view that is creating internal child
views so that it can properly remove them later. Note that if you use
createChildView
, this property is set automatically for you.
- Default value:
- false
- See:
- SC.View#createChildView
The current design mode of the application and this view.
If the application has designModes
specified, this property will be set
automatically when the view is created and as the window size changes
across the design mode boundaries.
Defined in: design_mode.js.
- Default value:
- null
You can set this array to include any properties that should immediately invalidate the display. The display will be automatically invalidated when one of these properties change.
These are the properties that will be visible to any Render Delegate.
When the RenderDelegate asks for a property it needs, the view checks the
displayProperties
array. It first looks for the property name prefixed
by 'display'; for instance, if the render delegate needs a 'title',
the view will attempt to find 'displayTitle'. If there is no 'displayTitle'
in displayProperties
, the view will then try 'title'. If 'title' is not
in displayProperties
either, an error will be thrown.
This allows you to avoid collisions between your view's API and the Render Delegate's API.
Implementation note: 'isVisible' is also effectively a display property, but it is not declared as such because it is observed separately in order to manage the view's internal state.
The current enabled state of the view.
Views have a few possible enabled states:
SC.CoreView.ENABLED
SC.CoreView.DISABLED
SC.CoreView.DISABLED_BY_PARENT
Defined in: enabled.js.
- Default value:
- SC.CoreView.ENABLED
The first child of this view for the purposes of tab ordering. If not
provided, the first element of childViews
is used. Override this if
your view displays its child views in an order different from that
given in childViews
.
Defined in: keyboard.js.
- Default value:
- null
This child layout plugin automatically positions the view's child views in a horizontal stack and optionally adjusts the view's width to fit. It does this by checking the width of each child view and positioning the following child views accordingly. Afterwards, by default, any time that a child view's width or visibility changes, the view will use this plugin to re-adjust all following child views' positions and potentially its own width appropriately.
This allows you to stack absolutely positioned views that dynamically change their width and/or visibility without having to resort to using browser flow layout.
For example,
MyApp.MyView = SC.View.extend({
// Child views will be stacked in order horizontally.
childViewLayout: SC.View.HORIZONTAL_STACK,
// The order of child views is important!
childViews: ['sectionA', 'sectionB', 'sectionC'],
// The view will resize itself to fit its children.
// i.e. We don't need to specify layout.width, this is automatic.
// The actual layout will become { left: 10, bottom: 20, top: 20, width: 270 } initially.
layout: { left: 10, bottom: 20, top: 20 },
sectionA: SC.View.design({
// We don't need to specify layout.left, this is automatic.
// The actual layout will become { left: 0, bottom: 0, top: 0, width: 100 } initially.
layout: { width: 100 }
}),
sectionB: SC.View.design({
// We don't need to specify layout.left, this is automatic.
// The actual layout will become { border: 1, left: 100, bottom: 0, top: 0, width: 50 } initially.
layout: { border: 1, width: 50 }
}),
sectionC: SC.View.design({
// We don't need to specify layout.left, this is automatic.
// The actual layout will become { left: 150, bottom: 10, top: 10, width: 120 } initially.
layout: { right: 10, top: 10, width: 120 }
})
});
Modify the default behavior with childViewLayoutOptions
To modify the plugin behavior for all child view layouts, you can set the
following child view layout options in childViewLayoutOptions
on the view:
paddingBefore
- Adds padding before the first child view. Default: 0paddingAfter
- Adds padding after the last child view. Default: 0- spacing - Adds spacing between each child view. Default: 0
resizeToFit
- Whether to resize the view to fit the child views (requires that each child view has a layout width). Default: true
For example,
MyApp.MyView = SC.View.extend({
// Child views will be stacked in order horizontally.
childViewLayout: SC.View.HORIZONTAL_STACK,
// Change the behavior of the HORIZONTAL_STACK plugin
childViewLayoutOptions: {
paddingBefore: 10,
paddingAfter: 20,
spacing: 5
},
// The order of child views is important!
childViews: ['sectionA', 'sectionB', 'sectionC'],
// The view will resize itself to fit its children. The actual layout will become { left: 10, bottom: 20, top: 20, width: 310 }
layout: { left: 10, bottom: 20, top: 20 }, // Don't need to specify layout.width, this is automatic.
sectionA: SC.View.design({
// Actual layout will become { left: 10, bottom: 0, top: 0, width: 100 }
layout: { width: 100 } // Don't need to specify layout.left, this is automatic.
}),
sectionB: SC.View.design({
// Actual layout will become { border: 1, left: 115, bottom: 0, top: 0, width: 50 }
layout: { border: 1, width: 50 } // Don't need to specify layout.left, this is automatic.
}),
sectionC: SC.View.design({
// Actual layout will become { left: 170, top: 10, bottom: 10, width: 120 }
layout: { top: 10, bottom: 10, width: 120 } // Don't need to specify layout.left, this is automatic.
})
});
If resizeToFit
is set to false
, the view will not adjust itself to fit
its child views. This means that when resizeToFit
is false, the view should
specify its width component in its layout. A direct effect of this is the
possibility for the child views to automatically expand or shrink in order to
fill the empty, unclaimed space of the view.
This available space is shared between all children that don't specify a fixed width
such that their final width is calculated proportionally to the value of the
property fillRatio
.
For simplicity, when none of the children specifies fillRatio
,
you can ignore the last child view's layout width and the last child view
will stretch to fill the parent view.
For example,
MyApp.MyView = SC.View.extend({
// Child views will be stacked in order horizontally.
childViewLayout: SC.View.HORIZONTAL_STACK,
// Change the behavior of the HORIZONTAL_STACK plugin
childViewLayoutOptions: {
paddingBefore: 10,
paddingAfter: 20,
spacing: 5,
resizeToFit: false // Setting this to false, so that the child views stretch/contract to fit the parent's size.
},
// The order of child views is important!
childViews: ['sectionA', 'sectionB', 'sectionC'],
// The parent view will not resize itself to fit its contents, so we specify the width.
layout: { left: 10, bottom: 20, top: 20, width: 500 },
sectionA: SC.View.design({
// We don't need to specify layout.left, this is automatic. This child will not stretch, its width is set.
// Actual layout will become { left: 10, bottom: 0, top: 0, width: 100 }
layout: { width: 100 }
}),
sectionB: SC.View.design({
// The unclaimed space so far is 500 - 10 - 100 - 5 - 5 - 20, or 360px. This space will be shared between
// the two last sections, because we won't specity a width on them.
// This view will get 1/3 of the available space, because the other flexibile view has a ratio of 2.
fillRatio: 1,
// This section will take 1/3 * 360px = 120px.
// Actual layout will become { border: 1, left: 115, bottom: 0, top: 0, right: 265 }, in other words, width == 120
// We don't need to specify layout.left, layout.right or layout.width, this is automatic.
layout: { border: 1 }
}),
sectionC: SC.View.design({
// This view will get 2/3 of the available space, because the other flexibile view has a ratio of 1.
fillRatio: 2,
// This section will take 2/3 * 360px = 240px.
// Actual layout will become { left: 240, top: 10, bottom: 10, right: 20 }, in other words, width == 240
// We don't need to specify layout.left, layout.right or layout.width, this is automatic.
layout: { top: 10, bottom: 10 }
})
});
Modify specific child view layouts
To adjust the child layout on a granular level per child view, you can also set the following properties on each child view:
marginBefore
- Specify the minimum spacing above the child view.marginAfter
- Specify the minimum spacing below the child view.useAbsoluteLayout
- Don't include this child view in automatic layout, use absolute positioning based on the child view'slayout
property.useStaticLayout
- Don't include this child view in automatic layout. This child view uses relative positioning and is not eligible for automatic layout.isVisible
- Non-visible child views are not included in the stack.fillRatio
- When the parent view is configured with a fixed dimension, children not specifying a width but specifyingfillRatio
will be resized to fill the unclaimed space proportionally to this ratio.For example,
MyApp.MyView
=SC.View.extend(
{// Child views will be stacked in order horizontally.
childViewLayout
:SC.View.HORIZONTAL_STACK
,// Actual layout will become { left: 10, right: 10, top: 20, width: 570 } layout: { left: 10, right: 10, top: 20 },
// Keep the child views ordered!
childViews
: ['sectionA', 'float', 'sectionB', 'sectionC'],sectionA:
SC.View.design(
{ // Actual layout will become { left: 0, right: 50, top: 0, width: 100 } layout: { right: 50, width: 100 }, // The following child view will be at least 50px further right.marginAfter
: 50 }),float:
SC.View.design(
{ // This view will not be included in automatic layout and will not effect the stack. layout: { top: 5, right: 5, height: 50, width: 50 },useAbsoluteLayout
: true }),sectionB:
SC.View.design(
{ // Actual layout will become { left: 1500, right: 0, top: 0, width: 120 } layout: { width: 120 } }),sectionC:
SC.View.design(
{ // Actual layout will become { left: 470, bottom: 0, top: 0, width: 100 } layout: { width: 100 }, // This child view will be at least 200px to the right of the previous.marginBefore
: 200 })});
A Note About Spacing
Note that the spacing attribute in childViewLayoutOptions
becomes the
minimum margin between child views, without explicitly overriding it from
both sides using marginAfter
and marginBefore
. For example, if spacing
is 25, setting marginAfter
to 10 on a child view will not result in the
next child view being 10px to the right of it, unless the next child view also
specified marginBefore
as 10.
What this means is that it takes less configuration if you set spacing
to
be the smallest margin you wish to exist between child views and then use
the overrides to grow the margin if necessary. For example, if spacing
is 5, setting marginAfter
to 10 on a child view will result in the next
child view being 10px to the right of it, without having to also specify
marginBefore
on that next child view.
Defined in: stack_layout.js.
- Since:
- Version 1.10
Whether the view and its child views should be monitored for changes that affect the current child view layout.
When true
and using a childViewLayout
plugin, the view and its child views
will be observed for any changes that would affect the layout of all the
child views. For example, if isChildViewLayout
is true and using
SC.View.VERTICAL_STACK
, if any child view's height or visibility changes
all of the child views will be re-adjusted.
If you only want to automatically layout the child views once, you can
set this to false
to improve performance.
Defined in: layout.js.
- Default value:
- true
Set to true when the item is enabled. Note that changing this value
will alter the isEnabledInPane
property for this view and any
child views as well as to automatically add or remove a 'disabled' CSS
class name.
This property is observable and bindable.
Defined in: enabled.js.
Returns whether the height is 'fixed' or not. A fixed height is defined on the layout as an integer number of pixels. Fixed widths are therefore unaffected by changes to their parent view's height.
Defined in: layout.js.
Returns whether the position is 'fixed' or not. A fixed position means a fixed left & top position within its parent's frame. Fixed positions are therefore unaffected by changes to their parent view's size.
Defined in: layout.js.
Returns whether the size is 'fixed' or not. A fixed size means a fixed width and height. Fixed sizes are therefore unaffected by changes to their parent view's size.
Defined in: layout.js.
Returns whether the width is 'fixed' or not. A fixed width is defined on the layout as an integer number of pixels. Fixed widths are therefore unaffected by changes to their parent view's width.
Defined in: layout.js.
Determines if the user can select text within the view. Normally this is
set to NO
to disable text selection. You should set this to YES if you
are creating a view that includes editable text. Otherwise, settings this
to YES will probably make your controls harder to use and it is not
recommended.
The isVisible
property determines if the view should be displayed or not.
If you also set a transitionShow
or transitionHide
plugin, then when
isVisible
changes, the appropriate transition will execute as the view's
visibility changes.
Note that isVisible
can be set to true and the view may still not be
"visible" in the window. This can occur if:
- the view is not attached to the document.
- the view has a view ancestor with
isVisible
set to false.
- Default value:
- true
- See:
- SC.View#viewState
The last child of this view for the purposes of tab ordering. If not set, can be generated two different ways:
1. If firstKeyView
is provided, it will be generated by starting from firstKeyView
and traversing the childViews
nextKeyView
properties.
2. If firstKeyView
is not provided, it will simply return the last element of childViews
.
The first way is not very efficient, so if you provide firstKeyView
you should also provide lastKeyView
.
Defined in: keyboard.js.
- Default value:
- null
Set to YES
when the view's layer location is dirty. You can call
updateLayerLocationIfNeeded
() to clear this flag if it is set.
This property has no effect and is deprecated.
To cause a view to update immediately, you should just call updateLayer
or
updateLayerIfNeeded
. To cause a view to update at the end of the run loop
before any invokeLast
functions run, you should call displayDidChange
.
Set the layout to a hash of layout properties to describe in detail how your view should be positioned on screen. Like most application development environments, your views are laid out absolutely, relative to their parent view.
You can define your layout using combinations of the following positional properties:
- left
- top
- right
- bottom
- height
- width
- centerX: offset from center, horizontally
- centerY: offset from center, vertically
minWidth
minHeight
maxWidth
maxHeight
- scale: once positioned, scales the view in place.
transformOriginX
,transformOriginY
: defines the point (as a decimal percentage) around which your view will scale. (Also impacts rotation; see below.)
They are processed by SproutCore's layout engine and used to position the view's element onscreen. They are
also reliably and speedily processed into a scaled rectangle (with x, y, height, width, scale and origin
values) available on the frame property. See documentation on it and the clippingFrame
property for more.
Most of these properties take integer numbers of pixels, for example { left: 10 }, or fractional
percentages like { left 0.25 }. Exceptions include scale, which takes a scale factor (e.g. { scale:
2 } doubles the view's size), and transformOriginX
/Y which take a decimal percent, and default to 0.5
(the center of the view).
It's possible to define very sophisticated layouts with these properties alone. For example, you
can define a view which takes up the full screen until it reaches a certain width, and aligns to
the left thereafter, with { left: 0, right: 0, maxWidth
: 400 }. (If you need the flexibility to
assign entirely different layouts at different screen or window sizes, see the Design Modes
documentation under SC.Application.)
Certain layout combinations are nonsensical and of course should be avoided. For example, you can use left + right or left + width, but not left + right + width.
If your view has a CSS border, it's important that you specify its thickness in the layout hash, using one or more of the following border properties, as well as in your CSS. This is an unfortunate bit of repetition, but it's necessary to allow SproutCore to adjust the layout to compensate. (HTML positions borders outside of the body of an element; SproutCore positions them inside their rectangles.)
- border: border thickness on all sides
borderTop
: top border thicknessborderRight
: right border thicknessborderBottom
: bottom border thicknessborderLeft
: bottom left thickness
You can also use the following layout properties, which don't impact your view's frame.
- opacity: the opacity of the view
- rotate: once positioned, rotates the view in place.
zIndex
: position above or below other views (Not recommended. Control sibling view overlay withchildView
order (later views draw above earlier views) where possible.)
To change a layout property, you should use the adjust method, which handles some particulars for you.
Defined in: layout.js.
The dynamic adjustments to apply to this view depending on the current design mode.
If you specify designModes
on the application, this hash will be checked
for a matching adjustment to apply for the current design mode.
Defined in: design_mode.js.
- Default value:
- null
Optionally points to the next key view that should gain focus when tabbing
through an interface. If this is not set, then the next key view will
be set automatically to the next sibling as defined by its parent's
childViews
property.
If any views define this, all of their siblings should define it as well,
otherwise undefined behavior may occur. Their parent view should also define
a firstKeyView
.
This may also be set to a view that is not a sibling, but once again all views in the chain must define it or undefined behavior will occur.
Likewise, any view that sets nextKeyView
should also set previousKeyView
.
Defined in: keyboard.js.
- Default value:
- null
The page this view was instantiated from. This is set by the page object during instantiation.
- Default value:
- null
- Default value:
- null
If the view is currently inserted into the DOM of a parent view, this property will point to the parent of the view.
- Default value:
- null
Optionally points to the previous key view that should gain focus when tabbing
through an interface. If this is not set, then the previous key view will
be set automatically to the previous sibling as defined by its parent's
childViews
property.
If any views define this, all of their siblings should define it as well,
otherwise undefined behavior may occur. Their parent view should also define
a lastKeyView
.
This may also be set to a view that is not a sibling, but once again all views in the chain must define it or undefined behavior will occur.
Likewise, any view that sets previousKeyView
should also set nextKeyView
.
Defined in: keyboard.js.
- Default value:
- null
The name of the property of the current theme that contains the render delegate to use for this view.
By default, views are responsible for creating their own HTML representation. You can tell the view to instead delegate rendering to the theme by setting this property to the name of the corresponding property of the theme.
For example, to tell the view that it should render using the
SC.ButtonView
render delegate, set this property to
'buttonRenderDelegate'. When the view is created, it will retrieve the
buttonRenderDelegate
property from its theme and set the renderDelegate
property to that object.
Defined in: theming.js.
A child view without a cursor of its own inherits its parent's cursor by
default. Set this to NO
to prevent this behavior.
Defined in: cursor.js.
By default, setting isEnabled
to false on a view will place all of its
child views in a disabled state. To block this from happening to a
specific child view and its children, you can set shouldInheritEnabled
to false.
In this way you can set isEnabled
to false on a main pane to disable all
buttons, collections and other controls within it, but can still keep a
section of it editable using shouldInheritEnabled: false
.
Defined in: enabled.js.
Tag name for the view's outer element. The tag name is only used when
a layer is first created. If you change the tagName
for an element, you
must destroy and recreate the view layer.
- Default value:
- 'div'
Names which theme this view should use; the theme named by this property will be set to the view's 'theme' property.
Themes are identified by their name. In addition to looking for the theme globally, SproutCore will look for the theme inside 'baseTheme', which is almost always the parent view's theme.
If null (the default), the view will set its 'theme' property to be equal to 'baseTheme'.
Example: themeName
: 'ace'
Defined in: theming.js.
Tool tip property that will be set to the title attribute on the HTML rendered element.
A boundary set of distances outside which the touch will no longer be
considered "inside" the view anymore. This is useful when we want to allow
a bit of touch drag outside of the view before we consider that the User's
finger has completely left the view. For example, a User might touch down
on a button, but because of the wide surface of a finger, the touch might
slip outside of the button's frame as the person lifts up. If the button
uses touchIsInBoundary
it can make it easier for the User to hit it.
By default, up to 25px on each side.
Defined in: touch.js.
The transition plugin to use when this view is moved or resized by adjusting its layout.
SC.CoreView
uses a pluggable transition architecture where the transition
setup, execution and cleanup can be handled by a plugin. This allows you
to create complex transition animations and share them across all your views
with only a single line of code.
There are a number of pre-built transition adjust plugins available in the SproutCore foundation framework:
SC.View.SMOOTH_ADJUST
SC.View.BOUNCE_ADJUST
SC.View.SPRING_ADJUST
To create a custom transition plugin simply create a regular JavaScript
object that conforms to the SC.ViewTransitionProtocol
protocol.
NOTE: When creating custom transition adjust plugins, be aware that SC.View
will not call the setup
method of the plugin, only the run
method.
Defined in: layout.js.
- Default value:
- null
- Since:
- Version 1.10
The options for the given transitionAdjust
plugin.
These options are specific to the current transition plugin used and are used to modify the transition animation. To determine what options may be used for a given plugin and to see what the default options are, see the documentation for the transition plugin being used.
Most transitions will accept a duration and timing option, but may
also use other options. For example, SC.View.BOUNCE_ADJUST
accepts options
like:
transitionAdjustOptions: {
bounciness: 0.5, // how much the adjustment should bounce back each time
bounces: 4, // the number of bounces
duration: 0.25,
delay: 1
}
Defined in: layout.js.
- Default value:
- null
- Since:
- Version 1.10
The transition plugin to use when this view is hidden after being shown.
SC.View
uses a pluggable transition architecture where the transition setup,
execution and cleanup can be handled by a specified transition plugin.
There are a number of pre-built transition plugins available in the foundation framework:
SC.View.BOUNCE_OUT
SC.View.FADE_OUT
SC.View.SLIDE_OUT
SC.View.SCALE_OUT
SC.View.SPRING_OUT
You can even provide your own custom transition plugins. Just create a
transition object that conforms to the SC.ViewTransitionProtocol
protocol.
- Default value:
- null
- Since:
- Version 1.10
The options for the given transition hide plugin.
These options are specific to the current transition plugin used and are used to modify the transition animation. To determine what options may be used for a given plugin and to see what the default options are, see the documentation for the transition plugin being used.
Most transitions will accept a duration and timing option, but may
also use other options. For example, SC.View.SLIDE
accepts options
like:
transitionHideOptions: {
direction: 'right',
duration: 0.15,
timing: 'ease-in'
}
- Default value:
- null
- Since:
- Version 1.10
The transition plugin to use when this view is appended to the DOM.
SC.CoreView
uses a pluggable transition architecture where the transition
setup, execution and cleanup can be handled by a specified transition
plugin.
There are a number of pre-built transition plugins available in the foundation framework:
SC.View.BOUNCE_IN
SC.View.FADE_IN
SC.View.SLIDE_IN
SC.View.SCALE_IN
SC.View.SPRING_IN
You can even provide your own custom transition plugins. Just create a
transition object that conforms to the SC.ViewTransitionProtocol
protocol.
- Default value:
- null
- Since:
- Version 1.10
The options for the given transition in plugin.
These options are specific to the current transition plugin used and are used to modify the transition animation. To determine what options may be used for a given plugin and to see what the default options are, see the documentation for the transition plugin being used.
Most transitions will accept a duration and timing option, but may
also use other options. For example, SC.View.SLIDE_IN
accepts options
like:
transitionInOptions: {
direction: 'left',
duration: 0.25,
timing: 'ease-in-out'
}
- Default value:
- null
- Since:
- Version 1.10
The transition plugin to use when this view is removed from the DOM.
SC.View
uses a pluggable transition architecture where the transition setup,
execution and cleanup can be handled by a specified transition plugin.
There are a number of pre-built transition plugins available in the foundation framework:
SC.View.BOUNCE_OUT
SC.View.FADE_OUT
SC.View.SLIDE_OUT
SC.View.SCALE_OUT
SC.View.SPRING_OUT
You can even provide your own custom transition plugins. Just create a
transition object that conforms to the SC.ViewTransitionProtocol
protocol.
- Default value:
- null
- Since:
- Version 1.10
The options for the given transition out plugin.
These options are specific to the current transition plugin used and are used to modify the transition animation. To determine what options may be used for a given plugin and to see what the default options are, see the documentation for the transition plugin being used.
Most transitions will accept a duration and timing option, but may
also use other options. For example, SC.View.SLIDE
accepts options
like:
transitionOutOptions: {
direction: 'right',
duration: 0.15,
timing: 'ease-in'
}
- Default value:
- null
- Since:
- Version 1.10
The transition plugin to use when this view is made shown from being hidden.
SC.CoreView
uses a pluggable transition architecture where the transition setup,
execution and cleanup can be handled by a specified transition plugin.
There are a number of pre-built transition plugins available in the foundation framework:
SC.View.BOUNCE_IN
SC.View.FADE_IN
SC.View.SLIDE_IN
SC.View.SCALE_IN
SC.View.SPRING_IN
You can even provide your own custom transition plugins. Just create a
transition object that conforms to the SC.ViewTransitionProtocol
protocol.
- Default value:
- null
- Since:
- Version 1.10
The options for the given transition show plugin.
These options are specific to the current transition plugin used and are used to modify the transition animation. To determine what options may be used for a given plugin and to see what the default options are, see the documentation for the transition plugin being used.
Most transitions will accept a duration and timing option, but may
also use other options. For example, SC.View.SLIDE
accepts options
like:
transitionShowOptions: {
direction: 'left',
duration: 0.25,
timing: 'ease-in-out'
}
- Default value:
- null
- Since:
- Version 1.10
Defined in: layout.js.
- Default value:
- NO
This child layout plugin automatically positions the view's child views in a vertical stack and optionally adjusts the view's height to fit. It does this by checking the height of each child view and positioning the following child view accordingly. Afterwards, by default, any time that a child view's height or visibility changes, the view will use this plugin to re-adjust all following child views' positions and potentially its own height appropriately.
This allows you to stack absolutely positioned views that dynamically change their height and/or visibility without having to resort to using browser flow layout.
A typical usage scenario is a long "form" made of multiple subsection
views. If we want to adjust the height of a subsection, to make space for
an error label for example, it would be a lot of work to manually
reposition all the following sections below it. A much easier to code and
cleaner solution is to just set the childViewLayout
plugin on the wrapper
view.
For example,
MyApp.MyView = SC.View.extend({
// Child views will be stacked in order vertically.
childViewLayout: SC.View.VERTICAL_STACK,
// The order of child views is important!
childViews: ['sectionA', 'sectionB', 'sectionC'],
// The view will resize itself to fit its children.
// i.e. We don't need to specify layout.height, this is automatic.
// The actual layout will become { left: 10, right: 10, top: 20, height: 270 } initially.
layout: { left: 10, right: 10, top: 20 },
sectionA: SC.View.design({
// We don't need to specify layout.top, this is automatic.
// The actual layout will become { left: 0, right: 0, top: 0, height: 100 } initially.
layout: { height: 100 }
}),
sectionB: SC.View.design({
// We don't need to specify layout.top, this is automatic.
// The actual layout will become { border: 1, left: 0, right: 0, top: 100, height: 50 } initially.
layout: { border: 1, height: 50 }
}),
sectionC: SC.View.design({
// We don't need to specify layout.top, this is automatic.
// The actual layout will become { left: 10, right: 10, top: 150, height: 120 } initially.
layout: { left: 10, right: 10, height: 120 }
})
});
Modify the default behavior with childViewLayoutOptions
To modify the plugin behavior for all child view layouts, you can set the
following child view layout options in childViewLayoutOptions
on the view:
paddingBefore
- Adds padding before the first child view. Default: 0paddingAfter
- Adds padding after the last child view. Default: 0- spacing - Adds spacing between each child view. Default: 0
resizeToFit
- Whether to resize the view to fit the child views (requires that each child view has a layout height). Default: true
For example,
MyApp.MyView = SC.View.extend({
// Child views will be stacked in order vertically.
childViewLayout: SC.View.VERTICAL_STACK,
// Change the behavior of the VERTICAL_STACK plugin
childViewLayoutOptions: {
paddingBefore: 10,
paddingAfter: 20,
spacing: 5
},
// The order of child views is important!
childViews: ['sectionA', 'sectionB', 'sectionC'],
// The actual layout will become { left: 10, right: 10, top: 20, height: 310 } initially.
layout: { left: 10, right: 10, top: 20 }, // Don't need to specify layout.height, this is automatic.
sectionA: SC.View.design({
// We don't need to specify layout.top, this is automatic.
// The actual layout will become { left: 0, right: 0, top: 10, height: 100 } initially.
layout: { height: 100 }
}),
sectionB: SC.View.design({
// We don't need to specify layout.top, this is automatic.
// The actual layout will become { border: 1, left: 0, right: 0, top: 115, height: 50 } initially.
layout: { border: 1, height: 50 }
}),
sectionC: SC.View.design({
// We don't need to specify layout.top, this is automatic.
// The actual layout will become { left: 10, right: 10, top: 170, height: 120 } initially.
layout: { left: 10, right: 10, height: 120 }
})
});
If resizeToFit
is set to false
, the view will not adjust itself to fit
its child views. This means that when resizeToFit
is false, the view should
specify its height component in its layout. A direct effect is the possibility for
the child views to automatically extend or shrink in order to fill the empty, unclaimed space.
This available space is shared between the children not specifying a fixed height
and their final dimension is calculated proportionally to the value of the
property fillRatio
.
For simplicity, when none of the children specifies fillRatio
,
you can ignore the last child view's layout height if you want the last child view
to stretch to fill the parent view.
For example,
MyApp.MyView = SC.View.extend({
// Child views will be stacked in order vertically.
childViewLayout: SC.View.VERTICAL_STACK,
// Change the behavior of the VERTICAL_STACK plugin
childViewLayoutOptions: {
paddingBefore: 10,
paddingAfter: 20,
spacing: 5,
resizeToFit: false
},
// The order of child views is important!
childViews: ['sectionA', 'sectionB', 'sectionC'],
// Actual layout will become { left: 10, right: 10, top: 20, height: 500 }
layout: { left: 10, right: 10, top: 20, height: 500 }, // Need to specify layout.height.
sectionA: SC.View.design({
// We don't need to specify layout.top, this is automatic. This child will not stretch, its height is set.
// The actual layout will become { left: 0, right: 0, top: 10, height: 100 } initially.
layout: { height: 100 }
}),
sectionB: SC.View.design({
// The unclaimed space so far is 500 - 10 - 100 - 5 - 5 - 20, or 360px. This space will be shared between
// the two last sections, because we won't specity a height on them.
// This view will get 1/3 of the available space, because the other flexibile view has a ratio of 2.
fillRatio: 1,
// This section will take 1/3 * 360px = 120px.
// Actual layout will become { border: 1, left: 0, right: 0, top: 115, bottom: 265 }, in other words, height == 120
// We don't need to specify layout.top, layout.bottom or layout.height, this is automatic.
layout: { border: 1 }
}),
sectionC: SC.View.design({
// This view will get 2/3 of the available space, because the other flexibile view has a ratio of 1.
fillRatio: 2,
// This section will take 2/3 * 360px = 240px.
// Actual layout will become { left: 10, right: 10, top: 240, bottom: 20 }, in other words, height == 240
// We don't need to specify layout.top, layout.bottom or layout.height, this is automatic.
layout: { left: 10, right: 10 }
})
});
Modify specific child view layouts
To adjust the child layout on a granular level per child view, you can also set the following properties on each child view:
marginBefore
- Specify the minimum spacing above the child view.marginAfter
- Specify the minimum spacing below the child view.useAbsoluteLayout
- Don't include this child view in automatic layout, use absolute positioning based on the child view'slayout
property.useStaticLayout
- Don't include this child view in automatic layout. This child view uses relative positioning and is not eligible for automatic layout.isVisible
- Non-visible child views are not included in the stack.fillRatio
- When the parent view is configured with a fixed dimension, children not specifying a height but specifyingfillRatio
will be resized to fill the unclaimed space proportionally to this ratio.
For example,
MyApp.MyView = SC.View.extend({
// Child views will be stacked in order vertically.
childViewLayout: SC.View.VERTICAL_STACK,
// Actual layout will become { left: 10, right: 10, top: 20, height: 570 }
layout: { left: 10, right: 10, top: 20 },
// Keep the child views ordered!
childViews: ['sectionA', 'float', 'sectionB', 'sectionC'],
sectionA: SC.View.design({
// Actual layout will become { left: 0, right: 50, top: 0, height: 100 }
layout: { right: 50, height: 100 },
// The following child view will be at least 50px further down.
marginAfter: 50
}),
float: SC.View.design({
// This view will not be included in automatic layout and will not effect the stack.
layout: { top: 5, right: 5, width: 50, height: 50 },
useAbsoluteLayout: true
}),
sectionB: SC.View.design({
// Actual layout will become { left: 0, right: 0, top: 150, height: 120 }
layout: { height: 120 }
}),
sectionC: SC.View.design({
// Actual layout will become { left: 0, bottom: 0, top: 470, height: 100 }
layout: { height: 100 },
// This child view will be at least 200px below the previous.
marginBefore: 200
})
});
A Note About Spacing
Note that the spacing attribute in childViewLayoutOptions
becomes the
minimum margin between child views, without explicitly overriding it from
both sides using marginAfter
and marginBefore
. For example, if spacing
is 25, setting marginAfter
to 10 on a child view will not result in the
next child view being 10px below it, unless the next child view also
specified marginBefore
as 10.
What this means is that it takes less configuration if you set spacing
to
be the smallest margin you wish to exist between child views and then use
the overrides to grow the margin if necessary. For example, if spacing
is 5, setting marginAfter
to 10 on a child view will result in the next
child view being 10px below it, without having to also specify marginBefore
on that next child view.
Defined in: stack_layout.js.
- Since:
- Version 1.10
Class Method Detail
Defined in: layout.js.
- Parameters:
- layout
- parentFrame
Defined in: layout.js.
- Parameters:
- layout
- layoutParams
- parentFrame
Instance Method Detail
Get a CoreQuery object for this view's layer, or pass in a selector string to get a CoreQuery object for a DOM node nested within this layer.
- Parameters:
- sel String
- a CoreQuery-compatible selector string
- Returns:
- SC.CoreQuery
- the CoreQuery object for the DOM node
This convenience method will take the current layout, apply any changes you pass and set it again. It is more convenient than having to do this yourself sometimes.
You can pass just a key/value pair or a hash with several pairs. You can also pass a null value to delete a property.
This method will avoid actually setting the layout if the value you pass does not edit the layout.
Defined in: layout.js.
Animate a group of layout properties using CSS animations.
On supported platforms, this will apply the proper CSS transition style in order to animate the view to the new layout. The properties object should contain the names of the layout properties to animate with the new layout values as values.
Options
To control the transition, you must provide an options object that contains at least the duration property and optionally the timing and delay properties. The options properties are as follows:
duration: The duration of the transition in seconds. The default value is 0.25.
timing: The transition timing function. This may be a predefined CSS timing function (e.g. 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out') or it may be an array of values to make a cubic bezier (e.g. [0, 0, 0.58, 1.0]). The default value is 'ease'.
- 'linear' - Specifies a transition effect with the same speed from start to end (equivalent to cubic-bezier(0,0,1,1))
- 'ease' - Specifies a transition effect with a slow start, then fast, then end slowly (equivalent to cubic-bezier(0.25,0.1,0.25,1))
- 'ease-in' - Specifies a transition effect with a slow start (equivalent to cubic-bezier(0.42,0,1,1))
- 'ease-out' - Specifies a transition effect with a slow end (equivalent to cubic-bezier(0,0,0.58,1))
- 'ease-in-out' - Specifies a transition effect with a slow start and end (equivalent to cubic-bezier(0.42,0,0.58,1))
'cubic-bezier(n,n,n,n)' - Define your own values in the cubic-bezier function. Possible values are numeric values from 0 to 1
delay: The transition delay in seconds. The default value is 0.
For example,
var myView = SC.View.create({
layout: { top: 10, left: 10, width: 200, height: 400 }
});
MyApp.mainPane.appendChild(myView);
// The view will animate to the new top & left values.
myView.animate(
{ top: 200, left: 200 }, // properties
{ duration: 0.75, timing: 'ease-out', delay: 0.5 } // options
);
Callbacks
To execute code when the transition completes, you may provide an optional
target and/or method. When the given group of transitions completes,
the callback function will be called once and passed an animationResult
object with
properties containing the event
, the view
and a boolean isCancelled
which
indicates if the animation had been cancelled or not. The format of the
target and method follows the standard SproutCore format, where if the
target is not given then the view itself will be the target. The
method can be a function or a property path to look up on the target.
For example,
// Passing a function for method.
myView.animate(
{ top: 200, left: 200 }, // properties
{ duration: 0.75 }, // options
function (animationResult) { // method
// `this` will be myView
}
);
// Passing a target and method.
myView.animate(
{ scale: 0, opacity: 0 }, // properties
{ duration: 1.5 }, // options
MyApp.statechart, // target
'myViewDidShrink' // method
);
The animate functions are intelligent in how they apply animations and
calling animate in a manner that would affect an ongoing animation (i.e.
animating left again while it is still in transition) will result in
the ongoing animation callback firing immediately with isCancelled
set to
true and adjusting the transition to accomodate the new settings.
Note: This may not work if you are not using SproutCore for view layout,
which means you should not use animate
if the view has useStaticLayout
set to true.
A note about Hardware Acceleration.
If a view has a fixed layout (i.e. view.get('isFixedLayout') == true) then
it will be eligible for hardware accelerated position transitions. Having a
fixed layout, simply means that the view has a fixed size (width and height)
and a fixed position (left and top). If the view is eligible for hardware
acceleration, it must also set wantsAcceleratedLayer
to true for animate to
use hardware accelerated transitions when animating its position.
Occassionally, you may wish to animate a view with a non-fixed layout. To do so with hardware acceleration, you should convert the view to a fixed layout temporarily and then set it back to a flexible layout after the transition is complete.
For example,
// Flexible layout.
myView.set('layout', { left: 0, top: 10, right: 0, bottom: 10 });
// Prepare to animate by converting to a fixed layout.
frame = myView.get('frame');
height = frame.height;
width = frame.width;
myView.adjust({ right: null, bottom: null, height: height, width: width });
// Animate (will be hardware accelerated if myView.get('wantsAcceleratedLayout') is true).
myView.animate('left', width, { duration: 1 }, function () {
// Revert back to flexible layout.
myView.adjust({ right: -width, bottom: 10 });
});
Defined in: animation.js.
- Parameters:
- properties Object|String
- Hash of property names with new layout values or a single property name.
- value Number Optional
- The new layout value for a single property (only provide if the first parameter is a String).
- Duration Number|Object
- or hash of transition options.
- target Object Optional, Default: this
- The target for the method.
- method AnimateCallback|String Optional
- The method to run when the transition completes. May be a function or a property path.
- Returns:
- SC.View
- receiver
Appends the specified view to the end of the receivers childViews
array.
This is equivalent to calling insertBefore
(view, null);
Defined in: manipulation.js.
- Parameters:
- view
- {SC.View} the view to insert
- Returns:
- SC.View
- the receiver
- Parameters:
- context
Call this method when you plan to begin a live resize. This will notify the receiver view and any of its children that are interested that the resize is about to begin.
Defined in: layout.js.
- Returns:
- SC.View
- receiver
Defined in: layout.js.
Defined in: manipulation.js.
Call this to append a child while building it in. If the child is not
buildable, this is the same as calling appendChild
.
Defined in: manipulation.js.
- Parameters:
- view
Implement this if you need to do anything special when cancelling build in. You probably won't be able to do anything. I mean, what are you gonna do?
If build in was cancelled, it means build out is probably happening.
So, any timers or anything you had going, you can cancel.
Then buildOut
will happen.
Defined in: manipulation.js.
Defined in: manipulation.js.
Defined in: manipulation.js.
- Parameters:
- child
Defined in: manipulation.js.
Call to remove a child after building it out. If the child is not buildable,
this will simply call removeChild
.
Defined in: manipulation.js.
- Parameters:
- view
Implement this if you need to do anything special when cancelling build out;
note that buildIn
will subsequently be called, so you usually won't need to do
anything.
This is basically called whenever build in happens.
Defined in: manipulation.js.
Defined in: manipulation.js.
Cancels the animation, adjusting the view's layout immediately to one of
three values depending on the layoutState
parameter.
If no layoutState
is given or if SC.LayoutState.END
is given, the view
will be adjusted to its final layout. If SC.LayoutState.START
is given,
the view will be adjusted back to its initial layout and if
SC.LayoutState.CURRENT
is given, the view will stop at its current layout
value, which will be some transient value between the start and end values.
Note: The animation callbacks will be called with the animationResult
object's
isCancelled
property set to YES
.
Defined in: animation.js.
- Parameters:
- layoutState SC.LayoutState Optional, Default: SC.LayoutState.END
- The layout to immediately adjust the view to.
- Returns:
- SC.View
- this
The clipping frame returns the visible portion of the view, taking into
account the clippingFrame
of the parent view. (Note that, in contrast
to frame
, clippingFrame
is in the context of the view itself, not
its parent view.)
Normally this will be calculated based on the intersection of your own
clippingFrame
and your parentView
's clippingFrame
.
Computes the frame of the view by examining the view's DOM representation. If no representation exists, returns null.
If the view has a parent view, the parent's bounds will be taken into account when calculating the frame.
- Returns:
- Rect
- the computed frame
Defined in: layout.js.
- Parameters:
- frame
Returns the DOM element that should be used to hold child views when they are added/remove via DOM manipulation. The default implementation simply returns the layer itself. You can override this to return a DOM element within the layer.
- Parameters:
- evt
- {SC.Event} the contextmenu event
- Returns:
- YES if the contextmenu will be allowed to show up
Converts a frame offset in the coordinates of another view system to the receiver's view.
Note that the convext of a view's frame is relative to the view's
parentFrame
. For example, if you want to convert the frame of view that
belongs to another view to the receiver's frame you would do:
var frame = view.get('frame');
var newFrame = this.convertFrameFromView(frame, view.get('parentView'));
Defined in: layout.js.
- Parameters:
- frame Rect
- the source frame
- targetView SC.View
- the target view to convert to
- Returns:
- Rect
- converted frame
Converts a frame from the receiver's offset to the target offset. Both the receiver and the target must belong to the same pane. If you pass null, the conversion will be to the pane level.
Note that the context of a view's frame is the view's parent frame. In other words, if you want to convert the frame of your view to the global frame, then you should do:
var pv = this.get('parentView'), frame = this.get('frame');
var newFrame = pv ? pv.convertFrameToView(frame, null) : frame;
Defined in: layout.js.
- Parameters:
- frame Rect
- the source frame
- targetView SC.View
- the target view to convert to
- Returns:
- Rect
- converted frame
Instantiates a view to be added to the childViews
array during view
initialization. You generally will not call this method directly unless
you are overriding createChildViews
(). Note that this method will
automatically configure the correct settings on the new view instance to
act as a child of the parent.
If the given view is a class, then createdByParent
will be set to true on
the returned instance.
This method is called when your view is first created to setup any child views that are already defined on your class. If any are found, it will instantiate them for you.
The default implementation of this method simply steps through your
childViews
array, which is expects to either be empty or to contain View
designs that can be instantiated
Alternatively, you can implement this method yourself in your own
subclasses to look for views defined on specific properties and then build
a childViews
array yourself.
Note that when you implement this method yourself, you should never instantiate views directly. Instead, you should use this.createChildView() method instead. This method can be much faster in a production environment than creating views yourself.
- Returns:
- SC.View
- receiver
Creates the layer by creating a renderContext
and invoking the view's
render() method. This will only create the layer if the layer does not
already exist.
When you create a layer, it is expected that your render() method will
also render the HTML for all child views as well. This method will
notify the view along with any of its childViews
that its layer has been
created.
- Returns:
- SC.View
- receiver
You can set this to an SC.Cursor
instance; whenever that SC.Cursor's
'cursorStyle' changes, the cursor for this view will automatically
be updated to match. This allows you to coordinate the cursors of
many views by making them all share the same cursor instance.
For example, SC.SplitView
uses this ensure that it and all of its
children have the same cursor while dragging, so that whether you are
hovering over the divider or another child of the split view, the
proper cursor is visible.
Defined in: cursor.js.
- Parameters:
- key
- value
Completely destroys a view instance so that it may be garbage collected.
You must call this method on a view to destroy the view (and all of its child views). This will remove the view from any parent, detach the view's layer from the DOM if it is attached and clear the view's layer if it is rendered.
Once a view is destroyed it can not be reused.
- Returns:
- SC.View
- receiver
Destroys any existing layer along with the layer for any child views as well. If the view does not currently have a layer, then this method will do nothing.
If you implement willDestroyLayer
() on your view or if any mixins
implement willDestroLayerMixin
(), then this method will be invoked on your
view before your layer is destroyed to give you a chance to clean up any
event handlers, etc.
If you write a willDestroyLayer
() handler, you can assume that your
didCreateLayer
() handler was called earlier for the same layer.
Normally you will not call or override this method yourself, but you may want to implement the above callbacks when it is run.
- Returns:
- SC.View
- receiver
Invoked just after the responder gains key responder status. By default, it calls focus on the view root element. For accessibility purposes.
Defined in: keyboard.js.
- Parameters:
- responder SC.Responder
Defined in: keyboard.js.
- Parameters:
- responder SC.Responder
This method is invoked whenever a display property changes and updates
the view's content once at the end of the run loop before any invokeLast
functions run.
To cause the view to be updated you can call this method directly and if you need to perform additional setup whenever the display changes, you can override this method as well.
- Returns:
- SC.View
- receiver
The computed tooltip. This is generated by localizing the toolTip
property if necessary.
Extend SC.View
with emitDesign()
which will encode the view and all of its
subviews then computes an empty element to attach to the design.
Defined in: view.js.
Patch SC.View
to respond to encodeDesign()
. This will proxy to the
paired designer, if there is one. If there is no paired designer, returns
NO
.
Defined in: view.js.
- Parameters:
- coder
Call this method when you are finished with a live resize. This will notify the receiver view and any of its children that are interested that the live resize has ended.
Defined in: layout.js.
- Returns:
- SC.View
- receiver
Attempts to discover the layer in the parent layer. The default
implementation looks for an element with an ID of layerId
(or the view's
guid if layerId
is null). You can override this method to provide your
own form of lookup. For example, if you want to discover your layer using
a CSS class name instead of an ID.
- Parameters:
- parentLayer DOMElement
- the parent's DOM layer
- Returns:
- DOMElement
- the discovered layer
Frame describes this view's current bounding rect, relative to its parent view. You can use this, for example, to reliably access a width for a view whose layout is defined with left and right. (Note that width and height values are calculated in the parent view's frame of reference as well, which has consequences for scaled views.)
Insert the view into the the receiver's childNodes
array.
The view will be added to the childNodes
array before the beforeView
. If
beforeView
is null, then the view will be added to the end of the array.
This will also add the view's rootElement
DOM node to the receivers
containerElement
DOM node as a child.
If the specified view already belongs to another parent, it will be removed from that view first.
Defined in: manipulation.js.
This method is invoked by interpretKeyEvents
() when you receive a key
event matching some plain text. You can use this to actually insert the
text into your application, if needed.
Defined in: keyboard.js.
This method will process a key input event, attempting to convert it to
an appropriate action method and sending it up the responder chain. The
event is converted using the key bindings hashes, (SC.BASE_KEY_BINDINGS
and SC.MODIFIED_KEY_BINDINGS)
which map key events to method names. If
no key binding method is found, then the key event will be passed along
to any insertText
() method found.
Defined in: keyboard.js.
Invokes a method on the render delegate, if one is present and it implements that method.
Defined in: theming.js.
- Parameters:
- method String
- The name of the method to call.
- arg
- One or more arguments.
By default we don't disable the context menu. Overriding this property can enable/disable the context menu per view.
Defined in: visibility.js.
Returns YES
if the receiver is a subview of a given view or if it's
identical to that view. Otherwise, it returns NO.
- Parameters:
- view
Computed property returns YES
if the view and all of its parent views
are enabled in the pane. You should use this property when deciding
whether to respond to an incoming event or not.
Defined in: enabled.js.
Returns whether the layout is 'fixed' or not. A fixed layout means a fixed left & top position and fixed width & height. Fixed layouts are therefore unaffected by changes to their parent view's layout.
Defined in: layout.js.
- Returns:
- Boolean
- YES if fixed, NO otherwise
Returns the current layer for the view. The layer for a view is only generated when the view first becomes visible in the window and even then it will not be computed until you request this layer property.
If the layer is not actually set on the view itself, then the layer will be found by calling this.findLayerInParentLayer().
You can also set the layer by calling set on this property.
- Parameters:
- key
- value
The ID to use when trying to locate the layer in the DOM. If you do not
set the layerId
explicitly, then the view's GUID will be used instead.
This ID must be set at the time the view is created.
- Parameters:
- key
- value
Defined in: manipulation.js.
Applies the current layout to the layer. This method is usually only called once per runloop. You can override this method to provide your own layout updating method if you want, though usually the better option is to override the layout method from the parent view.
The default implementation of this method simply calls the updateLayout
()
method on the views that need layout.
Defined in: layout.js.
- Parameters:
- force Boolean
- Force the update to the layer's layout style immediately even if the view is not in a shown state. Otherwise the style will be updated when the view returns to a shown state.
- Returns:
- void
Called your layout method if the view currently needs to layout some child views.
Defined in: layout.js.
This method is called whenever a property changes that invalidates the layout of the view. Changing the layout will do this automatically, but you can add others if you want.
Implementation Note: In a traditional setup, we would simply observe
'layout' here, but as described above in the documentation for our custom
implementation of propertyDidChange
(), this method must always run
immediately after 'layout' is updated to avoid the potential for stale
(incorrect) cached 'frame' values.
Defined in: layout.js.
- Returns:
- SC.View
- receiver
One of two methods that are invoked whenever one of your childViews
layout changes. This method is invoked every time a child view's layout
changes to give you a chance to record the information about the view.
Since this method may be called many times during a single run loop, you
should keep this method pretty short. The other method called when layout
changes, layoutChildViews
(), is invoked only once at the end of
the run loop. You should do any expensive operations (including changing
a childView
's actual layer) in this other method.
Note that if as a result of running this method you decide that you do not
need your layoutChildViews
() method run later, you can set the
childViewsNeedsLayout
property to NO
from this method and the layout
method will not be called layer.
Defined in: layout.js.
- Parameters:
- childView SC.View
- the view whose layout has changed.
- Returns:
- void
layoutStyle
describes the current styles to be written to your element
based on the layout you defined. Both layoutStyle
and frame reset when
you edit the layout property. Both are read only.
Computes the layout style settings needed for the current anchor.
Defined in: layout_style.js.
The view responsible for laying out this view. The default version returns the current parent view.
Defined in: layout.js.
Computes the next valid key view. This is the next key view that
acceptsFirstResponder
. Computed using depth first search. If the current view
is not valid, it will first traverse its children before trying siblings. If
the current view is the only valid view, the current view will be returned. Will
return null if no valid view can be found.
Defined in: keyboard.js.
If the parent view has changed, we need to insert this view's layer into the layer of the new parent view.
This method may be called on your view whenever the parent view resizes.
The default version of this method will reset the frame and then call
viewDidResize
() if its size may have changed. You will not usually override
this method, but you may override the viewDidResize
() method.
Defined in: layout.js.
- Parameters:
- parentFrame Frame
- the parent view's current frame.
- Returns:
- void
Recursively travels down the view hierarchy looking for a view that
implements the key equivalent (returning to YES
to indicate it handled
the event). You can override this method to handle specific key
equivalents yourself.
The keystring is a string description of the key combination pressed.
The evt is the event itself. If you handle the equivalent, return YES
.
Otherwise, you should just return sc_super.
Defined in: keyboard.js.
Computes the previous valid key view. This is the previous key view that
acceptsFirstResponder
. Traverse views in the opposite order from
nextValidKeyView
. If the current view is the pane, tries deepest child. If the
current view has a previous view, tries its last child. If this view is the
first child, tries the parent. Will return null if no valid view can be
found.
Defined in: keyboard.js.
The 'frame' property depends on the 'layout' property as well as the parent view's frame. In order to properly invalidate any cached values, we need to invalidate the cache whenever 'layout' changes. However, observing 'layout' does not guarantee that; the observer might not be run before all other observers.
In order to avoid any window of opportunity where the cached frame could
be invalid, we need to force layoutDidChange
() to immediately run
whenever 'layout' is set.
Defined in: layout.js.
- Parameters:
- key
- value
- _keepCache
The visibility of the view does not need to be computed any longer as it
is maintained by the internal SC.View
statechart.
Defined in: visibility.js.
- Returns:
- SC.View
- receiver
Removes all children from the parentView
and destroys them and their
layers.
Note that if any child view uses a transitionOut
plugin, it will not be
fully removed until the transition completes. To force all child views to
remove immediately you can pass true as the optional immediately
argument.
Tip: If you know that there are no transitions for the child views, you should pass true to optimize the document removal.
Removes the child view from the parent view and detaches it from the document.
This does not remove the child view's layer (i.e. the node still exists, but is no longer in the document) and does not destroy the child view (i.e. it can still be re-attached to the document).
Note that if the child view uses a transitionOut
plugin, it will not be
fully detached until the transition completes. To force the view to detach
immediately you can pass true for the optional immediately
argument.
If you wish to remove the child and discard it, use removeChildAndDestroy
.
Removes the child view from the parent view, detaches it from the document and* destroys the view and its layer.
Note that if the child view uses a transitionOut
plugin, it will not be
fully detached and destroyed until the transition completes. To force the
view to detach immediately you can pass true for the optional immediately
argument.
If you wish to remove the child and keep it for further re-use, use
removeChild
.
- Parameters:
- view SC.View
- The view to remove as a child view and destroy.
- immediately Boolean Optional, Default: false
- Forces the child view to be removed and destroyed immediately regardless if it uses a transitionOut plugin.
- Returns:
- SC.View
- receiver
- See:
- SC.View#removeChild
Removes the view from its parentView
, if one is found. Otherwise
does nothing.
- Returns:
- SC.View
- receiver
Invoked whenever your view needs to create its HTML representation.
You will normally override this method in your subclassed views to provide whatever drawing functionality you will need in order to render your content.
This method is usually only called once per view. After that, the update method will be called to allow you to update the existing HTML representation.
The default implementation of this method calls renderChildViews
().
For backwards compatibility, this method will also call the appropriate method on a render delegate object, if your view has one.
Defined in: theming.js.
- Parameters:
- context SC.RenderContext
- the render context
- firstTime
- Returns:
- void
Your render method should invoke this method to render any child views,
especially if this is the first time the view will be rendered. This will
walk down the childView
chain, rendering all of the children in a nested
way.
- Parameters:
- context SC.RenderContext
- the context
- Returns:
- SC.RenderContext
- the render context
Creates a new renderContext
with the passed tagName
or element. You
can override this method to provide further customization to the context
if needed. Normally you will not need to call or override this method.
- Parameters:
- tagNameOrElement
- Returns:
- SC.RenderContext
The object to which rendering and updating the HTML representation of this view should be delegated.
By default, views are responsible for creating their own HTML
representation. In some cases, however, you may want to create an object
that is responsible for rendering all views of a certain type. For example,
you may want rendering of SC.ButtonView
to be controlled by an object that
is specific to the current theme.
By setting a render delegate, the render and update methods will be called on that object instead of the view itself.
For your convenience, the view will provide its displayProperties
to the
RenderDelegate. In some cases, you may have a conflict between the RenderDelegate's
API and your view's. For instance, you may have a 'value' property that is
any number, but the render delegate expects a percentage. Make a 'displayValue'
property, add it to displayProperties
instead of 'value', and the Render Delegate
will automatically use that when it wants to find 'value.'
You can also set the render delegate by using the 'renderDelegateName' property.
Defined in: theming.js.
- Parameters:
- key
- value
[RO] Pass this object as the data source for render delegates. This proxy object for the view relays requests for properties like 'title' to 'displayTitle' as necessary.
If you ever communicate with your view's render delegate, you should pass this object as the data source.
The proxy that forwards RenderDelegate requests for properties to the view, handling display*, keeps track of the delegate's state, etc.
Defined in: theming.js.
Default method called by the layout view to actually apply the current
layout to the layer. The default implementation simply assigns the
current layoutStyle
to the layer. This method is also called whenever
the layer is first created.
Defined in: layout.js.
- Parameters:
- the SC.RenderContext
- render context
- Returns:
- void
Replaces the current array of child views with the new array of child views.
This will remove and destroy all of the existing child views and their layers.
Warning: The new array must be made of child views (i.e. created using this.createChildView() on the parent).
Defined in: manipulation.js.
Replace the oldView
with the specified view in the receivers childNodes
array. This will also replace the DOM node of the oldView
with the DOM
node of the new view in the receivers DOM.
If the specified view already belongs to another parent, it will be removed from that view first.
Defined in: manipulation.js.
- Parameters:
- view
- {SC.View} the view to insert in the DOM
- view
- {SC.View} the view to remove from the DOM.
- Returns:
- SC.View
- the receiver
Destroys and recreates the current layer. Doing this on a parent view can be more efficient than modifying individual child views independently.
- Returns:
- SC.View
- receiver
Defined in: animation.js.
This should reset (without animation) any internal states; sometimes called before.
It is usually called before a build in, by the parent view.
Defined in: manipulation.js.
Defined in: manipulation.js.
Defined in: view_designer.js.
- Parameters:
- methodName
Attempt to scroll the view to visible. This will walk up the parent
view hierarchy looking looking for a scrollable view. It will then
call scrollToVisible
() on it.
Returns YES
if an actual scroll took place, no otherwise.
Defined in: layout.js.
- Returns:
- Boolean
Default method called when a selectstart event is triggered. This event is only supported by IE. Used in sproutcore to disable text selection and IE8 accelerators. The accelerators will be enabled only in text selectable views. In FF and Safari we use the css style 'allow-select'.
If you want to enable text selection in certain controls is recommended
to override this function to always return YES
, instead of setting
isTextSelectable
to true.
For example in textfield you do not want to enable textSelection
on the text
hint only on the actual text you are entering. You can achieve that by
only overriding this method.
- Parameters:
- evt
- {SC.Event} the selectstart event
- Returns:
- YES if selectable
The SC.Theme
instance which this view should use to render.
Note: the actual code for this function is in _themeProperty for backwards-compatibility: some older views specify a string value for 'theme', which would override this property, breaking it.
Defined in: theming.js.
Returns YES
if the provided touch is within the boundary set by
touchBoundary
.
Defined in: touch.js.
- Parameters:
- touch
If the view has a designer, give it an opportunity to handle an event before passing it on to the main view.
Defined in: view_designer.js.
- Parameters:
- methodName
- arg1
- arg2
Updates the design mode for this view.
This method is called automatically by the view's pane whenever the pane
determines that the design mode, as specified in the pane's designModes
property, has changed. You should likely never need to call it manually.
This method updates the designMode
property of the view, adjusts
the layout if a matching design adjustment in the view's designAdjustments
property is found and adds a class name to the view for the current
design mode.
Note that updating the design mode also updates all child views of this view.
Defined in: design_mode.js.
This is the core method invoked to update a view layer whenever it has changed. This method simply creates a render context focused on the layer element and then calls your render() method.
You will not usually call or override this method directly. Instead you
should set the layerNeedsUpdate
property to YES
to cause this method to
run at the end of the run loop, or you can call updateLayerIfNeeded
()
to force the layer to update immediately.
Instead of overriding this method, consider overriding the render() method instead, which is called both when creating and updating a layer. If you do not want your render() method called when updating a layer, then you should override this method instead.
- Returns:
- SC.View
- receiver
Updates the view's layer if the view is in a shown state. Otherwise, the view will be updated the next time it enters a shown state.
This is the same behavior as displayDidChange
except that calling
updateLayerIfNeeded
will attempt to update each time it is called,
while displayDidChange
will only attempt to update the layer once per run
loop.
- Parameters:
- skipIsVisibleInWindowCheck
- Returns:
- SC.View
- receiver
This method is called when a view changes its location in the view hierarchy. This method will update the underlying DOM-location of the layer so that it reflects the new location.
- Returns:
- SC.View
- receiver
Calls updateLayerLocation
(), but only if the view's layer location
currently needs to be updated.
- Returns:
- SC.View
- receiver
Invoked by the layoutChildViews
method to update the layout on a
particular view. This method creates a render context and calls the
renderLayout
() method, which is probably what you want to override instead
of this.
You will not usually override this method, but you may call it if you
implement layoutChildViews
() in a view yourself.
Defined in: layout.js.
This method is invoked on your view when the view resizes due to a layout change or potentially due to the parent view resizing (if your view’s size depends on the size of your parent view). You can override this method to implement your own layout if you like, such as performing a grid layout.
The default implementation simply notifies about the change to 'frame' and
then calls parentViewDidResize
on all of your children.
Defined in: layout.js.
- Returns:
- void
This method is invoked just before you become the key responder. The
passed view is the view that is about to lose keyResponder
status. You
can use this to do any setup before the view changes.
Remember that you can gain/lose key responder status either because
another view in the same pane is becoming first responder or because
another pane is about to become key.
Defined in: keyboard.js.
- Parameters:
- responder SC.Responder
This method is invoked just before you lost the key responder status.
The passed view is the view that is about to gain keyResponder
status.
This gives you a chance to do any early setup. Remember that you can
gain/lose key responder status either because another view in the same
pane is becoming first responder or because another pane is about to
become key.
Defined in: keyboard.js.
- Parameters:
- responder SC.Responder