I have been able to get events to fire in my marionette controllers like so:
...snip...
var Controller = {};
_.extend(Controller, Backbone.Events);
// private
var Layout = Marionette.Layout.extend({
template: _.template(layout),
regions: {
inspectorStart: "#inspector_start",
loginStart: "#login_start",
playerStart: "#player_start"
}
});
// private
var _initializeLayout = function() {
console.log('initialize Start Layout...');
Controller.layout = new Layout();
Controller.layout.on('show', function() { **// This works**
Controller.trigger('startLayout:rendered'); **// This works**
});
vent.trigger('app:show', Controller.layout); **// This works**
};
// Listen for events ///////////////////////////////////////////
// controller attach a sub view
Controller.on("startLayout:rendered", function() { **// This works**
console.log('startLayout:rendered =>StartController'); **// This works**
// render views for the existing HTML in the template,...
var inspectorStartView = new InspectorStartView();
// and attach it to the layout (i.e. don't double render)
Controller.layout.inspectorStart.attachView(inspectorStartView);
Controller.trigger('inspectorStart:show', inspectorStartView); **// This works**
...snip...
However, when I try to use the extended marionette ItemView I can't get events or triggers to work.
// views/InspectorStartView.js
// -------
define(["jquery", "marionette", "text!templates/InspectorStart.html"],
function($, marionette, template){
var InspectorStartView = marionette.ItemView.extend({
template: template,
events: {
'click .starting_thumbnail' : 'start'
//'click #inspectorStart' : 'start' **// didn't work either**
},
//I had also tried triggers
triggers: {
//'click .starting_thumbnail' : 'inspectorStart:start'
'click #inspectorStart' : 'inspectorStart:start' **// didn't work either**
},
start:function (){ **// Doesn't get called**
console("Caught InspectorStartView click")
this.trigger("inspectorStart:start")
}
});
// Returns the View class
return InspectorStartView;
});
Here is the template:
<!-- InspectorStart.html -->
<div id="inspectorStart" class="thumbnail starting_thumbnail">
<img src="/img/detective-97715888.jpg" alt="Inspector" width="200px" height="300px">
<div class="caption">
<h3>Inspectors Enter Here</h3>
<p>Den Masters, Teachers, Parents, House Mothers, this is where you start.</p>
</div>
</div>
I did have to create the starting_thumbnail class so that I would get a pointer:
.starting_thumbnail{
cursor: pointer;
}
Do I need to do something else to make a div clickable?
On my first attempt I passed in App.vent and tried to use it to no avail now I'm extending the Controller {} with _.extend(Controller, Backbone.Events);
Following some debugging advice from #Ingro I logged what this.$el id for the ItemView. This:
console.log(["InspectorStartView initalise ",this.$el])
Here is the output. There is nodeName: "DIV" and the localName is div.
["InspectorStartView initalise ", jQuery.fn.jQuery.init[1]]
0: "InspectorStartView initalise "
1: jQuery.fn.jQuery.init[1]
0: div
accessKey: ""
align: ""
attributes: NamedNodeMap
baseURI: "http://localhost:8001/index.html"
childElementCount: 1
childNodes: NodeList[3]
children: HTMLCollection[1]
classList: DOMTokenList
className: ""
clientHeight: 496
clientLeft: 0
clientTop: 0
clientWidth: 300
contentEditable: "inherit"
dataset: DOMStringMap
dir: ""
draggable: false
firstChild: #comment
firstElementChild: div#inspectorStart.thumbnail starting_thumbnail
hidden: false
id: ""
innerHTML: "<!-- InspectorStart.html -->↵<div id="inspectorStart" class="thumbnail starting_thumbnail">↵ <img src="/img/detective-97715888.jpg" alt="Inspector" width="200px" height="300px">↵ <div class="caption">↵ <h3>Inspectors Enter Here</h3>↵ <p>Den Masters, Teachers, Parents, House Mothers, this is where you start.</p>↵ </div>↵</div>"
innerText: "↵Inspectors Enter Here↵Den Masters, Teachers, Parents, House Mothers, this is where you start.↵↵"
isContentEditable: false
lang: ""
lastChild: div#inspectorStart.thumbnail starting_thumbnail
lastElementChild: div#inspectorStart.thumbnail starting_thumbnail
localName: "div"
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: null
nextSibling: null
nodeName: "DIV"
nodeType: 1
nodeValue: null
offsetHeight: 496
offsetLeft: 621
offsetParent: body
offsetTop: 388
offsetWidth: 300
<!-- all the on<eventname> were null -->
outerHTML: "<div><!-- InspectorStart.html -->↵<div id="inspectorStart" class="thumbnail starting_thumbnail">...snip..."
ownerDocument: #document
parentElement: li#inspector_start.span4
parentNode: li#inspector_start.span4
prefix: null
previousElementSibling: null
previousSibling: null
scrollHeight: 496
scrollLeft: 0
scrollTop: 0
scrollWidth: 300
spellcheck: true
style: CSSStyleDeclaration
tabIndex: -1
tagName: "DIV"
Of course above is inside the initialize method. I wanted to see the difference after creating a 'new' one:
/ controller show inspector in the layout / subview
Controller.on('inspectorStart:show', function(inspectorStartView) {
console.log('show inspector start view');
console.log(**'InspectorVartView instance this.$el : ', inspectorStartView.el**);
Controller.layout.inspectorStart.show(inspectorStartView);
});
The output is much smaller:
InspectorVartView instance this.$el :
<div>
<!-- InspectorStart.html -->
<div id="inspectorStart" class="thumbnail starting_thumbnail">…</div>
</div>
#Ingro that is wrapped in a div why would that matter?
Does anyone see what I'm doing incorrectly?
Thanks,
Andrew jsFiddle(see comments below)
Turns out I had corrupted jquery somehow. I used jsfiddle to prove my code was correct. then I started looking at version number requirements and replaced jquery and it started working.
Thanks to #Ingro for your input.
Andrew
Related
Let me know if you can help me out somehow, i'm kind of struggling to get my head around.
Starting with some Marionette application logics:
app.js
//basic setup
this.Graph = new joint.dia.Graph;
this.Paper = new joint.dia.Paper({ width: 640, height: 480, model: this.Graph });
// [...] lots of code
//adding elements
app.Elements.add(element);
So far so good. Now the tricky part. I want a collection.
JointCollectionView.js
module.exports = Marionette.CollectionView.extend({
tagName: 'div',
className: 'row',
childView: JointView,
addChild: function(child, ChildView, index){
//does that make sense?
app.Graph.addCell(child);
//should i add it to collection?
if (child.shouldBeShown()) {
return Marionette.CollectionView.prototype.addChild.call(this, child, ChildView, index);
}
},
getChildView: function(item) {
return app.Graph.getCell(item);
}
//[...]
})
Now even more tricky. How do i handle the joint-view to make it work with collections and also display html elements?
JointView.js
module.exports = joint.dia.ElementView.extend({ /* ?!?!?! */ });
//OR ?
module.exports = Marionette.ItemView.extend({
jointElementView: null, //this will be like above somewhere else...
initialize: function(options){
jointElementView = new JointElementView({ /* ... */ });
}
})
I'm no JointJS expert, but your implementation looks perfect.
You want to use the second option:
JointView.js
module.exports = Marionette.ItemView.extend({
template: _.template("");
jointElementView: null, //this will be like above somewhere else...
initialize: function(options){
this.jointElementView = new JointElementView({ /* ... */ });
}
});
since a Marionette.CollectionView expects a Marionette view (sp. a Marionette.ItemView or descendent [LayoutView/CompositeView]).
What I would add to JointView.js is a method to inject the result from this.jointElementView into the JointView.js html. So, add a property to it, like:
onRender: function () {
this.$el.append(this.jointElementView.el); // Where this.jointElementView.el is the JointJS view html
}
With the help of #seebiscuit i looked much deeper into jointjs and narrowed down how i should approach this problem (You didn't seem to be interested in the points though, so i'll answer myself)
The following files were edited:
app.js (changed, important!)
//this step is necessary to create these element before the paper is created.
//Make jointjs GLOBAL!!!!!!
joint.shapes.html = {};
joint.shapes.html.Element = require('views/Element'); //this dude im gonna use to create the elements
joint.shapes.html.ElementView = require('views/ElementView'); //this badboy will fire when i create those elements. MAGIC!
//basic setup
this.Graph = new joint.dia.Graph;
this.Paper = new joint.dia.Paper({ width: 640, height: 480, model: this.Graph });
// [...] lots of code
//adding elements
app.Elements.add(element);
JointCollectionView.js (beauti-/simplyfied)
module.exports = Marionette.CollectionView.extend({
tagName: 'div',
className: 'row',
childView: JointView,
onRender: function(){
// jointjs' paper is added here long after jointjs custom element init.
this.el.appendChild(app.Paper.el);
},
onDestroy: function(){
// removal of the paper is done here
this.el.removeChild(app.Paper.el);
},
buildChildView: function(child, JointView, childViewOptions){
// add model, jointjs' paper and graph into JointView's options
var options = _.extend({model: child}, childViewOptions);
options = _.extend({paper: app.Paper, graph: app.Graph}, options);
return new JointView(options);
}
//[...]
})
JointView.js (magic here!)
module.exports = Marionette.ItemView.extend({
tagName: 'div',
className: 'html-element',
template: "#agentTmpl",
// store here just in case
cell: null,
// [...]
initialize: function() {
// initialize joinjs element-shape here
Marionette.bindEntityEvents(this, this.model, this.modelEvents);
if(this.cell == null){
//notice `el: this.el` This will actually pass the option el to ElementView. Surprised?
//Yeah me too. From there i can do with the dom-element whatever i want
this.cell = new joint.shapes.html.Element({ el: this.el, position: { x: 80, y: 80 }, size: { width: 250 } });
}
},
onRender: function(){
// after rendering add cell to graph
this.options.graph.addCell(this.cell);
},
onDestroy: function(){
// after removal remove cell from graph
this.cell.remove();
}
});
Element.js
ElementView.js
For simplicity more or less like here: http://www.jointjs.com/tutorial/html-elements
To summarize what actually happens is: whenever a new Element is created ElementView will fire all necessary event (initialize, render & whatnot). From there you can manipulate the drawn svg elements or overlap (similar to the tutorial) with my previously created JointView's html. I basically put my JointView dom-element over the SVG which is drawn by jointjs.
There you go. Fixed!
I will try to be simple, i'm on the final stage of my app (a portfolio page), and i only need the interaction between pages, so:
short question:
how to select an specific item of some custom-element made with template is="dom-repeat" and publish like a property to bind later outside with another element attribute (selected="{{}}")
long question:
Form top to bottom. I've got a custom element with two elements inside of neon-animated-pages. The first element is a grid of cards made whit template is="dom-repeat", and the second is another neon animated pages, inside of this are all the works-pages (all pages make a change in a declarative way like this demo)
portfolio-page template:
<neon-animated-pages id="page" class="flex" selected="{{projectSelected}}">
<portfolio-grid id="grid" on-tap="_goToProject" card-selected="{{selected}}"> <-- card-selected not defined yet -->
</portfolio-grid>
<work-pages work-selected="{{selected}}" on-back-portfolio="_backPortfolio">
</work-pages>
</neon-animated-pages>
portfolio-page script:
Polymer({
is: "portfolio-page",
properties:{
projectSelected:{
type: Number,
value: 0
}
},
_goToProject: function(){
this.projectSelected = 1;
},
_backPortfolio: function(){
this.projectSelected = 0;
}
});
Inside of portfolio grid, is another custom element, a simple card with attributes like title and description, the img attribute here is the css id inside of the portfolio-card which sets the background image of my card:
<dom-module id="portfolio-grid">
<template>
<style>
SOME STYLE HERE
</style>
<div class="layout horizontal wrap">
<template is="dom-repeat" id="cardList" items="[[cards]]">
<portfolio-card class$="{{item.class}}" img="{{item.img}}"
title="{{item.title}}" description="{{item.description}}">
</portfolio-card>
</template>
</div>
</template>
<script>
Polymer({
is: "portfolio-grid",
behaviors: [
Polymer.NeonAnimatableBehavior
],
properties: {
cards: {
type: Array,
value: function(){
return [
{ img: 'monalisa', title: 'The Mona Lisa',
description: 'Painting', class: 'cardSmall'},
{ img: 'starrynight', title: 'Starry Night',
description: 'Painting', class: 'cardSmall'},
{ img: 'david', title: 'David',
description: 'Sculpture', class: 'cardMedium'},
{ img: 'memory', title: 'The Persistence Of Memory',
description: 'Painting', class: 'cardSmall'},
{ img: 'venus', title: 'Venus de milo',
description: 'Sculpture', class: 'cardSmall'},
{ img: 'birth', title: 'Birth of Venus',
description: 'Painting', class: 'cardMedium'},
{ img: 'guernica', title: 'The Guernica',
description: 'Painting', class: 'cardBig'},
{ img: 'nightwatch', title: 'The Night Watch',
description: 'Painting', class: 'cardSmall'},
{ img: 'kiss', title: 'The Kiss',
description: 'Painting', class: 'cardSmall'}
]
}
},
animationConfig: {
value: function() {
return {
'entry': {
name: 'fade-in-animation',
node: this,
timing: 2000
},
'exit': {
name: 'fade-out-animation',
node: this
}
}
}
}
}
});
</script>
</dom-module>
And finally my work-pages, here i've got all the works i want to show with fixed navigation controls, all working good (next, previous and back to portfolio grid):
<dom-module id="work-pages">
<template>
<style>
SOME STYLE HERE
</style>
<section id="container" class="layout vertical">
<neon-animated-pages id="works" class="flex" attr-for-selected="work" selected="{{workSelected}}">
<workpage-monalisa work="monalisa"></workpage-monalisa>
<workpage-starrynight work="starrynight"></workpage-starrynight>
<workpage-david work="david"></workpage-david>
<workpage-memory work="memory"></workpage-memory>
<workpage-venus work="venus"></workpage-venus>
<workpage-birth work="birth"></workpage-birth>
<workpage-guernica work="guernica"></workpage-guernica>
<workpage-nightwatch work=nightwatch""></workpage-nightwatch>
<workpage-kiss work="kiss"></workpage-kiss>
</neon-animated-pages>
</section>
<!-- Navigation Buttons -->
<div class="controls">
<!-- Back Work Button -->
<iron-icon id="menuIcon" icon="mrcauko-icons:menu"></iron-icon>
<!-- Back Work Button -->
<div id="back">
<iron-icon class="button" icon="mrcauko-icons:back" on-tap="_goPrev"></iron-icon>
</div>
<!-- Next Work Button -->
<div id="next">
<iron-icon class="button" icon="mrcauko-icons:next" on-tap="_goNext"></iron-icon>
</div>
<!-- Bottom Bar -->
<div class="bottomBar layout horizontal">
<div class="flex"></div>
<iron-icon id="backToPortfolio" icon="mrcauko-icons:view-portfolio" on-tap="_goBackPortfolio"></iron-icon>
<div class="flex"></div>
</div>
</div>
</template>
<script>
Polymer({
is: "work-pages",
behaviors: [
Polymer.NeonAnimatableBehavior
],
properties: {
workSelected: {
type: String,
notify: true
},
animationConfig: {
type: Object,
value: function() {
return {
'entry': {
name: 'fade-in-animation',
node: this
},
'exit': {
name: 'fade-out-animation',
node: this
}
}
}
}
},
listeners: {
'neon-animation-finish': '_onNeonAnimationFinish'
},
_onNeonAnimationFinish: function(){ //This isn't working
this.$.works.scroller.scrollTop = 0;
},
_goBackPortfolio: function(){
this.fire('back-portfolio');
},
_goPrev: function() {
this.$.works.selectPrevious();
},
_goNext: function() {
this.$.works.selectNext();
}
});
</script>
I've been thinking different aproaches but don't know how to implement them.
Because i've got the same name in item.img and attr-for-selected="work" in the work-pages, somehow say "hey, when i click this card, the item.work is the same as the work-selected"(see portfolio-page)
Don't know if i need to use the array selector
Wrap the portfolio-grid inside an iron-selector element, to establish attr-for-selected$="{{item.img}}"(not tried yet but i think this way is using too many elements, and im sure there is a better way)
I know there is demos with neon-animated-pages, but my project is more specific, besides the code of the demos is too complicated for my poor knowledge of js (that's why i love polymer, 'cause i can create great things, and i'm not an expertise in js). I'm not asking to do my job, just only some enlightening to continue. So I ask for help from the immortals like you guys.
If you only need your data to flow from <portfolio-grid> to <work-pages>, then I think the array selector is the way to go.
It should be fairly simple to implement, just like the example in the documentation (see the link your provided).
I try to setup custom dropdown in Kendo UI.
I have a reference to my issue.
http://dojo.telerik.com/aFIZa/13
My issue is that I do not know how I can setup the selected text in the template attribute? I want to show the text field but save the id as a value. And I do not want to use external datasource. I would like it as inline in the json.
The code is below:
$scope.mainGridOptions = {
dataSource: $scope.dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{ field: "Category", title: "Category", width: "180px",
editor: function(container, options) {
var editor = $('<input kendo-drop-down-list required k-data-text-field="\'cat\'" k-data-value-field="\'id\'" k-data-source="{data:[{id: 1, cat: \'test\'}, {id: 2, cat: \'test2\'}]}" data-bind="value:Category"/>')
.appendTo(container);
$compile(editor)($scope);
editor.css("visibility", "visible");
}
, template:"selected text in the combo "
}
], editable: true
}
Ok, this was a tough one, but I think I could achieve what you want, or at least I got closer:
$scope.mainGridOptions =
{
dataSource: $scope.dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{
field: "Category", title: "Category", width: "180px",
editor: function(container, options)
{
// #1
var editor = $('<input kendo-drop-down-list required k-data-text-field="\'cat\'" k-data-value-field="\'id\'" k-data-source="{data:[{id: 1, cat: \'test\'}, {id: 2, cat: \'test2\'}]}" data-bind="value:Category,events:{ change: onChange }"/>')
.appendTo(container);
$compile(editor)($scope);
editor.css("visibility", "visible");
},
// #2
template:kendo.template($("#column-template").html())
}],
editable: true,
// #3
edit: function(e)
{
var ko = kendo.observable(
{
onChange: function(e)
{
var el = $(e.sender.element);
var ddl = el.data("kendoDropDownList");
var ds = $scope.dataSource.getByUid(el.closest("tr").data("uid"));
ds.OptionText = ddl.text();
},
});
var widget = $(e.container).find("input");
kendo.bind(widget, ko);
}
}});
Demo.
In the code you can notice 3 changes:
data-bind="value:Category,events:{ change: onChange }" Look that I have added an events object in the bind, which I declare onChange as the change event handler. We'll talk about this in the 3rd item below;
For a complex template(with javascript code and logic) I created a script content and rendered it at the template property. The template is this:
<script id="column-template" type="text/x-kendo-template">
# if (data.hasOwnProperty('OptionText')) { #
#: OptionText #
# } else { #
#: "selected text in the combo" #
# } #
</script>
In the template I simply check for the property OptionText in the model(dataSource's current item) and: if it exists, use it; else, use the default text. We'll talk about OptionText in the 3rd item, below;
Now, here I have added an edit event to the grid. In that event I created an observable object, where I define the onChange function handler. In that function I seek for the current dataSource(ds) and I add text of the selected item in the dropdownlist in it, as the property OptionText, which I use in the template above explained.
I hope this explains how it works(in fact I hate working with those binders and observables, but sometimes they are needed).
Good luck.
Is it possible to dynamically add and remove regions to a layout with Marionette? My app needs to be able to push and pop regions from a layout. This is similar to how GitHub pushes and pops views when you drill down in the source code of a project. They have the slide over animation when presenting the next view and then it slides back when you're backing out. The idea is that I need to keep the previous views around. Another analogy would be how UINavigationControllers work on iOS.
Or maybe I should just define a custom layout that is able to handle adding and removing regions on the fly?
I ended up implementing a container view to fit my needs. It cleans up event refs like you'd expect in Marionette.
https://github.com/ayoung/backbone-vs-marionette/blob/marionette/public/js/views/mainContainer.js
I'm not sure but you may be getting confused with the existence of some html and the displaying of that html?
I mean you can make a CompositeView of Items and only show one of the items at a time. Then use jQuery animate or another animation library to move through the CompositeView's Items.
Yes it is possible. Here is the code I use.
The layout:
var Layout = Marionette.LayoutView.extend({
initialize: function(options) {
options = _.extend({ regionTag: 'div' }, options);
this.mergeOptions(options, ['regionTag', 'regionName']);
},
template: false,
regions: {},
append: function(view) {
var viewClass = 'dynamic-layout-' + this.regionName,
viewCount = $('.' + viewClass).length + 1,
viewId = this.regionName + '-view-' + viewCount,
$el = $('<' + this.regionTag + '/>', {
id: viewId,
class: viewClass
});
this.$el.append($el);
var region = Marionette.Region.extend({
el: '#' + viewId
});
this.regionManager.addRegion(viewId, region);
this.regionManager.get(viewId).show(view);
},
appendEmpty: function(id, className, tag) {
tag = tag || 'div';
var data = { id: id, className: className, tag: tag };
var $el = Marionette.Renderer.render('#append-layout-template', data);
this.$el.append($el);
var region = Marionette.Region.extend({
el: '#' + id
});
this.regionManager.addRegion(id, region);
},
customRemove: function(regionId) {
this.regionManager.removeRegion(regionId);
}
});
A helpful template:
<script type="text/template" id="append-layout-template">
<<%= tag %> id='<%= id %>' class='<%= className %>'></<%= tag %>>
</script>
The controller:
var view = new SomeView();
// the region name will be a part of a unique id
var layout = new Layout({ regionName: 'myRegion' });
// add a dynamic region to the layout and a view to that region
layout.append(view);
// same as above (you have to name the id and class yourself)
var regionId = 'myRegionId';
layout.appendEmpty(regionId, 'someClassName', 'span');
layout.getRegion(regionId).show(view);
// remove a region
layout.customRemove(regionId);
When the user clicks on this element, I want it to show an alert.
However, when I click on the DIV that this Panel generates, nothing happens.
How can I make an alert execute when the user clicks on the following panel?
var content = new Ext.Panel({
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="test123">This is where the content goes for each selection.</p>',
click: function() {
alert('was clicked');
}
});
You haven't accepted an answer, so I'll assume you're still unclear on this. Here are a few pointers...
First, as coded your Panel will render as a plain square. If you're expecting it to look like a Panel, you should give it a title (so the title bar will render).
Second, as mentioned, click is not a Panel event (it's an Element event). So you have several ways of getting to the behavior you want. You can manually attach a listener to the underlying DOM element after the Panel is rendered:
Ext.get('txest123').on('click', function(){
alert('foo');
});
You could also do as I mentioned in the comments of another answer to generically handle any body click:
// .body is a Panel property for the body element
content.body.on('click', function(){
alert('foo');
});
If you really want to restrict the click to only the child p you could add a check:
// e is the event object, t is the target DOM node
content.body.on('click', function(e,t){
if(t.id == 'txest123'){
alert('clicked the p');
}
});
If I was coding this, I'd probably do something more like this:
var content = new Ext.Panel({
region:'center',
renderTo: document.body,
margins:'5 0 5 5',
cls:'empty',
title: 'My Panel',
id: 'txest123',
bodyStyle:'background:ivory; font-size: 13pt',
html:'This is where the content goes for each selection.',
listeners: {
'render': {
fn: function() {
this.body.on('click', this.handleClick, this);
},
scope: content,
single: true
}
},
handleClick: function(e, t){
alert(this.id); // the panel
alert(t.innerHTML); // the clicked el
}
});
Now the id is on the Panel (where it should be) and you can use Panel and/or Element methods to access child elements as needed. It's best to keep id's at the highest level possible. You'll notice too that the callback function is executed in the scope of the Panel (scope:this) so that inside handleClick you can treat this as the Panel itself and access any of its properties or methods.
So, without knowing exactly what you're trying to achieve, I can't provide you with the exact code you need. However, this should hopefully give you some ideas.
EDIT: I meant to say this originally... in your code (as posted) you are not actually rendering the Panel. As I mentioned in my answer to your related question, if you are adding the Panel as an item to a container that is lazy-rendered, the Panel's DOM won't be available for selection until after the container has rendered it. In my code above I added renderTo so that I don't have this issue, but if you're not doing that you'll have to wait until the Panel is rendered at some time later to access it.
The Panel Component does not expose a click event, so the one you're passing into the config never gets fired.
Try putting an id on your Ext.Panel object and then getting its element using Ext.get(). Then add a click event through on():
var content = new Ext.Panel({
id: 'myPanel',
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="txest123">This is where the content goes for each selection.</p>'
});
Ext.get('myPanel').on('click', function() {alert('You clicked me');});
The following sample is a bit rough but it works for me. It is a panel with a box component, which is showing a thumbnail. When clicking on the thumbnail, it is showing a lightbox with slimbox2. Not pretty, but very effective. The hardcoded images are just for test here.
var panel = new Ext.Panel({
title : 'Image',
header : false,
frame : true,
border : false,
bodyStyle : 'padding : 5px',
width : 125,
items : [{
xtype : 'box',
height : 115,
width : 115,
listeners : {
'render': function() {
var id = Ext.id(this);
Ext.fly(id).addListener('click', function () {
jQuery.slimbox('thisisnotanimage', 'CBX');
});
}
},
autoEl: {
tag : 'div',
html : 'somehtmltagstuff'
}
}
]
});
According to the API, click is not a valid event for Panels... However, you should still be able to add the click event to the underlying DIV element.
Ext.fly(e.id).addListener('click', Ext.getCmp(e.id) , this);
I believe you need something like:
var content = new Ext.Panel({
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="test123">This is where the content goes for each selection.</p>',
listeners: {
click: function() {
alert('was clicked');
}
}
});