Guide applies to: modern
Introduction
In this lab, you’ll create the dialog window that shows the iTunes music video preview.
1.Create the Dialog class
Create the file app/desktop/src/view/Preview.js
using this code:
Ext.define('ModernTunes.view.Preview', {
extend: 'Ext.Dialog',
xtype: 'preview',
resizable: true,
closable: true,
bodyPadding: 16,
width: 640,
height: 480
});
2.Detect a click on a thumbnail in the dataview or on a record in the grid
Observe the listeners config on the instances. This is how we can ‘listen’ to
Edit app/desktop/src/view/main/MainView.js
and add this select
listener to the dataview:
{
xtype: 'tunesview',
listeners: {
select: 'onThumbSelect'
},
bind: {
store: '{tunes}'
}
}
… and do the same for the grid:
{
xtype: 'tunesgrid',
listeners: {
select: 'onGridSelect'
},
bind: {
store: '{tunes}'
}
}
Now edit app/desktop/src/view/main/MainViewontroller.js
and add the onThumbSelect and onGridSelect event handlers with simple console logs to the artist field in the record:
onThumbSelect: function(thumbs, record) {
console.log(record.data.artist);
},
onGridSelect: function(grid, records) {
console.log(records[0].data.artist);
}
Notice that each event handler has a different function signature to reference the current record, but both are to perform the same action: displaying the video. So to reach the video field we are looking to render in the Dialog, in app/desktop/src/view/main/MainCViewontroller.js
we will compose a function we will call onShowPreview that will instantiate an instance of the Preview class we just defined:
onShowPreview: function (record) {
var vid = Ext.create({
xtype: 'preview'
});
vid.show();
}
Dialogs do not show automatically, you have to run the show()
method on the instance of the dialog (similiar to the autoLoad
property we have on a store instance).
We will the call the onShowPreview function from both event handlers (replacing the console logs), passing in the appropriate reference (dataview and grid records are passed in different ways):
onThumbSelect: function(thumbs, record) {
this.onShowPreview(record);
},
onGridSelect: function(grid, records) {
this.onShowPreview(records[0]);
}
Remember, you can’t use a class without loading it and adding the file to the build. That means you also need to add a requires
array entry for Tunes.view.Preview to MainViewController.js
.
requires: [
'ModernTunes.view.Preview'
],
Save and refresh in the browser, and the method creates a placeholder instance of Tunes.view.Preview regardless of the tab from which it is called.
3.Render the video in the Dialog container
To render the video and the svg iTunes image link in the dialog, in the onShowPreview
function in MainViewController
we will compose an items array containing instances of each in a simple layout:
first, an instance of the video, using the record object to access the preview video
url
itself and the placeholder imageposterUrl
var videoConfig = {
xtype: 'video',
url: record.data.preview,
posterUrl: record.data.image
};
next, an instance of a generic component that uses the
itunesstore
field from the current recordvar linkConfig = {
docked: 'bottom',
xtype: 'component',
data: {
itunesstore: record.data.itunesstore
}
};
finally, create an instance of a generic container that will have the previous two instances (+videoConfig+ and linkConfig) as children to its
items
arrayvar containerConfig = { // parent container of the video and the anchor/link
xtype: 'container',
title: record.data.title + ' — ' + record.data.artist,
style: '{background-color: black;}',
layout: 'fit',
items: [
videoConfig,
linkConfig
]
};
Then, we can revise our previous
vid
variable to be the following:var vid = Ext.create({ // instance of the Preview Dialog class displaying the container
xtype: 'preview',
title: record.data.title,
layout: 'fit',
items: [containerConfig],
});
vid.show();
So as you can see our revised instance of Preview has an items array added that has as its sole child an istance of the container of the current video instance and the button linking back to iTunes for the current song.
Save, and review the revised version of the app in the browser. Click on a thumbnail, click on a record and try it out! That’s awesome!
4.By the way …
- a minor modification of the code is to check if the current video has been called already (repeat clicks on the same record) and if has, do not call another instance of the same one. We will place this as the first line of the function.
onShowPreview: function(record) {
if (this.getView().down('video')) {
return;
}
...
}
5.This is the finished code
Ext.define('ModernTunes.view.main.MainViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.mainviewcontroller',
requires: [
'ModernTunes.view.Preview'
],
onShowPreview: function(record) {
if (this.getView().down('video')) {
return;
}
var videoConfig = { // instance of the video
xtype: 'video',
url: record.data.preview,
posterUrl: record.data.image
};
var linkConfig = { // instance of the anchor/link back to iTunes
docked: 'bottom',
xtype: 'component',
tpl: [
'<a href="{itunesstore}" target="itunes_store">',
'<img src="resources/images/get-it-itunes.svg" style="margin: 16px; display: block; margin-left: auto; margin-right: auto; width: 75px;">',
'</a>'
],
data: {
itunesstore: record.data.itunesstore
}
};
var containerConfig = { // parent container of the video and the anchor/link
xtype: 'container',
title: record.data.title + ' — ' + record.data.artist,
style: '{background-color: black;}',
layout: 'fit',
items: [
videoConfig,
linkConfig
]
};
var vid = Ext.create({ // instance of the Preview Dialog class displaying the container
xtype: 'preview',
title: record.data.title,
layout: 'fit',
items: [containerConfig],
});
vid.show();
},
onThumbSelect: function(thumbs, record) {
this.onShowPreview(record);
},
onGridSelect: function(grid, records) {
this.onShowPreview(records[0]);
}
});