netzke-basepack 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +9 -1
- data/javascripts/xdatetime.js +195 -0
- data/lib/netzke/active_record/attributes.rb +2 -2
- data/lib/netzke/basepack.rb +1 -2
- data/lib/netzke/basepack/data_accessor.rb +1 -3
- data/lib/netzke/basepack/form_panel.rb +1 -10
- data/lib/netzke/basepack/form_panel/fields.rb +3 -7
- data/lib/netzke/basepack/grid_panel.rb +3 -0
- data/lib/netzke/basepack/grid_panel/columns.rb +4 -4
- data/lib/netzke/basepack/grid_panel/javascripts/grid_panel.js +31 -9
- data/lib/netzke/basepack/grid_panel/services.rb +2 -0
- data/lib/netzke/basepack/search_window.rb +1 -0
- data/lib/netzke/basepack/version.rb +1 -1
- data/lib/netzke/basepack/window/javascripts/window.js +7 -5
- data/netzke-basepack.gemspec +12 -26
- data/test/basepack_test_app/Gemfile.lock +48 -49
- data/test/basepack_test_app/app/components/book_form_with_custom_fields.rb +2 -1
- data/test/basepack_test_app/app/components/window_component_loader.rb +1 -1
- data/test/basepack_test_app/db/seeds.rb +4 -0
- data/test/basepack_test_app/features/form_panel.feature +13 -4
- data/test/basepack_test_app/features/grid_panel.feature +10 -4
- data/test/basepack_test_app/features/step_definitions/form_panel_steps.rb +17 -1
- data/test/basepack_test_app/features/step_definitions/grid_panel_steps.rb +9 -1
- metadata +10 -10
- data/javascripts/datetimefield.js +0 -24
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
= 0.7.4 - 2012-03-05
|
2
|
+
* bug fix
|
3
|
+
* :enable_pagination is now respected in GridPanel
|
4
|
+
* Virtual columns are not sortable by default now
|
5
|
+
* Datetime column now works
|
6
|
+
* Make Window respect persistence: false
|
7
|
+
* Disable persistence for search window in GridPanel
|
8
|
+
|
1
9
|
= 0.7.3 - 2011-10-23
|
2
10
|
* bug fix
|
3
|
-
* :sorting_scope
|
11
|
+
* :sorting_scope is now respected in GridPanel
|
4
12
|
* regression: filtering on association column is fix (covered with tests)
|
5
13
|
|
6
14
|
= 0.7.2 - 2011-10-20
|
@@ -0,0 +1,195 @@
|
|
1
|
+
/**
|
2
|
+
* @class Ext.ux.form.field.DateTime
|
3
|
+
* @extends Ext.form.FieldContainer
|
4
|
+
* @version 0.2 (July 20th, 2011)
|
5
|
+
* @author atian25 (http://www.sencha.com/forum/member.php?51682-atian25)
|
6
|
+
* @author ontho (http://www.sencha.com/forum/member.php?285806-ontho)
|
7
|
+
* @author jakob.ketterl (http://www.sencha.com/forum/member.php?25102-jakob.ketterl)
|
8
|
+
* @link http://www.sencha.com/forum/showthread.php?134345-Ext.ux.form.field.DateTime
|
9
|
+
*/
|
10
|
+
Ext.define('Ext.ux.form.field.DateTime', {
|
11
|
+
extend:'Ext.form.FieldContainer',
|
12
|
+
mixins:{
|
13
|
+
field:'Ext.form.field.Field'
|
14
|
+
},
|
15
|
+
alias: 'widget.xdatetime',
|
16
|
+
|
17
|
+
//configurables
|
18
|
+
|
19
|
+
combineErrors: true,
|
20
|
+
msgTarget: 'under',
|
21
|
+
layout: 'hbox',
|
22
|
+
readOnly: false,
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @cfg {String} dateFormat
|
26
|
+
* Convenience config for specifying the format of the date portion.
|
27
|
+
* This value is overridden if format is specified in the dateConfig.
|
28
|
+
* The default is 'Y-m-d'
|
29
|
+
*/
|
30
|
+
dateFormat: 'Y-m-d',
|
31
|
+
/**
|
32
|
+
* @cfg {String} timeFormat
|
33
|
+
* Convenience config for specifying the format of the time portion.
|
34
|
+
* This value is overridden if format is specified in the timeConfig.
|
35
|
+
* The default is 'H:i:s'
|
36
|
+
*/
|
37
|
+
timeFormat: 'H:i:s',
|
38
|
+
// /**
|
39
|
+
// * @cfg {String} dateTimeFormat
|
40
|
+
// * The format used when submitting the combined value.
|
41
|
+
// * Defaults to 'Y-m-d H:i:s'
|
42
|
+
// */
|
43
|
+
// dateTimeFormat: 'Y-m-d H:i:s',
|
44
|
+
/**
|
45
|
+
* @cfg {Object} dateConfig
|
46
|
+
* Additional config options for the date field.
|
47
|
+
*/
|
48
|
+
dateConfig:{},
|
49
|
+
/**
|
50
|
+
* @cfg {Object} timeConfig
|
51
|
+
* Additional config options for the time field.
|
52
|
+
*/
|
53
|
+
timeConfig:{},
|
54
|
+
|
55
|
+
|
56
|
+
// properties
|
57
|
+
|
58
|
+
dateValue: null, // Holds the actual date
|
59
|
+
/**
|
60
|
+
* @property dateField
|
61
|
+
* @type Ext.form.field.Date
|
62
|
+
*/
|
63
|
+
dateField: null,
|
64
|
+
/**
|
65
|
+
* @property timeField
|
66
|
+
* @type Ext.form.field.Time
|
67
|
+
*/
|
68
|
+
timeField: null,
|
69
|
+
|
70
|
+
initComponent: function(){
|
71
|
+
var me = this
|
72
|
+
,i = 0
|
73
|
+
,key
|
74
|
+
,tab;
|
75
|
+
|
76
|
+
me.items = me.items || [];
|
77
|
+
|
78
|
+
me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
|
79
|
+
format:me.dateFormat,
|
80
|
+
flex:1,
|
81
|
+
isFormField:false, //exclude from field query's
|
82
|
+
submitValue:false
|
83
|
+
}, me.dateConfig));
|
84
|
+
me.items.push(me.dateField);
|
85
|
+
|
86
|
+
me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
|
87
|
+
format:me.timeFormat,
|
88
|
+
flex:1,
|
89
|
+
isFormField:false, //exclude from field query's
|
90
|
+
submitValue:false
|
91
|
+
}, me.timeConfig));
|
92
|
+
me.items.push(me.timeField);
|
93
|
+
|
94
|
+
for (; i < me.items.length; i++) {
|
95
|
+
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
|
96
|
+
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
|
97
|
+
me.items[i].on('specialkey', function(field, event){
|
98
|
+
key = event.getKey();
|
99
|
+
tab = key == event.TAB;
|
100
|
+
|
101
|
+
if (tab && me.focussedItem == me.dateField) {
|
102
|
+
event.stopEvent();
|
103
|
+
me.timeField.focus();
|
104
|
+
return;
|
105
|
+
}
|
106
|
+
|
107
|
+
me.fireEvent('specialkey', field, event);
|
108
|
+
});
|
109
|
+
}
|
110
|
+
|
111
|
+
me.callParent();
|
112
|
+
|
113
|
+
// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
|
114
|
+
this.inputEl = {
|
115
|
+
dom:{},
|
116
|
+
swallowEvent:function(){}
|
117
|
+
};
|
118
|
+
|
119
|
+
me.initField();
|
120
|
+
},
|
121
|
+
|
122
|
+
focus:function(){
|
123
|
+
this.callParent();
|
124
|
+
this.dateField.focus();
|
125
|
+
},
|
126
|
+
|
127
|
+
onItemFocus:function(item){
|
128
|
+
if (this.blurTask){
|
129
|
+
this.blurTask.cancel();
|
130
|
+
}
|
131
|
+
this.focussedItem = item;
|
132
|
+
},
|
133
|
+
|
134
|
+
onItemBlur:function(item){
|
135
|
+
var me = this;
|
136
|
+
if (item != me.focussedItem){ return; }
|
137
|
+
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
|
138
|
+
me.blurTask = new Ext.util.DelayedTask(function(){
|
139
|
+
me.fireEvent('blur', me);
|
140
|
+
});
|
141
|
+
me.blurTask.delay(100);
|
142
|
+
},
|
143
|
+
|
144
|
+
getValue: function(){
|
145
|
+
var value = null
|
146
|
+
,date = this.dateField.getSubmitValue()
|
147
|
+
,time = this.timeField.getSubmitValue()
|
148
|
+
,format;
|
149
|
+
|
150
|
+
if (date){
|
151
|
+
if (time){
|
152
|
+
format = this.getFormat();
|
153
|
+
value = Ext.Date.parse(date + ' ' + time, format);
|
154
|
+
} else {
|
155
|
+
value = this.dateField.getValue();
|
156
|
+
}
|
157
|
+
}
|
158
|
+
return value;
|
159
|
+
},
|
160
|
+
|
161
|
+
getSubmitValue: function(){
|
162
|
+
// var value = this.getValue();
|
163
|
+
// return value ? Ext.Date.format(value, this.dateTimeFormat) : null;
|
164
|
+
|
165
|
+
var me = this
|
166
|
+
,format = me.getFormat()
|
167
|
+
,value = me.getValue();
|
168
|
+
|
169
|
+
return value ? Ext.Date.format(value, format) : null;
|
170
|
+
},
|
171
|
+
|
172
|
+
setValue: function(value){
|
173
|
+
if (Ext.isString(value)){
|
174
|
+
value = Ext.Date.parse(value, this.getFormat()); //this.dateTimeFormat
|
175
|
+
}
|
176
|
+
this.dateField.setValue(value);
|
177
|
+
this.timeField.setValue(value);
|
178
|
+
},
|
179
|
+
|
180
|
+
getFormat: function(){
|
181
|
+
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format);
|
182
|
+
},
|
183
|
+
|
184
|
+
// Bug? A field-mixin submits the data from getValue, not getSubmitValue
|
185
|
+
getSubmitData: function(){
|
186
|
+
var me = this
|
187
|
+
,data = null;
|
188
|
+
|
189
|
+
if (!me.disabled && me.submitValue && !me.isFileUpload()) {
|
190
|
+
data = {};
|
191
|
+
data[me.getName()] = '' + me.getSubmitValue();
|
192
|
+
}
|
193
|
+
return data;
|
194
|
+
}
|
195
|
+
});
|
@@ -184,7 +184,7 @@ module Netzke
|
|
184
184
|
end
|
185
185
|
|
186
186
|
# a work-around for to_json not taking the current timezone into account when serializing ActiveSupport::TimeWithZone
|
187
|
-
v = v.to_datetime.to_s(:db) if [ActiveSupport::TimeWithZone
|
187
|
+
v = v.to_datetime.to_s(:db) if [ActiveSupport::TimeWithZone].include?(v.class)
|
188
188
|
|
189
189
|
v
|
190
190
|
end
|
@@ -242,4 +242,4 @@ module Netzke
|
|
242
242
|
|
243
243
|
end
|
244
244
|
end
|
245
|
-
end
|
245
|
+
end
|
data/lib/netzke/basepack.rb
CHANGED
@@ -17,10 +17,9 @@ module Netzke
|
|
17
17
|
|
18
18
|
# Called from netzke-basepack.rb
|
19
19
|
def init
|
20
|
-
|
20
|
+
Netzke::Core.ext_javascripts << "#{File.dirname(__FILE__)}/../../javascripts/xdatetime.js"
|
21
21
|
Netzke::Core.ext_javascripts << "#{File.dirname(__FILE__)}/../../javascripts/basepack.js"
|
22
22
|
|
23
|
-
Netzke::Core.ext_stylesheets << "#{File.dirname(__FILE__)}/../../stylesheets/datetimefield.css"
|
24
23
|
Netzke::Core.ext_stylesheets << "#{File.dirname(__FILE__)}/../../stylesheets/basepack.css"
|
25
24
|
end
|
26
25
|
|
@@ -23,7 +23,7 @@ module Netzke
|
|
23
23
|
|
24
24
|
if assoc.klass.column_names.include?(assoc_method)
|
25
25
|
# apply query
|
26
|
-
relation = relation.where(
|
26
|
+
relation = relation.where(["#{assoc_method} like ?", "%#{query}%"]) if query.present?
|
27
27
|
relation.all.map{ |r| [r.id, r.send(assoc_method)] }
|
28
28
|
else
|
29
29
|
relation.all.map{ |r| [r.id, r.send(assoc_method)] }.select{ |id,value| value =~ /^#{query}/ }
|
@@ -43,8 +43,6 @@ module Netzke
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
return res
|
46
|
-
|
47
|
-
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -106,16 +106,7 @@ module Netzke
|
|
106
106
|
|
107
107
|
# A hash of record data including the meta field
|
108
108
|
def js_record_data
|
109
|
-
|
110
|
-
|
111
|
-
# HACK: a dirty hack cutting off the time part from the datetime string to please the form's datefield - until we have a real datetimefield
|
112
|
-
hsh.each_pair do |k,v|
|
113
|
-
if v && [:datetime, :date].include?(fields[k.to_sym].try(:fetch, :attr_type, nil))
|
114
|
-
hsh[k] = v.split.first
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
hsh
|
109
|
+
record.to_hash(fields).merge(:_meta => meta_field).literalize_keys
|
119
110
|
end
|
120
111
|
|
121
112
|
def record
|
@@ -101,9 +101,8 @@ module Netzke
|
|
101
101
|
set_default_read_only(field)
|
102
102
|
|
103
103
|
# temporal datetime setup, while we don't have real datetime field
|
104
|
-
if field[:attr_type] == :
|
105
|
-
field[:format] ||= "Y-m-d"
|
106
|
-
field[:submit_format] = "Y-m-d"
|
104
|
+
if field[:attr_type] == :date
|
105
|
+
field[:format] ||= "Y-m-d"
|
107
106
|
end
|
108
107
|
|
109
108
|
# provide our special combobox with our id
|
@@ -187,10 +186,7 @@ module Netzke
|
|
187
186
|
:integer => :numberfield,
|
188
187
|
:boolean => config[:multi_edit] ? :tricheckbox : :checkboxfield,
|
189
188
|
:date => :datefield,
|
190
|
-
|
191
|
-
# :datetime => :datetimefield,
|
192
|
-
:datetime => :datefield,
|
193
|
-
|
189
|
+
:datetime => :xdatetime,
|
194
190
|
:text => :textarea,
|
195
191
|
:json => :jsonfield,
|
196
192
|
:string => :textfield
|
@@ -40,6 +40,7 @@ module Netzke
|
|
40
40
|
# * +enable_edit_in_form+ - (defaults to true) provide buttons into the toolbar that activate editing/adding records via a form
|
41
41
|
# * +enable_extended_search+ - (defaults to true) provide a button into the toolbar that shows configurable search form
|
42
42
|
# * +enable_context_menu+ - (defaults to true) enable rows context menu
|
43
|
+
# * +context_menu+ - an array of actions (e.g. [:edit.action, "-", :del.action] - see the Actions section) or +false+ to disable the context menu
|
43
44
|
# * +enable_rows_reordering+ - (defaults to false) enable reordering of rows with drag-n-drop; underlying model (specified in +model+) must implement "acts_as_list"-compatible functionality
|
44
45
|
# * +enable_pagination+ - (defaults to true) enable pagination
|
45
46
|
# * +rows_per_page+ - (defaults to 30) number of rows per page (ignored when +enable_pagination+ is set to +false+)
|
@@ -74,6 +75,8 @@ module Netzke
|
|
74
75
|
# }
|
75
76
|
# end
|
76
77
|
#
|
78
|
+
# * +format+ - the format to display data in case of date and datetime columns, e.g. 'Y-m-d g:i:s'.
|
79
|
+
#
|
77
80
|
# Besides these options, a column can receive any meaningful config option understood by Ext.grid.column.Column.
|
78
81
|
#
|
79
82
|
# == One-to-many association support
|
@@ -214,7 +214,8 @@ module Netzke
|
|
214
214
|
end
|
215
215
|
|
216
216
|
def set_default_sortable(c)
|
217
|
-
|
217
|
+
# this *has* to be set to false if we don't want the column to be sortable (it's sortable by default in Ext)
|
218
|
+
c[:sortable] = !(c[:virtual] && !c[:sorting_scope]) if c[:sortable].nil?
|
218
219
|
end
|
219
220
|
|
220
221
|
def set_default_filterable(c)
|
@@ -309,8 +310,7 @@ module Netzke
|
|
309
310
|
:integer => :numberfield,
|
310
311
|
:boolean => :checkbox,
|
311
312
|
:date => :datefield,
|
312
|
-
|
313
|
-
:datetime => :datefield,
|
313
|
+
:datetime => :xdatetime,
|
314
314
|
:text => :textarea,
|
315
315
|
:string => :textfield
|
316
316
|
}
|
@@ -321,7 +321,7 @@ module Netzke
|
|
321
321
|
# :integer => :numbercolumn, # don't like the default formatter
|
322
322
|
:boolean => :checkcolumn,
|
323
323
|
:date => :datecolumn,
|
324
|
-
|
324
|
+
#:datetime => :datecolumn # TODO: replace with datetimepicker
|
325
325
|
}
|
326
326
|
end
|
327
327
|
|
@@ -23,13 +23,27 @@
|
|
23
23
|
// Run through columns and set up different configuration for each
|
24
24
|
Ext.each(this.columns, function(c, i){
|
25
25
|
|
26
|
+
this.normalizeRenderer(c);
|
27
|
+
|
26
28
|
// Build the field configuration for this column
|
27
29
|
var fieldConfig = {name: c.name, defaultValue: c.defaultValue};
|
28
30
|
|
29
31
|
if (c.name !== '_meta') fieldConfig.type = this.fieldTypeForAttrType(c.attrType); // field type (grid editors need this to function well)
|
30
32
|
|
31
|
-
if (c.attrType == 'datetime'
|
33
|
+
if (c.attrType == 'datetime') {
|
32
34
|
fieldConfig.dateFormat = 'Y-m-d g:i:s'; // in this format we receive dates from the server
|
35
|
+
|
36
|
+
if (!c.renderer) {
|
37
|
+
c.renderer = Ext.util.Format.dateRenderer(c.format || fieldConfig.dateFormat); // format in which the data will be rendered
|
38
|
+
}
|
39
|
+
};
|
40
|
+
|
41
|
+
if (c.attrType == 'date') {
|
42
|
+
fieldConfig.dateFormat = 'Y-m-d'; // in this format we receive dates from the server
|
43
|
+
|
44
|
+
if (!c.renderer) {
|
45
|
+
c.renderer = Ext.util.Format.dateRenderer(c.format || fieldConfig.dateFormat); // format in which the data will be rendered
|
46
|
+
}
|
33
47
|
};
|
34
48
|
|
35
49
|
fields.push(fieldConfig);
|
@@ -45,7 +59,6 @@
|
|
45
59
|
// c.editor = {xtype: "combobox", options: c.comboboxOptions.split('\\n')}
|
46
60
|
// }
|
47
61
|
|
48
|
-
this.normalizeRenderer(c);
|
49
62
|
|
50
63
|
// Set rendeder for association columns (the one displaying associations by the specified method instead of id)
|
51
64
|
if (c.assoc) {
|
@@ -163,14 +176,23 @@
|
|
163
176
|
this.plugins.push(Ext.create('Ext.grid.plugin.CellEditing', {pluginId: 'celleditor'}));
|
164
177
|
}
|
165
178
|
|
166
|
-
//
|
179
|
+
// Toolbar
|
167
180
|
this.dockedItems = this.dockedItems || [];
|
168
|
-
this.
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
181
|
+
if (this.enablePagination) {
|
182
|
+
this.dockedItems.push({
|
183
|
+
xtype: 'pagingtoolbar',
|
184
|
+
dock: 'bottom',
|
185
|
+
store: this.store,
|
186
|
+
items: this.bbar && ["-"].concat(this.bbar) // append the old bbar. TODO: get rid of it.
|
187
|
+
});
|
188
|
+
} else if (this.bbar) {
|
189
|
+
this.dockedItems.push({
|
190
|
+
xtype: 'toolbar',
|
191
|
+
dock: 'bottom',
|
192
|
+
items: this.bbar
|
193
|
+
});
|
194
|
+
}
|
195
|
+
|
174
196
|
|
175
197
|
delete this.bbar;
|
176
198
|
|
@@ -5,14 +5,16 @@
|
|
5
5
|
this.callParent();
|
6
6
|
|
7
7
|
// set the move and resize events after window is shown, so that they don't fire at initial rendering
|
8
|
-
this.
|
9
|
-
this.on("
|
10
|
-
|
11
|
-
|
8
|
+
if (this.persistence) {
|
9
|
+
this.on("show", function(){
|
10
|
+
this.on("move", this.onMoveResize, this);
|
11
|
+
this.on("resize", this.onMoveResize, this);
|
12
|
+
}, this);
|
13
|
+
}
|
12
14
|
},
|
13
15
|
|
14
16
|
onMoveResize: function(){
|
15
17
|
var x = this.getPosition()[0], y = this.getPosition()[1], w = this.getSize().width, h = this.getSize().height;
|
16
18
|
this.setSizeAndPosition({x:x, y:y, w:w, h:h}); // API call
|
17
19
|
}
|
18
|
-
}
|
20
|
+
}
|
data/netzke-basepack.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.7.
|
7
|
+
s.name = "netzke-basepack"
|
8
|
+
s.version = "0.7.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
11
|
+
s.authors = ["Sergei Kozlov"]
|
12
|
+
s.date = "2012-03-05"
|
13
|
+
s.description = "A set of full-featured extendible Netzke components (such as FormPanel, GridPanel, Window, BorderLayoutPanel, etc) which can be used as building block for your RIA"
|
14
|
+
s.email = "sergei@playcode.nl"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
17
|
"README.md"
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
"init.rb",
|
30
30
|
"install.rb",
|
31
31
|
"javascripts/basepack.js",
|
32
|
-
"javascripts/
|
32
|
+
"javascripts/xdatetime.js",
|
33
33
|
"lib/generators/netzke/basepack_generator.rb",
|
34
34
|
"lib/generators/netzke/templates/assets/ts-checkbox.gif",
|
35
35
|
"lib/generators/netzke/templates/create_netzke_field_lists.rb",
|
@@ -269,25 +269,11 @@ Gem::Specification.new do |s|
|
|
269
269
|
"test/unit/tab_panel_test.rb",
|
270
270
|
"uninstall.rb"
|
271
271
|
]
|
272
|
-
s.homepage =
|
273
|
-
s.post_install_message =
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
Don't forget to run "rails generate netzke:baspack" to copy necessary
|
279
|
-
assets to your public folder!
|
280
|
-
|
281
|
-
Netzke home page: http://netzke.org
|
282
|
-
Netzke Google Groups: http://groups.google.com/group/netzke
|
283
|
-
Netzke tutorials: http://blog.writelesscode.com
|
284
|
-
|
285
|
-
========================================================================
|
286
|
-
|
287
|
-
}
|
288
|
-
s.require_paths = [%q{lib}]
|
289
|
-
s.rubygems_version = %q{1.8.6}
|
290
|
-
s.summary = %q{Pre-built Rails + ExtJS components for your RIA}
|
272
|
+
s.homepage = "http://netzke.org"
|
273
|
+
s.post_install_message = "\n========================================================================\n\n Thanks for installing netzke-basepack!\n\n Don't forget to run \"rails generate netzke:baspack\" to copy necessary\n assets to your public folder!\n\n Netzke home page: http://netzke.org\n Netzke Google Groups: http://groups.google.com/group/netzke\n Netzke tutorials: http://blog.writelesscode.com\n\n========================================================================\n\n"
|
274
|
+
s.require_paths = ["lib"]
|
275
|
+
s.rubygems_version = "1.8.10"
|
276
|
+
s.summary = "Pre-built Rails + ExtJS components for your RIA"
|
291
277
|
|
292
278
|
if s.respond_to? :specification_version then
|
293
279
|
s.specification_version = 3
|
@@ -44,54 +44,53 @@ GEM
|
|
44
44
|
acts_as_list (0.1.4)
|
45
45
|
addressable (2.2.6)
|
46
46
|
arel (2.2.1)
|
47
|
-
bcrypt-ruby (3.0.
|
47
|
+
bcrypt-ruby (3.0.1)
|
48
48
|
builder (3.0.0)
|
49
|
-
capybara (1.1.
|
49
|
+
capybara (1.1.2)
|
50
50
|
mime-types (>= 1.16)
|
51
51
|
nokogiri (>= 1.3.3)
|
52
52
|
rack (>= 1.0.0)
|
53
53
|
rack-test (>= 0.5.4)
|
54
54
|
selenium-webdriver (~> 2.0)
|
55
55
|
xpath (~> 0.1.4)
|
56
|
-
childprocess (0.2.
|
56
|
+
childprocess (0.2.8)
|
57
57
|
ffi (~> 1.0.6)
|
58
|
-
cucumber (1.
|
58
|
+
cucumber (1.1.4)
|
59
59
|
builder (>= 2.1.2)
|
60
60
|
diff-lcs (>= 1.1.2)
|
61
|
-
gherkin (~> 2.
|
61
|
+
gherkin (~> 2.7.1)
|
62
62
|
json (>= 1.4.6)
|
63
|
-
term-ansicolor (>= 1.0.
|
64
|
-
cucumber-rails (1.
|
65
|
-
capybara (>= 1.
|
66
|
-
cucumber (
|
67
|
-
nokogiri (>= 1.
|
68
|
-
database_cleaner (0.
|
63
|
+
term-ansicolor (>= 1.0.6)
|
64
|
+
cucumber-rails (1.2.1)
|
65
|
+
capybara (>= 1.1.2)
|
66
|
+
cucumber (>= 1.1.3)
|
67
|
+
nokogiri (>= 1.5.0)
|
68
|
+
database_cleaner (0.7.0)
|
69
69
|
diff-lcs (1.1.3)
|
70
70
|
erubis (2.7.0)
|
71
|
-
factory_girl (2.
|
72
|
-
|
73
|
-
|
71
|
+
factory_girl (2.3.2)
|
72
|
+
activesupport
|
73
|
+
ffi (1.0.11)
|
74
|
+
gherkin (2.7.2)
|
74
75
|
json (>= 1.4.6)
|
75
76
|
hike (1.2.1)
|
76
77
|
i18n (0.6.0)
|
77
|
-
json (1.
|
78
|
-
json_pure (1.5.4)
|
79
|
-
spruz (~> 0.2.8)
|
78
|
+
json (1.6.4)
|
80
79
|
launchy (2.0.5)
|
81
80
|
addressable (~> 2.2.6)
|
82
81
|
mail (2.3.0)
|
83
82
|
i18n (>= 0.4.0)
|
84
83
|
mime-types (~> 1.16)
|
85
84
|
treetop (~> 1.4.8)
|
86
|
-
mime-types (1.
|
87
|
-
multi_json (1.0.
|
88
|
-
mysql2 (0.3.
|
85
|
+
mime-types (1.17.2)
|
86
|
+
multi_json (1.0.4)
|
87
|
+
mysql2 (0.3.11)
|
89
88
|
nokogiri (1.5.0)
|
90
|
-
pickle (0.4.
|
89
|
+
pickle (0.4.10)
|
91
90
|
cucumber (>= 0.8)
|
92
91
|
rake
|
93
|
-
polyglot (0.3.
|
94
|
-
rack (1.3.
|
92
|
+
polyglot (0.3.3)
|
93
|
+
rack (1.3.6)
|
95
94
|
rack-cache (1.0.3)
|
96
95
|
rack (>= 0.4)
|
97
96
|
rack-mount (0.8.3)
|
@@ -115,44 +114,44 @@ GEM
|
|
115
114
|
rake (>= 0.8.7)
|
116
115
|
rdoc (~> 3.4)
|
117
116
|
thor (~> 0.14.6)
|
118
|
-
rake (0.9.2)
|
119
|
-
rdoc (3.
|
120
|
-
|
121
|
-
|
122
|
-
rspec-
|
123
|
-
rspec-
|
124
|
-
|
125
|
-
rspec-
|
117
|
+
rake (0.9.2.2)
|
118
|
+
rdoc (3.12)
|
119
|
+
json (~> 1.4)
|
120
|
+
rspec (2.8.0)
|
121
|
+
rspec-core (~> 2.8.0)
|
122
|
+
rspec-expectations (~> 2.8.0)
|
123
|
+
rspec-mocks (~> 2.8.0)
|
124
|
+
rspec-core (2.8.0)
|
125
|
+
rspec-expectations (2.8.0)
|
126
126
|
diff-lcs (~> 1.1.2)
|
127
|
-
rspec-mocks (2.
|
128
|
-
rspec-rails (2.
|
129
|
-
actionpack (
|
130
|
-
activesupport (
|
131
|
-
railties (
|
132
|
-
rspec (~> 2.
|
133
|
-
rubyzip (0.9.
|
134
|
-
selenium-webdriver (2.
|
135
|
-
childprocess (>= 0.2.
|
136
|
-
ffi (
|
137
|
-
|
127
|
+
rspec-mocks (2.8.0)
|
128
|
+
rspec-rails (2.8.1)
|
129
|
+
actionpack (>= 3.0)
|
130
|
+
activesupport (>= 3.0)
|
131
|
+
railties (>= 3.0)
|
132
|
+
rspec (~> 2.8.0)
|
133
|
+
rubyzip (0.9.5)
|
134
|
+
selenium-webdriver (2.16.0)
|
135
|
+
childprocess (>= 0.2.5)
|
136
|
+
ffi (~> 1.0.9)
|
137
|
+
multi_json (~> 1.0.4)
|
138
138
|
rubyzip
|
139
139
|
spork (0.8.5)
|
140
|
-
sprockets (2.0.
|
140
|
+
sprockets (2.0.3)
|
141
141
|
hike (~> 1.2)
|
142
142
|
rack (~> 1.0)
|
143
|
-
tilt (
|
144
|
-
|
145
|
-
sqlite3 (1.3.4)
|
143
|
+
tilt (~> 1.1, != 1.3.0)
|
144
|
+
sqlite3 (1.3.5)
|
146
145
|
sqlite3-ruby (1.3.3)
|
147
146
|
sqlite3 (>= 1.3.3)
|
148
|
-
term-ansicolor (1.0.
|
147
|
+
term-ansicolor (1.0.7)
|
149
148
|
thor (0.14.6)
|
150
149
|
tilt (1.3.3)
|
151
150
|
treetop (1.4.10)
|
152
151
|
polyglot
|
153
152
|
polyglot (>= 0.3.1)
|
154
|
-
tzinfo (0.3.
|
155
|
-
will_paginate (3.0.
|
153
|
+
tzinfo (0.3.31)
|
154
|
+
will_paginate (3.0.2)
|
156
155
|
xpath (0.1.4)
|
157
156
|
nokogiri (~> 1.3)
|
158
157
|
|
@@ -7,12 +7,14 @@
|
|
7
7
|
# Mayor.create(:name => 'Daley', :city => cities.first)
|
8
8
|
|
9
9
|
Role.delete_all
|
10
|
+
puts "Creating roles..."
|
10
11
|
Role.create([
|
11
12
|
{:name => "writer"},
|
12
13
|
{:name => "reader"}
|
13
14
|
])
|
14
15
|
|
15
16
|
User.delete_all
|
17
|
+
puts "Creating users..."
|
16
18
|
User.create([
|
17
19
|
{:first_name => "Mark", :last_name => "Twain", :role => Role.find_by_name("writer")},
|
18
20
|
{:first_name => "Carlos", :last_name => "Castaneda", :role => Role.find_by_name("writer")},
|
@@ -21,6 +23,7 @@ User.create([
|
|
21
23
|
])
|
22
24
|
|
23
25
|
Author.delete_all
|
26
|
+
puts "Creating authors..."
|
24
27
|
Author.create([
|
25
28
|
{:first_name => "Carlos", :last_name => "Castaneda"},
|
26
29
|
{:first_name => "Herman", :last_name => "Hesse"}
|
@@ -30,6 +33,7 @@ Book.delete_all
|
|
30
33
|
|
31
34
|
hesse = Author.find_by_last_name("Hesse")
|
32
35
|
castaneda = Author.find_by_last_name("Castaneda")
|
36
|
+
puts "Creating books..."
|
33
37
|
Book.create([
|
34
38
|
{:title => "Journey to Ixtlan", :author => castaneda},
|
35
39
|
{:title => "The Tales of Power", :author => castaneda},
|
@@ -13,9 +13,9 @@ Scenario: UserForm should be rendered properly along with the data for the first
|
|
13
13
|
|
14
14
|
@javascript
|
15
15
|
Scenario: A form should be rendered properly along with the data for the specified record
|
16
|
-
Given a book exists with title: "Great Book", last_read_at: "2005-01-23"
|
16
|
+
Given a book exists with title: "Great Book", last_read_at: "2005-01-23 11:12:13"
|
17
17
|
When I go to the BookFormWithDefaults test page
|
18
|
-
Then the form should show title: "Great Book", last_read_at: "2005-01-23"
|
18
|
+
Then the form should show title: "Great Book", last_read_at: "2005-01-23 11:12:13"
|
19
19
|
|
20
20
|
@javascript
|
21
21
|
Scenario: Editing the record
|
@@ -115,7 +115,16 @@ Scenario: Editing and immediately submitting the form
|
|
115
115
|
Scenario: Setting date
|
116
116
|
Given a book exists with title: "Some Title"
|
117
117
|
When I go to the BookFormWithDefaults test page
|
118
|
-
Then I fill in "
|
118
|
+
Then I fill in "Published on" with "2005-01-23"
|
119
119
|
And I press "Apply"
|
120
120
|
And I wait for the response from the server
|
121
|
-
Then a book should exist with
|
121
|
+
Then a book should exist with published_on: "2005-01-23"
|
122
|
+
|
123
|
+
@javascript
|
124
|
+
Scenario: Setting datetime
|
125
|
+
Given a book exists with title: "Some Title"
|
126
|
+
When I go to the BookFormWithDefaults test page
|
127
|
+
Then I fill in Ext field "Last read at" with "2005-01-23 11:12:13"
|
128
|
+
And I press "Apply"
|
129
|
+
And I wait for the response from the server
|
130
|
+
Then a book should exist with last_read_at: "2005-01-23 11:12:13"
|
@@ -4,13 +4,13 @@ Feature: Grid panel
|
|
4
4
|
I want feature
|
5
5
|
|
6
6
|
@javascript
|
7
|
-
Scenario:
|
7
|
+
Scenario: BookGrid should correctly display data
|
8
8
|
Given an author exists with first_name: "Vladimir", last_name: "Nabokov"
|
9
|
-
And a book exists with author: that author, title: "Lolita", last_read_at: "2011-12-13", published_on: "2005-01-30"
|
9
|
+
And a book exists with author: that author, title: "Lolita", last_read_at: "2011-12-13 11:12:13", published_on: "2005-01-30"
|
10
10
|
|
11
11
|
When I go to the BookGrid test page
|
12
12
|
Then I should see "Nabokov, Vladimir"
|
13
|
-
And I should see "12
|
13
|
+
And I should see "2011-12-13 11:12:13"
|
14
14
|
And I should see "01/30/2005"
|
15
15
|
|
16
16
|
@javascript
|
@@ -235,6 +235,12 @@ Scenario: GridPanel with overridden columns
|
|
235
235
|
Then I should see "LOLITA"
|
236
236
|
And I should see "Nabokov, Vladimir"
|
237
237
|
|
238
|
+
@javascript
|
239
|
+
Scenario: Virtual attributes should not be sortable
|
240
|
+
Given a book exists with title: "Some Title"
|
241
|
+
When I go to the BookGridWithVirtualAttributes test page
|
242
|
+
Then the grid's column "In abundance" should not be sortable
|
243
|
+
|
238
244
|
@javascript
|
239
245
|
Scenario: Virtual attributes should not be editable
|
240
246
|
Given a book exists with title: "Some Title"
|
@@ -248,4 +254,4 @@ Scenario: GridPanel with overridden columns
|
|
248
254
|
And I click the "Delete row" action icon
|
249
255
|
And I press "Yes"
|
250
256
|
Then I should see "Deleted 1 record(s)"
|
251
|
-
And a book should not exist with title: "Some Title"
|
257
|
+
And a book should not exist with title: "Some Title"
|
@@ -23,8 +23,24 @@ Then /the form should show #{capture_fields}$/ do |fields|
|
|
23
23
|
var form = Ext.ComponentQuery.query('form')[0].getForm();
|
24
24
|
var values = {#{fields}};
|
25
25
|
for (var fieldName in values) {
|
26
|
-
|
26
|
+
var field = form.findField(fieldName);
|
27
|
+
|
28
|
+
if (field.getXType() == 'xdatetime') {
|
29
|
+
// Treat xdatetime specially
|
30
|
+
var oldValue = field.getValue();
|
31
|
+
field.setValue(values[fieldName]);
|
32
|
+
return oldValue == field.getValue();
|
33
|
+
} else {
|
34
|
+
return (field.getValue() == values[fieldName] || field.getRawValue() == values[fieldName]);
|
35
|
+
}
|
27
36
|
}
|
28
37
|
return true;
|
29
38
|
JS
|
30
39
|
end
|
40
|
+
|
41
|
+
Then /^I fill in Ext field "([^"]*)" with "([^"]*)"$/ do |field_label, value|
|
42
|
+
page.driver.browser.execute_script <<-JS
|
43
|
+
var field = Ext.ComponentQuery.query("[fieldLabel='#{field_label}']")[0];
|
44
|
+
field.setValue("#{value}");
|
45
|
+
JS
|
46
|
+
end
|
@@ -165,6 +165,14 @@ Then /^the grid should have records sorted by "([^"]*)"\s?(asc|desc)?$/ do |colu
|
|
165
165
|
JS
|
166
166
|
end
|
167
167
|
|
168
|
+
Then /^the grid's column "([^"]*)" should not be sortable$/ do |column_name|
|
169
|
+
column = column_name.downcase.gsub(' ', '_')
|
170
|
+
page.driver.browser.execute_script(<<-JS).should_not be_true
|
171
|
+
var col = Ext.ComponentQuery.query('gridcolumn[name="#{column}"]')[0];
|
172
|
+
return col.sortable;
|
173
|
+
JS
|
174
|
+
end
|
175
|
+
|
168
176
|
Then /^the grid's column "([^"]*)" should not be editable$/ do |column_name|
|
169
177
|
column = column_name.downcase.gsub(' ', '_')
|
170
178
|
page.driver.browser.execute_script(<<-JS).should be_true
|
@@ -175,4 +183,4 @@ end
|
|
175
183
|
|
176
184
|
When /^I click the "([^"]*)" action icon$/ do |action_name|
|
177
185
|
find("img[data-qtip='#{action_name}']").click
|
178
|
-
end
|
186
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: netzke-basepack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: netzke-core
|
16
|
-
requirement: &
|
16
|
+
requirement: &70335624108560 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.7.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70335624108560
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: will_paginate
|
27
|
-
requirement: &
|
27
|
+
requirement: &70335624108080 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.0.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70335624108080
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: acts_as_list
|
38
|
-
requirement: &
|
38
|
+
requirement: &70335624107600 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 0.1.4
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70335624107600
|
47
47
|
description: A set of full-featured extendible Netzke components (such as FormPanel,
|
48
48
|
GridPanel, Window, BorderLayoutPanel, etc) which can be used as building block for
|
49
49
|
your RIA
|
@@ -66,7 +66,7 @@ files:
|
|
66
66
|
- init.rb
|
67
67
|
- install.rb
|
68
68
|
- javascripts/basepack.js
|
69
|
-
- javascripts/
|
69
|
+
- javascripts/xdatetime.js
|
70
70
|
- lib/generators/netzke/basepack_generator.rb
|
71
71
|
- lib/generators/netzke/templates/assets/ts-checkbox.gif
|
72
72
|
- lib/generators/netzke/templates/create_netzke_field_lists.rb
|
@@ -329,7 +329,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
329
329
|
version: '0'
|
330
330
|
requirements: []
|
331
331
|
rubyforge_project:
|
332
|
-
rubygems_version: 1.8.
|
332
|
+
rubygems_version: 1.8.10
|
333
333
|
signing_key:
|
334
334
|
specification_version: 3
|
335
335
|
summary: Pre-built Rails + ExtJS components for your RIA
|
@@ -1,24 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Ext.ux.DateTimePicker & Ext.ux.form.DateTimeField
|
3
|
-
* http://www.sencha.com/forum/showthread.php?98292-DateTime-field-again-and-again-)
|
4
|
-
* Copyright(c) 2011, Andrew Pleshkov andrew.pleshkov@gmail.com
|
5
|
-
*
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
11
|
-
* furnished to do so, subject to the following conditions:
|
12
|
-
*
|
13
|
-
* The above copyright notice and this permission notice shall be included in
|
14
|
-
* all copies or substantial portions of the Software.
|
15
|
-
*
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
-
* THE SOFTWARE.
|
23
|
-
*/
|
24
|
-
Ext.namespace("Ext.ux");(function(){var a=Ext.ux;a.BaseTimePicker=Ext.extend(Ext.Panel,{timeFormat:"g:i A",header:true,nowText:"Now",doneText:"Done",hourIncrement:1,minIncrement:1,hoursLabel:"Hours",minsLabel:"Minutes",cls:"ux-base-time-picker",width:210,layout:"form",labelAlign:"top",initComponent:function(){this.addEvents("select");this.hourSlider=new Ext.slider.SingleSlider({increment:this.hourIncrement,minValue:0,maxValue:23,fieldLabel:this.hoursLabel,listeners:{change:this._updateTimeValue,scope:this},plugins:new Ext.slider.Tip()});this.minSlider=new Ext.slider.SingleSlider({increment:this.minIncrement,minValue:0,maxValue:59,fieldLabel:this.minsLabel,listeners:{change:this._updateTimeValue,scope:this},plugins:new Ext.slider.Tip()});this.setCurrentTime(false);this.items=[this.hourSlider,this.minSlider];this.bbar=[{text:this.nowText,handler:this.setCurrentTime,scope:this},"->",{text:this.doneText,handler:this.onDone,scope:this}];a.BaseTimePicker.superclass.initComponent.call(this)},setCurrentTime:function(b){this.setValue(new Date(),!!b)},onDone:function(){this.fireEvent("select",this,this.getValue())},setValue:function(c,b){this.hourSlider.setValue(c.getHours(),b);this.minSlider.setValue(c.getMinutes(),b);this._updateTimeValue()},_extractValue:function(){var b=new Date();b.setHours(this.hourSlider.getValue());b.setMinutes(this.minSlider.getValue());return b},getValue:function(){return this._extractValue()},_updateTimeValue:function(){var b=this._extractValue().format(this.timeFormat);if(this.rendered){this.setTitle(b)}},afterRender:function(){a.BaseTimePicker.superclass.afterRender.call(this);this._updateTimeValue()},destroy:function(){this.purgeListeners();this.hourSlider=null;this.minSlider=null;a.BaseTimePicker.superclass.destroy.call(this)}});Ext.reg("basetimepicker",a.BaseTimePicker)})();Ext.namespace("Ext.ux");(function(){var a=Ext.ux;var c="ux-date-time-picker";a.DateTimePicker=Ext.extend(Ext.BoxComponent,{timeLabel:"Time",timeFormat:"g:i A",changeTimeText:"Change...",doneText:"Done",initComponent:function(){a.DateTimePicker.superclass.initComponent.call(this);this.addEvents("select");this.timePickerButton=new Ext.Button({text:this.changeTimeText,handler:this._showTimePicker,scope:this});this._initDatePicker();this.timeValue=new Date();if(this.value){this.setValue(this.value);delete this.value}},_initTimePicker:function(){if(!this.timeMenu){var d=this.initialConfig.timeMenu;if(d&&d.xtype){this.timeMenu=Ext.create(d)}else{var e=Ext.create(Ext.applyIf(this.initialConfig.timePicker||{},{timeFormat:this.timeFormat}),"basetimepicker");this.timeMenu=new b(e,d||{})}if(!Ext.isFunction(this.timeMenu.getPicker)){throw"Your time menu must provide the getPicker() method"}this.timeMenu.on("timeselect",this.onTimeSelect,this)}},_initDatePicker:function(){var e=this.initialConfig.datePicker||{};e.internalRender=this.initialConfig.internalRender;Ext.applyIf(e,{format:this.dateFormat||Ext.DatePicker.prototype.format});var d=this.datePicker=Ext.create(e,"datepicker");d.update=d.update.createSequence(function(){if(this.el!=null&&this.datePicker.rendered){var f=this.datePicker.el.getWidth();this.el.setWidth(f+this.el.getBorderWidth("lr")+this.el.getPadding("lr"))}},this)},_renderDatePicker:function(g){var e=this.datePicker;e.render(g);var j=e.getEl().child(".x-date-bottom");var f=j.getSize(true);var h=["position: absolute","bottom: 0","left: 0","overflow: hidden","width: "+f.width+"px","height: "+f.height+"px"].join(";");var i=g.createChild({tag:"div",cls:"x-date-bottom",style:h,children:[{tag:"table",cellspacing:0,style:"width: 100%",children:[{tag:"tr",children:[{tag:"td",align:"left"},{tag:"td",align:"right"}]}]}]});if(e.showToday){var d={};Ext.each(["text","tooltip","handler","scope"],function(k){d[k]=e.todayBtn.initialConfig[k]});this.todayBtn=new Ext.Button(d).render(i.child("td:first"))}this.doneBtn=new Ext.Button({text:this.doneText,handler:this.onDone,scope:this}).render(i.child("td:last"))},_getFormattedTimeValue:function(d){return d.format(this.timeFormat)},_renderValueField:function(f){var e=c+"-value-ct";var d=!Ext.isEmpty(this.timeLabel)?'<span class="'+e+'-value-label">'+this.timeLabel+":</span> ":"";var h=f.insertFirst({tag:"div",cls:[e,"x-date-bottom"].join(" ")});var g=h.createChild({tag:"table",cellspacing:0,style:"width: 100%",children:[{tag:"tr",children:[{tag:"td",align:"left",cls:e+"-value-cell",html:'<div class="'+e+'-value-wrap">'+d+'<span class="'+e+'-value">'+this._getFormattedTimeValue(this.timeValue)+"</span></div>"},{tag:"td",align:"right",cls:e+"-btn-cell"}]}]});this.timeValueEl=g.child("."+e+"-value");this.timeValueEl.on("click",this._showTimePicker,this);this.timePickerButton.render(g.child("td:last"))},onRender:function(e,d){this.el=e.createChild({tag:"div",cls:c,children:[{tag:"div",cls:c+"-inner"}]},d);a.DateTimePicker.superclass.onRender.call(this,e,d);var f=this.el.first();this._renderDatePicker(f);this._renderValueField(f)},_updateTimeValue:function(d){this.timeValue=d;if(this.timeValueEl!=null){this.timeValueEl.update(this._getFormattedTimeValue(d))}},setValue:function(d){this._updateTimeValue(d);this.datePicker.setValue(d.clone())},getValue:function(){var d=this.datePicker.getValue();var e=this.timeValue.getElapsed(this.timeValue.clone().clearTime());return new Date(d.getTime()+e)},onTimeSelect:function(f,d,e){this._updateTimeValue(e)},_showTimePicker:function(){this._initTimePicker();this.timeMenu.getPicker().setValue(this.timeValue,false);if(this.timeMenu.isVisible()){this.timeMenu.hide()}else{this.timeMenu.show(this.timePickerButton.el,null,this.parentMenu)}},onDone:function(){this.fireEvent("select",this,this.getValue())},destroy:function(){Ext.destroy(this.timePickerButton);this.timePickerButton=null;if(this.timeValueEl){this.timeValueEl.remove();this.timeValueEl=null}Ext.destroy(this.datePicker);this.datePicker=null;if(this.timeMenu){Ext.destroy(this.timeMenu);this.timeMenu=null}if(this.todayBtn){Ext.destroy(this.todayBtn);this.todayBtn=null}if(this.doneBtn){Ext.destroy(this.doneBtn);this.doneBtn=null}this.parentMenu=null;a.DateTimePicker.superclass.destroy.call(this)}});Ext.reg("datetimepicker",a.DateTimePicker);var b=a.DateTimePicker.Menu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:false,plain:true,showSeparator:false,constructor:function(e,d){d=d||{};if(d.picker){delete d.picker}this.picker=Ext.create(e);b.superclass.constructor.call(this,Ext.applyIf({items:this.picker},d));this.addEvents("timeselect");this.picker.on("select",this.onTimeSelect,this)},getPicker:function(){return this.picker},onTimeSelect:function(d,e){this.hide();this.fireEvent("timeselect",this,d,e)},destroy:function(){this.purgeListeners();this.picker=null;b.superclass.destroy.call(this)}})})();Ext.namespace("Ext.ux.form");(function(){var c=Ext.ux.form;var a=Ext.isIE7&&Ext.isStrict;var b=Ext.extend(Ext.menu.Menu,{enableScrolling:false,plain:true,showSeparator:false,hideOnClick:true,pickerId:null,cls:"x-date-menu x-date-time-menu",constructor:function(e,d){b.superclass.constructor.call(this,Ext.applyIf({items:e},d||{}));this.primaryPicker=e;e.parentMenu=this;this.on("beforeshow",this.onBeforeShow,this);this.strict=a;if(this.strict){this.on("show",this.onShow,this,{single:true,delay:20})}this.picker=e.datePicker;this.relayEvents(e,["select"]);this.on("show",e.focus,e);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}},onBeforeShow:function(){if(this.picker){this.picker.hideMonthPicker(true)}},onShow:function(){var d=this.picker.getEl();d.setWidth(d.getWidth())},destroy:function(){this.primaryPicker=null;this.picker=null;b.superclass.destroy.call(this)}});c.DateTimeField=Ext.extend(Ext.form.DateField,{timeFormat:"g:i A",defaultAutoCreate:{tag:"input",type:"text",size:"22",autocomplete:"off"},initComponent:function(){c.DateTimeField.superclass.initComponent.call(this);this.dateFormat=this.dateFormat||this.format;var d=this._createPicker();this.format=this.dateFormat+" "+this.timeFormat;this.menu=new b(d,{hideOnClick:false})},_createPicker:function(){var d=this.initialConfig.picker||{};Ext.apply(d,{ctCls:"x-menu-date-item",internalRender:a||!Ext.isIE});Ext.applyIf(d,{dateFormat:this.dateFormat,timeFormat:this.timeFormat});return Ext.create(d,"datetimepicker")},onTriggerClick:function(){c.DateTimeField.superclass.onTriggerClick.apply(this,arguments);this.menu.primaryPicker.setValue(this.getValue()||new Date())}});Ext.reg("datetimefield",c.DateTimeField)})();
|