tvheadend.weekdays = new Ext.data.SimpleStore({ fields: ['identifier', 'name'], id: 0, data: [['1', 'Mon'], ['2', 'Tue'], ['3', 'Wed'], ['4', 'Thu'], ['5', 'Fri'], ['6', 'Sat'], ['7', 'Sun']] }); //This should be loaded from tvheadend tvheadend.dvrprio = new Ext.data.SimpleStore({ fields: ['identifier', 'name'], id: 0, data: [['important', 'Important'], ['high', 'High'], ['normal', 'Normal'], ['low', 'Low'], ['unimportant', 'Unimportant']] }); //For the container configuration tvheadend.containers = new Ext.data.JsonStore({ autoLoad: true, root: 'entries', fields: ['name', 'description'], id: 'name', url: 'dvr_containers', baseParams: { op: 'list' } }); //For the cache configuration tvheadend.charsets = new Ext.data.JsonStore({ autoLoad: true, root: 'entries', fields: ['key', 'val'], id: 'key', url: 'api/intlconv/charsets', baseParams: { enum: 1 } }); //For the charset configuration tvheadend.caches = new Ext.data.JsonStore({ autoLoad: true, root: 'entries', fields: ['index', 'description'], id: 'name', url: 'dvr_caches', baseParams: { op: 'list' } }); /** * Configuration names */ tvheadend.configNames = new Ext.data.JsonStore({ autoLoad: true, root: 'entries', fields: ['identifier', 'name'], id: 'identifier', url: 'confignames', baseParams: { op: 'list' } }); tvheadend.configNames.setDefaultSort('name', 'ASC'); tvheadend.comet.on('dvrconfig', function(m) { if (m.reload != null) tvheadend.configNames.reload(); }); /** * */ tvheadend.dvrDetails = function(entry) { var content = ''; var but; if (entry.chicon != null && entry.chicon.length > 0) content += ''; content += '
' + entry.title + '
'; content += '
' + entry.description + '
'; content += '
'; content += '
Status: ' + entry.status + '
'; if (entry.url != null && entry.filesize > 0) { content += '
' + 'Download ' + parseInt(entry.filesize / 1000000) + ' MB
'; } var win = new Ext.Window({ title: entry.title, layout: 'fit', width: 400, height: 300, constrainHeader: true, buttonAlign: 'center', html: content }); switch (entry.schedstate) { case 'scheduled': win.addButton({ handler: cancelEvent, text: "Remove from schedule" }); break; case 'recording': case 'recordingError': win.addButton({ handler: cancelEvent, text: "Abort recording" }); break; case 'completedError': case 'completed': win.addButton({ handler: deleteEvent, text: "Delete recording" }); break; } win.show(); function cancelEvent() { Ext.Ajax.request({ url: 'dvr', params: { entryId: entry.id, op: 'cancelEntry' }, success: function(response, options) { win.close(); }, failure: function(response, options) { Ext.MessageBox.alert('DVR', response.statusText); } }); } function deleteEvent() { Ext.Ajax.request({ url: 'dvr', params: { entryId: entry.id, op: 'deleteEntry' }, success: function(response, options) { win.close(); }, failure: function(response, options) { Ext.MessageBox.alert('DVR', response.statusText); } }); } }; /** * */ tvheadend.dvrschedule = function(title, iconCls, dvrStore) { var actions = new Ext.ux.grid.RowActions({ header: '', dataIndex: 'actions', width: 45, actions: [{ iconIndex: 'schedstate' }] }); function renderDate(value) { var dt = new Date(value); return dt.format('D j M H:i'); } function renderDuration(value) { value = value / 60; /* Nevermind the seconds */ if (value >= 60) { var min = parseInt(value % 60); var hours = parseInt(value / 60); if (min === 0) { return hours + ' hrs'; } return hours + ' hrs, ' + min + ' min'; } else { return parseInt(value) + ' min'; } } function renderSize(value) { if (value == null) return ''; return parseInt(value / 1000000) + ' MB'; } function renderPri(value) { return tvheadend.dvrprio.getById(value).data.name; } var dvrCm = new Ext.grid.ColumnModel([actions, { width: 250, id: 'title', header: "Title", sortable: true, dataIndex: 'title' }, { width: 100, id: 'episode', header: "Episode", sortable: true, dataIndex: 'episode' }, { width: 100, id: 'pri', header: "Priority", sortable: true, dataIndex: 'pri', renderer: renderPri, hidden: iconCls !== 'clock' }, { width: 100, id: 'start', header: iconCls === 'clock' ? "Start" : "Date/Time", sortable: true, dataIndex: 'start', renderer: renderDate }, { width: 100, hidden: true, id: 'end', header: "End", sortable: true, dataIndex: 'end', renderer: renderDate }, { width: 100, id: 'duration', header: "Duration", sortable: true, dataIndex: 'duration', renderer: renderDuration }, { width: 100, id: 'filesize', header: "Filesize", sortable: true, dataIndex: 'filesize', renderer: renderSize, hidden: iconCls !== 'television' }, { width: 250, id: 'channel', header: "Channel", sortable: true, dataIndex: 'channel' }, { width: 200, id: 'creator', header: "Created by", sortable: true, hidden: true, dataIndex: 'creator' }, { width: 200, id: 'config_name', header: "DVR Configuration", sortable: true, renderer: function(value, metadata, record, row, col, store) { if (!value) { return '(default)'; } else { return value; } }, dataIndex: 'config_name', hidden: iconCls !== 'clock' }, { width: 200, id: 'status', header: "Status", sortable: true, dataIndex: 'status', hidden: iconCls !== 'exclamation' }]); function addEntry() { function createRecording() { panel.getForm().submit({ params: { 'op': 'createEntry' }, url: 'dvr/addentry', waitMsg: 'Creating entry...', failure: function(response, options) { Ext.MessageBox.alert('Server Error', 'Unable to create entry'); }, success: function() { win.close(); } }); } var panel = new Ext.FormPanel({ frame: true, border: true, bodyStyle: 'padding:5px', labelAlign: 'right', labelWidth: 110, defaultType: 'textfield', items: [new Ext.form.ComboBox({ fieldLabel: 'Channel', name: 'channel', hiddenName: 'channelid', editable: false, allowBlank: false, displayField: 'val', valueField: 'key', mode: 'remote', triggerAction: 'all', store: tvheadend.channels }), new Ext.form.DateField({ allowBlank: false, fieldLabel: 'Date', name: 'date' }), new Ext.form.TimeField({ allowBlank: false, fieldLabel: 'Start time', name: 'starttime', increment: 10, format: 'H:i' }), new Ext.form.TimeField({ allowBlank: false, fieldLabel: 'Stop time', name: 'stoptime', increment: 10, format: 'H:i' }), new Ext.form.ComboBox({ store: tvheadend.dvrprio, value: "normal", triggerAction: 'all', mode: 'local', fieldLabel: 'Priority', valueField: 'identifier', displayField: 'name', name: 'pri' }), { allowBlank: false, fieldLabel: 'Title', name: 'title' }, new Ext.form.ComboBox({ store: tvheadend.configNames, triggerAction: 'all', mode: 'local', fieldLabel: 'DVR Configuration', valueField: 'identifier', displayField: 'name', name: 'config_name', emptyText: '(default)', value: '', editable: false })], buttons: [{ text: 'Create', handler: createRecording }] }); win = new Ext.Window({ title: 'Add single recording', layout: 'fit', width: 500, height: 300, plain: true, items: panel }); win.show(); new Ext.form.ComboBox({ store: tvheadend.configNames, triggerAction: 'all', mode: 'local', fieldLabel: 'DVR Configuration', valueField: 'identifier', displayField: 'name', name: 'config_name', emptyText: '(default)', value: '', editable: false }); } ; /* Create combobox to allow user to select page size for upcoming/completed/failed recordings */ var itemPageCombo = new Ext.form.ComboBox({ name : 'itemsperpage', width: 50, mode : 'local', store: new Ext.data.ArrayStore({ fields: ['perpage'], data : [['10'],['20'],['30'],['40'],['50'],['60'],['70'],['80'],['90'],['100']] }), value : '20', listWidth : 40, triggerAction : 'all', displayField : 'perpage', valueField : 'perpage', editable : true, forceSelection : true, listeners : { scope: this, 'select' : function(combo, record) { bbar.pageSize = parseInt(record.get('perpage'), 10); bbar.doLoad(bbar.cursor); } } }); /* Bottom toolbar to include default previous/goto-page/next and refresh buttons, also number-of-items combobox */ var bbar = new Ext.PagingToolbar({ store : dvrStore, displayInfo : true, items : ['-','Recordings per page: ',itemPageCombo], displayMsg : 'Programs {0} - {1} of {2}', emptyMsg : "No programs to display" }); var panel = new Ext.grid.GridPanel({ loadMask: true, stripeRows: true, disableSelection: true, title: title, iconCls: iconCls, store: dvrStore, cm: dvrCm, plugins: [actions], viewConfig: { forceFit: true }, tbar: [{ tooltip: 'Schedule a new recording session on the server.', iconCls: 'add', text: 'Add entry', handler: addEntry }, '->', { text: 'Help', handler: function() { new tvheadend.help('Digital Video Recorder', 'dvrlog.html'); } }], bbar: bbar }); panel.on('rowclick', rowclicked); function rowclicked(grid, index) { new tvheadend.dvrDetails(grid.getStore().getAt(index).data); } return panel; }; /** * */ /** * */ tvheadend.autoreceditor = function() { var fm = Ext.form; var cm = new Ext.grid.ColumnModel({ defaultSortable: true, columns: [ { header: 'Enabled', dataIndex: 'enabled', width: 30, xtype: 'checkcolumn' }, { header: "Title (Regexp)", dataIndex: 'title', editor: new fm.TextField({ allowBlank: true }) }, { header: "Channel", dataIndex: 'channel', editor: new Ext.form.ComboBox({ loadingText: 'Loading...', displayField: 'val', valueField: 'key', store: tvheadend.channels, mode: 'local', editable: false, triggerAction: 'all', emptyText: 'Only include channel...' }), renderer: function(v, m, r) { var i = tvheadend.channels.find('key', v); if (i !== -1) v = tvheadend.channels.getAt(i).get('val'); return v; } }, { header: "SeriesLink", dataIndex: 'serieslink', renderer: function(v) { return v ? 'yes' : 'no'; } }, { header: "Channel tag", dataIndex: 'tag', editor: new Ext.form.ComboBox({ displayField: 'name', store: tvheadend.channelTags, mode: 'local', editable: false, triggerAction: 'all', emptyText: 'Only include tag...' }) }, { header: "Genre", dataIndex: 'contenttype', renderer: function(v) { return tvheadend.contentGroupLookupName(v); }, editor: new Ext.form.ComboBox({ valueField: 'code', displayField: 'name', store: tvheadend.ContentGroupStore, mode: 'local', editable: false, triggerAction: 'all', emptyText: 'Only include content...' }) }, { header: "Weekdays", dataIndex: 'weekdays', renderer: function(value, metadata, record, row, col, store) { if (value.split) value = value.split(','); if (value.length === 7) return 'All days'; if (value.length === 0 || value[0] === "") return 'No days'; ret = []; tags = value; for (var i = 0; i < tags.length; i++) { var tag = tvheadend.weekdays.getById(tags[i]); if (typeof tag !== 'undefined') ret.push(tag.data.name); } return ret.join(', '); }, editor: new Ext.ux.form.LovCombo({ store: tvheadend.weekdays, mode: 'local', valueField: 'identifier', displayField: 'name' }) }, { header: "Starting Around", dataIndex: 'approx_time', renderer: function(value, metadata, record, row, col, store) { if (typeof value === 'string') return value; if (value === 0) return ''; var hours = Math.floor(value / 60); var mins = value % 60; var dt = new Date(); dt.setHours(hours); dt.setMinutes(mins); return dt.format('H:i'); }, editor: new Ext.form.TimeField({ allowBlank: true, increment: 10, format: 'H:i' }) }, { header: "Priority", dataIndex: 'pri', width: 100, renderer: function(value, metadata, record, row, col, store) { return tvheadend.dvrprio.getById(value).data.name; }, editor: new fm.ComboBox({ store: tvheadend.dvrprio, triggerAction: 'all', mode: 'local', valueField: 'identifier', displayField: 'name' }) }, { header: "DVR Configuration", dataIndex: 'config_name', renderer: function(value, metadata, record, row, col, store) { if (!value) { return '(default)'; } else { return value; } }, editor: new Ext.form.ComboBox({ store: tvheadend.configNames, triggerAction: 'all', mode: 'local', valueField: 'identifier', displayField: 'name', name: 'config_name', emptyText: '(default)', editable: false }) }, { header: "Created by", dataIndex: 'creator', editor: new fm.TextField({ allowBlank: false }) }, { header: "Comment", dataIndex: 'comment', editor: new fm.TextField({ allowBlank: false }) }]}); return new tvheadend.tableEditor('Automatic Recorder', 'autorec', cm, tvheadend.autorecRecord, [], tvheadend.autorecStore, 'autorec.html', 'wand'); }; /** * */ tvheadend.dvr = function() { function datastoreBuilder(url) { return new Ext.data.JsonStore({ root: 'entries', totalProperty: 'totalCount', fields: [{ name: 'id' }, { name: 'channel' }, { name: 'title' }, { name: 'episode' }, { name: 'pri' }, { name: 'description' }, { name: 'chicon' }, { name: 'start', type: 'date', dateFormat: 'U' /* unix time */ }, { name: 'end', type: 'date', dateFormat: 'U' /* unix time */ }, { name: 'config_name' }, { name: 'status' }, { name: 'schedstate' }, { name: 'error' }, { name: 'creator' }, { name: 'duration' }, { name: 'filesize' }, { name: 'url' }], url: url, autoLoad: true, id: 'id' }); } tvheadend.dvrStoreUpcoming = datastoreBuilder('dvrlist_upcoming'); tvheadend.dvrStoreFinished = datastoreBuilder('dvrlist_finished'); tvheadend.dvrStoreFailed = datastoreBuilder('dvrlist_failed'); tvheadend.dvrStores = [tvheadend.dvrStoreUpcoming, tvheadend.dvrStoreFinished, tvheadend.dvrStoreFailed]; function updateDvrStore(store, r, m) { r.data.status = m.status; r.data.schedstate = m.schedstate; store.afterEdit(r); store.fireEvent('updated', store, r, Ext.data.Record.COMMIT); } function reloadStores() { for (var i = 0; i < tvheadend.dvrStores.length; i++) { tvheadend.dvrStores[i].reload(); } } tvheadend.comet.on('dvrdb', function(m) { if (m.reload != null) { reloadStores(); } if (m.updateEntry != null) { for (var i = 0; i < tvheadend.dvrStores.length; i++) { var store = tvheadend.dvrStores[i]; r = tvheadend.dvrStoreUpcoming.getById(m.id); if (typeof r !== 'undefined') { updateDvrStore(store, r, m); return; } } reloadStores(); } }); tvheadend.autorecRecord = Ext.data.Record.create(['enabled', 'title', 'serieslink', 'channel', 'tag', 'creator', 'contenttype', 'comment', 'weekdays', 'pri', 'approx_time', 'config_name']); tvheadend.autorecStore = new Ext.data.JsonStore({ root: 'entries', fields: tvheadend.autorecRecord, url: "tablemgr", autoLoad: true, id: 'id', baseParams: { table: "autorec", op: "get" } }); tvheadend.comet.on('autorec', function(m) { if (m.reload != null) tvheadend.autorecStore.reload(); }); var panel = new Ext.TabPanel({ activeTab: 0, autoScroll: true, title: 'Digital Video Recorder', iconCls: 'drive', items: [ new tvheadend.dvrschedule('Upcoming recordings', 'clock', tvheadend.dvrStoreUpcoming), new tvheadend.dvrschedule('Finished recordings', 'television', tvheadend.dvrStoreFinished), new tvheadend.dvrschedule('Failed recordings', 'exclamation', tvheadend.dvrStoreFailed), new tvheadend.autoreceditor ] }); return panel; }; /** * Configuration panel (located under configuration) */ tvheadend.dvrsettings = function() { var confreader = new Ext.data.JsonReader({ root: 'dvrSettings' }, ['storage', 'filePermissions', 'dirPermissions', 'postproc', 'retention', 'dayDirs', 'channelDirs', 'channelInTitle', 'container', 'cache', 'charset', 'dateInTitle', 'timeInTitle', 'preExtraTime', 'postExtraTime', 'whitespaceInTitle', 'titleDirs', 'episodeInTitle', 'cleanTitle', 'tagFiles', 'commSkip', 'subtitleInTitle', 'episodeBeforeDate', 'rewritePAT', 'rewritePMT']); var confcombo = new Ext.form.ComboBox({ store: tvheadend.configNames, triggerAction: 'all', mode: 'local', displayField: 'name', name: 'config_name', emptyText: '(default)', value: '', editable: true }); var delButton = new Ext.Toolbar.Button({ tooltip: 'Delete named configuration', iconCls: 'remove', text: "Delete configuration", handler: deleteConfiguration, disabled: true }); /* Config panel variables */ /* DVR Behaviour */ var recordingContainer = new Ext.form.ComboBox({ store: tvheadend.containers, fieldLabel: 'Media container', triggerAction: 'all', displayField: 'description', valueField: 'name', editable: false, width: 350, hiddenName: 'container' }); var cacheScheme = new Ext.form.ComboBox({ store: tvheadend.caches, fieldLabel: 'Cache scheme', triggerAction: 'all', displayField: 'description', valueField: 'index', editable: false, width: 350, hiddenName: 'cache' }); var logRetention = new Ext.form.NumberField({ allowNegative: false, allowDecimals: false, minValue: 1, fieldLabel: 'DVR Log retention time (days)', name: 'retention' }); var timeBefore = new Ext.form.NumberField({ allowDecimals: false, fieldLabel: 'Extra time before recordings (minutes)', name: 'preExtraTime' }); var timeAfter = new Ext.form.NumberField({ allowDecimals: false, fieldLabel: 'Extra time after recordings (minutes)', name: 'postExtraTime' }); var postProcessing = new Ext.form.TextField({ width: 350, fieldLabel: 'Post-processor command', name: 'postproc' }); /* Recording File Options */ var recordingPath = new Ext.form.TextField({ width: 350, fieldLabel: 'Recording system path', name: 'storage' }); /* NB: recordingPermissions is defined as a TextField for validation purposes (leading zeros), but is ultimately a number */ var recordingPermissions = new Ext.form.TextField({ regex: /^[0][0-7]{3}$/, maskRe: /[0-7]/, width: 125, allowBlank: false, blankText: 'You must provide a value - use octal chmod notation, e.g. 0664', fieldLabel: 'File permissions (octal, e.g. 0664)', name: 'filePermissions' }); var charset = new Ext.form.ComboBox({ store: tvheadend.charsets, fieldLabel: 'Filename charset', triggerAction: 'all', displayField: 'val', valueField: 'key', editable: false, width: 200, hiddenName: 'charset' }); /* TO DO - Add 'override user umask?' option, then trigger fchmod in mkmux.c, muxer_pass.c after file created */ var PATrewrite = new Ext.form.Checkbox({ fieldLabel: 'Rewrite PAT in passthrough mode', name: 'rewritePAT' }); var PMTrewrite = new Ext.form.Checkbox({ fieldLabel: 'Rewrite PMT in passthrough mode', name: 'rewritePMT' }); var tagMetadata = new Ext.form.Checkbox({ fieldLabel: 'Tag files with metadata', name: 'tagFiles' }); var skipCommercials = new Ext.form.Checkbox({ fieldLabel: 'Skip commercials', name: 'commSkip' }); /* Subdirectories and filename handling */ /* NB: directoryPermissions is defined as a TextField for validation purposes (leading zeros), but is ultimately a number */ var directoryPermissions = new Ext.form.TextField({ regex: /^[0][0-7]{3}$/, maskRe: /[0-7]/, width: 125, allowBlank: false, blankText: 'You must provide a value - use octal chmod notation, e.g. 0775', fieldLabel: 'Directory permissions (octal, e.g. 0775)', name: 'dirPermissions' }); /* TO DO - Add 'override user umask?' option, then trigger fchmod in utils.c after directory created */ var dirsPerDay = new Ext.form.Checkbox({ fieldLabel: 'Make subdirectories per day', name: 'dayDirs' }); var dirsPerChannel = new Ext.form.Checkbox({ fieldLabel: 'Make subdirectories per channel', name: 'channelDirs' }); var dirsPerTitle = new Ext.form.Checkbox({ fieldLabel: 'Make subdirectories per title', name: 'titleDirs' }); var incChannelInTitle = new Ext.form.Checkbox({ fieldLabel: 'Include channel name in filename', name: 'channelInTitle' }); var incDateInTitle = new Ext.form.Checkbox({ fieldLabel: 'Include date in filename', name: 'dateInTitle' }); var incTimeInTitle = new Ext.form.Checkbox({ fieldLabel: 'Include time in filename', name: 'timeInTitle' }); var incEpisodeInTitle = new Ext.form.Checkbox({ fieldLabel: 'Include episode in filename', name: 'episodeInTitle' }); var incSubtitleInTitle = new Ext.form.Checkbox({ fieldLabel: 'Include subtitle in filename', name: 'subtitleInTitle' }); var episodeFirst = new Ext.form.Checkbox({ fieldLabel: 'Put episode in filename before date and time', name: 'episodeBeforeDate' }); var stripUnsafeChars = new Ext.form.Checkbox({ fieldLabel: 'Remove all unsafe characters from filename', name: 'cleanTitle' }); var stripWhitespace = new Ext.form.Checkbox({ fieldLabel: 'Replace whitespace in title with \'-\'', name: 'whitespaceInTitle' }); /* Sub-Panel - DVR behaviour */ var DVRBehaviour = new Ext.form.FieldSet({ title: 'DVR Behaviour', width: 700, autoHeight: true, collapsible: true, animCollapse: true, items: [recordingContainer, cacheScheme, logRetention, timeBefore, timeAfter, postProcessing] }); /* Sub-Panel - File Output */ var FileOutputPanel = new Ext.form.FieldSet({ title: 'Recording File Options', width: 700, autoHeight: true, collapsible: true, animCollapse: true, items: [recordingPath, recordingPermissions, charset, PATrewrite, PMTrewrite, tagMetadata, skipCommercials] }); /* Sub-Panel - Directory operations */ var DirHandlingPanel = new Ext.form.FieldSet({ title: 'Subdirectory Options', width: 700, autoHeight: true, collapsible: true, animCollapse: true, items: [directoryPermissions, dirsPerDay, dirsPerChannel, dirsPerTitle] }); /* Sub-Panel - File operations - Break into two 4-item panels */ var FileHandlingPanelA = new Ext.form.FieldSet({ width: 350, border: false, autoHeight: true, items : [incChannelInTitle, incDateInTitle, incTimeInTitle, incEpisodeInTitle] }); var FileHandlingPanelB = new Ext.form.FieldSet({ width: 350, border: false, autoHeight: true, items : [incSubtitleInTitle, episodeFirst, stripUnsafeChars, stripWhitespace] }); var FileHandlingPanel = new Ext.form.FieldSet({ title: 'Filename Options', width: 700, autoHeight: true, collapsible: true, animCollapse : true, items : [{ layout: 'column', border: false, items : [FileHandlingPanelA, FileHandlingPanelB] }] }); /* Main (form) panel */ var confpanel = new Ext.FormPanel({ title: 'Digital Video Recorder', iconCls: 'drive', border: false, bodyStyle: 'padding:15px', anchor: '100% 50%', labelAlign: 'right', labelWidth: 300, autoScroll: true, waitMsgTarget: true, reader: confreader, defaultType: 'textfield', layout: 'form', items: [DVRBehaviour, FileOutputPanel, DirHandlingPanel, FileHandlingPanel], tbar: [confcombo, { tooltip: 'Save changes made to dvr configuration below', iconCls: 'save', text: "Save configuration", handler: saveChanges }, delButton, '->', { text: 'Help', handler: function() { new tvheadend.help('DVR configuration', 'config_dvr.html'); } }] }); function loadConfig() { confpanel.getForm().load({ url: 'dvr', params: { 'op': 'loadSettings', 'config_name': confcombo.getValue() }, success: function(form, action) { confpanel.enable(); } }); } confcombo.on('select', function() { if (confcombo.getValue() === '') delButton.disable(); else delButton.enable(); loadConfig(); }); confpanel.on('render', function() { loadConfig(); }); function saveChanges() { var config_name = confcombo.getValue(); confpanel.getForm().submit({ url: 'dvr', params: { 'op': 'saveSettings', 'config_name': config_name }, waitMsg: 'Saving Data...', success: function(form, action) { confcombo.setValue(config_name); confcombo.fireEvent('select'); }, failure: function(form, action) { Ext.Msg.alert('Save failed', action.result.errormsg); } }); } function deleteConfiguration() { if (confcombo.getValue() !== "") { Ext.MessageBox.confirm('Message', 'Do you really want to delete DVR configuration \'' + confcombo.getValue() + '\'?', deleteAction); } } function deleteAction(btn) { if (btn === 'yes') { confpanel.getForm().submit({ url: 'dvr', params: { 'op': 'deleteSettings', 'config_name': confcombo.getValue() }, waitMsg: 'Deleting Data...', success: function(form, action) { confcombo.setValue(''); confcombo.fireEvent('select'); }, failure: function(form, action) { Ext.Msg.alert('Delete failed', action.result.errormsg); } }); } } return confpanel; };