skozlov-netzke-basepack 0.1.1.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +1 -0
- data/.gitignore +5 -0
- data/LICENSE +2 -19
- data/README.rdoc +87 -0
- data/Rakefile +28 -12
- data/TODO.rdoc +7 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +3 -0
- data/init.rb +0 -1
- data/javascripts/basepack.js +839 -49
- data/lib/app/models/netzke_auto_column.rb +56 -0
- data/lib/netzke/accordion_panel.rb +113 -0
- data/lib/netzke/active_record/basepack.rb +104 -0
- data/lib/netzke/active_record/data_accessor.rb +21 -0
- data/lib/netzke/basic_app.rb +325 -0
- data/lib/netzke/border_layout_panel.rb +128 -0
- data/lib/netzke/configuration_panel.rb +24 -0
- data/lib/netzke/data_accessor.rb +71 -0
- data/lib/netzke/ext.rb +6 -0
- data/lib/netzke/field_model.rb +131 -0
- data/lib/netzke/fields_configurator.rb +95 -0
- data/lib/netzke/form_panel.rb +214 -0
- data/lib/netzke/form_panel_api.rb +74 -0
- data/lib/netzke/form_panel_extras/javascripts/xcheckbox.js +82 -0
- data/lib/netzke/form_panel_js.rb +129 -0
- data/lib/netzke/grid_panel.rb +442 -0
- data/lib/netzke/grid_panel_api.rb +352 -0
- data/lib/netzke/grid_panel_extras/javascripts/check-column.js +33 -0
- data/{javascripts → lib/netzke/grid_panel_extras/javascripts}/filters.js +0 -0
- data/lib/netzke/grid_panel_extras/javascripts/rows-dd.js +280 -0
- data/lib/netzke/grid_panel_js.rb +721 -0
- data/lib/netzke/panel.rb +13 -0
- data/lib/netzke/plugins/configuration_tool.rb +121 -0
- data/lib/netzke/property_editor.rb +105 -0
- data/lib/netzke/property_editor_extras/helper_model.rb +126 -0
- data/lib/netzke/search_panel.rb +62 -0
- data/lib/netzke/tab_panel.rb +160 -0
- data/lib/netzke/table_editor.rb +118 -0
- data/lib/netzke/tree_panel.rb +73 -0
- data/lib/netzke/wrapper.rb +42 -0
- data/lib/netzke-basepack.rb +9 -15
- data/netzke-basepack.gemspec +147 -20
- data/stylesheets/basepack.css +26 -0
- data/test/app_root/app/models/book.rb +1 -1
- data/test/app_root/config/environment.rb +1 -0
- data/test/app_root/db/migrate/20081222033440_create_genres.rb +1 -0
- data/test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb +1 -1
- data/test/app_root/db/migrate/20090102223630_create_netzke_layouts.rb +14 -0
- data/test/app_root/vendor/plugins/acts_as_list/README +23 -0
- data/test/app_root/vendor/plugins/acts_as_list/init.rb +3 -0
- data/test/app_root/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
- data/test/test_helper.rb +1 -2
- data/test/unit/accordion_panel_test.rb +20 -0
- data/test/unit/active_record_basepack_test.rb +54 -0
- data/test/unit/grid_panel_test.rb +43 -0
- data/test/unit/helper_model_test.rb +30 -0
- data/test/unit/netzke_basepack_test.rb +4 -0
- data/test/unit/tab_panel_test.rb +21 -0
- metadata +96 -72
- data/CHANGELOG +0 -14
- data/Manifest +0 -65
- data/README.mdown +0 -18
- data/generators/netzke_basepack/USAGE +0 -8
- data/generators/netzke_basepack/netzke_basepack_generator.rb +0 -8
- data/generators/netzke_basepack/netzke_grid_generator.rb +0 -7
- data/generators/netzke_basepack/templates/create_netzke_grid_columns.rb +0 -21
- data/lib/app/models/netzke_grid_column.rb +0 -23
- data/lib/netzke/accordion.rb +0 -11
- data/lib/netzke/ar_ext.rb +0 -163
- data/lib/netzke/column.rb +0 -43
- data/lib/netzke/container.rb +0 -81
- data/lib/netzke/grid.rb +0 -120
- data/lib/netzke/grid_interface.rb +0 -156
- data/lib/netzke/grid_js_builder.rb +0 -276
- data/lib/netzke/preference_grid.rb +0 -43
- data/lib/netzke/properties_tool.rb +0 -66
- data/lib/netzke/property_grid.rb +0 -60
- data/test/ar_ext_test.rb +0 -39
- data/test/column_test.rb +0 -27
- data/test/grid_test.rb +0 -43
- data/test/netzke_basepack_test.rb +0 -8
data/.autotest
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'autotest/redgreen'
|
data/.gitignore
ADDED
data/LICENSE
CHANGED
@@ -1,20 +1,3 @@
|
|
1
|
-
Copyright (c) 2008 Sergei Kozlov
|
1
|
+
Copyright (c) 2008-2009 Sergei Kozlov
|
2
2
|
|
3
|
-
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
3
|
+
GNU GPL license v3
|
data/README.rdoc
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
= netzke-basepack
|
2
|
+
A pack of basic Rails/ExtJS widgets as a part of the Netzke framework. Live demo/tutorials on http://blog.writelesscode.com. Introduction to the Netzke framework: http://github.com/skozlov/netzke/tree/master
|
3
|
+
|
4
|
+
Note that if you would like to modify this code or experiment with it, you may be better off cloning this project into your app's vendor/plugin directory - it will then behave as a Rails plugin.
|
5
|
+
|
6
|
+
= Prerequisites
|
7
|
+
1. Rails >= 2.2
|
8
|
+
2. Ext JS >= 2.0: its root *must* be accessible as RAILS_ROOT/public/extjs. You may symlink your Ext JS library here like this (from your app folder):
|
9
|
+
cd public && ln -s ~/Developer/extjs/ext-2.2 extjs
|
10
|
+
|
11
|
+
3. acts_as_list plugin must be installed:
|
12
|
+
./script/plugin install git://github.com/rails/acts_as_list.git
|
13
|
+
|
14
|
+
= Installation
|
15
|
+
Install the gem:
|
16
|
+
gem install skozlov-netzke-basepack
|
17
|
+
|
18
|
+
Include it into environment.rb:
|
19
|
+
config.gem "skozlov-netzke-basepack"
|
20
|
+
|
21
|
+
Include mapping for Netzke controller providing *.js and *.css (in routes.rb):
|
22
|
+
map.netzke
|
23
|
+
|
24
|
+
= Usage
|
25
|
+
First, run the generators to have the necessary migrations:
|
26
|
+
./script/generate netzke_core
|
27
|
+
|
28
|
+
Do the migrations:
|
29
|
+
rake db:migrate
|
30
|
+
|
31
|
+
The following example will provide you with a grid-based scaffold for ActiveRecord-model called Book. You may generate it like this:
|
32
|
+
./script/generate model Book title:string amount:integer
|
33
|
+
(don't forget to re-run the migrations after it)
|
34
|
+
|
35
|
+
In the controller declare the widget:
|
36
|
+
|
37
|
+
class WelcomeController < ApplicationController
|
38
|
+
netzke :books, :widget_class_name => 'GridPanel', :data_class_name => 'Book'
|
39
|
+
end
|
40
|
+
|
41
|
+
After a widget is declared in the controller, it can be accessed in 3 different ways: 1) loaded by means of an automatically created controller action which will produce a basic HTML-page with the widget (handy for testing), 2) embedded directly into a view (by means of helpers), 3) dynamically loaded by other widgets (like BasicApp-derived, if you want a desktop-like, AJAX-driven web-app).
|
42
|
+
|
43
|
+
== Using automatically created controller action
|
44
|
+
Without writing any more code, you can access the widget by http://localhost:3000/welcome/books_test. That is to say, you simply append _test to your widget's name (as declared in the controller) to get the action's name.
|
45
|
+
|
46
|
+
== Embedding a widget into a view
|
47
|
+
netzke-core plugin provides the following 2 helpers to put inside your head-tag (use it in your layout):
|
48
|
+
|
49
|
+
1. netzke_js_include - to include extjs and netzke javascript files
|
50
|
+
2. netzke_css_include - to include the css. This one can take a parameter to specify a color schema you wish for Ext JS, e.g.: netzke_css_include(:gray)
|
51
|
+
|
52
|
+
Declaring a widget in the controller provides you with a couple of helpers that can be used in the view:
|
53
|
+
|
54
|
+
1. books_class_definition will contain the JavaScript code defining the code for the JS class.
|
55
|
+
2. books_widget_instance will declare a local JavaScript variable called 'book'.
|
56
|
+
3. books_widget_render will provide the JavaScript code that calls the "render" method on the variable declared by books_widget_instance.
|
57
|
+
|
58
|
+
Use these helpers inside of the script-tag like the following (in the view):
|
59
|
+
|
60
|
+
<script type="text/javascript" charset="utf-8">
|
61
|
+
<%= books_class_definition %>
|
62
|
+
Ext.onReady(function(){
|
63
|
+
<%= books_widget_instance %>
|
64
|
+
<%= books_widget_render %>
|
65
|
+
})
|
66
|
+
</script>
|
67
|
+
<div id="books">the widget will be rendered in this div</div>
|
68
|
+
|
69
|
+
If your layout already calls yield :javascripts wrapped in the <script>-tag, you can have all javascript-code in one place on the page:
|
70
|
+
|
71
|
+
<% content_for :javascripts do %>
|
72
|
+
<%= books_class_definition %>
|
73
|
+
Ext.onReady(function(){
|
74
|
+
<%= books_widget_instance %>
|
75
|
+
books.render("books");
|
76
|
+
})
|
77
|
+
<% end %>
|
78
|
+
<p>... your page content here ...</p>
|
79
|
+
<div id="books">the widget will be rendered in this div</div>
|
80
|
+
|
81
|
+
== Dynamic loading of widgets
|
82
|
+
TODO: this part will be covered later
|
83
|
+
|
84
|
+
= Credentials
|
85
|
+
Testing done with the help of http://github.com/pluginaweek/plugin_test_helper
|
86
|
+
|
87
|
+
Copyright (c) 2008-2009 Sergei Kozlov, released under the MIT license
|
data/Rakefile
CHANGED
@@ -1,14 +1,30 @@
|
|
1
|
-
require 'echoe'
|
1
|
+
# require 'echoe'
|
2
|
+
#
|
3
|
+
# Echoe.new("netzke-basepack") do |p|
|
4
|
+
# p.author = "Sergei Kozlov"
|
5
|
+
# p.email = "sergei@playcode.nl"
|
6
|
+
# p.summary = "Prebuilt Netzke widgets for your RIA"
|
7
|
+
# p.url = "http://playcode.nl"
|
8
|
+
# p.runtime_dependencies = ["binarylogic-searchlogic >= 2.0.0", "skozlov-netzke-core >= 0.4.0"]
|
9
|
+
# p.development_dependencies = []
|
10
|
+
# p.test_pattern = 'test/**/*_test.rb'
|
11
|
+
#
|
12
|
+
# # fixing the problem with lib/*-* files being removed while doing manifest
|
13
|
+
# p.clean_pattern = ["pkg", "doc", 'build/*', '**/coverage', '**/*.o', '**/*.so', '**/*.a', '**/*.log', "{ext,lib}/*.{bundle,so,obj,pdb,lib,def,exp}", "ext/Makefile", "{ext,lib}/**/*.{bundle,so,obj,pdb,lib,def,exp}", "ext/**/Makefile", "pkg", "*.gem", ".config"]
|
14
|
+
# end
|
2
15
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
16
|
+
begin
|
17
|
+
require 'jeweler'
|
18
|
+
Jeweler::Tasks.new do |gemspec|
|
19
|
+
gemspec.name = "netzke-basepack"
|
20
|
+
gemspec.summary = "Pre-built Netzke widgets for your RIA"
|
21
|
+
gemspec.description = "Pre-built Netzke widgets for your RIA"
|
22
|
+
gemspec.email = "sergei@playcode.nl"
|
23
|
+
gemspec.homepage = "http://github.com/skozlov/netzke-basepack"
|
24
|
+
gemspec.rubyforge_project = "netzke-basepack"
|
25
|
+
gemspec.authors = ["Sergei Kozlov"]
|
26
|
+
gemspec.add_dependency "skozlov-netzke-core", ">= 0.4.0"
|
27
|
+
end
|
28
|
+
rescue LoadError
|
29
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
14
30
|
end
|
data/TODO.rdoc
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.5.0
|
data/init.rb
CHANGED
data/javascripts/basepack.js
CHANGED
@@ -1,52 +1,842 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
1
|
+
Ext.apply(Ext.History, new Ext.util.Observable());
|
2
|
+
|
3
|
+
// A convenient passfield
|
4
|
+
Ext.netzke.PassField = Ext.extend(Ext.form.TextField, {
|
5
|
+
inputType: 'password'
|
6
|
+
});
|
7
|
+
Ext.reg('passfield', Ext.netzke.PassField);
|
8
|
+
|
9
|
+
// Combobox that knows to talk to the server side (used in both grids and panels)
|
10
|
+
Ext.netzke.ComboBox = Ext.extend(Ext.form.ComboBox, {
|
11
|
+
displayField : 'id',
|
12
|
+
valueField : 'id',
|
13
|
+
triggerAction : 'all',
|
14
|
+
typeAhead : true,
|
15
|
+
|
16
|
+
initComponent : function(){
|
17
|
+
if (this.options) {
|
18
|
+
Ext.apply(this, {
|
19
|
+
store : this.options,
|
20
|
+
mode : "local"
|
21
|
+
});
|
22
|
+
} else {
|
23
|
+
var row = Ext.data.Record.create([{name:'id'}]);
|
24
|
+
var store = new Ext.data.Store({
|
25
|
+
proxy : new Ext.data.HttpProxy({url:this.parentId+"__get_combobox_options", jsonData:{column:this.name}}),
|
26
|
+
reader : new Ext.data.ArrayReader({root:'data', id:0}, row)
|
27
|
+
});
|
28
|
+
|
29
|
+
Ext.apply(this, {
|
30
|
+
store : store
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
Ext.netzke.ComboBox.superclass.initComponent.apply(this, arguments);
|
35
|
+
|
36
|
+
this.on('blur', function(cb){
|
37
|
+
cb.setValue(cb.getRawValue());
|
38
|
+
});
|
39
|
+
|
40
|
+
this.on('specialkey', function(cb, event){
|
41
|
+
if (event.getKey() == 9 || event.getKey() == 13) {cb.setValue(cb.getRawValue());}
|
42
|
+
});
|
43
|
+
}
|
44
|
+
});
|
45
|
+
|
46
|
+
Ext.reg('combobox', Ext.netzke.ComboBox);
|
47
|
+
|
48
|
+
/*
|
49
|
+
Accepts a string which either contains:
|
50
|
+
Ext.util.Format method (e.g. 'usMoney'),
|
51
|
+
or
|
52
|
+
JSON-encoded array, where the first element is Ext.util.Format method (e.g. 'ellipsis'),
|
53
|
+
and the rest of the elements - configuration parameters that should be passed to this method besids
|
54
|
+
the value to be rendered (e.g. '2');
|
55
|
+
|
56
|
+
Example of the latter: ["defaultValue", "MyDefaultValue"]
|
57
|
+
*/
|
58
|
+
Ext.netzke.normalizedRenderer = function(config) {
|
59
|
+
res = null;
|
60
|
+
|
61
|
+
if (config) {
|
62
|
+
try{
|
63
|
+
config = Ext.decode(config); // it's an array consisting of renderer's name *and* eventual options
|
64
|
+
} catch(e) {
|
65
|
+
// leave config as is - it's supposed to be the renderer's name
|
66
|
+
}
|
67
|
+
|
68
|
+
if (Ext.isArray(config)) {
|
69
|
+
res = function(v){
|
70
|
+
var formatMethod = config[0];
|
71
|
+
var valueAndOptions = config.slice(1);
|
72
|
+
valueAndOptions.unshift(v);
|
73
|
+
// call the Format function with the argument *and* configuration
|
74
|
+
return Ext.util.Format[formatMethod] ? Ext.util.Format[formatMethod].apply(this, valueAndOptions) : "Unknown renderer";
|
75
|
+
}
|
76
|
+
} else {
|
77
|
+
res = Ext.util.Format[config] ? Ext.util.Format[config] : function(v){return "Unknown renderer"}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
return res;
|
82
|
+
};
|
83
|
+
|
84
|
+
Ext.util.Format.mask = function(v){
|
85
|
+
return "********";
|
42
86
|
};
|
43
87
|
|
44
|
-
// Mapping of
|
88
|
+
// Mapping of editor field to grid filters
|
45
89
|
Ext.netzke.filterMap = {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
}
|
90
|
+
numberfield:'Numeric',
|
91
|
+
textfield:'String',
|
92
|
+
xdatetime:'String',
|
93
|
+
checkbox:'Boolean',
|
94
|
+
combobox:'String',
|
95
|
+
datefield:'Date'
|
96
|
+
};
|
97
|
+
|
98
|
+
Ext.override(Ext.StatusBar, {
|
99
|
+
hideBusy : function(){
|
100
|
+
return this.setStatus({
|
101
|
+
text: this.defaultText,
|
102
|
+
iconCls: this.defaultIconCls
|
103
|
+
});
|
104
|
+
}
|
105
|
+
});
|
106
|
+
|
107
|
+
Ext.data.RecordArrayReader = Ext.extend(Ext.data.JsonReader, {
|
108
|
+
/**
|
109
|
+
* Create a data block containing Ext.data.Records from an Array.
|
110
|
+
* @param {Object} o An Array of row objects which represents the dataset.
|
111
|
+
* @return {Object} data A data block which is used by an Ext.data.Store object as
|
112
|
+
* a cache of Ext.data.Records.
|
113
|
+
*/
|
114
|
+
readRecord : function(o){
|
115
|
+
var sid = this.meta ? this.meta.id : null;
|
116
|
+
var recordType = this.recordType, fields = recordType.prototype.fields;
|
117
|
+
var records = [];
|
118
|
+
var root = o;
|
119
|
+
var n = root;
|
120
|
+
var values = {};
|
121
|
+
var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
|
122
|
+
for(var j = 0, jlen = fields.length; j < jlen; j++){
|
123
|
+
var f = fields.items[j];
|
124
|
+
var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
|
125
|
+
var v = n[k] !== undefined ? n[k] : f.defaultValue;
|
126
|
+
v = f.convert(v, n);
|
127
|
+
values[f.name] = v;
|
128
|
+
}
|
129
|
+
var record = new recordType(values, id);
|
130
|
+
record.json = n;
|
131
|
+
return record;
|
132
|
+
}
|
133
|
+
});
|
134
|
+
|
135
|
+
Ext.netzke.JsonField = Ext.extend(Ext.form.TextField, {
|
136
|
+
validator: function(value) {
|
137
|
+
try{
|
138
|
+
var d = Ext.decode(value);
|
139
|
+
return true;
|
140
|
+
} catch(e) {
|
141
|
+
return "Invalid JSON"
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
,setValue: function(value) {
|
146
|
+
this.setRawValue(Ext.encode(value));
|
147
|
+
}
|
148
|
+
|
149
|
+
});
|
150
|
+
|
151
|
+
Ext.reg('jsonfield', Ext.netzke.JsonField);
|
152
|
+
|
153
|
+
Ext.ns('Ext.netzke.form');
|
154
|
+
|
155
|
+
Ext.netzke.form.FileWithType = Ext.extend(Ext.form.Field, {
|
156
|
+
defaultAutoCreate:{tag:'input', type:'hidden'},
|
157
|
+
|
158
|
+
initComponent: function(){
|
159
|
+
Ext.netzke.form.FileWithType.superclass.initComponent.call(this);
|
160
|
+
|
161
|
+
// this.ft = new Ext.form.ComboBox({
|
162
|
+
// });
|
163
|
+
this.ft = new Ext.form.TextField({
|
164
|
+
name: this.name + "_filetype"
|
165
|
+
});
|
166
|
+
this.ft.ownerCt = this;
|
167
|
+
|
168
|
+
this.f = new Ext.form.TextField({
|
169
|
+
inputType:'file',
|
170
|
+
name: this.name + "_file"
|
171
|
+
});
|
172
|
+
this.f.ownerCt = this;
|
173
|
+
},
|
174
|
+
|
175
|
+
onRender: function(ct, position){
|
176
|
+
if(this.isRendered) {
|
177
|
+
return;
|
178
|
+
}
|
179
|
+
|
180
|
+
// render underlying hidden field
|
181
|
+
Ext.netzke.form.FileWithType.superclass.onRender.call(this, ct, position);
|
182
|
+
|
183
|
+
var t; // table
|
184
|
+
|
185
|
+
t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
|
186
|
+
{tag:'tr',children:[
|
187
|
+
{tag:'td', style:'padding:4px', cls:'ux-filewithtype-type'},
|
188
|
+
{tag:'td', style:'padding:4px', cls:'ux-filewithtype-file'}
|
189
|
+
]}
|
190
|
+
]}, true);
|
191
|
+
|
192
|
+
this.ft.render(t.child('td.ux-filewithtype-type'));
|
193
|
+
this.f.render(t.child('td.ux-filewithtype-file'));
|
194
|
+
|
195
|
+
this.el.dom.removeAttribute("name");
|
196
|
+
|
197
|
+
//
|
198
|
+
// this.tableEl = t;
|
199
|
+
|
200
|
+
// we're rendered flag
|
201
|
+
this.isRendered = true;
|
202
|
+
|
203
|
+
// this.updateHidden();
|
204
|
+
}
|
205
|
+
});
|
206
|
+
|
207
|
+
Ext.reg('filewithtype', Ext.netzke.form.FileWithType);
|
208
|
+
|
209
|
+
/**
|
210
|
+
* @class Ext.ux.form.DateTime
|
211
|
+
* @extends Ext.form.Field
|
212
|
+
*
|
213
|
+
* DateTime field, combination of DateField and TimeField
|
214
|
+
*
|
215
|
+
* @author Ing. Jozef Sak�lo�
|
216
|
+
* @copyright (c) 2008, Ing. Jozef Sak�lo�
|
217
|
+
* @version 2.0
|
218
|
+
* @revision $Id: Ext.ux.form.DateTime.js 513 2009-01-29 19:59:22Z jozo $
|
219
|
+
*
|
220
|
+
* @license Ext.ux.form.DateTime is licensed under the terms of
|
221
|
+
* the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
|
222
|
+
* that the code/component(s) do NOT become part of another Open Source or Commercially
|
223
|
+
* licensed development library or toolkit without explicit permission.
|
224
|
+
*
|
225
|
+
* <p>License details: <a href="http://www.gnu.org/licenses/lgpl.html"
|
226
|
+
* target="_blank">http://www.gnu.org/licenses/lgpl.html</a></p>
|
227
|
+
*
|
228
|
+
* @forum 22661
|
229
|
+
*/
|
230
|
+
|
231
|
+
Ext.ns('Ext.ux.form');
|
232
|
+
|
233
|
+
/**
|
234
|
+
* @constructor
|
235
|
+
* Creates new DateTime
|
236
|
+
* @param {Object} config The config object
|
237
|
+
*/
|
238
|
+
Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {
|
239
|
+
/**
|
240
|
+
* @cfg {String/Object} defaultAutoCreate DomHelper element spec
|
241
|
+
* Let superclass to create hidden field instead of textbox. Hidden will be submittend to server
|
242
|
+
*/
|
243
|
+
defaultAutoCreate:{tag:'input', type:'hidden'}
|
244
|
+
/**
|
245
|
+
* @cfg {Number} timeWidth Width of time field in pixels (defaults to 100)
|
246
|
+
*/
|
247
|
+
,timeWidth:80
|
248
|
+
/**
|
249
|
+
* @cfg {String} dtSeparator Date - Time separator. Used to split date and time (defaults to ' ' (space))
|
250
|
+
*/
|
251
|
+
,dtSeparator:' '
|
252
|
+
/**
|
253
|
+
* @cfg {String} hiddenFormat Format of datetime used to store value in hidden field
|
254
|
+
* and submitted to server (defaults to 'Y-m-d H:i:s' that is mysql format)
|
255
|
+
*/
|
256
|
+
,hiddenFormat:'Y-m-d H:i:s'
|
257
|
+
/**
|
258
|
+
* @cfg {Boolean} otherToNow Set other field to now() if not explicly filled in (defaults to true)
|
259
|
+
*/
|
260
|
+
,otherToNow:true
|
261
|
+
/**
|
262
|
+
* @cfg {Boolean} emptyToNow Set field value to now on attempt to set empty value.
|
263
|
+
* If it is true then setValue() sets value of field to current date and time (defaults to false)
|
264
|
+
*/
|
265
|
+
/**
|
266
|
+
* @cfg {String} timePosition Where the time field should be rendered. 'right' is suitable for forms
|
267
|
+
* and 'below' is suitable if the field is used as the grid editor (defaults to 'right')
|
268
|
+
*/
|
269
|
+
,timePosition:'right' // valid values:'below', 'right'
|
270
|
+
/**
|
271
|
+
* @cfg {String} dateFormat Format of DateField. Can be localized. (defaults to 'm/y/d')
|
272
|
+
*/
|
273
|
+
,dateFormat:'m/d/y'
|
274
|
+
/**
|
275
|
+
* @cfg {String} timeFormat Format of TimeField. Can be localized. (defaults to 'g:i A')
|
276
|
+
*/
|
277
|
+
,timeFormat:'g:i A'
|
278
|
+
/**
|
279
|
+
* @cfg {Object} dateConfig Config for DateField constructor.
|
280
|
+
*/
|
281
|
+
/**
|
282
|
+
* @cfg {Object} timeConfig Config for TimeField constructor.
|
283
|
+
*/
|
284
|
+
|
285
|
+
// {{{
|
286
|
+
/**
|
287
|
+
* @private
|
288
|
+
* creates DateField and TimeField and installs the necessary event handlers
|
289
|
+
*/
|
290
|
+
,initComponent:function() {
|
291
|
+
// call parent initComponent
|
292
|
+
Ext.ux.form.DateTime.superclass.initComponent.call(this);
|
293
|
+
|
294
|
+
// create DateField
|
295
|
+
var dateConfig = Ext.apply({}, {
|
296
|
+
id:this.id + '-date'
|
297
|
+
,format:this.dateFormat || Ext.form.DateField.prototype.format
|
298
|
+
,width:this.timeWidth
|
299
|
+
,selectOnFocus:this.selectOnFocus
|
300
|
+
,listeners:{
|
301
|
+
blur:{scope:this, fn:this.onBlur}
|
302
|
+
,focus:{scope:this, fn:this.onFocus}
|
303
|
+
}
|
304
|
+
}, this.dateConfig);
|
305
|
+
this.df = new Ext.form.DateField(dateConfig);
|
306
|
+
this.df.ownerCt = this;
|
307
|
+
delete(this.dateFormat);
|
308
|
+
|
309
|
+
|
310
|
+
// create TimeField
|
311
|
+
var timeConfig = Ext.apply({}, {
|
312
|
+
id:this.id + '-time'
|
313
|
+
,format:this.timeFormat || Ext.form.TimeField.prototype.format
|
314
|
+
,width:this.timeWidth
|
315
|
+
,selectOnFocus:this.selectOnFocus
|
316
|
+
,listeners:{
|
317
|
+
blur:{scope:this, fn:this.onBlur}
|
318
|
+
,focus:{scope:this, fn:this.onFocus}
|
319
|
+
}
|
320
|
+
}, this.timeConfig);
|
321
|
+
this.tf = new Ext.form.TimeField(timeConfig);
|
322
|
+
this.tf.ownerCt = this;
|
323
|
+
delete(this.timeFormat);
|
324
|
+
|
325
|
+
// relay events
|
326
|
+
this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']);
|
327
|
+
this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);
|
328
|
+
|
329
|
+
} // eo function initComponent
|
330
|
+
// }}}
|
331
|
+
// {{{
|
332
|
+
/**
|
333
|
+
* @private
|
334
|
+
* Renders underlying DateField and TimeField and provides a workaround for side error icon bug
|
335
|
+
*/
|
336
|
+
,onRender:function(ct, position) {
|
337
|
+
// don't run more than once
|
338
|
+
if(this.isRendered) {
|
339
|
+
return;
|
340
|
+
}
|
341
|
+
|
342
|
+
// render underlying hidden field
|
343
|
+
Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);
|
344
|
+
|
345
|
+
// render DateField and TimeField
|
346
|
+
// create bounding table
|
347
|
+
var t;
|
348
|
+
if('below' === this.timePosition || 'bellow' === this.timePosition) {
|
349
|
+
t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
|
350
|
+
{tag:'tr',children:[{tag:'td', style:'padding-bottom:1px', cls:'ux-datetime-date'}]}
|
351
|
+
,{tag:'tr',children:[{tag:'td', cls:'ux-datetime-time'}]}
|
352
|
+
]}, true);
|
353
|
+
}
|
354
|
+
else {
|
355
|
+
t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
|
356
|
+
{tag:'tr',children:[
|
357
|
+
{tag:'td',style:'padding-right:4px', cls:'ux-datetime-date'},{tag:'td', cls:'ux-datetime-time'}
|
358
|
+
]}
|
359
|
+
]}, true);
|
360
|
+
}
|
361
|
+
|
362
|
+
this.tableEl = t;
|
363
|
+
// this.wrap = t.wrap({cls:'x-form-field-wrap'});
|
364
|
+
this.wrap = t.wrap();
|
365
|
+
this.wrap.on("mousedown", this.onMouseDown, this, {delay:10});
|
366
|
+
|
367
|
+
// render DateField & TimeField
|
368
|
+
this.df.render(t.child('td.ux-datetime-date'));
|
369
|
+
this.tf.render(t.child('td.ux-datetime-time'));
|
370
|
+
|
371
|
+
// workaround for IE trigger misalignment bug
|
372
|
+
if(Ext.isIE && Ext.isStrict) {
|
373
|
+
t.select('input').applyStyles({top:0});
|
374
|
+
}
|
375
|
+
|
376
|
+
this.on('specialkey', this.onSpecialKey, this);
|
377
|
+
this.df.el.swallowEvent(['keydown', 'keypress']);
|
378
|
+
this.tf.el.swallowEvent(['keydown', 'keypress']);
|
379
|
+
|
380
|
+
// create icon for side invalid errorIcon
|
381
|
+
if('side' === this.msgTarget) {
|
382
|
+
var elp = this.el.findParent('.x-form-element', 10, true);
|
383
|
+
this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
|
384
|
+
|
385
|
+
this.df.errorIcon = this.errorIcon;
|
386
|
+
this.tf.errorIcon = this.errorIcon;
|
387
|
+
}
|
388
|
+
|
389
|
+
// setup name for submit
|
390
|
+
this.el.dom.name = this.hiddenName || this.name || this.id;
|
391
|
+
|
392
|
+
// prevent helper fields from being submitted
|
393
|
+
this.df.el.dom.removeAttribute("name");
|
394
|
+
this.tf.el.dom.removeAttribute("name");
|
395
|
+
|
396
|
+
// we're rendered flag
|
397
|
+
this.isRendered = true;
|
398
|
+
|
399
|
+
// update hidden field
|
400
|
+
this.updateHidden();
|
401
|
+
|
402
|
+
} // eo function onRender
|
403
|
+
// }}}
|
404
|
+
// {{{
|
405
|
+
/**
|
406
|
+
* @private
|
407
|
+
*/
|
408
|
+
,adjustSize:Ext.BoxComponent.prototype.adjustSize
|
409
|
+
// }}}
|
410
|
+
// {{{
|
411
|
+
/**
|
412
|
+
* @private
|
413
|
+
*/
|
414
|
+
,alignErrorIcon:function() {
|
415
|
+
this.errorIcon.alignTo(this.tableEl, 'tl-tr', [2, 0]);
|
416
|
+
}
|
417
|
+
// }}}
|
418
|
+
// {{{
|
419
|
+
/**
|
420
|
+
* @private initializes internal dateValue
|
421
|
+
*/
|
422
|
+
,initDateValue:function() {
|
423
|
+
this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
|
424
|
+
}
|
425
|
+
// }}}
|
426
|
+
// {{{
|
427
|
+
/**
|
428
|
+
* Calls clearInvalid on the DateField and TimeField
|
429
|
+
*/
|
430
|
+
,clearInvalid:function(){
|
431
|
+
this.df.clearInvalid();
|
432
|
+
this.tf.clearInvalid();
|
433
|
+
} // eo function clearInvalid
|
434
|
+
// }}}
|
435
|
+
// {{{
|
436
|
+
/**
|
437
|
+
* @private
|
438
|
+
* called from Component::destroy.
|
439
|
+
* Destroys all elements and removes all listeners we've created.
|
440
|
+
*/
|
441
|
+
,beforeDestroy:function() {
|
442
|
+
if(this.isRendered) {
|
443
|
+
// this.removeAllListeners();
|
444
|
+
this.wrap.removeAllListeners();
|
445
|
+
this.wrap.remove();
|
446
|
+
this.tableEl.remove();
|
447
|
+
this.df.destroy();
|
448
|
+
this.tf.destroy();
|
449
|
+
}
|
450
|
+
} // eo function beforeDestroy
|
451
|
+
// }}}
|
452
|
+
// {{{
|
453
|
+
/**
|
454
|
+
* Disable this component.
|
455
|
+
* @return {Ext.Component} this
|
456
|
+
*/
|
457
|
+
,disable:function() {
|
458
|
+
if(this.isRendered) {
|
459
|
+
this.df.disabled = this.disabled;
|
460
|
+
this.df.onDisable();
|
461
|
+
this.tf.onDisable();
|
462
|
+
}
|
463
|
+
this.disabled = true;
|
464
|
+
this.df.disabled = true;
|
465
|
+
this.tf.disabled = true;
|
466
|
+
this.fireEvent("disable", this);
|
467
|
+
return this;
|
468
|
+
} // eo function disable
|
469
|
+
// }}}
|
470
|
+
// {{{
|
471
|
+
/**
|
472
|
+
* Enable this component.
|
473
|
+
* @return {Ext.Component} this
|
474
|
+
*/
|
475
|
+
,enable:function() {
|
476
|
+
if(this.rendered){
|
477
|
+
this.df.onEnable();
|
478
|
+
this.tf.onEnable();
|
479
|
+
}
|
480
|
+
this.disabled = false;
|
481
|
+
this.df.disabled = false;
|
482
|
+
this.tf.disabled = false;
|
483
|
+
this.fireEvent("enable", this);
|
484
|
+
return this;
|
485
|
+
} // eo function enable
|
486
|
+
// }}}
|
487
|
+
// {{{
|
488
|
+
/**
|
489
|
+
* @private Focus date filed
|
490
|
+
*/
|
491
|
+
,focus:function() {
|
492
|
+
this.df.focus();
|
493
|
+
} // eo function focus
|
494
|
+
// }}}
|
495
|
+
// {{{
|
496
|
+
/**
|
497
|
+
* @private
|
498
|
+
*/
|
499
|
+
,getPositionEl:function() {
|
500
|
+
return this.wrap;
|
501
|
+
}
|
502
|
+
// }}}
|
503
|
+
// {{{
|
504
|
+
/**
|
505
|
+
* @private
|
506
|
+
*/
|
507
|
+
,getResizeEl:function() {
|
508
|
+
return this.wrap;
|
509
|
+
}
|
510
|
+
// }}}
|
511
|
+
// {{{
|
512
|
+
/**
|
513
|
+
* @return {Date/String} Returns value of this field
|
514
|
+
*/
|
515
|
+
,getValue:function() {
|
516
|
+
// create new instance of date
|
517
|
+
return this.dateValue ? new Date(this.dateValue) : '';
|
518
|
+
} // eo function getValue
|
519
|
+
// }}}
|
520
|
+
// {{{
|
521
|
+
/**
|
522
|
+
* @return {Boolean} true = valid, false = invalid
|
523
|
+
* @private Calls isValid methods of underlying DateField and TimeField and returns the result
|
524
|
+
*/
|
525
|
+
,isValid:function() {
|
526
|
+
return this.df.isValid() && this.tf.isValid();
|
527
|
+
} // eo function isValid
|
528
|
+
// }}}
|
529
|
+
// {{{
|
530
|
+
/**
|
531
|
+
* Returns true if this component is visible
|
532
|
+
* @return {boolean}
|
533
|
+
*/
|
534
|
+
,isVisible : function(){
|
535
|
+
return this.df.rendered && this.df.getActionEl().isVisible();
|
536
|
+
} // eo function isVisible
|
537
|
+
// }}}
|
538
|
+
// {{{
|
539
|
+
/**
|
540
|
+
* @private Handles blur event
|
541
|
+
*/
|
542
|
+
,onBlur:function(f) {
|
543
|
+
// called by both DateField and TimeField blur events
|
544
|
+
|
545
|
+
// revert focus to previous field if clicked in between
|
546
|
+
if(this.wrapClick) {
|
547
|
+
f.focus();
|
548
|
+
this.wrapClick = false;
|
549
|
+
}
|
550
|
+
|
551
|
+
// update underlying value
|
552
|
+
if(f === this.df) {
|
553
|
+
this.updateDate();
|
554
|
+
}
|
555
|
+
else {
|
556
|
+
this.updateTime();
|
557
|
+
}
|
558
|
+
this.updateHidden();
|
559
|
+
|
560
|
+
// fire events later
|
561
|
+
(function() {
|
562
|
+
if(!this.df.hasFocus && !this.tf.hasFocus) {
|
563
|
+
var v = this.getValue();
|
564
|
+
if(String(v) !== String(this.startValue)) {
|
565
|
+
this.fireEvent("change", this, v, this.startValue);
|
566
|
+
}
|
567
|
+
this.hasFocus = false;
|
568
|
+
this.fireEvent('blur', this);
|
569
|
+
}
|
570
|
+
}).defer(100, this);
|
571
|
+
|
572
|
+
} // eo function onBlur
|
573
|
+
// }}}
|
574
|
+
// {{{
|
575
|
+
/**
|
576
|
+
* @private Handles focus event
|
577
|
+
*/
|
578
|
+
,onFocus:function() {
|
579
|
+
if(!this.hasFocus){
|
580
|
+
this.hasFocus = true;
|
581
|
+
this.startValue = this.getValue();
|
582
|
+
this.fireEvent("focus", this);
|
583
|
+
}
|
584
|
+
}
|
585
|
+
// }}}
|
586
|
+
// {{{
|
587
|
+
/**
|
588
|
+
* @private Just to prevent blur event when clicked in the middle of fields
|
589
|
+
*/
|
590
|
+
,onMouseDown:function(e) {
|
591
|
+
if(!this.disabled) {
|
592
|
+
this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
|
593
|
+
}
|
594
|
+
}
|
595
|
+
// }}}
|
596
|
+
// {{{
|
597
|
+
/**
|
598
|
+
* @private
|
599
|
+
* Handles Tab and Shift-Tab events
|
600
|
+
*/
|
601
|
+
,onSpecialKey:function(t, e) {
|
602
|
+
var key = e.getKey();
|
603
|
+
if(key === e.TAB) {
|
604
|
+
if(t === this.df && !e.shiftKey) {
|
605
|
+
e.stopEvent();
|
606
|
+
this.tf.focus();
|
607
|
+
}
|
608
|
+
if(t === this.tf && e.shiftKey) {
|
609
|
+
e.stopEvent();
|
610
|
+
this.df.focus();
|
611
|
+
}
|
612
|
+
}
|
613
|
+
// otherwise it misbehaves in editor grid
|
614
|
+
if(key === e.ENTER) {
|
615
|
+
this.updateValue();
|
616
|
+
}
|
617
|
+
|
618
|
+
} // eo function onSpecialKey
|
619
|
+
// }}}
|
620
|
+
// {{{
|
621
|
+
/**
|
622
|
+
* @private Sets the value of DateField
|
623
|
+
*/
|
624
|
+
,setDate:function(date) {
|
625
|
+
this.df.setValue(date);
|
626
|
+
} // eo function setDate
|
627
|
+
// }}}
|
628
|
+
// {{{
|
629
|
+
/**
|
630
|
+
* @private Sets the value of TimeField
|
631
|
+
*/
|
632
|
+
,setTime:function(date) {
|
633
|
+
this.tf.setValue(date);
|
634
|
+
} // eo function setTime
|
635
|
+
// }}}
|
636
|
+
// {{{
|
637
|
+
/**
|
638
|
+
* @private
|
639
|
+
* Sets correct sizes of underlying DateField and TimeField
|
640
|
+
* With workarounds for IE bugs
|
641
|
+
*/
|
642
|
+
,setSize:function(w, h) {
|
643
|
+
if(!w) {
|
644
|
+
return;
|
645
|
+
}
|
646
|
+
if('below' === this.timePosition) {
|
647
|
+
this.df.setSize(w, h);
|
648
|
+
this.tf.setSize(w, h);
|
649
|
+
if(Ext.isIE) {
|
650
|
+
this.df.el.up('td').setWidth(w);
|
651
|
+
this.tf.el.up('td').setWidth(w);
|
652
|
+
}
|
653
|
+
}
|
654
|
+
else {
|
655
|
+
this.df.setSize(w - this.timeWidth - 4, h);
|
656
|
+
this.tf.setSize(this.timeWidth, h);
|
657
|
+
|
658
|
+
if(Ext.isIE) {
|
659
|
+
this.df.el.up('td').setWidth(w - this.timeWidth - 4);
|
660
|
+
this.tf.el.up('td').setWidth(this.timeWidth);
|
661
|
+
}
|
662
|
+
}
|
663
|
+
} // eo function setSize
|
664
|
+
// }}}
|
665
|
+
// {{{
|
666
|
+
/**
|
667
|
+
* @param {Mixed} val Value to set
|
668
|
+
* Sets the value of this field
|
669
|
+
*/
|
670
|
+
,setValue:function(val) {
|
671
|
+
if(!val && true === this.emptyToNow) {
|
672
|
+
this.setValue(new Date());
|
673
|
+
return;
|
674
|
+
}
|
675
|
+
else if(!val) {
|
676
|
+
this.setDate('');
|
677
|
+
this.setTime('');
|
678
|
+
this.updateValue();
|
679
|
+
return;
|
680
|
+
}
|
681
|
+
if ('number' === typeof val) {
|
682
|
+
val = new Date(val);
|
683
|
+
}
|
684
|
+
else if('string' === typeof val && this.hiddenFormat) {
|
685
|
+
val = Date.parseDate(val, this.hiddenFormat)
|
686
|
+
}
|
687
|
+
val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
|
688
|
+
var da, time;
|
689
|
+
if(val instanceof Date) {
|
690
|
+
this.setDate(val);
|
691
|
+
this.setTime(val);
|
692
|
+
this.dateValue = new Date(val);
|
693
|
+
}
|
694
|
+
else {
|
695
|
+
da = val.split(this.dtSeparator);
|
696
|
+
this.setDate(da[0]);
|
697
|
+
if(da[1]) {
|
698
|
+
if(da[2]) {
|
699
|
+
// add am/pm part back to time
|
700
|
+
da[1] += da[2];
|
701
|
+
}
|
702
|
+
this.setTime(da[1]);
|
703
|
+
}
|
704
|
+
}
|
705
|
+
this.updateValue();
|
706
|
+
} // eo function setValue
|
707
|
+
// }}}
|
708
|
+
// {{{
|
709
|
+
/**
|
710
|
+
* Hide or show this component by boolean
|
711
|
+
* @return {Ext.Component} this
|
712
|
+
*/
|
713
|
+
,setVisible: function(visible){
|
714
|
+
if(visible) {
|
715
|
+
this.df.show();
|
716
|
+
this.tf.show();
|
717
|
+
}else{
|
718
|
+
this.df.hide();
|
719
|
+
this.tf.hide();
|
720
|
+
}
|
721
|
+
return this;
|
722
|
+
} // eo function setVisible
|
723
|
+
// }}}
|
724
|
+
//{{{
|
725
|
+
,show:function() {
|
726
|
+
return this.setVisible(true);
|
727
|
+
} // eo function show
|
728
|
+
//}}}
|
729
|
+
//{{{
|
730
|
+
,hide:function() {
|
731
|
+
return this.setVisible(false);
|
732
|
+
} // eo function hide
|
733
|
+
//}}}
|
734
|
+
// {{{
|
735
|
+
/**
|
736
|
+
* @private Updates the date part
|
737
|
+
*/
|
738
|
+
,updateDate:function() {
|
739
|
+
|
740
|
+
var d = this.df.getValue();
|
741
|
+
if(d) {
|
742
|
+
if(!(this.dateValue instanceof Date)) {
|
743
|
+
this.initDateValue();
|
744
|
+
if(!this.tf.getValue()) {
|
745
|
+
this.setTime(this.dateValue);
|
746
|
+
}
|
747
|
+
}
|
748
|
+
this.dateValue.setMonth(0); // because of leap years
|
749
|
+
this.dateValue.setFullYear(d.getFullYear());
|
750
|
+
this.dateValue.setMonth(d.getMonth(), d.getDate());
|
751
|
+
// this.dateValue.setDate(d.getDate());
|
752
|
+
}
|
753
|
+
else {
|
754
|
+
this.dateValue = '';
|
755
|
+
this.setTime('');
|
756
|
+
}
|
757
|
+
} // eo function updateDate
|
758
|
+
// }}}
|
759
|
+
// {{{
|
760
|
+
/**
|
761
|
+
* @private
|
762
|
+
* Updates the time part
|
763
|
+
*/
|
764
|
+
,updateTime:function() {
|
765
|
+
var t = this.tf.getValue();
|
766
|
+
if(t && !(t instanceof Date)) {
|
767
|
+
t = Date.parseDate(t, this.tf.format);
|
768
|
+
}
|
769
|
+
if(t && !this.df.getValue()) {
|
770
|
+
this.initDateValue();
|
771
|
+
this.setDate(this.dateValue);
|
772
|
+
}
|
773
|
+
if(this.dateValue instanceof Date) {
|
774
|
+
if(t) {
|
775
|
+
this.dateValue.setHours(t.getHours());
|
776
|
+
this.dateValue.setMinutes(t.getMinutes());
|
777
|
+
this.dateValue.setSeconds(t.getSeconds());
|
778
|
+
}
|
779
|
+
else {
|
780
|
+
this.dateValue.setHours(0);
|
781
|
+
this.dateValue.setMinutes(0);
|
782
|
+
this.dateValue.setSeconds(0);
|
783
|
+
}
|
784
|
+
}
|
785
|
+
} // eo function updateTime
|
786
|
+
// }}}
|
787
|
+
// {{{
|
788
|
+
/**
|
789
|
+
* @private Updates the underlying hidden field value
|
790
|
+
*/
|
791
|
+
,updateHidden:function() {
|
792
|
+
if(this.isRendered) {
|
793
|
+
var value = this.dateValue instanceof Date ? this.dateValue.format(this.hiddenFormat) : '';
|
794
|
+
this.el.dom.value = value;
|
795
|
+
}
|
796
|
+
}
|
797
|
+
// }}}
|
798
|
+
// {{{
|
799
|
+
/**
|
800
|
+
* @private Updates all of Date, Time and Hidden
|
801
|
+
*/
|
802
|
+
,updateValue:function() {
|
803
|
+
|
804
|
+
this.updateDate();
|
805
|
+
this.updateTime();
|
806
|
+
this.updateHidden();
|
807
|
+
|
808
|
+
return;
|
809
|
+
} // eo function updateValue
|
810
|
+
// }}}
|
811
|
+
// {{{
|
812
|
+
/**
|
813
|
+
* @return {Boolean} true = valid, false = invalid
|
814
|
+
* calls validate methods of DateField and TimeField
|
815
|
+
*/
|
816
|
+
,validate:function() {
|
817
|
+
return this.df.validate() && this.tf.validate();
|
818
|
+
} // eo function validate
|
819
|
+
// }}}
|
820
|
+
// {{{
|
821
|
+
/**
|
822
|
+
* Returns renderer suitable to render this field
|
823
|
+
* @param {Object} Column model config
|
824
|
+
*/
|
825
|
+
,renderer: function(field) {
|
826
|
+
var format = field.editor.dateFormat || Ext.ux.form.DateTime.prototype.dateFormat;
|
827
|
+
format += ' ' + (field.editor.timeFormat || Ext.ux.form.DateTime.prototype.timeFormat);
|
828
|
+
var renderer = function(val) {
|
829
|
+
var retval = Ext.util.Format.date(val, format);
|
830
|
+
return retval;
|
831
|
+
};
|
832
|
+
return renderer;
|
833
|
+
} // eo function renderer
|
834
|
+
// }}}
|
835
|
+
|
836
|
+
}); // eo extend
|
837
|
+
|
838
|
+
// register xtype
|
839
|
+
Ext.reg('xdatetime', Ext.ux.form.DateTime);
|
840
|
+
|
841
|
+
// eof
|
842
|
+
|