Meta Box - Version 4.2

Version Description

  • Bug fix: save only last element of select field with multiple values. Link
  • Improvement: add js_options attribute for date, datetime, time fields to adjust jQuery date/datetime picker options. See demo/demo.php for usage
  • Improvement: add options attribute for wysiwyg. You now can pass arguments same as for wp_editor function
  • Improvement: clone feature now works with checkbox_list and select with multiple values
  • Improvement: add rwmb-{$field_type}-wrapper class to field markup
  • Improvement: Add [rwmb_meta meta_key="..."] shortcode. Attributes are the same as rwmb_meta function.
  • Code refactored
Download this release

Release Info

Developer rilwis
Plugin Icon 128x128 Meta Box
Version 4.2
Comparing to
See all releases

Code changes from version 4.1.11 to 4.2

css/plupload-image.css CHANGED
@@ -1,15 +1,6 @@
1
  div.rwmb-drag-drop {
2
  border: 4px dashed #ddd;
3
- }
4
- div.rwmb-drag-drop-inside {
5
- margin: 50px auto;
6
- }
7
- div.rwmb-drag-drop-inside p {
8
- text-align: center;
9
- display: block;
10
- font-size: 20px;
11
- margin: 5px 0;
12
- color: #aaa;
13
  }
14
 
15
  div.rwmb-image-uploading-bar {
@@ -18,11 +9,9 @@ div.rwmb-image-uploading-bar {
18
  height: 0%;
19
  bottom: 0;
20
  }
21
-
22
  div.rwmb-image-uploading-status {
23
  position: absolute;
24
  }
25
-
26
  li.rwmb-image-error {
27
  border: 3px solid #c00;
28
  background: #903838;
1
  div.rwmb-drag-drop {
2
  border: 4px dashed #ddd;
3
+ height: 200px;
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
  div.rwmb-image-uploading-bar {
9
  height: 0%;
10
  bottom: 0;
11
  }
 
12
  div.rwmb-image-uploading-status {
13
  position: absolute;
14
  }
 
15
  li.rwmb-image-error {
16
  border: 3px solid #c00;
17
  background: #903838;
css/style.css CHANGED
@@ -1,22 +1,10 @@
1
  /* =Styles for 'normal' meta boxes
2
  -------------------------------------------------------------- */
3
 
4
- /* BEGIN jquery.validate styles */
5
- label.error {
6
- padding-left: 3px;
7
- color: red;
8
- }
9
-
10
- input.error, textarea.error, select.error {
11
- border: #CC0000 solid 1px !important;
12
- background-color: #FFEBE8 !important;
13
- }
14
- /* END jquery.validate styles */
15
-
16
  .rwmb-field {
17
  margin: 10px 0;
18
  }
19
- .rwmb-label,
20
  .rwmb-input {
21
  display: inline-block;
22
  vertical-align: top;
@@ -24,11 +12,14 @@ input.error, textarea.error, select.error {
24
  .rwmb-label {
25
  width: 24%;
26
  }
27
- .rwmb-label > .required
28
- {
29
- color: red;
30
- font-weight:bold;
31
- }
 
 
 
32
  /* 75% if field has label, 100% if no label */
33
  .rwmb-input {
34
  width: 100%;
@@ -37,36 +28,34 @@ input.error, textarea.error, select.error {
37
  width: 75%;
38
  }
39
  .rwmb-input h4 {
40
- margin-top: 0;
41
  }
42
  .rwmb-textarea {
43
  resize: vertical;
44
  }
 
 
45
  .rwmb-clone {
46
  min-height: 24px;
47
  }
48
- .rwmb-clone > input[type="radio"],
49
- .rwmb-clone > input[type="checkbox"] {
50
- margin: 6px 0 0 4px;
51
- }
52
- /* fix width to not overlap button for cloned sliders */
53
- .rwmb-clone .rwmb-slider {
54
- width: 80%;
55
- margin: 6px 0 0;
56
- }
57
- /* fix buttons after sliders */
58
- .clearfix + .rwmb-button {
59
- margin-top: -16px;
60
- }
61
  .rwmb-button {
62
  display: inline;
63
  float: right;
64
  }
65
- /* Hidden labels, :input fields, buttons */
66
- .rwmb-label.hidden,
67
- .rwmb-input.hidden,
68
- .hidden .rwmb-button {
69
- display: none;
 
 
 
 
 
70
  }
71
 
72
  /* Fix empty block below admin footer (issue #24) */
@@ -74,10 +63,22 @@ input.error, textarea.error, select.error {
74
  display: none;
75
  }
76
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  /* =Styles for 'side' meta boxes
78
  -------------------------------------------------------------- */
79
 
80
- #side-sortables .rwmb-label,
81
  #side-sortables .rwmb-input {
82
  width: 100%;
83
  }
1
  /* =Styles for 'normal' meta boxes
2
  -------------------------------------------------------------- */
3
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  .rwmb-field {
5
  margin: 10px 0;
6
  }
7
+ .rwmb-label,
8
  .rwmb-input {
9
  display: inline-block;
10
  vertical-align: top;
12
  .rwmb-label {
13
  width: 24%;
14
  }
15
+ .rwmb-label.required {
16
+ font-weight: bold;
17
+ }
18
+ .rwmb-label.required > span
19
+ {
20
+ color: #c00;
21
+ }
22
+
23
  /* 75% if field has label, 100% if no label */
24
  .rwmb-input {
25
  width: 100%;
28
  width: 75%;
29
  }
30
  .rwmb-input h4 {
31
+ margin: 0;
32
  }
33
  .rwmb-textarea {
34
  resize: vertical;
35
  }
36
+
37
+ /* Clone */
38
  .rwmb-clone {
39
  min-height: 24px;
40
  }
41
+ .rwmb-clone > input[type="radio"],
42
+ .rwmb-clone > input[type="checkbox"] {
43
+ margin: 6px 0 0 4px;
44
+ }
 
 
 
 
 
 
 
 
 
45
  .rwmb-button {
46
  display: inline;
47
  float: right;
48
  }
49
+
50
+ /* Fix width to not overlap button for cloned sliders */
51
+ .rwmb-clone .rwmb-slider {
52
+ width: 80%;
53
+ margin: 6px 0 0;
54
+ }
55
+
56
+ /* Fix buttons after sliders */
57
+ .clearfix + .rwmb-button {
58
+ margin-top: -16px;
59
  }
60
 
61
  /* Fix empty block below admin footer (issue #24) */
63
  display: none;
64
  }
65
 
66
+ /* jQuery validation */
67
+ label.error {
68
+ padding-left: 3px;
69
+ color: red;
70
+ }
71
+ input.error,
72
+ textarea.error,
73
+ select.error {
74
+ border: #c00 solid 1px !important;
75
+ background: #ffebe8 !important;
76
+ }
77
+
78
  /* =Styles for 'side' meta boxes
79
  -------------------------------------------------------------- */
80
 
81
+ #side-sortables .rwmb-label,
82
  #side-sortables .rwmb-input {
83
  width: 100%;
84
  }
demo/date-time-js-options.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ add_action( 'admin_init', 'YOUR_PREFIX_register_meta_boxes' );
3
+
4
+ function YOUR_PREFIX_register_meta_boxes()
5
+ {
6
+ if ( !class_exists( 'RW_Meta_Box' ) )
7
+ return;
8
+
9
+ $prefix = 'YOUR_PREFIX_';
10
+ $meta_box = array(
11
+ 'title' => 'Date Time Picker With JS Options',
12
+
13
+ 'fields' => array(
14
+ array(
15
+ 'name' => 'Date',
16
+ 'id' => $prefix . 'date',
17
+ 'type' => 'date',
18
+
19
+ // jQuery date picker options. See here http://jqueryui.com/demos/datepicker
20
+ 'js_options' => array(
21
+ 'appendText' => '(yyyy-mm-dd)',
22
+ 'autoSize' => true,
23
+ 'buttonText' => 'Select Date',
24
+ 'dateFormat' => 'yy-mm-dd',
25
+ 'numberOfMonths' => 2,
26
+ 'showButtonPanel' => true,
27
+ ),
28
+ ),
29
+ array(
30
+ 'name' => 'Datetime',
31
+ 'id' => $prefix . 'datetime',
32
+ 'type' => 'datetime',
33
+
34
+ // jQuery datetime picker options. See here http://trentrichardson.com/examples/timepicker/
35
+ 'js_options' => array(
36
+ 'stepMinute' => 15,
37
+ 'showTimepicker' => true,
38
+ ),
39
+ ),
40
+ array(
41
+ 'name' => 'Time',
42
+ 'id' => $prefix . 'time',
43
+ 'type' => 'time',
44
+
45
+ // jQuery datetime picker options. See here http://trentrichardson.com/examples/timepicker/
46
+ 'js_options' => array(
47
+ 'stepMinute' => 5,
48
+ 'showSecond' => true,
49
+ 'stepSecond' => 10,
50
+ ),
51
+ ),
52
+ ),
53
+ );
54
+
55
+ new RW_Meta_Box( $meta_box );
56
+ }
demo/demo.php CHANGED
@@ -28,13 +28,13 @@ $meta_boxes = array();
28
  // 1st meta box
29
  $meta_boxes[] = array(
30
  // Meta box id, UNIQUE per meta box. Optional since 4.1.5
31
- 'id' => 'personal',
32
 
33
  // Meta box title - Will appear at the drag and drop handle bar. Required.
34
- 'title' => 'Personal Information',
35
 
36
  // Post types, accept custom post types as well - DEFAULT is array('post'). Optional.
37
- 'pages' => array( 'post', 'slider' ),
38
 
39
  // Where the meta box appear: normal (default), advanced, side. Optional.
40
  'context' => 'normal',
@@ -47,114 +47,83 @@ $meta_boxes[] = array(
47
  // TEXT
48
  array(
49
  // Field name - Will be used as label
50
- 'name' => 'Full name',
51
  // Field ID, i.e. the meta key
52
- 'id' => $prefix . 'fname',
53
  // Field description (optional)
54
- 'desc' => 'Format: First Last',
55
- // CLONES: Add to make the field cloneable (i.e. have multiple value)
56
- 'clone' => true,
57
  'type' => 'text',
58
  // Default value (optional)
59
- 'std' => 'Anh Tran',
 
 
60
  ),
61
- // DATE
62
  array(
63
- 'name' => 'Day of Birth',
64
- 'id' => "{$prefix}dob",
65
- 'type' => 'date',
66
- // Date format, default yy-mm-dd. Optional. See: http://goo.gl/po8vf
67
- 'format' => 'd MM, yy',
68
  ),
69
  // RADIO BUTTONS
70
  array(
71
- 'name' => 'Gender',
72
- 'id' => "{$prefix}gender",
73
- 'type' => 'radio',
74
  // Array of 'value' => 'Label' pairs for radio options.
75
- // Note: the 'key' is stored in meta field, not the 'value'
76
- 'options' => array(
77
- 'm' => 'Male',
78
- 'f' => 'Female',
79
  ),
80
- 'std' => 'm',
81
- 'desc' => 'Need an explaination?',
82
- ),
83
- // TEXTAREA
84
- array(
85
- 'name' => 'Bio',
86
- 'desc' => "What's your professions? What have you done so far?",
87
- 'id' => "{$prefix}bio",
88
- 'type' => 'textarea',
89
- 'std' => "I'm a special agent from Vietnam.",
90
- 'cols' => '40',
91
- 'rows' => '8',
92
  ),
93
  // SELECT BOX
94
  array(
95
- 'name' => 'Where do you live?',
96
- 'id' => "{$prefix}place",
97
- 'type' => 'select',
98
  // Array of 'value' => 'Label' pairs for select box
99
- 'options' => array(
100
- 'usa' => 'USA',
101
- 'vn' => 'Vietnam',
102
  ),
103
  // Select multiple values, optional. Default is false.
104
- 'multiple' => true,
105
- // Default value, can be string (single value) or array (for both single and multiple values)
106
- 'std' => array( 'vn' ),
107
- 'desc' => 'Select the current place, not in the past',
108
- ),
109
- // CHECKBOX
110
- array(
111
- 'name' => 'About WordPress',
112
- 'id' => "{$prefix}love_wp",
113
- 'type' => 'checkbox',
114
- 'desc' => 'I love WordPress',
115
- // Value can be 0 or 1
116
- 'std' => 1,
117
  ),
118
  // HIDDEN
119
  array(
120
- 'id' => "{$prefix}invisible",
121
  'type' => 'hidden',
122
  // Hidden field must have predefined value
123
- 'std' => "No, I'm visible",
124
  ),
125
  // PASSWORD
126
  array(
127
- 'name' => 'Your favorite password',
128
- 'id' => "{$prefix}pass",
129
  'type' => 'password',
130
  ),
131
- // CONFIRM PASSWORD
132
  array(
133
- 'name' => 'Confirm your password',
134
- 'id' => "{$prefix}pass_confirm",
135
- 'type' => 'password',
 
 
 
136
  ),
137
  ),
138
  'validation' => array(
139
  'rules' => array(
140
- // optionally make post/page title required
141
- 'post_title' => array(
142
- 'required' => true,
143
- ),
144
- $prefix . 'fname' => array(
145
- 'required' => true,
146
- ),
147
- "{$prefix}pass" => array(
148
  'required' => true,
149
  'minlength' => 7,
150
  ),
151
  ),
152
  // optional override of default jquery.validate messages
153
  'messages' => array(
154
- $prefix . 'fname' => array(
155
- 'required' => 'Your name is required',
156
- ),
157
- "{$prefix}pass" => array(
158
  'required' => 'Password is required',
159
  'minlength' => 'Password must be at least 7 characters',
160
  ),
@@ -164,96 +133,79 @@ $meta_boxes[] = array(
164
 
165
  // 2nd meta box
166
  $meta_boxes[] = array(
167
- 'id' => 'additional',
168
- 'title' => 'Additional Information',
169
- 'pages' => array( 'post', 'film', 'slider' ),
170
 
171
  'fields' => array(
172
- // WYSIWYG/RICH TEXT EDITOR
173
- array(
174
- 'name' => 'Your thoughts about Deluxe Blog Tips',
175
- 'id' => "{$prefix}thoughts",
176
- 'type' => 'wysiwyg',
177
- 'std' => "It's great!",
178
- 'desc' => 'Do you think so?',
179
- ),
180
- // FILE UPLOAD
181
  array(
182
- 'name' => 'Upload your source code',
183
- 'desc' => 'Any modified code, or extending code',
184
- 'id' => "{$prefix}code",
185
- 'type' => 'file',
 
 
186
  ),
187
- // IMAGE UPLOAD
188
  array(
189
- 'name' => 'Screenshots',
190
- 'desc' => 'Screenshots of problems, warnings, etc.',
191
- 'id' => "{$prefix}screenshot",
192
- 'type' => 'image',
 
 
 
 
 
 
 
 
193
  ),
194
- // PLUPLOAD IMAGE UPLOAD (WP 3.3+)
195
  array(
196
- 'name' => 'Screenshots (plupload)',
197
- 'desc' => 'Screenshots of problems, warnings, etc.',
198
- 'id' => "{$prefix}screenshot2",
199
- 'type' => 'plupload_image',
200
- 'max_file_uploads' => 4,
 
 
 
 
201
  ),
202
- // THICKBOX IMAGE UPLOAD (WP 3.3+)
203
  array(
204
- 'name' => 'Screenshots (thickbox upload)',
205
- 'desc' => 'Screenshots of problems, warnings, etc.',
206
- 'id' => "{$prefix}screenshot3",
207
- 'type' => 'thickbox_image',
208
- )
209
- )
210
- );
211
-
212
- // 3rd meta box
213
- $meta_boxes[] = array(
214
- 'id' => 'survey',
215
- 'title' => 'Survey',
216
- 'pages' => array( 'post', 'slider', 'page' ),
217
 
218
- 'fields' => array(
 
 
 
 
 
 
219
  // COLOR
220
  array(
221
- 'name' => 'Your favorite color',
222
  'id' => "{$prefix}color",
223
  'type' => 'color',
224
  ),
225
  // CHECKBOX LIST
226
  array(
227
- 'name' => 'Your hobby',
228
- 'id' => "{$prefix}hobby",
229
  'type' => 'checkbox_list',
230
  // Options of checkboxes, in format 'value' => 'Label'
231
  'options' => array(
232
- 'reading' => 'Books',
233
- 'sport' => 'Gym, Boxing',
234
  ),
235
- 'desc' => 'What do you do in free time?',
236
- ),
237
- // TIME
238
- array(
239
- 'name' => 'When do you get up?',
240
- 'id' => "{$prefix}getdown",
241
- 'type' => 'time',
242
- // Time format, default hh:mm. Optional. @link See: http://goo.gl/hXHWz
243
- 'format' => 'hh:mm:ss',
244
- ),
245
- // DATETIME
246
- array(
247
- 'name' => 'When were you born?',
248
- 'id' => "{$prefix}born_time",
249
- 'type' => 'datetime',
250
- // Time format, default yy-mm-dd hh:mm. Optional. @link See: http://goo.gl/hXHWz
251
- 'format' => 'hh:mm:ss',
252
  ),
253
  // TAXONOMY
254
  array(
255
- 'name' => 'Categories',
256
- 'id' => "{$prefix}cats",
257
  'type' => 'taxonomy',
258
  'options' => array(
259
  // Taxonomy name
@@ -263,12 +215,49 @@ $meta_boxes[] = array(
263
  // Additional arguments for get_terms() function. Optional
264
  'args' => array()
265
  ),
266
- 'desc' => 'Choose One Category',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  ),
268
  )
269
  );
270
 
271
-
272
  /********************* META BOX REGISTERING ***********************/
273
 
274
  /**
@@ -278,15 +267,14 @@ $meta_boxes[] = array(
278
  */
279
  function YOUR_PREFIX_register_meta_boxes()
280
  {
281
- global $meta_boxes;
282
-
283
  // Make sure there's no errors when the plugin is deactivated or during upgrade
284
- if ( class_exists( 'RW_Meta_Box' ) )
 
 
 
 
285
  {
286
- foreach ( $meta_boxes as $meta_box )
287
- {
288
- new RW_Meta_Box( $meta_box );
289
- }
290
  }
291
  }
292
  // Hook to 'admin_init' to make sure the meta box class is loaded before
28
  // 1st meta box
29
  $meta_boxes[] = array(
30
  // Meta box id, UNIQUE per meta box. Optional since 4.1.5
31
+ 'id' => 'standard',
32
 
33
  // Meta box title - Will appear at the drag and drop handle bar. Required.
34
+ 'title' => 'Standard Fields',
35
 
36
  // Post types, accept custom post types as well - DEFAULT is array('post'). Optional.
37
+ 'pages' => array( 'post', 'page' ),
38
 
39
  // Where the meta box appear: normal (default), advanced, side. Optional.
40
  'context' => 'normal',
47
  // TEXT
48
  array(
49
  // Field name - Will be used as label
50
+ 'name' => 'Text',
51
  // Field ID, i.e. the meta key
52
+ 'id' => "{$prefix}text",
53
  // Field description (optional)
54
+ 'desc' => 'Text description',
 
 
55
  'type' => 'text',
56
  // Default value (optional)
57
+ 'std' => 'Default text value',
58
+ // CLONES: Add to make the field cloneable (i.e. have multiple value)
59
+ 'clone' => true,
60
  ),
61
+ // CHECKBOX
62
  array(
63
+ 'name' => 'Checkbox',
64
+ 'id' => "{$prefix}checkbox",
65
+ 'type' => 'checkbox',
66
+ // Value can be 0 or 1
67
+ 'std' => 1,
68
  ),
69
  // RADIO BUTTONS
70
  array(
71
+ 'name' => 'Radio',
72
+ 'id' => "{$prefix}radio",
73
+ 'type' => 'radio',
74
  // Array of 'value' => 'Label' pairs for radio options.
75
+ // Note: the 'value' is stored in meta field, not the 'Label'
76
+ 'options' => array(
77
+ 'value1' => 'Label1',
78
+ 'value2' => 'Label2',
79
  ),
 
 
 
 
 
 
 
 
 
 
 
 
80
  ),
81
  // SELECT BOX
82
  array(
83
+ 'name' => 'Select',
84
+ 'id' => "{$prefix}select",
85
+ 'type' => 'select',
86
  // Array of 'value' => 'Label' pairs for select box
87
+ 'options' => array(
88
+ 'value1' => 'Label1',
89
+ 'value2' => 'Label2',
90
  ),
91
  // Select multiple values, optional. Default is false.
92
+ 'multiple' => false,
 
 
 
 
 
 
 
 
 
 
 
 
93
  ),
94
  // HIDDEN
95
  array(
96
+ 'id' => "{$prefix}hidden",
97
  'type' => 'hidden',
98
  // Hidden field must have predefined value
99
+ 'std' => 'Hidden value',
100
  ),
101
  // PASSWORD
102
  array(
103
+ 'name' => 'Password',
104
+ 'id' => "{$prefix}password",
105
  'type' => 'password',
106
  ),
107
+ // TEXTAREA
108
  array(
109
+ 'name' => 'Textarea',
110
+ 'desc' => 'Textarea description',
111
+ 'id' => "{$prefix}textarea",
112
+ 'type' => 'textarea',
113
+ 'cols' => '20',
114
+ 'rows' => '3',
115
  ),
116
  ),
117
  'validation' => array(
118
  'rules' => array(
119
+ "{$prefix}password" => array(
 
 
 
 
 
 
 
120
  'required' => true,
121
  'minlength' => 7,
122
  ),
123
  ),
124
  // optional override of default jquery.validate messages
125
  'messages' => array(
126
+ "{$prefix}password" => array(
 
 
 
127
  'required' => 'Password is required',
128
  'minlength' => 'Password must be at least 7 characters',
129
  ),
133
 
134
  // 2nd meta box
135
  $meta_boxes[] = array(
136
+ 'title' => 'Advanced Fields',
 
 
137
 
138
  'fields' => array(
139
+ // NUMBER
 
 
 
 
 
 
 
 
140
  array(
141
+ 'name' => 'Number',
142
+ 'id' => "{$prefix}number",
143
+ 'type' => 'number',
144
+
145
+ 'min' => 0,
146
+ 'step' => 5,
147
  ),
148
+ // DATE
149
  array(
150
+ 'name' => 'Date picker',
151
+ 'id' => "{$prefix}date",
152
+ 'type' => 'date',
153
+
154
+ // jQuery date picker options. See here http://jqueryui.com/demos/datepicker
155
+ 'js_options' => array(
156
+ 'appendText' => '(yyyy-mm-dd)',
157
+ 'dateFormat' => 'yy-mm-dd',
158
+ 'changeMonth' => true,
159
+ 'changeYear' => true,
160
+ 'showButtonPanel' => true,
161
+ ),
162
  ),
163
+ // DATETIME
164
  array(
165
+ 'name' => 'Datetime picker',
166
+ 'id' => $prefix . 'datetime',
167
+ 'type' => 'datetime',
168
+
169
+ // jQuery datetime picker options. See here http://trentrichardson.com/examples/timepicker/
170
+ 'js_options' => array(
171
+ 'stepMinute' => 15,
172
+ 'showTimepicker' => true,
173
+ ),
174
  ),
175
+ // TIME
176
  array(
177
+ 'name' => 'Time picker',
178
+ 'id' => $prefix . 'time',
179
+ 'type' => 'time',
 
 
 
 
 
 
 
 
 
 
180
 
181
+ // jQuery datetime picker options. See here http://trentrichardson.com/examples/timepicker/
182
+ 'js_options' => array(
183
+ 'stepMinute' => 5,
184
+ 'showSecond' => true,
185
+ 'stepSecond' => 10,
186
+ ),
187
+ ),
188
  // COLOR
189
  array(
190
+ 'name' => 'Color picker',
191
  'id' => "{$prefix}color",
192
  'type' => 'color',
193
  ),
194
  // CHECKBOX LIST
195
  array(
196
+ 'name' => 'Checkbox list',
197
+ 'id' => "{$prefix}checkbox_list",
198
  'type' => 'checkbox_list',
199
  // Options of checkboxes, in format 'value' => 'Label'
200
  'options' => array(
201
+ 'value1' => 'Label1',
202
+ 'value2' => 'Label2',
203
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  ),
205
  // TAXONOMY
206
  array(
207
+ 'name' => 'Taxonomy',
208
+ 'id' => "{$prefix}taxonomy",
209
  'type' => 'taxonomy',
210
  'options' => array(
211
  // Taxonomy name
215
  // Additional arguments for get_terms() function. Optional
216
  'args' => array()
217
  ),
218
+ ),
219
+ // WYSIWYG/RICH TEXT EDITOR
220
+ array(
221
+ 'name' => 'WYSIWYG / Rich Text Editor',
222
+ 'id' => "{$prefix}wysiwyg",
223
+ 'type' => 'wysiwyg',
224
+ 'std' => 'WYSIWYG default value',
225
+
226
+ // Editor settings, see wp_editor() function: look4wp.com/wp_editor
227
+ 'options' => array(
228
+ 'textarea_rows' => 4,
229
+ 'teeny' => true,
230
+ 'media_buttons' => false,
231
+ ),
232
+ ),
233
+ // FILE UPLOAD
234
+ array(
235
+ 'name' => 'File Upload',
236
+ 'id' => "{$prefix}file",
237
+ 'type' => 'file',
238
+ ),
239
+ // IMAGE UPLOAD
240
+ array(
241
+ 'name' => 'Image Upload',
242
+ 'id' => "{$prefix}image",
243
+ 'type' => 'image',
244
+ ),
245
+ // THICKBOX IMAGE UPLOAD (WP 3.3+)
246
+ array(
247
+ 'name' => 'Thichbox Image Upload',
248
+ 'id' => "{$prefix}thickbox",
249
+ 'type' => 'thickbox_image',
250
+ ),
251
+ // PLUPLOAD IMAGE UPLOAD (WP 3.3+)
252
+ array(
253
+ 'name' => 'Plupload Image Upload',
254
+ 'id' => "{$prefix}plupload",
255
+ 'type' => 'plupload_image',
256
+ 'max_file_uploads' => 4,
257
  ),
258
  )
259
  );
260
 
 
261
  /********************* META BOX REGISTERING ***********************/
262
 
263
  /**
267
  */
268
  function YOUR_PREFIX_register_meta_boxes()
269
  {
 
 
270
  // Make sure there's no errors when the plugin is deactivated or during upgrade
271
+ if ( !class_exists( 'RW_Meta_Box' ) )
272
+ return;
273
+
274
+ global $meta_boxes;
275
+ foreach ( $meta_boxes as $meta_box )
276
  {
277
+ new RW_Meta_Box( $meta_box );
 
 
 
278
  }
279
  }
280
  // Hook to 'admin_init' to make sure the meta box class is loaded before
inc/classes/meta-box.php CHANGED
@@ -56,17 +56,14 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
56
  $this->fields = &$this->meta_box['fields'];
57
  $this->validation = &$this->meta_box['validation'];
58
 
59
- // List of meta box field types
60
- $this->types = array_unique( wp_list_pluck( $this->fields, 'type' ) );
61
-
62
  // Enqueue common styles and scripts
63
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
64
 
65
- foreach ( $this->types as $type )
 
66
  {
67
- $class = self::get_class_name( $type );
68
 
69
- // Add additional actions for fields
70
  if ( method_exists( $class, 'add_actions' ) )
71
  call_user_func( array( $class, 'add_actions' ) );
72
  }
@@ -100,11 +97,11 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
100
  $has_clone = false;
101
  foreach ( $this->fields as $field )
102
  {
103
- if ( self::is_cloneable( $field ) )
104
  $has_clone = true;
105
 
106
  // Enqueue scripts and styles for fields
107
- $class = self::get_class_name( $field['type'] );
108
  if ( method_exists( $class, 'admin_enqueue_scripts' ) )
109
  call_user_func( array( $class, 'admin_enqueue_scripts' ) );
110
  }
@@ -173,7 +170,7 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
173
 
174
  foreach ( $this->fields as $field )
175
  {
176
- $group = ""; // Empty the clone-group field
177
  $type = $field['type'];
178
  $id = $field['id'];
179
  $meta = self::apply_field_class_filters( $field, 'meta', '', $post->ID, $saved );
@@ -190,42 +187,32 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
190
  $begin = apply_filters( "rwmb_{$type}_begin_html", $begin, $field, $meta );
191
  $begin = apply_filters( "rwmb_{$id}_begin_html", $begin, $field, $meta );
192
 
193
- // Separate code for clonable and non-cloneable fields to make easy to maintain
194
 
195
  // Cloneable fields
196
- if ( self::is_cloneable( $field ) )
197
  {
198
  if ( isset( $field['clone-group'] ) )
199
  $group = " clone-group='{$field['clone-group']}'";
200
 
201
- if ( ! is_array( $field['field_name'] ) )
202
- $field['field_name'] = (array) $field['field_name'];
203
-
204
  $meta = (array) $meta;
205
 
206
- foreach ( array_keys( $meta ) as $i )
207
- $field['field_name'][$i] = $field['id'] . "[{$i}]";
208
-
209
  $field_html = '';
210
 
211
- $index = 0;
212
- foreach ( $meta as $meta_data )
213
  {
214
- if ( is_array( $field['field_name'] ) )
215
- {
216
- $subfield = $field;
217
- $subfield['field_name'] = $field['field_name'][$index];
218
- }
219
- else
220
- $subfield = $field;
221
 
222
- add_filter( "rwmb_{$id}_html", array( $this, 'add_delete_clone_button' ), 10, 3 );
223
 
224
  // Wrap field HTML in a div with class="rwmb-clone" if needed
225
  $input_html = '<div class="rwmb-clone">';
226
 
227
  // Call separated methods for displaying each type of field
228
- $input_html .= self::apply_field_class_filters( $subfield, 'html', '', $meta_data );
229
 
230
  // Apply filter to field HTML
231
  // 1st filter applies to all fields with the same type
@@ -236,7 +223,6 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
236
  $input_html .= '</div>';
237
 
238
  $field_html .= $input_html;
239
- $index++;
240
  }
241
  }
242
  // Non-cloneable fields
@@ -270,16 +256,20 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
270
  $html = apply_filters( "rwmb_{$id}_wrapper_html", $html, $field, $meta );
271
 
272
  // Display label and input in DIV and allow user-defined classes to be appended
273
- $class = 'rwmb-field';
274
- if ( isset( $field['required'] ) && $field['required'] )
275
- $class .= ' required';
276
- if ( isset( $field['class'] ) )
277
- $class = $this->add_cssclass( $field['class'], $class );
278
-
279
- // Hide the div if field has 'hidden' type
280
  if ( 'hidden' === $field['type'] )
281
- $class = $this->add_cssclass( 'hidden', $class );
282
- echo "<div class='{$class}'{$group}>{$html}</div>";
 
 
 
 
 
 
 
 
 
 
283
  }
284
 
285
  // Include validation settings for this meta-box
@@ -297,14 +287,7 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
297
  else
298
  {
299
  var tempOptions = jQuery.parseJSON( \'' . json_encode( $this->validation ) . '\' );
300
- jQuery.each( tempOptions.rules, function( k, v )
301
- {
302
- rwmb.validationOptions.rules[k] = v;
303
- });
304
- jQuery.each( tempOptions.messages, function( k, v )
305
- {
306
- rwmb.validationOptions.messages[k] = v;
307
- });
308
  };
309
  </script>
310
  ';
@@ -328,22 +311,17 @@ if ( ! class_exists( 'RW_Meta_Box' ) )
328
  */
329
  static function begin_html( $html, $meta, $field )
330
  {
331
- $class = 'rwmb-label';
332
-
333
- if ( ! empty( $field['class'] ) )
334
- $class = self::add_cssclass( $field['class'], $class );
335
-
336
  if ( empty( $field['name'] ) )
337
  return '<div class="rwmb-input">';
338
 
339
- $html = <<<HTML
340
- <div class="{$class}">
341
- <label for="{$field['id']}">{$field['name']}</label>
342
- </div>
343
- <div class="rwmb-input">
344
- HTML;
345
-
346
- return $html;
347
  }
348
 
349
  /**
@@ -360,7 +338,7 @@ HTML;
360
  $id = $field['id'];
361
 
362
  $button = '';
363
- if ( self::is_cloneable( $field ) )
364
  $button = '<a href="#" class="rwmb-button button-primary add-clone">' . __( '+', 'rwmb' ) . '</a>';
365
 
366
  $desc = ! empty( $field['desc'] ) ? "<p id='{$id}_description' class='description'>{$field['desc']}</p>" : '';
@@ -381,11 +359,9 @@ HTML;
381
  *
382
  * @return string $html
383
  */
384
- static function add_delete_clone_button( $html, $field, $meta_data )
385
  {
386
- $id = $field['id'];
387
-
388
- $button = '<a href="#" class="rwmb-button button-secondary remove-clone">' . __( '&#8211;', 'rwmb' ) . '</a>';
389
 
390
  return "{$html}{$button}";
391
  }
@@ -482,15 +458,23 @@ HTML;
482
  {
483
  $name = $field['id'];
484
 
485
- delete_post_meta( $post_id, $name );
486
  if ( '' === $new || array() === $new )
 
 
487
  return;
 
488
 
489
  if ( $field['multiple'] )
490
  {
491
- foreach ( $new as $add_new )
492
  {
493
- add_post_meta( $post_id, $name, $add_new, false );
 
 
 
 
 
 
494
  }
495
  }
496
  else
@@ -513,27 +497,23 @@ HTML;
513
  static function normalize( $meta_box )
514
  {
515
  // Set default values for meta box
516
- $meta_box = wp_parse_args(
517
- $meta_box, array(
518
- 'id' => sanitize_title( $meta_box['title'] ),
519
- 'context' => 'normal',
520
- 'priority' => 'high',
521
- 'pages' => array( 'post' )
522
- )
523
- );
524
 
525
  // Set default values for fields
526
  foreach ( $meta_box['fields'] as &$field )
527
  {
528
- $field = wp_parse_args(
529
- $field, array(
530
- 'multiple' => false,
531
- 'clone' => false,
532
- 'std' => '',
533
- 'desc' => '',
534
- 'format' => '',
535
- )
536
- );
537
 
538
  // Allow field class add/change default field values
539
  $field = self::apply_field_class_filters( $field, 'normalize_field', $field );
@@ -541,7 +521,7 @@ HTML;
541
  // Allow field class to manually change field_name
542
  // @see taxonomy.php for example
543
  if ( ! isset( $field['field_name'] ) )
544
- $field['field_name'] = $field['id'] . ( $field['multiple'] || $field['clone'] ? '[0]' : '' );
545
  }
546
 
547
  return $meta_box;
@@ -550,13 +530,13 @@ HTML;
550
  /**
551
  * Get field class name
552
  *
553
- * @param string $type Field type
554
  *
555
  * @return bool|string Field class name OR false on failure
556
  */
557
- static function get_class_name( $type )
558
  {
559
- $type = ucwords( $type );
560
  $class = "RWMB_{$type}_Field";
561
 
562
  if ( class_exists( $class ) )
@@ -581,7 +561,7 @@ HTML;
581
 
582
  // Call: field class method
583
  // Fallback: RW_Meta_Box method
584
- $class = self::get_class_name( $field['type'] );
585
  if ( method_exists( $class, $method_name ) )
586
  {
587
  $value = call_user_func_array( array( $class, $method_name ), $args );
@@ -609,7 +589,7 @@ HTML;
609
 
610
  // Call: field class method
611
  // Fallback: RW_Meta_Box method
612
- $class = self::get_class_name( $field['type'] );
613
  if ( method_exists( $class, $method_name ) )
614
  {
615
  call_user_func_array( array( $class, $method_name ), $args );
@@ -658,35 +638,5 @@ HTML;
658
  }
659
  return $saved;
660
  }
661
-
662
- /**
663
- * Adds a css class
664
- * Mainly a copy of the core admin menu function
665
- * As the core function is only meant to be used by core internally,
666
- * We copy it here - in case core changes functionality or drops the function.
667
- *
668
- * @param string $add
669
- * @param string $class | Class name - Default: empty
670
- *
671
- * @return string $class
672
- */
673
- static function add_cssclass( $add, $class = '' )
674
- {
675
- $class .= empty( $class ) ? $add : " {$add}";
676
-
677
- return $class;
678
- }
679
-
680
- /**
681
- * Helper function to check for multi/clone field IDs
682
- *
683
- * @param array $field
684
- *
685
- * @return bool False if no cloneable
686
- */
687
- static function is_cloneable( $field )
688
- {
689
- return $field['clone'];
690
- }
691
  }
692
  }
56
  $this->fields = &$this->meta_box['fields'];
57
  $this->validation = &$this->meta_box['validation'];
58
 
 
 
 
59
  // Enqueue common styles and scripts
60
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
61
 
62
+ // Add additional actions for fields
63
+ foreach ( $this->fields as $field )
64
  {
65
+ $class = self::get_class_name( $field );
66
 
 
67
  if ( method_exists( $class, 'add_actions' ) )
68
  call_user_func( array( $class, 'add_actions' ) );
69
  }
97
  $has_clone = false;
98
  foreach ( $this->fields as $field )
99
  {
100
+ if ( $field['clone'] )
101
  $has_clone = true;
102
 
103
  // Enqueue scripts and styles for fields
104
+ $class = self::get_class_name( $field );
105
  if ( method_exists( $class, 'admin_enqueue_scripts' ) )
106
  call_user_func( array( $class, 'admin_enqueue_scripts' ) );
107
  }
170
 
171
  foreach ( $this->fields as $field )
172
  {
173
+ $group = ''; // Empty the clone-group field
174
  $type = $field['type'];
175
  $id = $field['id'];
176
  $meta = self::apply_field_class_filters( $field, 'meta', '', $post->ID, $saved );
187
  $begin = apply_filters( "rwmb_{$type}_begin_html", $begin, $field, $meta );
188
  $begin = apply_filters( "rwmb_{$id}_begin_html", $begin, $field, $meta );
189
 
190
+ // Separate code for cloneable and non-cloneable fields to make easy to maintain
191
 
192
  // Cloneable fields
193
+ if ( $field['clone'] )
194
  {
195
  if ( isset( $field['clone-group'] ) )
196
  $group = " clone-group='{$field['clone-group']}'";
197
 
 
 
 
198
  $meta = (array) $meta;
199
 
 
 
 
200
  $field_html = '';
201
 
202
+ foreach ( $meta as $index => $meta_data )
 
203
  {
204
+ $sub_field = $field;
205
+ $sub_field['field_name'] = $field['field_name'] . "[{$index}]";
206
+ if ( $field['multiple'] )
207
+ $sub_field['field_name'] .= '[]';
 
 
 
208
 
209
+ add_filter( "rwmb_{$id}_html", array( $this, 'add_clone_buttons' ), 10, 3 );
210
 
211
  // Wrap field HTML in a div with class="rwmb-clone" if needed
212
  $input_html = '<div class="rwmb-clone">';
213
 
214
  // Call separated methods for displaying each type of field
215
+ $input_html .= self::apply_field_class_filters( $sub_field, 'html', '', $meta_data );
216
 
217
  // Apply filter to field HTML
218
  // 1st filter applies to all fields with the same type
223
  $input_html .= '</div>';
224
 
225
  $field_html .= $input_html;
 
226
  }
227
  }
228
  // Non-cloneable fields
256
  $html = apply_filters( "rwmb_{$id}_wrapper_html", $html, $field, $meta );
257
 
258
  // Display label and input in DIV and allow user-defined classes to be appended
259
+ $classes = array( 'rwmb-field', "rwmb-{$field['type']}-wrapper" );
 
 
 
 
 
 
260
  if ( 'hidden' === $field['type'] )
261
+ $classes[] = 'hidden';
262
+ if ( !empty( $field['required'] ) )
263
+ $classes[] = 'required';
264
+ if ( !empty( $field['class'] ) )
265
+ $classes[] = $field['class'];
266
+
267
+ printf(
268
+ '<div class="%s"%s>%s</div>',
269
+ implode( ' ', $classes ),
270
+ $group,
271
+ $html
272
+ );
273
  }
274
 
275
  // Include validation settings for this meta-box
287
  else
288
  {
289
  var tempOptions = jQuery.parseJSON( \'' . json_encode( $this->validation ) . '\' );
290
+ jQuery.extend( true, rwmb.validationOptions, tempOptions );
 
 
 
 
 
 
 
291
  };
292
  </script>
293
  ';
311
  */
312
  static function begin_html( $html, $meta, $field )
313
  {
 
 
 
 
 
314
  if ( empty( $field['name'] ) )
315
  return '<div class="rwmb-input">';
316
 
317
+ return sprintf(
318
+ '<div class="rwmb-label">
319
+ <label for="%s">%s</label>
320
+ </div>
321
+ <div class="rwmb-input">',
322
+ $field['id'],
323
+ $field['name']
324
+ );
325
  }
326
 
327
  /**
338
  $id = $field['id'];
339
 
340
  $button = '';
341
+ if ( $field['clone'] )
342
  $button = '<a href="#" class="rwmb-button button-primary add-clone">' . __( '+', 'rwmb' ) . '</a>';
343
 
344
  $desc = ! empty( $field['desc'] ) ? "<p id='{$id}_description' class='description'>{$field['desc']}</p>" : '';
359
  *
360
  * @return string $html
361
  */
362
+ static function add_clone_buttons( $html, $field, $meta_data )
363
  {
364
+ $button = '<a href="#" class="rwmb-button button remove-clone">' . __( '&#8211;', 'rwmb' ) . '</a>';
 
 
365
 
366
  return "{$html}{$button}";
367
  }
458
  {
459
  $name = $field['id'];
460
 
 
461
  if ( '' === $new || array() === $new )
462
+ {
463
+ delete_post_meta( $post_id, $name );
464
  return;
465
+ }
466
 
467
  if ( $field['multiple'] )
468
  {
469
+ foreach ( $new as $new_value )
470
  {
471
+ if ( !in_array( $new_value, $old ) )
472
+ add_post_meta( $post_id, $name, $new_value, false );
473
+ }
474
+ foreach ( $old as $old_value )
475
+ {
476
+ if ( !in_array( $old_value, $new ) )
477
+ delete_post_meta( $post_id, $name, $old_value );
478
  }
479
  }
480
  else
497
  static function normalize( $meta_box )
498
  {
499
  // Set default values for meta box
500
+ $meta_box = wp_parse_args( $meta_box, array(
501
+ 'id' => sanitize_title( $meta_box['title'] ),
502
+ 'context' => 'normal',
503
+ 'priority' => 'high',
504
+ 'pages' => array( 'post' )
505
+ ) );
 
 
506
 
507
  // Set default values for fields
508
  foreach ( $meta_box['fields'] as &$field )
509
  {
510
+ $field = wp_parse_args( $field, array(
511
+ 'multiple' => false,
512
+ 'clone' => false,
513
+ 'std' => '',
514
+ 'desc' => '',
515
+ 'format' => '',
516
+ ) );
 
 
517
 
518
  // Allow field class add/change default field values
519
  $field = self::apply_field_class_filters( $field, 'normalize_field', $field );
521
  // Allow field class to manually change field_name
522
  // @see taxonomy.php for example
523
  if ( ! isset( $field['field_name'] ) )
524
+ $field['field_name'] = $field['id'];
525
  }
526
 
527
  return $meta_box;
530
  /**
531
  * Get field class name
532
  *
533
+ * @param array $field Field array
534
  *
535
  * @return bool|string Field class name OR false on failure
536
  */
537
+ static function get_class_name( $field )
538
  {
539
+ $type = ucwords( $field['type'] );
540
  $class = "RWMB_{$type}_Field";
541
 
542
  if ( class_exists( $class ) )
561
 
562
  // Call: field class method
563
  // Fallback: RW_Meta_Box method
564
+ $class = self::get_class_name( $field );
565
  if ( method_exists( $class, $method_name ) )
566
  {
567
  $value = call_user_func_array( array( $class, $method_name ), $args );
589
 
590
  // Call: field class method
591
  // Fallback: RW_Meta_Box method
592
+ $class = self::get_class_name( $field );
593
  if ( method_exists( $class, $method_name ) )
594
  {
595
  call_user_func_array( array( $class, $method_name ), $args );
638
  }
639
  return $saved;
640
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
  }
642
  }
inc/fields/checkbox-list.php CHANGED
@@ -17,21 +17,70 @@ if ( ! class_exists( 'RWMB_Checkbox_List_Field' ) )
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
- if ( ! is_array( $meta ) )
21
- $meta = (array) $meta;
22
-
23
  $html = array();
24
- $name = "name='{$field['field_name']}'";
25
 
26
- foreach ( $field['options'] as $key => $value )
27
  {
28
- $val = " value='{$key}'";
29
- $checked = checked( in_array( $key, $meta ), true, false );
30
- $html[] = "<label><input type='checkbox' class='rwmb-checkbox-list'{$name}{$val}{$checked} /> {$value}</label>";
 
 
 
 
31
  }
32
  return implode( '<br />', $html );
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  /**
36
  * Normalize parameters for field
37
  *
@@ -42,8 +91,9 @@ if ( ! class_exists( 'RWMB_Checkbox_List_Field' ) )
42
  static function normalize_field( $field )
43
  {
44
  $field['multiple'] = true;
45
- $field['std'] = empty( $field['std'] ) ? array() : $field['std'];
46
- $field['field_name'] = "{$field['id']}[]";
 
47
  return $field;
48
  }
49
  }
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
+ $meta = (array) $meta;
 
 
21
  $html = array();
22
+ $tpl = '<label><input type="checkbox" class="rwmb-checkbox-list" name="%s" value="%s" %s /> %s</label>';
23
 
24
+ foreach ( $field['options'] as $value => $label )
25
  {
26
+ $html[] = sprintf(
27
+ $tpl,
28
+ $field['field_name'],
29
+ $value,
30
+ checked( in_array( $value, $meta ), 1, false ),
31
+ $label
32
+ );
33
  }
34
  return implode( '<br />', $html );
35
  }
36
 
37
+ /**
38
+ * Get meta value
39
+ * If field is cloneable, value is saved as a single entry in DB
40
+ * Otherwise value is saved as multiple entries (for backward compatibility)
41
+ *
42
+ * @see "save" method for better understanding
43
+ *
44
+ * TODO: A good way to ALWAYS save values in single entry in DB, while maintaining backward compatibility
45
+ *
46
+ * @param $meta
47
+ * @param $post_id
48
+ * @param $saved
49
+ * @param $field
50
+ *
51
+ * @return array
52
+ */
53
+ static function meta( $meta, $post_id, $saved, $field )
54
+ {
55
+ return (array) get_post_meta( $post_id, $field['id'], $field['clone'] );
56
+ }
57
+
58
+ /**
59
+ * Save meta value
60
+ * If field is cloneable, value is saved as a single entry in DB
61
+ * Otherwise value is saved as multiple entries (for backward compatibility)
62
+ *
63
+ * TODO: A good way to ALWAYS save values in single entry in DB, while maintaining backward compatibility
64
+ *
65
+ * @param $new
66
+ * @param $old
67
+ * @param $post_id
68
+ * @param $field
69
+ */
70
+ static function save( $new, $old, $post_id, $field )
71
+ {
72
+ if ( !$field['clone'] )
73
+ {
74
+ RW_Meta_Box::save( $new, $old, $post_id, $field );
75
+ return;
76
+ }
77
+
78
+ if ( empty( $new ) )
79
+ delete_post_meta( $post_id, $field['id'] );
80
+ else
81
+ update_post_meta( $post_id, $field['id'], $new );
82
+ }
83
+
84
  /**
85
  * Normalize parameters for field
86
  *
91
  static function normalize_field( $field )
92
  {
93
  $field['multiple'] = true;
94
+ $field['field_name'] = $field['id'];
95
+ if ( !$field['clone'] )
96
+ $field['field_name'] .= '[]';
97
  return $field;
98
  }
99
  }
inc/fields/checkbox.php CHANGED
@@ -17,12 +17,12 @@ if ( ! class_exists( 'RWMB_Checkbox_Field' ) )
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
- $checked = checked( ! empty( $meta ), true, false );
21
- $name = "name='{$field['field_name']}'";
22
- $id = " id='{$field['id']}'";
23
- $html = "<input type='checkbox' class='rwmb-checkbox'{$name}{$id}{$checked} />";
24
-
25
- return $html;
26
  }
27
 
28
  /**
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
+ return sprintf(
21
+ '<input type="checkbox" class="rwmb-checkbox" name="%s" id="%s" value="1" %s />',
22
+ $field['field_name'],
23
+ $field['id'],
24
+ checked( !empty( $meta ), 1, false )
25
+ );
26
  }
27
 
28
  /**
inc/fields/color.php CHANGED
@@ -13,8 +13,8 @@ if ( ! class_exists( 'RWMB_Color_Field' ) )
13
  */
14
  static function admin_enqueue_scripts()
15
  {
16
- wp_enqueue_style( 'rwmb-color', RWMB_CSS_URL.'color.css', array( 'farbtastic' ), RWMB_VER );
17
- wp_enqueue_script( 'rwmb-color', RWMB_JS_URL.'color.js', array( 'farbtastic' ), RWMB_VER, true );
18
  }
19
 
20
  /**
@@ -28,18 +28,45 @@ if ( ! class_exists( 'RWMB_Color_Field' ) )
28
  */
29
  static function html( $html, $meta, $field )
30
  {
31
- if ( empty( $meta ) )
32
- $meta = '#';
33
- $name = " name='{$field['field_name']}'";
34
- $id = isset( $field['clone'] ) && $field['clone'] ? '' : " id='{$field['id']}'";
35
- $value = " value='{$meta}'";
 
 
 
 
36
 
37
- $html = <<<HTML
38
- <input class="rwmb-color" type="text"{$name}{$id}{$value} size="8" />
39
- <div class="rwmb-color-picker"></div>
40
- HTML;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- return $html;
43
  }
44
  }
45
  }
13
  */
14
  static function admin_enqueue_scripts()
15
  {
16
+ wp_enqueue_style( 'rwmb-color', RWMB_CSS_URL . 'color.css', array( 'farbtastic' ), RWMB_VER );
17
+ wp_enqueue_script( 'rwmb-color', RWMB_JS_URL . 'color.js', array( 'farbtastic' ), RWMB_VER, true );
18
  }
19
 
20
  /**
28
  */
29
  static function html( $html, $meta, $field )
30
  {
31
+ return sprintf(
32
+ '<input class="rwmb-color" type="text" name="%s" id="%s" value="%s" size="%s" />
33
+ <div class="rwmb-color-picker"></div>',
34
+ $field['field_name'],
35
+ empty( $field['clone'] ) ? $field['id'] : '',
36
+ $meta,
37
+ $field['size']
38
+ );
39
+ }
40
 
41
+ /**
42
+ * Don't save '#' when no color is chosen
43
+ *
44
+ * @param mixed $new
45
+ * @param mixed $old
46
+ * @param int $post_id
47
+ * @param array $field
48
+ *
49
+ * @return int
50
+ */
51
+ static function value( $new, $old, $post_id, $field )
52
+ {
53
+ return '#' === $new ? '' : $new;
54
+ }
55
+
56
+ /**
57
+ * Normalize parameters for field
58
+ *
59
+ * @param array $field
60
+ *
61
+ * @return array
62
+ */
63
+ static function normalize_field( $field )
64
+ {
65
+ $field = wp_parse_args( $field, array(
66
+ 'size' => 7,
67
+ ) );
68
 
69
+ return $field;
70
  }
71
  }
72
  }
inc/fields/date.php CHANGED
@@ -18,8 +18,6 @@ if ( ! class_exists( 'RWMB_Date_Field' ) )
18
  wp_register_style( 'jquery-ui-theme', "{$url}/jquery.ui.theme.css", array(), '1.8.17' );
19
  wp_enqueue_style( 'jquery-ui-datepicker', "{$url}/jquery.ui.datepicker.css", array( 'jquery-ui-core', 'jquery-ui-theme' ), '1.8.17' );
20
 
21
- $url = RWMB_JS_URL . 'jqueryui';
22
- wp_register_script( 'jquery-ui-datepicker', "{$url}/jquery.ui.datepicker.min.js", array( 'jquery-ui-core' ), '1.8.17', true );
23
  wp_enqueue_script( 'rwmb-date', RWMB_JS_URL . 'date.js', array( 'jquery-ui-datepicker' ), RWMB_VER, true );
24
  }
25
 
@@ -34,15 +32,14 @@ if ( ! class_exists( 'RWMB_Date_Field' ) )
34
  */
35
  static function html( $html, $meta, $field )
36
  {
37
- $name = " name='{$field['field_name']}'";
38
- $id = isset( $field['clone'] ) && $field['clone'] ? '' : " id='{$field['id']}'";
39
- $value = " value='{$meta}'";
40
- $size = " size='{$field['size']}'";
41
- $format = " rel='{$field['format']}'";
42
-
43
- $html = "<input type='text' class='rwmb-date'{$name}{$id}{$value}{$size}{$format} />";
44
-
45
- return $html;
46
  }
47
 
48
  /**
@@ -54,8 +51,18 @@ if ( ! class_exists( 'RWMB_Date_Field' ) )
54
  */
55
  static function normalize_field( $field )
56
  {
57
- $field['format'] = empty( $field['format'] ) ? 'yy-mm-dd' : $field['format'];
58
- $field['size'] = empty( $field['size'] ) ? 10 : $field['size'];
 
 
 
 
 
 
 
 
 
 
59
  return $field;
60
  }
61
  }
18
  wp_register_style( 'jquery-ui-theme', "{$url}/jquery.ui.theme.css", array(), '1.8.17' );
19
  wp_enqueue_style( 'jquery-ui-datepicker', "{$url}/jquery.ui.datepicker.css", array( 'jquery-ui-core', 'jquery-ui-theme' ), '1.8.17' );
20
 
 
 
21
  wp_enqueue_script( 'rwmb-date', RWMB_JS_URL . 'date.js', array( 'jquery-ui-datepicker' ), RWMB_VER, true );
22
  }
23
 
32
  */
33
  static function html( $html, $meta, $field )
34
  {
35
+ return sprintf(
36
+ '<input type="text" class="rwmb-date" name="%s" value="%s" id="%s" size="%s" data-options="%s" />',
37
+ $field['field_name'],
38
+ $meta,
39
+ isset( $field['clone'] ) && $field['clone'] ? '' : $field['id'],
40
+ $field['size'],
41
+ esc_attr( json_encode( $field['js_options'] ) )
42
+ );
 
43
  }
44
 
45
  /**
51
  */
52
  static function normalize_field( $field )
53
  {
54
+ $field = wp_parse_args( $field, array(
55
+ 'size' => 30,
56
+ 'js_options' => array(),
57
+ ) );
58
+
59
+ // Deprecate 'format', but keep it for backward compatible
60
+ // Use 'js_options' instead
61
+ $field['js_options'] = wp_parse_args( $field['js_options'], array(
62
+ 'dateFormat' => empty( $field['format'] ) ? 'yy-mm-dd' : $field['format'],
63
+ 'showButtonPanel' => true,
64
+ ) );
65
+
66
  return $field;
67
  }
68
  }
inc/fields/datetime.php CHANGED
@@ -21,8 +21,6 @@ if ( ! class_exists( 'RWMB_Datetime_Field' ) )
21
  wp_enqueue_style( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.css", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7' );
22
 
23
  $url = RWMB_JS_URL . 'jqueryui';
24
- wp_register_script( 'jquery-ui-datepicker', "{$url}/jquery.ui.datepicker.min.js", array( 'jquery-ui-core' ), '1.8.17', true );
25
- wp_register_script( 'jquery-ui-slider', "{$url}/jquery.ui.slider.min.js", array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse' ), '1.8.17', true );
26
  wp_register_script( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.js", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7', true );
27
  wp_enqueue_script( 'rwmb-datetime', RWMB_JS_URL . 'datetime.js', array( 'jquery-ui-timepicker' ), RWMB_VER, true );
28
  }
@@ -38,16 +36,16 @@ if ( ! class_exists( 'RWMB_Datetime_Field' ) )
38
  */
39
  static function html( $html, $meta, $field )
40
  {
41
- $name = " name='{$field['field_name']}'";
42
- $id = isset( $field['clone'] ) && $field['clone'] ? '' : " id='{$field['id']}'";
43
- $value = " value='{$meta}'";
44
- $size = " size='{$field['size']}'";
45
- $format = " rel='{$field['format']}'";
46
- $html .= "<input type='text' class='rwmb-datetime'{$name}{$id}{$value}{$size}{$format} />";
47
-
48
- return $html;
49
  }
50
-
51
  /**
52
  * Normalize parameters for field
53
  *
@@ -57,8 +55,19 @@ if ( ! class_exists( 'RWMB_Datetime_Field' ) )
57
  */
58
  static function normalize_field( $field )
59
  {
60
- $field['format'] = empty( $field['format'] ) ? 'yy-mm-dd hh:ss' : $field['format'];
61
- $field['size'] = empty( $field['size'] ) ? 20 : $field['size'];
 
 
 
 
 
 
 
 
 
 
 
62
  return $field;
63
  }
64
  }
21
  wp_enqueue_style( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.css", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7' );
22
 
23
  $url = RWMB_JS_URL . 'jqueryui';
 
 
24
  wp_register_script( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.js", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7', true );
25
  wp_enqueue_script( 'rwmb-datetime', RWMB_JS_URL . 'datetime.js', array( 'jquery-ui-timepicker' ), RWMB_VER, true );
26
  }
36
  */
37
  static function html( $html, $meta, $field )
38
  {
39
+ return sprintf(
40
+ '<input type="text" class="rwmb-datetime" name="%s" value="%s" id="%s" size="%s" data-options="%s" />',
41
+ $field['field_name'],
42
+ $meta,
43
+ isset( $field['clone'] ) && $field['clone'] ? '' : $field['id'],
44
+ $field['size'],
45
+ esc_attr( json_encode( $field['js_options'] ) )
46
+ );
47
  }
48
+
49
  /**
50
  * Normalize parameters for field
51
  *
55
  */
56
  static function normalize_field( $field )
57
  {
58
+ $field = wp_parse_args( $field, array(
59
+ 'size' => 30,
60
+ 'js_options' => array(),
61
+ ) );
62
+
63
+ // Deprecate 'format', but keep it for backward compatible
64
+ // Use 'js_options' instead
65
+ $field['js_options'] = wp_parse_args( $field['js_options'], array(
66
+ 'dateFormat' => empty( $field['format'] ) ? 'yy-mm-dd' : $field['format'],
67
+ 'timeFormat' => 'hh:mm',
68
+ 'showButtonPanel' => true,
69
+ ) );
70
+
71
  return $field;
72
  }
73
  }
inc/fields/file.php CHANGED
@@ -55,8 +55,8 @@ if ( ! class_exists( 'RWMB_File_Field' ) )
55
 
56
  check_admin_referer( "rwmb-delete-file_{$field_id}" );
57
 
58
- $ok = delete_post_meta( $post_id, $field_id, $attachment_id );
59
- $ok = $ok && wp_delete_attachment( $attachment_id );
60
 
61
  if ( $ok )
62
  RW_Meta_Box::ajax_response( '', 'success' );
@@ -75,56 +75,66 @@ if ( ! class_exists( 'RWMB_File_Field' ) )
75
  */
76
  static function html( $html, $meta, $field )
77
  {
78
- $i18n_msg = _x( 'Uploaded files', 'file upload', 'rwmb' );
79
- $i18n_del_file = _x( 'Delete this file', 'file upload', 'rwmb' );
80
- $i18n_delete = _x( 'Delete', 'file upload', 'rwmb' );
81
- $i18n_title = _x( 'Upload files', 'file upload', 'rwmb' );
82
- $i18n_more = _x( '+ Add new file', 'file upload', 'rwmb' );
83
 
84
- $html = wp_nonce_field( "rwmb-delete-file_{$field['id']}", "nonce-delete-file_{$field['id']}", false, false );
85
- $html .= "<input type='hidden' class='field-id' value='{$field['id']}' />";
86
 
87
  // Uploaded files
88
  if ( ! empty( $meta ) )
89
  {
90
- $html .= "<h4>{$i18n_msg}</h4>";
91
  $html .= '<ol class="rwmb-uploaded">';
 
92
 
93
  foreach ( $meta as $attachment_id )
94
  {
95
  $attachment = wp_get_attachment_link( $attachment_id );
96
- $html .= "<li>{$attachment} (<a title='{$i18n_del_file}' class='rwmb-delete-file' href='#' rel='{$attachment_id}'>{$i18n_delete}</a>)</li>";
 
 
 
 
 
 
 
97
  }
98
 
99
  $html .= '</ol>';
100
  }
101
 
102
  // Show form upload
103
- $html .= "
104
- <h4>{$i18n_title}</h4>
105
- <div class='new-files'>
106
- <div class='file-input'><input type='file' name='{$field['id']}[]' /></div>
107
- <a class='rwmb-add-file' href='#'><strong>{$i18n_more}</strong></a>
108
- </div>
109
- ";
 
 
 
110
 
111
  return $html;
112
  }
113
 
114
  /**
115
- * Save file field
116
  *
117
  * @param mixed $new
118
  * @param mixed $old
119
  * @param int $post_id
120
  * @param array $field
 
 
121
  */
122
- static function save( $new, $old, $post_id, $field )
123
  {
124
  $name = $field['id'];
125
  if ( empty( $_FILES[ $name ] ) )
126
- return;
127
 
 
128
  $files = self::fix_file_array( $_FILES[ $name ] );
129
 
130
  foreach ( $files as $file_item )
@@ -150,9 +160,11 @@ if ( ! class_exists( 'RWMB_File_Field' ) )
150
  wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file_name ) );
151
 
152
  // Save file ID in meta field
153
- add_post_meta( $post_id, $name, $id, false );
154
  }
155
  }
 
 
156
  }
157
 
158
  /**
55
 
56
  check_admin_referer( "rwmb-delete-file_{$field_id}" );
57
 
58
+ delete_post_meta( $post_id, $field_id, $attachment_id );
59
+ $ok = wp_delete_attachment( $attachment_id );
60
 
61
  if ( $ok )
62
  RW_Meta_Box::ajax_response( '', 'success' );
75
  */
76
  static function html( $html, $meta, $field )
77
  {
78
+ $i18n_delete = _x( 'Delete', 'file upload', 'rwmb' );
79
+ $i18n_title = _x( 'Upload files', 'file upload', 'rwmb' );
80
+ $i18n_more = _x( '+ Add new file', 'file upload', 'rwmb' );
 
 
81
 
82
+ $html = wp_nonce_field( "rwmb-delete-file_{$field['id']}", "nonce-delete-file_{$field['id']}", false, false );
 
83
 
84
  // Uploaded files
85
  if ( ! empty( $meta ) )
86
  {
 
87
  $html .= '<ol class="rwmb-uploaded">';
88
+ $li = '<li>%s (<a title="%s" class="rwmb-delete-file" href="#" data-field_id="%s" data-attachment_id="%s">%s</a>)</li>';
89
 
90
  foreach ( $meta as $attachment_id )
91
  {
92
  $attachment = wp_get_attachment_link( $attachment_id );
93
+ $html .= sprintf(
94
+ $li,
95
+ $attachment,
96
+ $i18n_delete,
97
+ $field['id'],
98
+ $attachment_id,
99
+ $i18n_delete
100
+ );
101
  }
102
 
103
  $html .= '</ol>';
104
  }
105
 
106
  // Show form upload
107
+ $html .= sprintf(
108
+ '<h4>%s</h4>
109
+ <div class="new-files">
110
+ <div class="file-input"><input type="file" name="%s[]" /></div>
111
+ <a class="rwmb-add-file" href="#"><strong>%s</strong></a>
112
+ </div>',
113
+ $i18n_title,
114
+ $field['id'],
115
+ $i18n_more
116
+ );
117
 
118
  return $html;
119
  }
120
 
121
  /**
122
+ * Get meta values to save
123
  *
124
  * @param mixed $new
125
  * @param mixed $old
126
  * @param int $post_id
127
  * @param array $field
128
+ *
129
+ * @return array|mixed
130
  */
131
+ static function value( $new, $old, $post_id, $field )
132
  {
133
  $name = $field['id'];
134
  if ( empty( $_FILES[ $name ] ) )
135
+ return $new;
136
 
137
+ $new = array();
138
  $files = self::fix_file_array( $_FILES[ $name ] );
139
 
140
  foreach ( $files as $file_item )
160
  wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file_name ) );
161
 
162
  // Save file ID in meta field
163
+ $new[] = $id;
164
  }
165
  }
166
+
167
+ return array_unique( array_merge( $old, $new ) );
168
  }
169
 
170
  /**
inc/fields/file_single.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Prevent loading this file directly
3
+ defined( 'ABSPATH' ) || exit;
4
+
5
+ if ( ! class_exists( 'RWMB_File_Field' ) )
6
+ {
7
+ class RWMB_File_Field
8
+ {
9
+ /**
10
+ * Enqueue scripts and styles
11
+ *
12
+ * @return void
13
+ */
14
+ static function admin_enqueue_scripts()
15
+ {
16
+ wp_enqueue_script( 'rwmb-file', RWMB_JS_URL . 'file.js', array( 'jquery', 'wp-ajax-response' ), RWMB_VER, true );
17
+ }
18
+
19
+ /**
20
+ * Add actions
21
+ *
22
+ * @return void
23
+ */
24
+ static function add_actions()
25
+ {
26
+ // Add data encoding type for file uploading
27
+ add_action( 'post_edit_form_tag', array( __CLASS__, 'post_edit_form_tag' ) );
28
+
29
+ // Delete file via Ajax
30
+ add_action( 'wp_ajax_rwmb_delete_file', array( __CLASS__, 'wp_ajax_delete_file' ) );
31
+ }
32
+
33
+ /**
34
+ * Add data encoding type for file uploading
35
+ *
36
+ * @return void
37
+ */
38
+ static function post_edit_form_tag()
39
+ {
40
+ echo ' enctype="multipart/form-data"';
41
+ }
42
+
43
+ /**
44
+ * Ajax callback for deleting files.
45
+ * Modified from a function used by "Verve Meta Boxes" plugin
46
+ *
47
+ * @link http://goo.gl/LzYSq
48
+ * @return void
49
+ */
50
+ static function wp_ajax_delete_file()
51
+ {
52
+ $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
53
+ $field_id = isset( $_POST['field_id'] ) ? $_POST['field_id'] : 0;
54
+ $attachment_id = isset( $_POST['attachment_id'] ) ? intval( $_POST['attachment_id'] ) : 0;
55
+
56
+ check_admin_referer( "rwmb-delete-file_{$field_id}" );
57
+
58
+ delete_post_meta( $post_id, $field_id, $attachment_id );
59
+ $ok = wp_delete_attachment( $attachment_id );
60
+
61
+ if ( $ok )
62
+ RW_Meta_Box::ajax_response( '', 'success' );
63
+ else
64
+ RW_Meta_Box::ajax_response( __( 'Error: Cannot delete file', 'rwmb' ), 'error' );
65
+ }
66
+
67
+ /**
68
+ * Get field HTML
69
+ *
70
+ * @param string $html
71
+ * @param mixed $meta
72
+ * @param array $field
73
+ *
74
+ * @return string
75
+ */
76
+ static function html( $html, $meta, $field )
77
+ {
78
+ $i18n_delete = _x( 'Delete', 'file upload', 'rwmb' );
79
+
80
+ $html = wp_nonce_field( "rwmb-delete-file_{$field['id']}", "nonce-delete-file_{$field['id']}", false, false );
81
+
82
+ if ( $meta )
83
+ {
84
+ $html .= '<ol class="rwmb-uploaded">';
85
+ $li = '<li>%s (<a title="%s" class="rwmb-delete-file" href="#" data-field_id="%s" data-attachment_id="%s">%s</a>)</li>';
86
+
87
+ $attachment = wp_get_attachment_link( $meta );
88
+ $html .= sprintf(
89
+ $li,
90
+ $attachment,
91
+ $i18n_delete,
92
+ $field['id'],
93
+ $meta,
94
+ $i18n_delete
95
+ );
96
+
97
+ $html .= '</ol>';
98
+ }
99
+
100
+ // Show form upload
101
+ $html .= sprintf(
102
+ '<input type="file" name="%s" />',
103
+ $field['field_name']
104
+ );
105
+
106
+ return $html;
107
+ }
108
+
109
+ /**
110
+ * Get meta values to save
111
+ *
112
+ * @param mixed $new
113
+ * @param mixed $old
114
+ * @param int $post_id
115
+ * @param array $field
116
+ *
117
+ * @return array|mixed
118
+ */
119
+ static function value( $new, $old, $post_id, $field )
120
+ {
121
+ $name = $field['id'];
122
+ if ( empty( $_FILES[$name] ) )
123
+ return $new;
124
+
125
+ $new = array();
126
+ if ( $field['clone'] )
127
+ $files = self::fix_file_array( $_FILES[$name] );
128
+ else
129
+ $files = array( $_FILES[$name] );
130
+
131
+ foreach ( $files as $file_item )
132
+ {
133
+ $file = wp_handle_upload( $file_item, array( 'test_form' => false ) );
134
+
135
+ if ( ! isset( $file['file'] ) )
136
+ continue;
137
+
138
+ $file_name = $file['file'];
139
+
140
+ $attachment = array(
141
+ 'post_mime_type' => $file['type'],
142
+ 'guid' => $file['url'],
143
+ 'post_parent' => $post_id,
144
+ 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_name ) ),
145
+ 'post_content' => '',
146
+ );
147
+ $id = wp_insert_attachment( $attachment, $file_name, $post_id );
148
+
149
+ if ( ! is_wp_error( $id ) )
150
+ {
151
+ wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file_name ) );
152
+
153
+ // Save file ID in meta field
154
+ $new[] = $id;
155
+ }
156
+ }
157
+
158
+ return $field['clone'] ? $new : array_shift( $new );
159
+ }
160
+
161
+ /**
162
+ * Fixes the odd indexing of multiple file uploads from the format:
163
+ * $_FILES['field']['key']['index']
164
+ * To the more standard and appropriate:
165
+ * $_FILES['field']['index']['key']
166
+ *
167
+ * @param array $files
168
+ *
169
+ * @return array
170
+ */
171
+ static function fix_file_array( $files )
172
+ {
173
+ $output = array();
174
+ foreach ( $files as $key => $list )
175
+ {
176
+ foreach ( $list as $index => $value )
177
+ {
178
+ $output[$index][$key] = $value;
179
+ }
180
+ }
181
+ return $output;
182
+ }
183
+
184
+ /**
185
+ * Normalize parameters for field
186
+ *
187
+ * @param array $field
188
+ *
189
+ * @return array
190
+ */
191
+ // static function normalize_field( $field )
192
+ // {
193
+ // $field['multiple'] = true;
194
+ // $field['std'] = empty( $field['std'] ) ? array() : $field['std'];
195
+ // return $field;
196
+ // }
197
+ }
198
+ }
inc/fields/hidden.php CHANGED
@@ -6,20 +6,6 @@ if ( ! class_exists( 'RWMB_Hidden_Field' ) )
6
  {
7
  class RWMB_Hidden_Field
8
  {
9
- /**
10
- * Show begin HTML markup for fields
11
- *
12
- * @param string $html
13
- * @param mixed $meta
14
- * @param array $field
15
- *
16
- * @return string
17
- */
18
- static function begin_html( $html, $meta, $field )
19
- {
20
- return '<div class="hidden">';
21
- }
22
-
23
  /**
24
  * Get field HTML
25
  *
@@ -31,12 +17,12 @@ if ( ! class_exists( 'RWMB_Hidden_Field' ) )
31
  */
32
  static function html( $html, $meta, $field )
33
  {
34
- $val = " value='{$meta}'";
35
- $name = " name='{$field['field_name']}'";
36
- $id = " id='{$field['id']}'";
37
- $html .= "<input type='hidden' class='rwmb-hidden'{$name}{$id}{$val} />";
38
-
39
- return $html;
40
  }
41
  }
42
  }
6
  {
7
  class RWMB_Hidden_Field
8
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  /**
10
  * Get field HTML
11
  *
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
+ return sprintf(
21
+ '<input type="hidden" class="rwmb-hidden" name="%s" id="%s" value="%s" />',
22
+ $field['field_name'],
23
+ $field['id'],
24
+ $meta
25
+ );
26
  }
27
  }
28
  }
inc/fields/image.php CHANGED
@@ -75,14 +75,8 @@ if ( ! class_exists( 'RWMB_Image_Field' ) )
75
  */
76
  static function html( $html, $meta, $field )
77
  {
78
- global $wpdb;
79
-
80
- $i18n_msg = _x( 'Uploaded files', 'image upload', 'rwmb' );
81
- $i18n_del_file = _x( 'Delete this file', 'image upload', 'rwmb' );
82
- $i18n_delete = _x( 'Delete', 'image upload', 'rwmb' );
83
- $i18n_edit = _x( 'Edit', 'image upload', 'rwmb' );
84
- $i18n_title = _x( 'Upload files', 'image upload', 'rwmb' );
85
- $i18n_more = _x( '+ Add new image', 'image upload', 'rwmb' );
86
 
87
  $html = wp_nonce_field( "rwmb-delete-file_{$field['id']}", "nonce-delete-file_{$field['id']}", false, false );
88
  $html .= wp_nonce_field( "rwmb-reorder-images_{$field['id']}", "nonce-reorder-images_{$field['id']}", false, false );
@@ -90,39 +84,80 @@ if ( ! class_exists( 'RWMB_Image_Field' ) )
90
 
91
  // Uploaded images
92
  if ( ! empty( $meta ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  {
94
- $html .= "<h4>{$i18n_msg}</h4>";
95
- $html .= "<ul class='rwmb-images rwmb-uploaded'>";
96
-
97
- foreach ( $meta as $image )
98
- {
99
- $src = wp_get_attachment_image_src( $image, 'thumbnail' );
100
- $src = $src[0];
101
- $link = get_edit_post_link( $image );
102
-
103
- $html .= "<li id='item_{$image}'>
104
- <img src='{$src}' />
105
- <div class='rwmb-image-bar'>
106
- <a title='{$i18n_edit}' class='rwmb-edit-file' href='{$link}' target='_blank'>{$i18n_edit}</a> |
107
- <a title='{$i18n_del_file}' class='rwmb-delete-file' href='#' rel='{$image}'>{$i18n_delete}</a>
108
- </div>
109
- </li>";
110
- }
111
-
112
- $html .= '</ul>';
113
  }
114
 
115
- // Show form upload
116
- $html .= "
117
- <h4>{$i18n_title}</h4>
118
- <div class='new-files'>
119
- <div class='file-input'><input type='file' name='{$field['id']}[]' /></div>
120
- <a class='rwmb-add-file' href='#'><strong>{$i18n_more}</strong></a>
121
- </div>";
122
 
123
  return $html;
124
  }
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  /**
127
  * Standard meta retrieval
128
  *
75
  */
76
  static function html( $html, $meta, $field )
77
  {
78
+ $i18n_title = _x( 'Upload images', 'image upload', 'rwmb' );
79
+ $i18n_more = _x( '+ Add new image', 'image upload', 'rwmb' );
 
 
 
 
 
 
80
 
81
  $html = wp_nonce_field( "rwmb-delete-file_{$field['id']}", "nonce-delete-file_{$field['id']}", false, false );
82
  $html .= wp_nonce_field( "rwmb-reorder-images_{$field['id']}", "nonce-reorder-images_{$field['id']}", false, false );
84
 
85
  // Uploaded images
86
  if ( ! empty( $meta ) )
87
+ $html .= self::get_uploaded_images( $meta, $field );
88
+
89
+ // Show form upload
90
+ $html .= sprintf(
91
+ '<h4>%s</h4>
92
+ <div class="new-files">
93
+ <div class="file-input"><input type="file" name="%s[]" /></div>
94
+ <a class="rwmb-add-file" href="#"><strong>%s</strong></a>
95
+ </div>',
96
+ $i18n_title,
97
+ $field['id'],
98
+ $i18n_more
99
+ );
100
+
101
+ return $html;
102
+ }
103
+
104
+ /**
105
+ * Get HTML markup for uploaded images
106
+ *
107
+ * @param array $images
108
+ * @param array $field
109
+ *
110
+ * @return string
111
+ */
112
+ static function get_uploaded_images( $images, $field )
113
+ {
114
+ $html = '<ul class="rwmb-images rwmb-uploaded">';
115
+
116
+ foreach ( $images as $image )
117
  {
118
+ $html .= self::img_html( $image, $field['id'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  }
120
 
121
+ $html .= '</ul>';
 
 
 
 
 
 
122
 
123
  return $html;
124
  }
125
 
126
+ /**
127
+ * Get HTML markup for ONE uploaded image
128
+ *
129
+ * @param int $image Image ID
130
+ * @param int $field_id Field ID, used to delete action
131
+ *
132
+ * @return string
133
+ */
134
+ static function img_html( $image, $field_id )
135
+ {
136
+ $i18n_delete = _x( 'Delete', 'image upload', 'rwmb' );
137
+ $i18n_edit = _x( 'Edit', 'image upload', 'rwmb' );
138
+ $li = '
139
+ <li id="item_%s">
140
+ <img src="%s" />
141
+ <div class="rwmb-image-bar">
142
+ <a title="%s" class="rwmb-edit-file" href="%s" target="_blank">%s</a> |
143
+ <a title="%s" class="rwmb-delete-file" href="#" data-field_id="%s" data-attachment_id="%s">%s</a>
144
+ </div>
145
+ </li>
146
+ ';
147
+
148
+ $src = wp_get_attachment_image_src( $image, 'thumbnail' );
149
+ $src = $src[0];
150
+ $link = get_edit_post_link( $image );
151
+
152
+ return sprintf(
153
+ $li,
154
+ $image,
155
+ $src,
156
+ $i18n_edit, $link, $i18n_edit,
157
+ $i18n_delete, $field_id, $image, $i18n_delete
158
+ );
159
+ }
160
+
161
  /**
162
  * Standard meta retrieval
163
  *
inc/fields/number.php CHANGED
@@ -2,46 +2,45 @@
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
- if ( ! class_exists( 'RWMB_Number_Field' ) )
6
  {
7
- class RWMB_Number_Field
8
- {
9
- /**
10
- * Get field HTML
11
- *
12
- * @param string $html
13
- * @param mixed $meta
14
- * @param array $field
15
- *
16
- * @return string
17
- */
18
- static function html( $html, $meta, $field )
19
- {
20
- $name = " name='{$field['field_name']}'";
21
- $id = isset( $field['clone'] ) && $field['clone'] ? '' : " id='{$field['id']}'";
22
- $value = " value='{$meta}'";
23
- $step = " step='{$field['step']}'";
24
- $min = " min='{$field['min']}'";
 
 
 
 
25
 
26
- $html .= "<input type='number' class='rwmb-number'{$name}{$id}{$value}{$step}{$min} />";
27
-
28
- return $html;
29
- }
30
-
31
- /**
32
- * Normalize parameters for field
33
- *
34
- * @param array $field
35
- *
36
- * @return array
37
- */
38
- static function normalize_field( $field )
39
- {
40
- if ( empty( $field['step'] ) )
41
- $field['step'] = 1;
42
- if ( empty( $field['min'] ) )
43
- $field['min'] = 0;
44
- return $field;
45
- }
46
- }
47
  }
2
  // Prevent loading this file directly
3
  defined( 'ABSPATH' ) || exit;
4
 
5
+ if ( !class_exists( 'RWMB_Number_Field' ) )
6
  {
7
+ class RWMB_Number_Field
8
+ {
9
+ /**
10
+ * Get field HTML
11
+ *
12
+ * @param string $html
13
+ * @param mixed $meta
14
+ * @param array $field
15
+ *
16
+ * @return string
17
+ */
18
+ static function html( $html, $meta, $field )
19
+ {
20
+ return sprintf(
21
+ '<input type="number" class="rwmb-number" name="%s" id="%s" value="%s" step="%s" min="%s" />',
22
+ $field['field_name'],
23
+ empty( $field['clone'] ) ? $field['id'] : '',
24
+ $meta,
25
+ $field['step'],
26
+ $field['min']
27
+ );
28
+ }
29
 
30
+ /**
31
+ * Normalize parameters for field
32
+ *
33
+ * @param array $field
34
+ *
35
+ * @return array
36
+ */
37
+ static function normalize_field( $field )
38
+ {
39
+ $field = wp_parse_args( $field, array(
40
+ 'step' => 1,
41
+ 'min' => 0,
42
+ ) );
43
+ return $field;
44
+ }
45
+ }
 
 
 
 
 
46
  }
inc/fields/password.php CHANGED
@@ -17,12 +17,29 @@ if ( ! class_exists( 'RWMB_Password_Field' ) )
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
- $val = " value='{$meta}'";
21
- $name = "name='{$field['field_name']}'";
22
- $id = " id='{$field['id']}'";
23
- $html .= "<input type='password' class='rwmb-password'{$name}{$id}{$val} size='30' />";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- return $html;
26
  }
27
  }
28
  }
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
+ return sprintf(
21
+ '<input type="password" class="rwmb-password" name="%s" id="%s" value="%s" size="%s" />',
22
+ $field['field_name'],
23
+ $field['id'],
24
+ $meta,
25
+ $field['size']
26
+ );
27
+ }
28
+
29
+ /**
30
+ * Normalize parameters for field
31
+ *
32
+ * @param array $field
33
+ *
34
+ * @return array
35
+ */
36
+ static function normalize_field( $field )
37
+ {
38
+ $field = wp_parse_args( $field, array(
39
+ 'size' => 30,
40
+ ) );
41
 
42
+ return $field;
43
  }
44
  }
45
  }
inc/fields/plupload-image.php CHANGED
@@ -14,7 +14,7 @@ if ( ! class_exists( 'RWMB_Plupload_Image_Field' ) )
14
  static function add_actions()
15
  {
16
  parent::add_actions();
17
- add_action( 'wp_ajax_plupload_image_upload', array( __CLASS__, 'handle_upload' ) );
18
  }
19
 
20
  /**
@@ -33,12 +33,7 @@ if ( ! class_exists( 'RWMB_Plupload_Image_Field' ) )
33
 
34
  // You can use WP's wp_handle_upload() function:
35
  $file = $_FILES['async-upload'];
36
- $file_attr = wp_handle_upload(
37
- $file, array(
38
- 'test_form' => true,
39
- 'action' => 'plupload_image_upload',
40
- )
41
- );
42
  $attachment = array(
43
  'guid' => $file_attr['url'],
44
  'post_mime_type' => $file_attr['type'],
@@ -57,14 +52,7 @@ if ( ! class_exists( 'RWMB_Plupload_Image_Field' ) )
57
  if ( isset( $_REQUEST['field_id'] ) )
58
  add_post_meta( $post_id, $_REQUEST['field_id'], $id, false );
59
 
60
- $response = new WP_Ajax_Response();
61
- $response->add(
62
- array(
63
- 'what' => 'rwmb_image_response',
64
- 'data' => self::img_html( $id ),
65
- )
66
- );
67
- $response->send();
68
  }
69
 
70
  exit;
@@ -79,7 +67,7 @@ if ( ! class_exists( 'RWMB_Plupload_Image_Field' ) )
79
  {
80
  // Enqueue same scripts and styles as for file field
81
  parent::admin_enqueue_scripts();
82
- wp_enqueue_style( 'rwmb-plupload-image', RWMB_CSS_URL . 'plupload-image.css', array(), RWMB_VER );
83
  wp_enqueue_script( 'rwmb-plupload-image', RWMB_JS_URL . 'plupload-image.js', array( 'jquery-ui-sortable', 'wp-ajax-response', 'plupload-all' ), RWMB_VER, true );
84
  wp_localize_script( 'rwmb-plupload-image', 'RWMB', array( 'url' => RWMB_URL ) );
85
  wp_localize_script(
@@ -103,35 +91,6 @@ if ( ! class_exists( 'RWMB_Plupload_Image_Field' ) )
103
  );
104
  }
105
 
106
- /**
107
- * Get image html
108
- *
109
- * @param int $img_id
110
- *
111
- * @return string
112
- */
113
- static function img_html( $img_id )
114
- {
115
- $i18n_del_file = _x( 'Delete this file', 'image upload', 'rwmb' );
116
- $i18n_delete = _x( 'Delete', 'image upload', 'rwmb' );
117
- $i18n_edit = _x( 'Edit', 'image upload', 'rwmb' );
118
-
119
- $src = wp_get_attachment_image_src( $img_id, 'thumbnail' );
120
- $src = $src[0];
121
- $link = get_edit_post_link( $img_id );
122
-
123
- $html = <<<HTML
124
- <li id='item_{$img_id}'>
125
- <img src='{$src}' />
126
- <div class='rwmb-image-bar'>
127
- <a title='{$i18n_edit}' class='rwmb-edit-file' href='{$link}' target='_blank'>{$i18n_edit}</a> |
128
- <a title='{$i18n_del_file}' class='rwmb-delete-file' href='#' rel='{$img_id}'>{$i18n_delete}</a>
129
- </div>
130
- </li>
131
- HTML;
132
- return $html;
133
- }
134
-
135
  /**
136
  * Get field HTML
137
  *
@@ -146,9 +105,6 @@ HTML;
146
  if ( ! is_array( $meta ) )
147
  $meta = ( array ) $meta;
148
 
149
- $i18n_msg = _x( 'Uploaded files', 'image upload', 'rwmb' );
150
- $i18n_title = _x( 'Upload files', 'image upload', 'rwmb' );
151
-
152
  // Filter to change the drag & drop box background string
153
  $i18n_drop = apply_filters( 'rwmb_upload_drop_string', _x( 'Drop images here', 'image upload', 'rwmb' ) );
154
  $i18n_or = _x( 'or', 'image upload', 'rwmb' );
@@ -164,38 +120,54 @@ HTML;
164
  $html .= "<div id='{$img_prefix}-container'>";
165
 
166
  // Check for max_file_uploads
167
- $class = 'rwmb-drag-drop hide-if-no-js';
168
  if ( ! empty( $field['max_file_uploads'] ) )
169
  {
170
  $max_file_uploads = (int) $field['max_file_uploads'];
171
  $html .= "<input class='max_file_uploads' type='hidden' value='{$max_file_uploads}' />";
172
  if ( count( $meta ) >= $max_file_uploads )
173
- $class = RW_Meta_Box::add_cssclass( 'hidden', $class );
174
  }
175
 
176
- $html .= "<h4 class='rwmb-uploaded-title'>{$i18n_msg}</h4>";
177
- $html .= "<ul class='rwmb-images rwmb-uploaded'>";
178
- foreach ( $meta as $image )
179
- {
180
- $html .= self::img_html( $image );
181
- }
182
- $html .= '</ul>';
183
 
184
  // Show form upload
185
- $html .= "
186
- <h4>{$i18n_title}</h4>
187
- <div id='{$img_prefix}-dragdrop' class='{$class}'>
188
- <div class = 'rwmb-drag-drop-inside'>
189
- <p>{$i18n_drop}</p>
190
- <p>{$i18n_or}</p>
191
- <p><input id='{$img_prefix}-browse-button' type='button' value='{$i18n_select}' class='button' /></p>
192
  </div>
193
- </div>
194
- ";
 
 
 
 
 
 
195
 
196
  $html .= '</div>';
197
 
198
  return $html;
199
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
  }
14
  static function add_actions()
15
  {
16
  parent::add_actions();
17
+ add_action( 'wp_ajax_rwmb_plupload_image_upload', array( __CLASS__, 'handle_upload' ) );
18
  }
19
 
20
  /**
33
 
34
  // You can use WP's wp_handle_upload() function:
35
  $file = $_FILES['async-upload'];
36
+ $file_attr = wp_handle_upload( $file, array( 'test_form' => false ) );
 
 
 
 
 
37
  $attachment = array(
38
  'guid' => $file_attr['url'],
39
  'post_mime_type' => $file_attr['type'],
52
  if ( isset( $_REQUEST['field_id'] ) )
53
  add_post_meta( $post_id, $_REQUEST['field_id'], $id, false );
54
 
55
+ RW_Meta_Box::ajax_response( self::img_html( $id, $_REQUEST['field_id'] ), 'success' );
 
 
 
 
 
 
 
56
  }
57
 
58
  exit;
67
  {
68
  // Enqueue same scripts and styles as for file field
69
  parent::admin_enqueue_scripts();
70
+ wp_enqueue_style( 'rwmb-plupload-image', RWMB_CSS_URL . 'plupload-image.css', array( 'wp-admin' ), RWMB_VER );
71
  wp_enqueue_script( 'rwmb-plupload-image', RWMB_JS_URL . 'plupload-image.js', array( 'jquery-ui-sortable', 'wp-ajax-response', 'plupload-all' ), RWMB_VER, true );
72
  wp_localize_script( 'rwmb-plupload-image', 'RWMB', array( 'url' => RWMB_URL ) );
73
  wp_localize_script(
91
  );
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Get field HTML
96
  *
105
  if ( ! is_array( $meta ) )
106
  $meta = ( array ) $meta;
107
 
 
 
 
108
  // Filter to change the drag & drop box background string
109
  $i18n_drop = apply_filters( 'rwmb_upload_drop_string', _x( 'Drop images here', 'image upload', 'rwmb' ) );
110
  $i18n_or = _x( 'or', 'image upload', 'rwmb' );
120
  $html .= "<div id='{$img_prefix}-container'>";
121
 
122
  // Check for max_file_uploads
123
+ $classes = array( 'rwmb-drag-drop', 'drag-drop', 'hide-if-no-js' );
124
  if ( ! empty( $field['max_file_uploads'] ) )
125
  {
126
  $max_file_uploads = (int) $field['max_file_uploads'];
127
  $html .= "<input class='max_file_uploads' type='hidden' value='{$max_file_uploads}' />";
128
  if ( count( $meta ) >= $max_file_uploads )
129
+ $classes[] = 'hidden';
130
  }
131
 
132
+ $html .= self::get_uploaded_images( $meta, $field );
 
 
 
 
 
 
133
 
134
  // Show form upload
135
+ $html .= sprintf(
136
+ '<div id="%s-dragdrop" class="%s">
137
+ <div class = "drag-drop-inside">
138
+ <p class="drag-drop-info">%s</p>
139
+ <p>%s</p>
140
+ <p class="drag-drop-buttons"><input id="%s-browse-button" type="button" value="%s" class="button" /></p>
 
141
  </div>
142
+ </div>',
143
+ $img_prefix,
144
+ implode( ' ', $classes ),
145
+ $i18n_drop,
146
+ $i18n_or,
147
+ $img_prefix,
148
+ $i18n_select
149
+ );
150
 
151
  $html .= '</div>';
152
 
153
  return $html;
154
  }
155
+
156
+ /**
157
+ * Get field value
158
+ * It's the combination of new (uploaded) images and saved images
159
+ *
160
+ * @param array $new
161
+ * @param array $old
162
+ * @param int $post_id
163
+ * @param array $field
164
+ *
165
+ * @return array|mixed
166
+ */
167
+ static function value( $new, $old, $post_id, $field )
168
+ {
169
+ $new = (array) $new;
170
+ return array_unique( array_merge( $old, $new ) );
171
+ }
172
  }
173
  }
inc/fields/radio.php CHANGED
@@ -18,16 +18,17 @@ if ( ! class_exists( 'RWMB_Radio_Field' ) )
18
  static function html( $html, $meta, $field )
19
  {
20
  $html = '';
21
- $name = "name='{$field['field_name']}'";
22
 
23
- foreach ( $field['options'] as $key => $label )
24
  {
25
- $id = strstr( $field['id'], '[]' ) ? str_replace( '[]', "-{$key}[]", $field['id'] ) : $field['id'];
26
- $id = " id='{$id}'";
27
- $value = " value='{$key}'";
28
- $checked = checked( $meta, $key, false );
29
-
30
- $html .= "<label><input type='radio' class='rwmb-radio'{$name}{$id}{$value}{$checked} /> {$label}</label> ";
 
31
  }
32
 
33
  return $html;
18
  static function html( $html, $meta, $field )
19
  {
20
  $html = '';
21
+ $tpl = '<label><input type="radio" class="rwmb-radio" name="%s" value="%s" %s /> %s</label>';
22
 
23
+ foreach ( $field['options'] as $value => $label )
24
  {
25
+ $html .= sprintf(
26
+ $tpl,
27
+ $field['field_name'],
28
+ $value,
29
+ checked( $value, $meta, false ),
30
+ $label
31
+ );
32
  }
33
 
34
  return $html;
inc/fields/select.php CHANGED
@@ -30,21 +30,76 @@ if ( ! class_exists( 'RWMB_Select_Field' ) )
30
  if ( ! is_array( $meta ) )
31
  $meta = (array) $meta;
32
 
33
- $name = " name='{$field['field_name']}'";
34
- $id = " id='{$field['id']}'";
35
- $multiple = $field['multiple'] ? " multiple='multiple'" : '' ;
 
 
 
 
36
 
37
- $html = "<select class='rwmb-select'{$name}{$id}{$multiple}>";
38
- foreach ( $field['options'] as $key => $value )
39
  {
40
- $selected = selected( in_array( $key, $meta ), true, false );
41
- $html .= "<option value='{$key}'{$selected}>{$value}</option>";
 
 
 
 
42
  }
43
  $html .= '</select>';
44
 
45
  return $html;
46
  }
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  /**
49
  * Normalize parameters for field
50
  *
@@ -54,7 +109,9 @@ if ( ! class_exists( 'RWMB_Select_Field' ) )
54
  */
55
  static function normalize_field( $field )
56
  {
57
- $field['multiple'] = empty( $field['multiple'] ) ? false : $field['multiple'];
 
 
58
  return $field;
59
  }
60
  }
30
  if ( ! is_array( $meta ) )
31
  $meta = (array) $meta;
32
 
33
+ $html = sprintf(
34
+ '<select class="rwmb-select" name="%s" id="%s"%s>',
35
+ $field['field_name'],
36
+ $field['id'],
37
+ $field['multiple'] ? ' multiple="multiple"' : ''
38
+ );
39
+ $option = '<option value="%s" %s>%s</option>';
40
 
41
+ foreach ( $field['options'] as $value => $label )
 
42
  {
43
+ $html .= sprintf(
44
+ $option,
45
+ $value,
46
+ selected( in_array( $value, $meta ), true, false ),
47
+ $label
48
+ );
49
  }
50
  $html .= '</select>';
51
 
52
  return $html;
53
  }
54
 
55
+ /**
56
+ * Get meta value
57
+ * If field is cloneable, value is saved as a single entry in DB
58
+ * Otherwise value is saved as multiple entries (for backward compatibility)
59
+ *
60
+ * @see "save" method for better understanding
61
+ *
62
+ * TODO: A good way to ALWAYS save values in single entry in DB, while maintaining backward compatibility
63
+ *
64
+ * @param $meta
65
+ * @param $post_id
66
+ * @param $saved
67
+ * @param $field
68
+ *
69
+ * @return array
70
+ */
71
+ static function meta( $meta, $post_id, $saved, $field )
72
+ {
73
+ $single = $field['clone'] || !$field['multiple'];
74
+ return (array) get_post_meta( $post_id, $field['id'], $single );
75
+ }
76
+
77
+ /**
78
+ * Save meta value
79
+ * If field is cloneable, value is saved as a single entry in DB
80
+ * Otherwise value is saved as multiple entries (for backward compatibility)
81
+ *
82
+ * TODO: A good way to ALWAYS save values in single entry in DB, while maintaining backward compatibility
83
+ *
84
+ * @param $new
85
+ * @param $old
86
+ * @param $post_id
87
+ * @param $field
88
+ */
89
+ static function save( $new, $old, $post_id, $field )
90
+ {
91
+ if ( !$field['clone'] )
92
+ {
93
+ RW_Meta_Box::save( $new, $old, $post_id, $field );
94
+ return;
95
+ }
96
+
97
+ if ( empty( $new ) )
98
+ delete_post_meta( $post_id, $field['id'] );
99
+ else
100
+ update_post_meta( $post_id, $field['id'], $new );
101
+ }
102
+
103
  /**
104
  * Normalize parameters for field
105
  *
109
  */
110
  static function normalize_field( $field )
111
  {
112
+ $field['field_name'] = $field['id'];
113
+ if ( !$field['clone'] && $field['multiple'] )
114
+ $field['field_name'] .= '[]';
115
  return $field;
116
  }
117
  }
inc/fields/slider.php CHANGED
@@ -17,8 +17,6 @@ if ( ! class_exists( 'RWMB_Slider_Field' ) )
17
  wp_enqueue_style( 'jquery-ui-core', "{$url}/jquery.ui.core.css", array(), '1.8.17' );
18
  wp_enqueue_style( 'jquery-ui-theme', "{$url}/jquery.ui.theme.css", array(), '1.8.17' );
19
 
20
- $url = RWMB_JS_URL . 'jqueryui';
21
- wp_enqueue_script( 'jquery-ui-slider', "{$url}/jquery.ui.slider.min.js", array( 'jquery-ui-core' ), '1.8.17', true );
22
  wp_enqueue_script( 'rwmb-slider', RWMB_JS_URL . 'slider.js', array( 'jquery-ui-slider' ), RWMB_VER, true );
23
  }
24
 
@@ -33,18 +31,16 @@ if ( ! class_exists( 'RWMB_Slider_Field' ) )
33
  */
34
  static function html( $html, $meta, $field )
35
  {
36
- $id = " id='{$field['id']}'";
37
- $name = "name='{$field['field_name']}'";
38
- $val = " value='{$meta}'";
39
- $for = " for='{$field['id']}'";
40
- $format = " rel='{$field['format']}'";
41
- $html .= "
42
- <div class='clearfix'>
43
- <div class='rwmb-slider'{$format}{$id}></div>
44
- <input type='hidden'{$name}{$val} />
45
- </div>";
46
-
47
- return $html;
48
  }
49
  }
50
  }
17
  wp_enqueue_style( 'jquery-ui-core', "{$url}/jquery.ui.core.css", array(), '1.8.17' );
18
  wp_enqueue_style( 'jquery-ui-theme', "{$url}/jquery.ui.theme.css", array(), '1.8.17' );
19
 
 
 
20
  wp_enqueue_script( 'rwmb-slider', RWMB_JS_URL . 'slider.js', array( 'jquery-ui-slider' ), RWMB_VER, true );
21
  }
22
 
31
  */
32
  static function html( $html, $meta, $field )
33
  {
34
+ return sprintf(
35
+ '<div class="clearfix">
36
+ <div class="rwmb-slider" rel="%s" id="%s"></div>
37
+ <input type="hidden" name="%s" value="%s" />
38
+ </div>',
39
+ $field['format'],
40
+ $field['id'],
41
+ $field['field_name'],
42
+ $meta
43
+ );
 
 
44
  }
45
  }
46
  }
inc/fields/taxonomy.php CHANGED
@@ -13,18 +13,8 @@ if ( ! class_exists( 'RWMB_Taxonomy_Field' ) )
13
  */
14
  static function admin_enqueue_scripts()
15
  {
16
- wp_enqueue_style(
17
- 'rwmb-taxonomy',
18
- RWMB_CSS_URL . 'taxonomy.css',
19
- RWMB_VER
20
- );
21
- wp_enqueue_script(
22
- 'rwmb-taxonomy',
23
- RWMB_JS_URL . 'taxonomy.js',
24
- array( 'jquery', 'wp-ajax-response' ),
25
- RWMB_VER,
26
- true
27
- );
28
  }
29
 
30
  /**
@@ -97,10 +87,16 @@ if ( ! class_exists( 'RWMB_Taxonomy_Field' ) )
97
  if ( 'checkbox_list' === $options['type'] )
98
  {
99
  $html = array();
 
100
  foreach ( $terms as $term )
101
  {
102
- $checked = checked( in_array( $term->slug, $meta ), true, false );
103
- $html[] = "<label><input type='checkbox' name='{$field['field_name']}' value='{$term->slug}'{$checked} /> {$term->name}</label>";
 
 
 
 
 
104
  }
105
  $html = implode( '<br />', $html );
106
  }
@@ -121,10 +117,15 @@ if ( ! class_exists( 'RWMB_Taxonomy_Field' ) )
121
  {
122
  $multiple = $field['multiple'] ? " multiple='multiple' style='height: auto;'" : '';
123
  $html .= "<select name='{$field['field_name']}'{$multiple}>";
 
124
  foreach ( $terms as $term )
125
  {
126
- $selected = selected( in_array( $term->slug, $meta ), true, false );
127
- $html .= "<option value='{$term->slug}'{$selected}>{$term->name}</option>";
 
 
 
 
128
  }
129
  $html .= '</select>';
130
  }
@@ -151,11 +152,17 @@ if ( ! class_exists( 'RWMB_Taxonomy_Field' ) )
151
  $hidden = ( !$active ? 'hidden' : '' );
152
 
153
  $html = "<ul class = 'rw-taxonomy-tree {$hidden}'>";
 
154
  foreach ( $terms as $term )
155
  {
156
- $checked = checked( in_array( $term->slug, $meta ), true, false );
157
- $html .= "<li><label><input type='checkbox' name='{$field['field_name']}' value='{$term->slug}'{$checked} /> {$term->name}</label>";
158
- $html .= self::walk_checkbox_tree( $meta, $field, $elements, $term->term_id, ( in_array( $term->slug, $meta ) ) && $active ) . '</li>';
 
 
 
 
 
159
  }
160
  $html .= '</ul>';
161
 
@@ -187,10 +194,16 @@ if ( ! class_exists( 'RWMB_Taxonomy_Field' ) )
187
  $html = "<div{$id} class='rw-taxonomy-tree {$hidden}'>";
188
  $html .= "<select name='{$field['field_name']}'{$disabled}{$multiple}>";
189
  $html .= "<option value=''>None</option>";
 
 
190
  foreach ( $terms as $term )
191
  {
192
- $selected = selected( in_array( $term->slug, $meta ), true, false );
193
- $html .= "<option value='{$term->slug}'{$selected}>{$term->name}</option>";
 
 
 
 
194
  }
195
  $html .= '</select>';
196
  foreach ( $terms as $term )
@@ -254,5 +267,5 @@ if ( ! class_exists( 'RWMB_Taxonomy_Field' ) )
254
 
255
  return $meta;
256
  }
257
- } // END Class RWMB_Taxonomy_Field
258
- } // endif;
13
  */
14
  static function admin_enqueue_scripts()
15
  {
16
+ wp_enqueue_style( 'rwmb-taxonomy', RWMB_CSS_URL . 'taxonomy.css', array(), RWMB_VER );
17
+ wp_enqueue_script( 'rwmb-taxonomy', RWMB_JS_URL . 'taxonomy.js', array( 'jquery', 'wp-ajax-response' ), RWMB_VER, true );
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
  /**
87
  if ( 'checkbox_list' === $options['type'] )
88
  {
89
  $html = array();
90
+ $tpl = '<label><input type="checkbox" name="%s" value="%s" %s /> %s</label>';
91
  foreach ( $terms as $term )
92
  {
93
+ $html[] = sprintf(
94
+ $tpl,
95
+ $field['field_name'],
96
+ $term->slug,
97
+ checked( in_array( $term->slug, $meta ), true, false ),
98
+ $term->name
99
+ );
100
  }
101
  $html = implode( '<br />', $html );
102
  }
117
  {
118
  $multiple = $field['multiple'] ? " multiple='multiple' style='height: auto;'" : '';
119
  $html .= "<select name='{$field['field_name']}'{$multiple}>";
120
+ $option = '<option value="%s" %s>%s</option>';
121
  foreach ( $terms as $term )
122
  {
123
+ $html .= sprintf(
124
+ $option,
125
+ $term->slug,
126
+ selected( in_array( $term->slug, $meta ), true, false ),
127
+ $term->name
128
+ );
129
  }
130
  $html .= '</select>';
131
  }
152
  $hidden = ( !$active ? 'hidden' : '' );
153
 
154
  $html = "<ul class = 'rw-taxonomy-tree {$hidden}'>";
155
+ $li = '<li><label><input type="checkbox" name="%s" value="%s" %s /> %s</label>';
156
  foreach ( $terms as $term )
157
  {
158
+ $html .= sprintf(
159
+ $li,
160
+ $field['field_name'],
161
+ $term->slug,
162
+ checked( in_array( $term->slug, $meta ), true, false ),
163
+ $term->name
164
+ );
165
+ $html .= self::walk_checkbox_tree( $meta, $field, $elements, $term->term_id, ( in_array( $term->slug, $meta ) ) && $active ) . '</li>';
166
  }
167
  $html .= '</ul>';
168
 
194
  $html = "<div{$id} class='rw-taxonomy-tree {$hidden}'>";
195
  $html .= "<select name='{$field['field_name']}'{$disabled}{$multiple}>";
196
  $html .= "<option value=''>None</option>";
197
+
198
+ $option = '<option value="%s" %s>%s</option>';
199
  foreach ( $terms as $term )
200
  {
201
+ $html .= sprintf(
202
+ $option,
203
+ $term->slug,
204
+ selected( in_array( $term->slug, $meta ), true, false ),
205
+ $term->name
206
+ );
207
  }
208
  $html .= '</select>';
209
  foreach ( $terms as $term )
267
 
268
  return $meta;
269
  }
270
+ }
271
+ }
inc/fields/text.php CHANGED
@@ -17,14 +17,13 @@ if ( ! class_exists( 'RWMB_Text_Field' ) )
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
- $name = " name='{$field['field_name']}'";
21
- $id = isset( $field['clone'] ) && $field['clone'] ? '' : " id='{$field['id']}'";
22
- $value = " value='{$meta}'";
23
- $size = " size='{$field['size']}'";
24
-
25
- $html .= "<input type='text' class='rwmb-text'{$name}{$id}{$value}{$size} />";
26
-
27
- return $html;
28
  }
29
 
30
  /**
@@ -36,7 +35,9 @@ if ( ! class_exists( 'RWMB_Text_Field' ) )
36
  */
37
  static function normalize_field( $field )
38
  {
39
- $field['size'] = empty( $field['size'] ) ? 30 : $field['size'];
 
 
40
  return $field;
41
  }
42
  }
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
+ return sprintf(
21
+ '<input type="text" class="rwmb-text" name="%s" id="%s" value="%s" size="%s" />',
22
+ $field['field_name'],
23
+ $field['id'],
24
+ $meta,
25
+ $field['size']
26
+ );
 
27
  }
28
 
29
  /**
35
  */
36
  static function normalize_field( $field )
37
  {
38
+ $field = wp_parse_args( $field, array(
39
+ 'size' => 30,
40
+ ) );
41
  return $field;
42
  }
43
  }
inc/fields/textarea.php CHANGED
@@ -17,16 +17,16 @@ if ( ! class_exists( 'RWMB_Textarea_Field' ) )
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
- $name = " name='{$field['field_name']}'";
21
- $id = isset( $field['clone'] ) && $field['clone'] ? '' : " id='{$field['id']}'";
22
- $cols = " cols='{$field['cols']}'";
23
- $rows = " rows='{$field['rows']}'";
24
-
25
- $html .= "<textarea class='rwmb-textarea large-text'{$name}{$id}{$cols}{$rows}>{$meta}</textarea>";
26
-
27
- return $html;
28
  }
29
-
30
  /**
31
  * Normalize parameters for field
32
  *
@@ -36,8 +36,10 @@ if ( ! class_exists( 'RWMB_Textarea_Field' ) )
36
  */
37
  static function normalize_field( $field )
38
  {
39
- $field['cols'] = empty( $field['cols'] ) ? 60 : $field['cols'];
40
- $field['rows'] = empty( $field['rows'] ) ? 4 : $field['rows'];
 
 
41
  return $field;
42
  }
43
  }
17
  */
18
  static function html( $html, $meta, $field )
19
  {
20
+ return sprintf(
21
+ '<textarea class="rwmb-textarea large-text" name="%s" id="%s" cols="%s" rows="%s">%s</textarea>',
22
+ $field['field_name'],
23
+ $field['id'],
24
+ $field['cols'],
25
+ $field['rows'],
26
+ $meta
27
+ );
28
  }
29
+
30
  /**
31
  * Normalize parameters for field
32
  *
36
  */
37
  static function normalize_field( $field )
38
  {
39
+ $field = wp_parse_args( $field, array(
40
+ 'cols' => 60,
41
+ 'rows' => 3,
42
+ ) );
43
  return $field;
44
  }
45
  }
inc/fields/thickbox-image.php CHANGED
@@ -32,82 +32,36 @@ if ( ! class_exists( 'RWMB_Thickbox_Image_Field' ) )
32
  */
33
  static function html( $html, $meta, $field )
34
  {
35
- global $wpdb;
36
-
37
- $i18n_msg = _x( 'Uploaded files', 'image upload', 'rwmb' );
38
- $i18n_delete = _x( 'Delete', 'image upload', 'rwmb' );
39
- $i18n_edit = _x( 'Edit', 'image upload', 'rwmb' );
40
- $i18n_upload = _x( 'Upload image', 'image upload', 'rwmb' );
41
 
42
  $html = wp_nonce_field( "rwmb-delete-file_{$field['id']}", "nonce-delete-file_{$field['id']}", false, false );
43
  $html .= wp_nonce_field( "rwmb-reorder-images_{$field['id']}", "nonce-reorder-images_{$field['id']}", false, false );
44
  $html .= "<input type='hidden' class='field-id' value='{$field['id']}' />";
45
 
46
  // Uploaded images
47
- if ( ! empty( $meta ) )
48
- {
49
- $html .= "<h4>{$i18n_msg}</h4>";
50
- $html .= "<ul class='rwmb-images rwmb-uploaded'>";
51
-
52
- // Change $meta order using the posts 'menu_order'
53
- // $meta_menu_order = array();
54
- // foreach ( $meta as $post_id )
55
- // {
56
- // $post_meta = get_post( $post_id );
57
- // $meta_menu_order[$post_meta->menu_order] = $post_id;
58
- // }
59
- // ksort( $meta_menu_order );
60
- // $meta = $meta_menu_order;
61
-
62
- foreach ( $meta as $image )
63
- {
64
- $src = wp_get_attachment_image_src( $image, 'thumbnail' );
65
- $src = $src[0];
66
- $link = get_edit_post_link( $image );
67
-
68
- $html .= "<li id='item_{$image}'>
69
- <img src='{$src}' />
70
- <div class='rwmb-image-bar'>
71
- <a title='{$i18n_edit}' class='rwmb-edit-file' href='{$link}' target='_blank'>{$i18n_edit}</a> |
72
- <a title='{$i18n_delete}' class='rwmb-delete-file' href='#' rel='{$image}'>{$i18n_delete}</a>
73
- </div>
74
- </li>";
75
- }
76
-
77
- $html .= '</ul>';
78
- }
79
- else
80
- {
81
- // Place holder for images
82
- $html .= "<ul class='rwmb-images rwmb-uploaded'></ul>";
83
- }
84
 
85
  // Show form upload
86
- $html .= "<a href='#' class='button-secondary rwmb-thickbox-upload' rel='{$field['id']}'>{$i18n_upload}</a>";
87
 
88
  return $html;
89
  }
90
 
91
  /**
92
- * Save file field
 
93
  *
94
- * @param mixed $new
95
- * @param mixed $old
96
  * @param int $post_id
97
  * @param array $field
 
 
98
  */
99
- static function save( $new, $old, $post_id, $field )
100
  {
101
- if ( ! is_array( $new ) || empty( $new ) )
102
- return;
103
-
104
- $name = $field['id'];
105
- $images = (array) get_post_meta( $post_id, $name, false );
106
- foreach ( $new as $add_new )
107
- {
108
- if ( ! in_array( $add_new, $images ) )
109
- add_post_meta( $post_id, $name, $add_new, false );
110
- }
111
  }
112
  }
113
  }
32
  */
33
  static function html( $html, $meta, $field )
34
  {
35
+ $i18n_title = _x( 'Upload images', 'image upload', 'rwmb' );
 
 
 
 
 
36
 
37
  $html = wp_nonce_field( "rwmb-delete-file_{$field['id']}", "nonce-delete-file_{$field['id']}", false, false );
38
  $html .= wp_nonce_field( "rwmb-reorder-images_{$field['id']}", "nonce-reorder-images_{$field['id']}", false, false );
39
  $html .= "<input type='hidden' class='field-id' value='{$field['id']}' />";
40
 
41
  // Uploaded images
42
+ $html .= self::get_uploaded_images( $meta, $field );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  // Show form upload
45
+ $html .= "<a href='#' class='button rwmb-thickbox-upload' rel='{$field['id']}'>{$i18n_title}</a>";
46
 
47
  return $html;
48
  }
49
 
50
  /**
51
+ * Get field value
52
+ * It's the combination of new (uploaded) images and saved images
53
  *
54
+ * @param array $new
55
+ * @param array $old
56
  * @param int $post_id
57
  * @param array $field
58
+ *
59
+ * @return array|mixed
60
  */
61
+ static function value( $new, $old, $post_id, $field )
62
  {
63
+ $new = (array) $new;
64
+ return array_unique( array_merge( $old, $new ) );
 
 
 
 
 
 
 
 
65
  }
66
  }
67
  }
inc/fields/time.php CHANGED
@@ -21,8 +21,6 @@ if ( ! class_exists( 'RWMB_Time_Field' ) )
21
  wp_enqueue_style( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.css", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7' );
22
 
23
  $url = RWMB_JS_URL . 'jqueryui';
24
- wp_register_script( 'jquery-ui-datepicker', "{$url}/jquery.ui.datepicker.min.js", array( 'jquery-ui-core' ), '1.8.17', true );
25
- wp_register_script( 'jquery-ui-slider', "{$url}/jquery.ui.slider.min.js", array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse' ), '1.8.17', true );
26
  wp_register_script( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.js", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7', true );
27
  wp_enqueue_script( 'rwmb-time', RWMB_JS_URL.'time.js', array( 'jquery-ui-timepicker' ), RWMB_VER, true );
28
  }
@@ -38,15 +36,14 @@ if ( ! class_exists( 'RWMB_Time_Field' ) )
38
  */
39
  static function html( $html, $meta, $field )
40
  {
41
- $name = " name='{$field['field_name']}'";
42
- $id = isset( $field['clone'] ) && $field['clone'] ? '' : " id='{$field['id']}'";
43
- $value = " value='{$meta}'";
44
- $size = " size='{$field['size']}'";
45
- $format = " rel='{$field['format']}'";
46
-
47
- $html .= "<input type='text' class='rwmb-time'{$name}{$id}{$value}{$size}{$format} />";
48
-
49
- return $html;
50
  }
51
 
52
  /**
@@ -58,8 +55,19 @@ if ( ! class_exists( 'RWMB_Time_Field' ) )
58
  */
59
  static function normalize_field( $field )
60
  {
61
- $field['format'] = empty( $field['format'] ) ? 'hh:mm' : $field['format'];
62
- $field['size'] = empty( $field['size'] ) ? 10 : $field['size'];
 
 
 
 
 
 
 
 
 
 
 
63
  return $field;
64
  }
65
  }
21
  wp_enqueue_style( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.css", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7' );
22
 
23
  $url = RWMB_JS_URL . 'jqueryui';
 
 
24
  wp_register_script( 'jquery-ui-timepicker', "{$url}/jquery-ui-timepicker-addon.js", array( 'jquery-ui-datepicker', 'jquery-ui-slider' ), '0.9.7', true );
25
  wp_enqueue_script( 'rwmb-time', RWMB_JS_URL.'time.js', array( 'jquery-ui-timepicker' ), RWMB_VER, true );
26
  }
36
  */
37
  static function html( $html, $meta, $field )
38
  {
39
+ return sprintf(
40
+ '<input type="text" class="rwmb-datetime" name="%s" value="%s" id="%s" size="%s" data-options="%s" />',
41
+ $field['field_name'],
42
+ $meta,
43
+ isset( $field['clone'] ) && $field['clone'] ? '' : $field['id'],
44
+ $field['size'],
45
+ esc_attr( json_encode( $field['js_options'] ) )
46
+ );
 
47
  }
48
 
49
  /**
55
  */
56
  static function normalize_field( $field )
57
  {
58
+ $field = wp_parse_args( $field, array(
59
+ 'size' => 30,
60
+ 'js_options' => array(),
61
+ ) );
62
+
63
+ // Deprecate 'format', but keep it for backward compatible
64
+ // Use 'js_options' instead
65
+ $field['js_options'] = wp_parse_args( $field['js_options'], array(
66
+ 'timeOnly' => true,
67
+ 'showButtonPanel' => true,
68
+ 'timeFormat' => empty( $field['format'] ) ? 'hh:mm:ss' : $field['format'],
69
+ ) );
70
+
71
  return $field;
72
  }
73
  }
inc/fields/wysiwyg.php CHANGED
@@ -60,23 +60,52 @@ if ( ! class_exists( 'RWMB_Wysiwyg_Field' ) )
60
  static function html( $html, $meta, $field )
61
  {
62
  global $wp_version;
63
- $name = "name='{$field['field_name']}'";
64
 
65
  if ( version_compare( $wp_version, '3.2.1' ) < 1 )
66
  {
67
- return "<textarea class='rwmb-wysiwyg theEditor large-text' {$name} id='{$field['id']}' cols='60' rows='10'>$meta</textarea>";
 
 
 
 
 
68
  }
69
  else
70
  {
71
- // Apply filter to wp_editor() settings
72
- $editor_settings = apply_filters( 'rwmb_wysiwyg_settings', array( 'editor_class' => 'rwmb-wysiwyg' ), 10, 1 );
73
  // Using output buffering because wp_editor() echos directly
74
  ob_start();
 
 
 
75
  // Use new wp_editor() since WP 3.3
76
- wp_editor( $meta, $field['id'], $editor_settings );
77
 
78
  return ob_get_clean();
79
  }
80
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
  }
60
  static function html( $html, $meta, $field )
61
  {
62
  global $wp_version;
 
63
 
64
  if ( version_compare( $wp_version, '3.2.1' ) < 1 )
65
  {
66
+ return sprintf(
67
+ '<textarea class="rwmb-wysiwyg theEditor large-text" name="%s" id="%s" cols="60" rows="4">%s</textarea>',
68
+ $field['field_name'],
69
+ $field['id'],
70
+ $meta
71
+ );
72
  }
73
  else
74
  {
 
 
75
  // Using output buffering because wp_editor() echos directly
76
  ob_start();
77
+
78
+ $field['options']['textarea_name'] = $field['field_name'];
79
+
80
  // Use new wp_editor() since WP 3.3
81
+ wp_editor( $meta, $field['id'], $field['options'] );
82
 
83
  return ob_get_clean();
84
  }
85
  }
86
+
87
+ /**
88
+ * Normalize parameters for field
89
+ *
90
+ * @param array $field
91
+ *
92
+ * @return array
93
+ */
94
+ static function normalize_field( $field )
95
+ {
96
+ $field = wp_parse_args( $field, array(
97
+ 'options' => array(),
98
+ ) );
99
+
100
+ $field['options'] = wp_parse_args( $field['options'], array(
101
+ 'editor_class' => 'rwmb-wysiwyg',
102
+ 'dfw' => true, // Use default WordPress full screen UI
103
+ ) );
104
+
105
+ // Keep the filter to be compatible with previous versions
106
+ $field['options'] = apply_filters( 'rwmb_wysiwyg_settings', $field['options'] );
107
+
108
+ return $field;
109
+ }
110
  }
111
  }
inc/helpers.php CHANGED
@@ -7,6 +7,105 @@
7
  // Prevent loading this file directly
8
  defined( 'ABSPATH' ) || exit;
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  /**
11
  * Get post meta
12
  *
@@ -32,7 +131,7 @@ function rwmb_meta( $key, $args = array(), $post_id = null )
32
  // Get uploaded files info
33
  if ( 'file' == $args['type'] )
34
  {
35
- if ( is_array( $meta ) && ! empty( $meta ) )
36
  {
37
  $files = array();
38
  foreach ( $meta as $id )
@@ -46,10 +145,10 @@ function rwmb_meta( $key, $args = array(), $post_id = null )
46
  // Get uploaded images info
47
  elseif ( in_array( $args['type'], array( 'image', 'plupload_image', 'thickbox_image' ) ) )
48
  {
49
- if ( is_array( $meta ) && ! empty( $meta ) )
50
  {
51
  global $wpdb;
52
- $meta = implode( ',' , $meta );
53
 
54
  // Re-arrange images with 'menu_order'
55
  $meta = $wpdb->get_col( "
@@ -74,7 +173,7 @@ function rwmb_meta( $key, $args = array(), $post_id = null )
74
  $meta = empty( $args['taxonomy'] ) ? array() : wp_get_post_terms( $post_id, $args['taxonomy'] );
75
  }
76
 
77
- return $meta;
78
  }
79
 
80
  /**
7
  // Prevent loading this file directly
8
  defined( 'ABSPATH' ) || exit;
9
 
10
+ add_shortcode( 'rwmb_meta', 'rwmb_meta_shortcode' );
11
+
12
+ /**
13
+ * Shortcode to display meta value
14
+ *
15
+ * @param $atts Array of shortcode attributes, same as rwmb_meta function, but has more "meta_key" parameter
16
+ * @see rwmb_meta function below
17
+ *
18
+ * @return string
19
+ */
20
+ function rwmb_meta_shortcode( $atts )
21
+ {
22
+ $atts = wp_parse_args( $atts, array(
23
+ 'type' => 'text',
24
+ 'post_id' => get_the_ID(),
25
+ ) );
26
+ if ( empty( $atts['meta_key'] ) )
27
+ return '';
28
+
29
+ $meta = rwmb_meta( $atts['meta_key'], $atts, $atts['post_id'] );
30
+
31
+ // Get uploaded files info
32
+ if ( 'file' == $atts['type'] )
33
+ {
34
+ $content = '<ul>';
35
+ foreach ( $meta as $file )
36
+ {
37
+ $content .= sprintf(
38
+ '<li><a href="%s" title="%s">%s</a></li>',
39
+ $file['url'],
40
+ $file['title'],
41
+ $file['name']
42
+ );
43
+ }
44
+ $content .= '</ul>';
45
+ }
46
+
47
+ // Get uploaded images info
48
+ elseif ( in_array( $atts['type'], array( 'image', 'plupload_image', 'thickbox_image' ) ) )
49
+ {
50
+ $content = '<ul>';
51
+ foreach ( $meta as $image )
52
+ {
53
+ // Link thumbnail to full size image?
54
+ if ( isset( $atts['link'] ) && $atts['link'] )
55
+ {
56
+ $content .= sprintf(
57
+ '<li><a href="%s" title="%s"><img src="%s" alt="%s" title="%s" /></a></li>',
58
+ $image['full_url'],
59
+ $image['title'],
60
+ $image['url'],
61
+ $image['alt'],
62
+ $image['title']
63
+ );
64
+ }
65
+ else
66
+ {
67
+ $content .= sprintf(
68
+ '<li><img src="%s" alt="%s" title="%s" /></li>',
69
+ $image['url'],
70
+ $image['alt'],
71
+ $image['title']
72
+ );
73
+ }
74
+ }
75
+ $content .= '</ul>';
76
+ }
77
+
78
+ // Get post terms
79
+ elseif ( 'taxonomy' == $atts['type'] )
80
+ {
81
+
82
+ $content = '<ul>';
83
+ foreach ( $meta as $term )
84
+ {
85
+ $content .= sprintf(
86
+ '<li><a href="%s" title="%s">%s</a></li>',
87
+ get_term_link( $term, $atts['taxonomy'] ),
88
+ $term->name,
89
+ $term->name
90
+ );
91
+ }
92
+ $content .= '</ul>';
93
+ }
94
+
95
+ // Normal multiple fields: checkbox_list, select with multiple values
96
+ elseif ( is_array( $meta ) )
97
+ {
98
+ $content = '<ul><li>' . implode( '</li><li>', $meta ) . '</li></ul>';
99
+ }
100
+
101
+ else
102
+ {
103
+ $content = $meta;
104
+ }
105
+
106
+ return apply_filters( __FUNCTION__, $content );
107
+ }
108
+
109
  /**
110
  * Get post meta
111
  *
131
  // Get uploaded files info
132
  if ( 'file' == $args['type'] )
133
  {
134
+ if ( is_array( $meta ) && !empty( $meta ) )
135
  {
136
  $files = array();
137
  foreach ( $meta as $id )
145
  // Get uploaded images info
146
  elseif ( in_array( $args['type'], array( 'image', 'plupload_image', 'thickbox_image' ) ) )
147
  {
148
+ if ( is_array( $meta ) && !empty( $meta ) )
149
  {
150
  global $wpdb;
151
+ $meta = implode( ',', $meta );
152
 
153
  // Re-arrange images with 'menu_order'
154
  $meta = $wpdb->get_col( "
173
  $meta = empty( $args['taxonomy'] ) ? array() : wp_get_post_terms( $post_id, $args['taxonomy'] );
174
  }
175
 
176
+ return apply_filters( __FUNCTION__, $meta );
177
  }
178
 
179
  /**
js/clone.js CHANGED
@@ -1,48 +1,27 @@
1
- jQuery( document ).ready( function ($)
2
  {
3
- /**
4
- * Hide remove buttons when there's only 1 of them
5
- *
6
- * @param $el jQuery element. If not supplied, the function will applies for all fields
7
- *
8
- * @return void
9
- */
10
- function toggle_remove_buttons( $el )
11
- {
12
- if ( ! $el )
13
- $el = $( '.rwmb-field' );
14
- $el.each( function()
15
- {
16
- var $remove_buttons = $( this ).find( '.remove-clone' );
17
- if ( $remove_buttons.length < 2 )
18
- $remove_buttons.hide();
19
- else
20
- $remove_buttons.show();
21
- } );
22
- }
23
-
24
- // Call it on first run
25
  toggle_remove_buttons();
26
 
27
  function add_cloned_fields( $input )
28
  {
29
- var $clone_last = $input.find( '.rwmb-clone:last' ),
30
- $clone = $clone_last.clone( true );
 
31
 
32
  $clone.insertAfter( $clone_last );
 
33
 
34
  // Reset value
35
- $clone.find( ':input' ).val( '' );
36
 
37
  // Get the field name, and increment
38
- var $index = $clone.find( ':input' ).attr("name").replace(/\[([0-9]+)\]$/,
39
- function(str, p1, p2, p3)
40
- {
41
- return mystr = '[' + (parseInt(p1) +1) + ']';
42
- });
43
 
44
  // Update the "name" attribute
45
- $clone.find( ':input' ).attr("name", $index);
46
 
47
  // Toggle remove buttons
48
  toggle_remove_buttons( $input );
@@ -50,15 +29,15 @@ jQuery( document ).ready( function ($)
50
  // Fix color picker
51
  if ( 'function' === typeof rwmb_update_color_picker )
52
  rwmb_update_color_picker();
53
-
54
  // Fix date picker
55
  if ( 'function' === typeof rwmb_update_date_picker )
56
  rwmb_update_date_picker();
57
-
58
  // Fix time picker
59
  if ( 'function' === typeof rwmb_update_time_picker )
60
  rwmb_update_time_picker();
61
-
62
  // Fix datetime picker
63
  if ( 'function' === typeof rwmb_update_datetime_picker )
64
  rwmb_update_datetime_picker();
@@ -67,64 +46,87 @@ jQuery( document ).ready( function ($)
67
  // Add more clones
68
  $( '.add-clone' ).click( function ()
69
  {
70
- var $input = $( this ).parents( '.rwmb-input' );
71
- var $clone_group = $( this ).parents( '.rwmb-field' ).attr("clone-group");
72
 
73
  // If the field is part of a clone group, get all fields in that
74
  // group and itterate over them
75
  if ( $clone_group )
76
  {
77
  // Get the parent metabox and then find the matching
78
- // clone-group elements inside
79
- var $metabox = $( this ).parents( '.inside' );
80
- var $clone_group_list = $metabox.find( 'div[clone-group="' + $clone_group + '"]' );
81
-
82
- $.each($clone_group_list.find( '.rwmb-input' ),
83
- function(key, value) {
84
- add_cloned_fields( $(value) );
85
- });
 
86
  }
87
  else
88
  add_cloned_fields( $input );
89
-
 
 
90
  return false;
91
  } );
92
 
93
  // Remove clones
94
- $( '.rwmb-input' ).delegate( '.remove-clone', 'click', function()
95
  {
96
- var $this = $( this ),
97
- $input = $this.parents( '.rwmb-input' );
98
- var $clone_group = $( this ).parents( '.rwmb-field' ).attr("clone-group");
99
 
100
  // Remove clone only if there're 2 or more of them
101
- if ( $input.find( '.rwmb-clone' ).length > 1 )
102
- {
103
- if ( $clone_group )
104
- {
105
- // Get the parent metabox and then find the matching
106
- // clone-group elements inside
107
- var $metabox = $( this ).parents( '.inside' );
108
- var $clone_group_list = $metabox.find( 'div[clone-group="' + $clone_group + '"]' );
109
- var $index = $this.parent().index();
110
-
111
- $.each($clone_group_list.find( '.rwmb-input' ),
112
- function(key, value) {
113
- $(value).children( '.rwmb-clone' ).eq($index).remove();
114
-
115
- // Toggle remove buttons
116
- toggle_remove_buttons( $(value) );
117
- });
118
- }
119
- else
120
- {
121
- $this.parent().remove();
122
-
123
- // Toggle remove buttons
124
- toggle_remove_buttons( $input );
125
- }
 
126
  }
127
 
128
  return false;
129
  } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  } );
1
+ jQuery( document ).ready( function ( $ )
2
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  toggle_remove_buttons();
4
 
5
  function add_cloned_fields( $input )
6
  {
7
+ var $clone_last = $input.find( '.rwmb-clone:last' ),
8
+ $clone = $clone_last.clone(),
9
+ $input, name;
10
 
11
  $clone.insertAfter( $clone_last );
12
+ $input = $clone.find( ':input' );
13
 
14
  // Reset value
15
+ $input.val( '' );
16
 
17
  // Get the field name, and increment
18
+ name = $input.attr( 'name' ).replace( /\[(\d+)\]/, function ( match, p1 )
19
+ {
20
+ return '[' + ( parseInt( p1 ) + 1 ) + ']';
21
+ } );
 
22
 
23
  // Update the "name" attribute
24
+ $input.attr( 'name', name );
25
 
26
  // Toggle remove buttons
27
  toggle_remove_buttons( $input );
29
  // Fix color picker
30
  if ( 'function' === typeof rwmb_update_color_picker )
31
  rwmb_update_color_picker();
32
+
33
  // Fix date picker
34
  if ( 'function' === typeof rwmb_update_date_picker )
35
  rwmb_update_date_picker();
36
+
37
  // Fix time picker
38
  if ( 'function' === typeof rwmb_update_time_picker )
39
  rwmb_update_time_picker();
40
+
41
  // Fix datetime picker
42
  if ( 'function' === typeof rwmb_update_datetime_picker )
43
  rwmb_update_datetime_picker();
46
  // Add more clones
47
  $( '.add-clone' ).click( function ()
48
  {
49
+ var $input = $( this ).parents( '.rwmb-input' ),
50
+ $clone_group = $( this ).parents( '.rwmb-field' ).attr( "clone-group" );
51
 
52
  // If the field is part of a clone group, get all fields in that
53
  // group and itterate over them
54
  if ( $clone_group )
55
  {
56
  // Get the parent metabox and then find the matching
57
+ // clone-group elements inside
58
+ var $metabox = $( this ).parents( '.inside' );
59
+ var $clone_group_list = $metabox.find( 'div[clone-group="' + $clone_group + '"]' );
60
+
61
+ $.each( $clone_group_list.find( '.rwmb-input' ),
62
+ function ( key, value )
63
+ {
64
+ add_cloned_fields( $( value ) );
65
+ } );
66
  }
67
  else
68
  add_cloned_fields( $input );
69
+
70
+ toggle_remove_buttons( $input );
71
+
72
  return false;
73
  } );
74
 
75
  // Remove clones
76
+ $( '.rwmb-input' ).delegate( '.remove-clone', 'click', function ()
77
  {
78
+ var $this = $( this ),
79
+ $input = $this.parents( '.rwmb-input' ),
80
+ $clone_group = $( this ).parents( '.rwmb-field' ).attr( 'clone-group' );
81
 
82
  // Remove clone only if there're 2 or more of them
83
+ if ( $input.find( '.rwmb-clone' ).length <= 1 )
84
+ return false;
85
+
86
+ if ( $clone_group )
87
+ {
88
+ // Get the parent metabox and then find the matching
89
+ // clone-group elements inside
90
+ var $metabox = $( this ).parents( '.inside' );
91
+ var $clone_group_list = $metabox.find( 'div[clone-group="' + $clone_group + '"]' );
92
+ var $index = $this.parent().index();
93
+
94
+ $.each( $clone_group_list.find( '.rwmb-input' ),
95
+ function ( key, value )
96
+ {
97
+ $( value ).children( '.rwmb-clone' ).eq( $index ).remove();
98
+
99
+ // Toggle remove buttons
100
+ toggle_remove_buttons( $( value ) );
101
+ } );
102
+ }
103
+ else
104
+ {
105
+ $this.parent().remove();
106
+
107
+ // Toggle remove buttons
108
+ toggle_remove_buttons( $input );
109
  }
110
 
111
  return false;
112
  } );
113
+
114
+ /**
115
+ * Hide remove buttons when there's only 1 of them
116
+ *
117
+ * @param $el jQuery element. If not supplied, the function will applies for all fields
118
+ *
119
+ * @return void
120
+ */
121
+ function toggle_remove_buttons( $el )
122
+ {
123
+ var $button;
124
+ if ( !$el )
125
+ $el = $( '.rwmb-field' );
126
+ $el.each( function ()
127
+ {
128
+ $button = $( this ).find( '.remove-clone' );
129
+ $button.length < 2 ? $button.hide() : $button.show();
130
+ } );
131
+ }
132
  } );
js/color.js CHANGED
@@ -20,11 +20,12 @@ function rwmb_update_color_picker()
20
 
21
  jQuery( document ).ready( function($)
22
  {
23
- $( '.rwmb-color' ).focus( function()
24
  {
25
  $( this ).siblings( '.rwmb-color-picker' ).show();
26
  return false;
27
- } ).blur( function() {
 
28
  $( this ).siblings( '.rwmb-color-picker' ).hide();
29
  return false;
30
  } );
20
 
21
  jQuery( document ).ready( function($)
22
  {
23
+ $( '.rwmb-input' ).delegate( '.rwmb-color', 'focus', function()
24
  {
25
  $( this ).siblings( '.rwmb-color-picker' ).show();
26
  return false;
27
+ } ).delegate( '.rwmb-color', 'blur', function()
28
+ {
29
  $( this ).siblings( '.rwmb-color-picker' ).hide();
30
  return false;
31
  } );
js/date.js CHANGED
@@ -9,12 +9,9 @@ function rwmb_update_date_picker()
9
  $( '.rwmb-date' ).each( function()
10
  {
11
  var $this = $( this ),
12
- format = $this.attr( 'rel' );
13
 
14
- $this.removeClass('hasDatepicker').attr('id', '').datepicker( {
15
- showButtonPanel: true,
16
- dateFormat: format
17
- } );
18
  } );
19
  }
20
 
9
  $( '.rwmb-date' ).each( function()
10
  {
11
  var $this = $( this ),
12
+ options = $this.data( 'options' );
13
 
14
+ $this.removeClass( 'hasDatepicker' ).attr( 'id', '' ).datepicker( options );
 
 
 
15
  } );
16
  }
17
 
js/datetime.js CHANGED
@@ -9,17 +9,9 @@ function rwmb_update_datetime_picker()
9
  $( '.rwmb-datetime' ).each( function()
10
  {
11
  var $this = $( this ),
12
- format = $this.attr( 'rel' ),
13
- show_amppm = /t/i.test(format),
14
- show_second = /:s/.test(format),
15
- show_millisec = /:l/.test(format);
16
 
17
- $this.removeClass('hasDatepicker').attr('id', '').datetimepicker( {
18
- showSecond : show_second,
19
- showMillisec: show_millisec,
20
- timeFormat : format,
21
- ampm : show_amppm,
22
- } );
23
  } );
24
  }
25
 
9
  $( '.rwmb-datetime' ).each( function()
10
  {
11
  var $this = $( this ),
12
+ options = $this.data( 'options' );
 
 
 
13
 
14
+ $this.removeClass( 'hasDatepicker' ).attr( 'id', '' ).datetimepicker( options );
 
 
 
 
 
15
  } );
16
  }
17
 
js/file.js CHANGED
@@ -1,7 +1,7 @@
1
- jQuery( document ).ready( function($)
2
  {
3
  // Add more file
4
- $( '.rwmb-add-file' ).click( function()
5
  {
6
  var $this = $( this ), $first = $this.parent().find( '.file-input:first' );
7
 
@@ -11,22 +11,23 @@ jQuery( document ).ready( function($)
11
  } );
12
 
13
  // Delete file via Ajax
14
- $( '.rwmb-uploaded' ).delegate( '.rwmb-delete-file', 'click', function()
15
  {
16
- var $this = $(this),
17
- $parent = $this.closest( 'li' ),
18
- field_id = $this.parents( '.rwmb-field' ).find( '.field-id' ).val(),
19
  data = {
20
  action : 'rwmb_delete_file',
21
- _wpnonce : $('#nonce-delete-file_' + field_id).val(),
22
- post_id : $('#post_ID').val(),
23
  field_id : field_id,
24
- attachment_id: $this.attr('rel')
25
  };
26
 
27
- $.post( ajaxurl, data, function( r )
28
  {
29
  var res = wpAjax.parseAjaxResponse( r, 'ajax-response' );
 
30
  if ( res.errors )
31
  alert( res.responses[0].errors[0].message );
32
  else
1
+ jQuery( document ).ready( function ( $ )
2
  {
3
  // Add more file
4
+ $( '.rwmb-add-file' ).click( function ()
5
  {
6
  var $this = $( this ), $first = $this.parent().find( '.file-input:first' );
7
 
11
  } );
12
 
13
  // Delete file via Ajax
14
+ $( '.rwmb-uploaded' ).delegate( '.rwmb-delete-file', 'click', function ()
15
  {
16
+ var $this = $( this ),
17
+ $parent = $this.parents( 'li' ),
18
+ field_id = $this.data( 'field_id' ),
19
  data = {
20
  action : 'rwmb_delete_file',
21
+ _wpnonce : $( '#nonce-delete-file_' + field_id ).val(),
22
+ post_id : $( '#post_ID' ).val(),
23
  field_id : field_id,
24
+ attachment_id: $this.data( 'attachment_id' )
25
  };
26
 
27
+ $.post( ajaxurl, data, function ( r )
28
  {
29
  var res = wpAjax.parseAjaxResponse( r, 'ajax-response' );
30
+
31
  if ( res.errors )
32
  alert( res.responses[0].errors[0].message );
33
  else
js/jquery.validate.min.js CHANGED
@@ -1,51 +1,4 @@
1
- /**
2
- * jQuery Validation Plugin 1.9.0
3
- *
4
- * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
- * http://docs.jquery.com/Plugins/Validation
6
- *
7
- * Copyright (c) 2006 - 2011 Jörn Zaefferer
8
- *
9
- * Dual licensed under the MIT and GPL licenses:
10
- * http://www.opensource.org/licenses/mit-license.php
11
- * http://www.gnu.org/licenses/gpl.html
12
- */
13
- (function(c){c.extend(c.fn,{validate:function(a){if(this.length){var b=c.data(this[0],"validator");if(b)return b;this.attr("novalidate","novalidate");b=new c.validator(a,this[0]);c.data(this[0],"validator",b);if(b.settings.onsubmit){a=this.find("input, button");a.filter(".cancel").click(function(){b.cancelSubmit=true});b.settings.submitHandler&&a.filter(":submit").click(function(){b.submitButton=this});this.submit(function(d){function e(){if(b.settings.submitHandler){if(b.submitButton)var f=c("<input type='hidden'/>").attr("name",
14
- b.submitButton.name).val(b.submitButton.value).appendTo(b.currentForm);b.settings.submitHandler.call(b,b.currentForm);b.submitButton&&f.remove();return false}return true}b.settings.debug&&d.preventDefault();if(b.cancelSubmit){b.cancelSubmit=false;return e()}if(b.form()){if(b.pendingRequest){b.formSubmitted=true;return false}return e()}else{b.focusInvalid();return false}})}return b}else a&&a.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing")},valid:function(){if(c(this[0]).is("form"))return this.validate().form();
15
- else{var a=true,b=c(this[0].form).validate();this.each(function(){a&=b.element(this)});return a}},removeAttrs:function(a){var b={},d=this;c.each(a.split(/\s/),function(e,f){b[f]=d.attr(f);d.removeAttr(f)});return b},rules:function(a,b){var d=this[0];if(a){var e=c.data(d.form,"validator").settings,f=e.rules,g=c.validator.staticRules(d);switch(a){case "add":c.extend(g,c.validator.normalizeRule(b));f[d.name]=g;if(b.messages)e.messages[d.name]=c.extend(e.messages[d.name],b.messages);break;case "remove":if(!b){delete f[d.name];
16
- return g}var h={};c.each(b.split(/\s/),function(j,i){h[i]=g[i];delete g[i]});return h}}d=c.validator.normalizeRules(c.extend({},c.validator.metadataRules(d),c.validator.classRules(d),c.validator.attributeRules(d),c.validator.staticRules(d)),d);if(d.required){e=d.required;delete d.required;d=c.extend({required:e},d)}return d}});c.extend(c.expr[":"],{blank:function(a){return!c.trim(""+a.value)},filled:function(a){return!!c.trim(""+a.value)},unchecked:function(a){return!a.checked}});c.validator=function(a,
17
- b){this.settings=c.extend(true,{},c.validator.defaults,a);this.currentForm=b;this.init()};c.validator.format=function(a,b){if(arguments.length==1)return function(){var d=c.makeArray(arguments);d.unshift(a);return c.validator.format.apply(this,d)};if(arguments.length>2&&b.constructor!=Array)b=c.makeArray(arguments).slice(1);if(b.constructor!=Array)b=[b];c.each(b,function(d,e){a=a.replace(RegExp("\\{"+d+"\\}","g"),e)});return a};c.extend(c.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",
18
- validClass:"valid",errorElement:"label",focusInvalid:true,errorContainer:c([]),errorLabelContainer:c([]),onsubmit:true,ignore:":hidden",ignoreTitle:false,onfocusin:function(a){this.lastActive=a;if(this.settings.focusCleanup&&!this.blockFocusCleanup){this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass);this.addWrapper(this.errorsFor(a)).hide()}},onfocusout:function(a){if(!this.checkable(a)&&(a.name in this.submitted||!this.optional(a)))this.element(a)},
19
- onkeyup:function(a){if(a.name in this.submitted||a==this.lastElement)this.element(a)},onclick:function(a){if(a.name in this.submitted)this.element(a);else a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(a,b,d){a.type==="radio"?this.findByName(a.name).addClass(b).removeClass(d):c(a).addClass(b).removeClass(d)},unhighlight:function(a,b,d){a.type==="radio"?this.findByName(a.name).removeClass(b).addClass(d):c(a).removeClass(b).addClass(d)}},setDefaults:function(a){c.extend(c.validator.defaults,
20
- a)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",accept:"Please enter a value with a valid extension.",maxlength:c.validator.format("Please enter no more than {0} characters."),
21
- minlength:c.validator.format("Please enter at least {0} characters."),rangelength:c.validator.format("Please enter a value between {0} and {1} characters long."),range:c.validator.format("Please enter a value between {0} and {1}."),max:c.validator.format("Please enter a value less than or equal to {0}."),min:c.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:false,prototype:{init:function(){function a(e){var f=c.data(this[0].form,"validator"),g="on"+e.type.replace(/^validate/,
22
- "");f.settings[g]&&f.settings[g].call(f,this[0],e)}this.labelContainer=c(this.settings.errorLabelContainer);this.errorContext=this.labelContainer.length&&this.labelContainer||c(this.currentForm);this.containers=c(this.settings.errorContainer).add(this.settings.errorLabelContainer);this.submitted={};this.valueCache={};this.pendingRequest=0;this.pending={};this.invalid={};this.reset();var b=this.groups={};c.each(this.settings.groups,function(e,f){c.each(f.split(/\s/),function(g,h){b[h]=e})});var d=
23
- this.settings.rules;c.each(d,function(e,f){d[e]=c.validator.normalizeRule(f)});c(this.currentForm).validateDelegate("[type='text'], [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",a).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",
24
- a);this.settings.invalidHandler&&c(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){this.checkForm();c.extend(this.submitted,this.errorMap);this.invalid=c.extend({},this.errorMap);this.valid()||c(this.currentForm).triggerHandler("invalid-form",[this]);this.showErrors();return this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(a){this.lastElement=
25
- a=this.validationTargetFor(this.clean(a));this.prepareElement(a);this.currentElements=c(a);var b=this.check(a);if(b)delete this.invalid[a.name];else this.invalid[a.name]=true;if(!this.numberOfInvalids())this.toHide=this.toHide.add(this.containers);this.showErrors();return b},showErrors:function(a){if(a){c.extend(this.errorMap,a);this.errorList=[];for(var b in a)this.errorList.push({message:a[b],element:this.findByName(b)[0]});this.successList=c.grep(this.successList,function(d){return!(d.name in a)})}this.settings.showErrors?
26
- this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){c.fn.resetForm&&c(this.currentForm).resetForm();this.submitted={};this.lastElement=null;this.prepareForm();this.hideErrors();this.elements().removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b=0,d;for(d in a)b++;return b},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return this.size()==
27
- 0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{c(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(a){}},findLastActive:function(){var a=this.lastActive;return a&&c.grep(this.errorList,function(b){return b.element.name==a.name}).length==1&&a},elements:function(){var a=this,b={};return c(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){!this.name&&
28
- a.settings.debug&&window.console&&console.error("%o has no name assigned",this);if(this.name in b||!a.objectLength(c(this).rules()))return false;return b[this.name]=true})},clean:function(a){return c(a)[0]},errors:function(){return c(this.settings.errorElement+"."+this.settings.errorClass,this.errorContext)},reset:function(){this.successList=[];this.errorList=[];this.errorMap={};this.toShow=c([]);this.toHide=c([]);this.currentElements=c([])},prepareForm:function(){this.reset();this.toHide=this.errors().add(this.containers)},
29
- prepareElement:function(a){this.reset();this.toHide=this.errorsFor(a)},check:function(a){a=this.validationTargetFor(this.clean(a));var b=c(a).rules(),d=false,e;for(e in b){var f={method:e,parameters:b[e]};try{var g=c.validator.methods[e].call(this,a.value.replace(/\r/g,""),a,f.parameters);if(g=="dependency-mismatch")d=true;else{d=false;if(g=="pending"){this.toHide=this.toHide.not(this.errorsFor(a));return}if(!g){this.formatAndAdd(a,f);return false}}}catch(h){this.settings.debug&&window.console&&console.log("exception occured when checking element "+
30
- a.id+", check the '"+f.method+"' method",h);throw h;}}if(!d){this.objectLength(b)&&this.successList.push(a);return true}},customMetaMessage:function(a,b){if(c.metadata){var d=this.settings.meta?c(a).metadata()[this.settings.meta]:c(a).metadata();return d&&d.messages&&d.messages[b]}},customMessage:function(a,b){var d=this.settings.messages[a];return d&&(d.constructor==String?d:d[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(arguments[a]!==undefined)return arguments[a]},defaultMessage:function(a,
31
- b){return this.findDefined(this.customMessage(a.name,b),this.customMetaMessage(a,b),!this.settings.ignoreTitle&&a.title||undefined,c.validator.messages[b],"<strong>Warning: No message defined for "+a.name+"</strong>")},formatAndAdd:function(a,b){var d=this.defaultMessage(a,b.method),e=/\$?\{(\d+)\}/g;if(typeof d=="function")d=d.call(this,b.parameters,a);else if(e.test(d))d=jQuery.format(d.replace(e,"{$1}"),b.parameters);this.errorList.push({message:d,element:a});this.errorMap[a.name]=d;this.submitted[a.name]=
32
- d},addWrapper:function(a){if(this.settings.wrapper)a=a.add(a.parent(this.settings.wrapper));return a},defaultShowErrors:function(){for(var a=0;this.errorList[a];a++){var b=this.errorList[a];this.settings.highlight&&this.settings.highlight.call(this,b.element,this.settings.errorClass,this.settings.validClass);this.showLabel(b.element,b.message)}if(this.errorList.length)this.toShow=this.toShow.add(this.containers);if(this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);
33
- if(this.settings.unhighlight){a=0;for(b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass)}this.toHide=this.toHide.not(this.toShow);this.hideErrors();this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return c(this.errorList).map(function(){return this.element})},showLabel:function(a,b){var d=this.errorsFor(a);if(d.length){d.removeClass(this.settings.validClass).addClass(this.settings.errorClass);
34
- d.attr("generated")&&d.html(b)}else{d=c("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(a),generated:true}).addClass(this.settings.errorClass).html(b||"");if(this.settings.wrapper)d=d.hide().show().wrap("<"+this.settings.wrapper+"/>").parent();this.labelContainer.append(d).length||(this.settings.errorPlacement?this.settings.errorPlacement(d,c(a)):d.insertAfter(a))}if(!b&&this.settings.success){d.text("");typeof this.settings.success=="string"?d.addClass(this.settings.success):this.settings.success(d)}this.toShow=
35
- this.toShow.add(d)},errorsFor:function(a){var b=this.idOrName(a);return this.errors().filter(function(){return c(this).attr("for")==b})},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(a){if(this.checkable(a))a=this.findByName(a.name).not(this.settings.ignore)[0];return a},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(a){var b=this.currentForm;return c(document.getElementsByName(a)).map(function(d,
36
- e){return e.form==b&&e.name==a&&e||null})},getLength:function(a,b){switch(b.nodeName.toLowerCase()){case "select":return c("option:selected",b).length;case "input":if(this.checkable(b))return this.findByName(b.name).filter(":checked").length}return a.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):true},dependTypes:{"boolean":function(a){return a},string:function(a,b){return!!c(a,b.form).length},"function":function(a,b){return a(b)}},optional:function(a){return!c.validator.methods.required.call(this,
37
- c.trim(a.value),a)&&"dependency-mismatch"},startRequest:function(a){if(!this.pending[a.name]){this.pendingRequest++;this.pending[a.name]=true}},stopRequest:function(a,b){this.pendingRequest--;if(this.pendingRequest<0)this.pendingRequest=0;delete this.pending[a.name];if(b&&this.pendingRequest==0&&this.formSubmitted&&this.form()){c(this.currentForm).submit();this.formSubmitted=false}else if(!b&&this.pendingRequest==0&&this.formSubmitted){c(this.currentForm).triggerHandler("invalid-form",[this]);this.formSubmitted=
38
- false}},previousValue:function(a){return c.data(a,"previousValue")||c.data(a,"previousValue",{old:null,valid:true,message:this.defaultMessage(a,"remote")})}},classRuleSettings:{required:{required:true},email:{email:true},url:{url:true},date:{date:true},dateISO:{dateISO:true},dateDE:{dateDE:true},number:{number:true},numberDE:{numberDE:true},digits:{digits:true},creditcard:{creditcard:true}},addClassRules:function(a,b){a.constructor==String?this.classRuleSettings[a]=b:c.extend(this.classRuleSettings,
39
- a)},classRules:function(a){var b={};(a=c(a).attr("class"))&&c.each(a.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(b,c.validator.classRuleSettings[this])});return b},attributeRules:function(a){var b={};a=c(a);for(var d in c.validator.methods){var e;if(e=d==="required"&&typeof c.fn.prop==="function"?a.prop(d):a.attr(d))b[d]=e;else if(a[0].getAttribute("type")===d)b[d]=true}b.maxlength&&/-1|2147483647|524288/.test(b.maxlength)&&delete b.maxlength;return b},metadataRules:function(a){if(!c.metadata)return{};
40
- var b=c.data(a.form,"validator").settings.meta;return b?c(a).metadata()[b]:c(a).metadata()},staticRules:function(a){var b={},d=c.data(a.form,"validator");if(d.settings.rules)b=c.validator.normalizeRule(d.settings.rules[a.name])||{};return b},normalizeRules:function(a,b){c.each(a,function(d,e){if(e===false)delete a[d];else if(e.param||e.depends){var f=true;switch(typeof e.depends){case "string":f=!!c(e.depends,b.form).length;break;case "function":f=e.depends.call(b,b)}if(f)a[d]=e.param!==undefined?
41
- e.param:true;else delete a[d]}});c.each(a,function(d,e){a[d]=c.isFunction(e)?e(b):e});c.each(["minlength","maxlength","min","max"],function(){if(a[this])a[this]=Number(a[this])});c.each(["rangelength","range"],function(){if(a[this])a[this]=[Number(a[this][0]),Number(a[this][1])]});if(c.validator.autoCreateRanges){if(a.min&&a.max){a.range=[a.min,a.max];delete a.min;delete a.max}if(a.minlength&&a.maxlength){a.rangelength=[a.minlength,a.maxlength];delete a.minlength;delete a.maxlength}}a.messages&&delete a.messages;
42
- return a},normalizeRule:function(a){if(typeof a=="string"){var b={};c.each(a.split(/\s/),function(){b[this]=true});a=b}return a},addMethod:function(a,b,d){c.validator.methods[a]=b;c.validator.messages[a]=d!=undefined?d:c.validator.messages[a];b.length<3&&c.validator.addClassRules(a,c.validator.normalizeRule(a))},methods:{required:function(a,b,d){if(!this.depend(d,b))return"dependency-mismatch";switch(b.nodeName.toLowerCase()){case "select":return(a=c(b).val())&&a.length>0;case "input":if(this.checkable(b))return this.getLength(a,
43
- b)>0;default:return c.trim(a).length>0}},remote:function(a,b,d){if(this.optional(b))return"dependency-mismatch";var e=this.previousValue(b);this.settings.messages[b.name]||(this.settings.messages[b.name]={});e.originalMessage=this.settings.messages[b.name].remote;this.settings.messages[b.name].remote=e.message;d=typeof d=="string"&&{url:d}||d;if(this.pending[b.name])return"pending";if(e.old===a)return e.valid;e.old=a;var f=this;this.startRequest(b);var g={};g[b.name]=a;c.ajax(c.extend(true,{url:d,
44
- mode:"abort",port:"validate"+b.name,dataType:"json",data:g,success:function(h){f.settings.messages[b.name].remote=e.originalMessage;var j=h===true;if(j){var i=f.formSubmitted;f.prepareElement(b);f.formSubmitted=i;f.successList.push(b);f.showErrors()}else{i={};h=h||f.defaultMessage(b,"remote");i[b.name]=e.message=c.isFunction(h)?h(a):h;f.showErrors(i)}e.valid=j;f.stopRequest(b,j)}},d));return"pending"},minlength:function(a,b,d){return this.optional(b)||this.getLength(c.trim(a),b)>=d},maxlength:function(a,
45
- b,d){return this.optional(b)||this.getLength(c.trim(a),b)<=d},rangelength:function(a,b,d){a=this.getLength(c.trim(a),b);return this.optional(b)||a>=d[0]&&a<=d[1]},min:function(a,b,d){return this.optional(b)||a>=d},max:function(a,b,d){return this.optional(b)||a<=d},range:function(a,b,d){return this.optional(b)||a>=d[0]&&a<=d[1]},email:function(a,b){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(a)},
46
- url:function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},
47
- date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a))},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 -]+/.test(a))return false;var d=0,e=0,f=false;a=a.replace(/\D/g,"");for(var g=a.length-1;g>=
48
- 0;g--){e=a.charAt(g);e=parseInt(e,10);if(f)if((e*=2)>9)e-=9;d+=e;f=!f}return d%10==0},accept:function(a,b,d){d=typeof d=="string"?d.replace(/,/g,"|"):"png|jpe?g|gif";return this.optional(b)||a.match(RegExp(".("+d+")$","i"))},equalTo:function(a,b,d){d=c(d).unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){c(b).valid()});return a==d.val()}}});c.format=c.validator.format})(jQuery);
49
- (function(c){var a={};if(c.ajaxPrefilter)c.ajaxPrefilter(function(d,e,f){e=d.port;if(d.mode=="abort"){a[e]&&a[e].abort();a[e]=f}});else{var b=c.ajax;c.ajax=function(d){var e=("port"in d?d:c.ajaxSettings).port;if(("mode"in d?d:c.ajaxSettings).mode=="abort"){a[e]&&a[e].abort();return a[e]=b.apply(this,arguments)}return b.apply(this,arguments)}}})(jQuery);
50
- (function(c){!jQuery.event.special.focusin&&!jQuery.event.special.focusout&&document.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.handle.call(this,e)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)},handler:function(e){arguments[0]=c.event.fix(e);arguments[0].type=b;return c.event.handle.apply(this,arguments)}}});c.extend(c.fn,{validateDelegate:function(a,
51
- b,d){return this.bind(b,function(e){var f=c(e.target);if(f.is(a))return d.apply(f,arguments)})}})})(jQuery);
1
+ /*! jQuery Validation Plugin - v1.10.0 - 9/7/2012
2
+ * https://github.com/jzaefferer/jquery-validation
3
+ * Copyright (c) 2012 Jörn Zaefferer; Licensed MIT, GPL */
4
+ (function(a){a.extend(a.fn,{validate:function(b){if(!this.length){b&&b.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing");return}var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","click",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(b.target).hasClass("cancel")&&(c.cancelSubmit=!0)}),this.submit(function(b){function d(){var d;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(c.submitButton.value).appendTo(c.currentForm)),c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){if(a(this[0]).is("form"))return this.validate().form();var b=!0,c=a(this[0].form).validate();return this.each(function(){b&=c.element(this)}),b},removeAttrs:function(b){var c={},d=this;return a.each(b.split(/\s/),function(a,b){c[b]=d.attr(b),d.removeAttr(b)}),c},rules:function(b,c){var d=this[0];if(b){var e=a.data(d.form,"validator").settings,f=e.rules,g=a.validator.staticRules(d);switch(b){case"add":a.extend(g,a.validator.normalizeRule(c)),f[d.name]=g,c.messages&&(e.messages[d.name]=a.extend(e.messages[d.name],c.messages));break;case"remove":if(!c)return delete f[d.name],g;var h={};return a.each(c.split(/\s/),function(a,b){h[b]=g[b],delete g[b]}),h}}var i=a.validator.normalizeRules(a.extend({},a.validator.metadataRules(d),a.validator.classRules(d),a.validator.attributeRules(d),a.validator.staticRules(d)),d);if(i.required){var j=i.required;delete i.required,i=a.extend({required:j},i)}return i}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+b.value)},filled:function(b){return!!a.trim(""+b.value)},unchecked:function(a){return!a.checked}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return arguments.length===1?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),c)}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a,b){this.lastActive=a,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(a)).hide())},onfocusout:function(a,b){!this.checkable(a)&&(a.name in this.submitted||!this.optional(a))&&this.element(a)},onkeyup:function(a,b){if(b.which===9&&this.elementValue(a)==="")return;(a.name in this.submitted||a===this.lastActive)&&this.element(a)},onclick:function(a,b){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){b.type==="radio"?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){b.type==="radio"?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function d(b){var c=a.data(this[0].form,"validator"),d="on"+b.type.replace(/^validate/,"");c.settings[d]&&c.settings[d].call(c,this[0],b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var b=this.groups={};a.each(this.settings.groups,function(c,d){a.each(d.split(/\s/),function(a,d){b[d]=c})});var c=this.settings.rules;a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",d).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",d),this.settings.invalidHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){b=this.validationTargetFor(this.clean(b)),this.lastElement=b,this.prepareElement(b),this.currentElements=a(b);var c=this.check(b)!==!1;return c?delete this.invalid[b.name]:this.invalid[b.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),c},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b=0;for(var c in a)b++;return b},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return this.size()===0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&a.grep(this.errorList,function(a){return a.element.name===b.name}).length===1&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.replace(" ",".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c=a(b).attr("type"),d=a(b).val();return c==="radio"||c==="checkbox"?a('input[name="'+a(b).attr("name")+'"]:checked').val():typeof d=="string"?d.replace(/\r/g,""):d},check:function(b){b=this.validationTargetFor(this.clean(b));var c=a(b).rules(),d=!1,e=this.elementValue(b),f;for(var g in c){var h={method:g,parameters:c[g]};try{f=a.validator.methods[g].call(this,e,b,h.parameters);if(f==="dependency-mismatch"){d=!0;continue}d=!1;if(f==="pending"){this.toHide=this.toHide.not(this.errorsFor(b));return}if(!f)return this.formatAndAdd(b,h),!1}catch(i){throw this.settings.debug&&window.console&&console.log("exception occured when checking element "+b.id+", check the '"+h.method+"' method",i),i}}if(d)return;return this.objectLength(c)&&this.successList.push(b),!0},customMetaMessage:function(b,c){if(!a.metadata)return;var d=this.settings.meta?a(b).metadata()[this.settings.meta]:a(b).metadata();return d&&d.messages&&d.messages[c]},customDataMessage:function(b,c){return a(b).data("msg-"+c.toLowerCase())||b.attributes&&a(b).attr("data-msg-"+c.toLowerCase())},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(arguments[a]!==undefined)return arguments[a];return undefined},defaultMessage:function(b,c){return this.findDefined(this.customMessage(b.name,c),this.customDataMessage(b,c),this.customMetaMessage(b,c),!this.settings.ignoreTitle&&b.title||undefined,a.validator.messages[c],"<strong>Warning: No message defined for "+b.name+"</strong>")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;typeof d=="function"?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b;for(a=0;this.errorList[a];a++){var c=this.errorList[a];this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message)}this.errorList.length&&(this.toShow=this.toShow.add(this.containers));if(this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d=this.errorsFor(b);d.length?(d.removeClass(this.settings.validClass).addClass(this.settings.errorClass),d.attr("generated")&&d.html(c)):(d=a("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(b),generated:!0}).addClass(this.settings.errorClass).html(c||""),this.settings.wrapper&&(d=d.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.append(d).length||(this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b))),!c&&this.settings.success&&(d.text(""),typeof this.settings.success=="string"?d.addClass(this.settings.success):this.settings.success(d,b)),this.toShow=this.toShow.add(d)},errorsFor:function(b){var c=this.idOrName(b);return this.errors().filter(function(){return a(this).attr("for")===c})},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(a){return this.checkable(a)&&(a=this.findByName(a.name).not(this.settings.ignore)[0]),a},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find('[name="'+b+'"]')},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a,b){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&this.pendingRequest===0&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&this.pendingRequest===0&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:function(b){var c={},d=a(b);for(var e in a.validator.methods){var f;e==="required"?(f=d.get(0).getAttribute(e),f===""&&(f=!0),f=!!f):f=d.attr(e),f?c[e]=f:d[0].getAttribute("type")===e&&(c[e]=!0)}return c.maxlength&&/-1|2147483647|524288/.test(c.maxlength)&&delete c.maxlength,c},metadataRules:function(b){if(!a.metadata)return{};var c=a.data(b.form,"validator").settings.meta;return c?a(b).metadata()[c]:a(b).metadata()},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1){delete b[d];return}if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=e.param!==undefined?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength","min","max"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){b[this]&&(b[this]=[Number(b[this][0]),Number(b[this][1])])}),a.validator.autoCreateRanges&&(b.min&&b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),b.minlength&&b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b.messages&&delete b.messages,b},normalizeRule:function(b){if(typeof b=="string"){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=d!==undefined?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if(c.nodeName.toLowerCase()==="select"){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.trim(b).length>0},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e=this.previousValue(c);this.settings.messages[c.name]||(this.settings.messages[c.name]={}),e.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=e.message,d=typeof d=="string"&&{url:d}||d;if(this.pending[c.name])return"pending";if(e.old===b)return e.valid;e.old=b;var f=this;this.startRequest(c);var g={};return g[c.name]=b,a.ajax(a.extend(!0,{url:d,mode:"abort",port:"validate"+c.name,dataType:"json",data:g,success:function(d){f.settings.messages[c.name].remote=e.originalMessage;var g=d===!0||d==="true";if(g){var h=f.formSubmitted;f.prepareElement(c),f.formSubmitted=h,f.successList.push(c),delete f.invalid[c.name],f.showErrors()}else{var i={},j=d||f.defaultMessage(c,"remote");i[c.name]=e.message=a.isFunction(j)?j(b):j,f.invalid[c.name]=!0,f.showErrors(i)}e.valid=g,f.stopRequest(c,g)}},d)),"pending"},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},email:function(a,b){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(a)},url:function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a))},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c=0,d=0,e=!1;a=a.replace(/\D/g,"");for(var f=a.length-1;f>=0;f--){var g=a.charAt(f);d=parseInt(g,10),e&&(d*=2)>9&&(d-=9),c+=d,e=!e}return c%10===0},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()}}}),a.format=a.validator.format})(jQuery),function(a){var b={};if(a.ajaxPrefilter)a.ajaxPrefilter(function(a,c,d){var e=a.port;a.mode==="abort"&&(b[e]&&b[e].abort(),b[e]=d)});else{var c=a.ajax;a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return e==="abort"?(b[f]&&b[f].abort(),b[f]=c.apply(this,arguments)):c.apply(this,arguments)}}}(jQuery),function(a){!jQuery.event.special.focusin&&!jQuery.event.special.focusout&&document.addEventListener&&a.each({focus:"focusin",blur:"focusout"},function(b,c){function d(b){return b=a.event.fix(b),b.type=c,a.event.handle.call(this,b)}a.event.special[c]={setup:function(){this.addEventListener(b,d,!0)},teardown:function(){this.removeEventListener(b,d,!0)},handler:function(b){var d=arguments;return d[0]=a.event.fix(b),d[0].type=c,a.event.handle.apply(this,d)}}}),a.extend(a.fn,{validateDelegate:function(b,c,d){return this.bind(c,function(c){var e=a(c.target);if(e.is(b))return d.apply(e,arguments)})}})}(jQuery)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jqueryui/jquery.ui.datepicker.min.js DELETED
@@ -1,13 +0,0 @@
1
- /*
2
- * jQuery UI Datepicker 1.8.17
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Datepicker
9
- *
10
- * Depends:
11
- * jquery.ui.core.js
12
- */(function($,undefined){function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);!c.length||c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);!$.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])&&!!d.length&&(d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover"))})}function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}$.extend($.ui,{datepicker:{version:"1.8.17"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);c.hasClass(this.markerClassName)||(this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a))},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$('<span class="'+this._appendClass+'">'+c+"</span>"),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('<button type="button"></button>').addClass(this._triggerClass).html(g==""?f:$("<img/>").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){$.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._showDatepicker(a[0]);return!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;d<a.length;d++)a[d].length>b&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);c.hasClass(this.markerClassName)||(c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block"))},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+g+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f);return this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return!0;return!1},_getInst:function(a){try{return $.data(a,PROP_NAME)}catch(b){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(a,b,c){var d=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?$.extend({},$.datepicker._defaults):d?b=="all"?$.extend({},d.settings):this._get(d,b):null;var e=b||{};typeof b=="string"&&(e={},e[b]=c);if(d){this._curInst==d&&this._hideDatepicker();var f=this._getDateDatepicker(a,!0),g=this._getMinMaxDate(d,"min"),h=this._getMinMaxDate(d,"max");extendRemove(d.settings,e),g!==null&&e.dateFormat!==undefined&&e.minDate===undefined&&(d.settings.minDate=this._formatDate(d,g)),h!==null&&e.dateFormat!==undefined&&e.maxDate===undefined&&(d.settings.maxDate=this._formatDate(d,h)),this._attachments($(a),d),this._autoSize(d),this._setDate(d,f),this._updateAlternate(d),this._updateDatepicker(d)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){var b=this._getInst(a);b&&this._updateDatepicker(b)},_setDateDatepicker:function(a,b){var c=this._getInst(a);c&&(this._setDate(c,b),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(a,b){var c=this._getInst(a);c&&!c.inline&&this._setDateFromField(c,b);return c?this._getDate(c):null},_doKeyDown:function(a){var b=$.datepicker._getInst(a.target),c=!0,d=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=!0;if($.datepicker._datepickerShowing)switch(a.keyCode){case 9:$.datepicker._hideDatepicker(),c=!1;break;case 13:var e=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",b.dpDiv);e[0]&&$.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,e[0]);var f=$.datepicker._get(b,"onSelect");if(f){var g=$.datepicker._formatDate(b);f.apply(b.input?b.input[0]:null,[g,b])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&$.datepicker._clearDate(a.target),c=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&$.datepicker._gotoToday(a.target),c=a.ctrlKey||a.metaKey;break;case 37:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?1:-1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,-7,"D"),c=a.ctrlKey||a.metaKey;break;case 39:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?-1:1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,7,"D"),c=a.ctrlKey||a.metaKey;break;default:c=!1}else a.keyCode==36&&a.ctrlKey?$.datepicker._showDatepicker(this):c=!1;c&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(a){var b=$.datepicker._getInst(a.target);if($.datepicker._get(b,"constrainInput")){var c=$.datepicker._possibleChars($.datepicker._get(b,"dateFormat")),d=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||d<" "||!c||c.indexOf(d)>-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(a){$.datepicker.log(a)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if(!$.datepicker._isDisabledDatepicker(a)&&$.datepicker._lastInput!=a){var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){e|=$(this).css("position")=="fixed";return!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0);return b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=$.data(a,PROP_NAME))&&this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=this,f=function(){$.datepicker._tidyDialog(b),e._curInst=null};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,f):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,f),c||f(),this._datepickerShowing=!1;var g=this._get(b,"onClose");g&&g.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!!$.datepicker._curInst){var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);this._isDisabledDatepicker(d[0])||(this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e))},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if(!$(d).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(e[0])){var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();b.setMonth(0),b.setDate(1);return Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1<a.length&&a.charAt(s+1)==b;c&&s++;return c},o=function(a){var c=n(a),d=a=="@"?14:a=="!"?20:a=="y"&&c?4:a=="o"?3:2,e=new RegExp("^\\d{1,"+d+"}"),f=b.substring(r).match(e);if(!f)throw"Missing number at position "+r;r+=f[0].length;return parseInt(f[0],10)},p=function(a,c,d){var e=$.map(n(a)?d:c,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),f=-1;$.each(e,function(a,c){var d=c[1];if(b.substr(r,d.length).toLowerCase()==d.toLowerCase()){f=c[0],r+=d.length;return!1}});if(f!=-1)return f+1;throw"Unknown name at position "+r},q=function(){if(b.charAt(r)!=a.charAt(s))throw"Unexpected literal at position "+r;r++},r=0;for(var s=0;s<a.length;s++)if(m)a.charAt(s)=="'"&&!n("'")?m=!1:q();else switch(a.charAt(s)){case"d":k=o("d");break;case"D":p("D",e,f);break;case"o":l=o("o");break;case"m":j=o("m");break;case"M":j=p("M",g,h);break;case"y":i=o("y");break;case"@":var t=new Date(o("@"));i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"!":var t=new Date((o("!")-this._ticksTo1970)/1e4);i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"'":n("'")?q():m=!0;break;default:q()}if(r<b.length)throw"Extra/unparsed characters found in date: "+b.substring(r);i==-1?i=(new Date).getFullYear():i<100&&(i+=(new Date).getFullYear()-(new Date).getFullYear()%100+(i<=d?0:-100));if(l>-1){j=1,k=l;for(;;){var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+1<a.length&&a.charAt(m+1)==b;c&&m++;return c},i=function(a,b,c){var d=""+b;if(h(a))while(d.length<c)d="0"+d;return d},j=function(a,b,c,d){return h(a)?d[b]:c[b]},k="",l=!1;if(b)for(var m=0;m<a.length;m++)if(l)a.charAt(m)=="'"&&!h("'")?l=!1:k+=a.charAt(m);else switch(a.charAt(m)){case"d":k+=i("d",b.getDate(),2);break;case"D":k+=j("D",b.getDay(),d,e);break;case"o":k+=i("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":k+=i("m",b.getMonth()+1,2);break;case"M":k+=j("M",b.getMonth(),f,g);break;case"y":k+=h("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case"@":k+=b.getTime();break;case"!":k+=b.getTime()*1e4+this._ticksTo1970;break;case"'":h("'")?k+="'":l=!0;break;default:k+=a.charAt(m)}return k},_possibleChars:function(a){var b="",c=!1,d=function(b){var c=e+1<a.length&&a.charAt(e+1)==b;c&&e++;return c};for(var e=0;e<a.length;e++)if(c)a.charAt(e)=="'"&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case"d":case"m":case"y":case"@":b+="0123456789";break;case"D":case"M":return null;case"'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),d=a.lastVal=a.input?a.input.val():null,e,f;e=f=this._getDefaultDate(a);var g=this._getFormatConfig(a);try{e=this.parseDate(c,d,g)||f}catch(h){this.log(h),d=b?"":d}a.selectedDay=e.getDate(),a.drawMonth=a.selectedMonth=e.getMonth(),a.drawYear=a.selectedYear=e.getFullYear(),a.currentDay=d?e.getDate():0,a.currentMonth=d?e.getMonth():0,a.currentYear=d?e.getFullYear():0,this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var d=function(a){var b=new Date;b.setDate(b.getDate()+a);return b},e=function(b){try{return $.datepicker.parseDate($.datepicker._get(a,"dateFormat"),b,$.datepicker._getFormatConfig(a))}catch(c){}var d=(b.toLowerCase().match(/^c/)?$.datepicker._getDate(a):null)||new Date,e=d.getFullYear(),f=d.getMonth(),g=d.getDate(),h=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,i=h.exec(b);while(i){switch(i[2]||"d"){case"d":case"D":g+=parseInt(i[1],10);break;case"w":case"W":g+=parseInt(i[1],10)*7;break;case"m":case"M":f+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f));break;case"y":case"Y":e+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f))}i=h.exec(b)}return new Date(e,f,g)},f=b==null||b===""?c:typeof b=="string"?e(b):typeof b=="number"?isNaN(b)?c:d(b):new Date(b.getTime());f=f&&f.toString()=="Invalid Date"?c:f,f&&(f.setHours(0),f.setMinutes(0),f.setSeconds(0),f.setMilliseconds(0));return this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&p<l?l:p;while(this._daylightSavingAdjust(new Date(o,n,1))>p)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', -"+i+", 'M');\""+' title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>":e?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', +"+i+", 'M');\""+' title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":e?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+dpuuid+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>",x=d?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?w:"")+(this._isInRange(a,v)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._gotoToday('#"+a.id+"');\""+">"+u+"</button>":"")+(c?"":w)+"</div>":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L<g[0];L++){var M="";this.maxRows=4;for(var N=0;N<g[1];N++){var O=this._daylightSavingAdjust(new Date(o,n,a.selectedDay)),P=" ui-corner-all",Q="";if(j){Q+='<div class="ui-datepicker-group';if(g[1]>1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+P+'">'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var R=z?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="<th"+((S+y+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+A[T]+'">'+C[T]+"</span></th>"}Q+=R+"</tr></thead><tbody>";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z<X;Z++){Q+="<tr>";var _=z?'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(Y)+"</td>":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Y<l||m&&Y>m;_+='<td class="'+((S+y+6)%7>=5?" ui-datepicker-week-end":"")+(bb?" ui-datepicker-other-month":"")+(Y.getTime()==O.getTime()&&n==a.selectedMonth&&a._keyEvent||J.getTime()==Y.getTime()&&J.getTime()==O.getTime()?" "+this._dayOverClass:"")+(bc?" "+this._unselectableClass+" ui-state-disabled":"")+(bb&&!G?"":" "+ba[1]+(Y.getTime()==k.getTime()?" "+this._currentClass:"")+(Y.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!bb||G)&&ba[2]?' title="'+ba[2]+'"':"")+(bc?"":' onclick="DP_jQuery_'+dpuuid+".datepicker._selectDay('#"+a.id+"',"+Y.getMonth()+","+Y.getFullYear()+', this);return false;"')+">"+(bb&&!G?"&#xa0;":bc?'<span class="ui-state-default">'+Y.getDate()+"</span>":'<a class="ui-state-default'+(Y.getTime()==b.getTime()?" ui-state-highlight":"")+(Y.getTime()==k.getTime()?" ui-state-active":"")+(bb?" ui-priority-secondary":"")+'" href="#">'+Y.getDate()+"</a>")+"</td>",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+"</tr>"}n++,n>11&&(n=0,o++),Q+="</tbody></table>"+(j?"</div>"+(g[0]>0&&N==g[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),M+=Q}K+=M}K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),a._keyEvent=!1;return K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this
13
- ._get(a,"showMonthAfterYear"),l='<div class="ui-datepicker-title">',m="";if(f||!i)m+='<span class="ui-datepicker-month">'+g[b]+"</span>";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" "+">";for(var p=0;p<12;p++)(!n||p>=d.getMonth())&&(!o||p<=e.getMonth())&&(m+='<option value="'+p+'"'+(p==b?' selected="selected"':"")+">"+h[p]+"</option>");m+="</select>"}k||(l+=m+(f||!i||!j?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+='<span class="ui-datepicker-year">'+c+"</span>";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" "+">";for(;t<=u;t++)a.yearshtml+='<option value="'+t+'"'+(t==c?' selected="selected"':"")+">"+t+"</option>";a.yearshtml+="</select>",l+=a.yearshtml,a.yearshtml=null}}l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?"&#xa0;":"")+m),l+="</div>";return l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&b<c?c:b;e=d&&e>d?d:e;return e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth()));return this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));return this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)})},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.17",window["DP_jQuery_"+dpuuid]=$})(jQuery)
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jqueryui/jquery.ui.slider.min.js DELETED
@@ -1,14 +0,0 @@
1
- /*
2
- * jQuery UI Slider 1.8.17
3
- *
4
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
- * Dual licensed under the MIT or GPL Version 2 licenses.
6
- * http://jquery.org/license
7
- *
8
- * http://docs.jquery.com/UI/Slider
9
- *
10
- * Depends:
11
- * jquery.ui.core.js
12
- * jquery.ui.mouse.js
13
- * jquery.ui.widget.js
14
- */(function(a,b){var c=5;a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var b=this,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",g=d.values&&d.values.length||1,h=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":"")),this.range=a([]),d.range&&(d.range===!0&&(d.values||(d.values=[this._valueMin(),this._valueMin()]),d.values.length&&d.values.length!==2&&(d.values=[d.values[0],d.values[0]])),this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;i<g;i+=1)h.push(f);this.handles=e.add(a(h.join("")).appendTo(b.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(a){a.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){d.disabled?a(this).blur():(a(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),a(this).addClass("ui-state-focus"))}).blur(function(){a(this).removeClass("ui-state-focus")}),this.handles.each(function(b){a(this).data("index.ui-slider-handle",b)}),this.handles.keydown(function(d){var e=!0,f=a(this).data("index.ui-slider-handle"),g,h,i,j;if(!b.options.disabled){switch(d.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:e=!1;if(!b._keySliding){b._keySliding=!0,a(this).addClass("ui-state-active"),g=b._start(d,f);if(g===!1)return}}j=b.options.step,b.options.values&&b.options.values.length?h=i=b.values(f):h=i=b.value();switch(d.keyCode){case a.ui.keyCode.HOME:i=b._valueMin();break;case a.ui.keyCode.END:i=b._valueMax();break;case a.ui.keyCode.PAGE_UP:i=b._trimAlignValue(h+(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.PAGE_DOWN:i=b._trimAlignValue(h-(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(h===b._valueMax())return;i=b._trimAlignValue(h+j);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(h===b._valueMin())return;i=b._trimAlignValue(h-j)}b._slide(d,f,i);return e}}).keyup(function(c){var d=a(this).data("index.ui-slider-handle");b._keySliding&&(b._keySliding=!1,b._stop(c,d),b._change(c,d),a(this).removeClass("ui-state-active"))}),this._refreshValue(),this._animateOff=!1},destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"),this._mouseDestroy();return this},_mouseCapture:function(b){var c=this.options,d,e,f,g,h,i,j,k,l;if(c.disabled)return!1;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),d={x:b.pageX,y:b.pageY},e=this._normValueFromMouse(d),f=this._valueMax()-this._valueMin()+1,h=this,this.handles.each(function(b){var c=Math.abs(e-h.values(b));f>c&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i);if(j===!1)return!1;this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0;return!0},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);this._slide(a,this._handleIndex,c);return!1},_mouseStop:function(a){this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1;return!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e;return this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values());return this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c<d)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c,!0))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("change",a,c)}},value:function(a){if(arguments.length)this.options.value=this._trimAlignValue(a),this._refreshValue(),this._change(null,0);else return this._value()},values:function(b,c){var d,e,f;if(arguments.length>1)this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);else{if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f<d.length;f+=1)d[f]=this._trimAlignValue(e[f]),this._change(null,f);this._refreshValue()}},_setOption:function(b,c){var d,e=0;a.isArray(this.options.values)&&(e=this.options.values.length),a.Widget.prototype._setOption.apply(this,arguments);switch(b){case"disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.propAttr("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.propAttr("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(d=0;d<e;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var a=this.options.value;a=this._trimAlignValue(a);return a},_values:function(a){var b,c,d;if(arguments.length){b=this.options.values[a],b=this._trimAlignValue(b);return b}c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);return c},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;Math.abs(c)*2>=b&&(d+=c>0?b:-b);return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.17"})})(jQuery)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/plupload-image.js CHANGED
@@ -51,7 +51,7 @@ jQuery( document ).ready( function($)
51
 
52
  // Add field_id to the ajax call
53
  rwmb_plupload_init['multipart_params'] = {
54
- action : 'plupload_image_upload',
55
  field_id: prefix,
56
  _wpnonce: nonce,
57
  post_id : $( '#post_ID' ).val()
51
 
52
  // Add field_id to the ajax call
53
  rwmb_plupload_init['multipart_params'] = {
54
+ action : 'rwmb_plupload_image_upload',
55
  field_id: prefix,
56
  _wpnonce: nonce,
57
  post_id : $( '#post_ID' ).val()
js/slider.js CHANGED
@@ -1,29 +1,29 @@
1
- jQuery( document ).ready( function($)
2
  {
3
- var
4
- id = null
5
- ,el = null
6
- ,input = null
7
- ,label = null
8
- ,format = null
9
- ,value = null
10
- ,update = null
11
- ;
12
- $( '.rwmb-slider' ).each( function( i, val )
13
  {
14
- id = $( val ).attr( 'id' );
15
- el = $( '#' + id );
16
- input = $( '[name=' + id + ']' );
17
- label = $( '[for=' + id + ']' );
18
- format = $( el ).attr( 'rel' );
19
 
20
  $( label ).append( ': <span id="' + id + '-label"></span>' );
21
- update = $( '#' + id + '-label' );
22
 
23
- if (
24
- ! $( input ).val()
25
- || 'undefined' === $( input ).val()
26
- || null === typeof $( input ).val()
27
  )
28
  {
29
  $( input ).val( $( el ).slider( "values", 0 ) );
@@ -38,13 +38,13 @@ jQuery( document ).ready( function($)
38
  $( update ).append( ' ' + format );
39
 
40
  el.slider(
41
- {
42
- value: value,
43
- slide: function( event, ui )
44
  {
45
- $( input ).val( ui.value );
46
- $( update ).text( ui.value + ' ' + format );
47
- }
48
- } );
49
- });
 
 
 
50
  } );
1
+ jQuery( document ).ready( function ( $ )
2
  {
3
+ var
4
+ id = null
5
+ , el = null
6
+ , input = null
7
+ , label = null
8
+ , format = null
9
+ , value = null
10
+ , update = null
11
+ ;
12
+ $( '.rwmb-slider' ).each( function ( i, val )
13
  {
14
+ id = $( val ).attr( 'id' );
15
+ el = $( '#' + id );
16
+ input = $( '[name=' + id + ']' );
17
+ label = $( '[for=' + id + ']' );
18
+ format = $( el ).attr( 'rel' );
19
 
20
  $( label ).append( ': <span id="' + id + '-label"></span>' );
21
+ update = $( '#' + id + '-label' );
22
 
23
+ if (
24
+ !$( input ).val()
25
+ || 'undefined' === $( input ).val()
26
+ || null === typeof $( input ).val()
27
  )
28
  {
29
  $( input ).val( $( el ).slider( "values", 0 ) );
38
  $( update ).append( ' ' + format );
39
 
40
  el.slider(
 
 
 
41
  {
42
+ value: value,
43
+ slide: function ( event, ui )
44
+ {
45
+ $( input ).val( ui.value );
46
+ $( update ).text( ui.value + ' ' + format );
47
+ }
48
+ } );
49
+ } );
50
  } );
js/thickbox-image.js CHANGED
@@ -17,7 +17,7 @@ jQuery( document ).ready( function( $ )
17
  html = '<li id="item_' + id + '">';
18
  html += '<img src="' + url + '" />';
19
  html += '<div class="rwmb-image-bar">';
20
- html += '<a class="rwmb-delete-file" href="#" rel="' + id + '">Delete</a>';
21
  html += '</div>';
22
  html += '<input type="hidden" name="' + field_id + '[]" value="' + id + '" />';
23
  html += '</li>';
17
  html = '<li id="item_' + id + '">';
18
  html += '<img src="' + url + '" />';
19
  html += '<div class="rwmb-image-bar">';
20
+ html += '<a class="rwmb-delete-file" href="#" data-field_id="' + field_id + '" data-attachment_id="' + id + '">Delete</a>';
21
  html += '</div>';
22
  html += '<input type="hidden" name="' + field_id + '[]" value="' + id + '" />';
23
  html += '</li>';
js/time.js CHANGED
@@ -9,17 +9,9 @@ function rwmb_update_time_picker()
9
  $( '.rwmb-time' ).each( function()
10
  {
11
  var $this = $( this ),
12
- format = $this.attr( 'rel' ),
13
- show_amppm = /t/i.test(format),
14
- show_second = /:s/.test(format),
15
- show_millisec = /:l/.test(format);
16
 
17
- $this.removeClass('hasDatepicker').attr('id', '').timepicker( {
18
- showSecond : show_second,
19
- showMillisec: show_millisec,
20
- timeFormat : format,
21
- ampm : show_amppm,
22
- } );
23
  } );
24
  }
25
 
9
  $( '.rwmb-time' ).each( function()
10
  {
11
  var $this = $( this ),
12
+ options = $this.data( 'options' );
 
 
 
13
 
14
+ $this.removeClass( 'hasDatepicker' ).attr( 'id', '' ).datetimepicker( options );
 
 
 
 
 
15
  } );
16
  }
17
 
js/validate.js CHANGED
@@ -1,14 +1,12 @@
1
  jQuery( document ).ready( function ( $ )
2
  {
 
 
3
  // Required field styling
4
  $.each( rwmb.validationOptions.rules, function( k, v )
5
  {
6
  if ( v['required'] )
7
- {
8
- var $label = $( '#' + k ).parent().siblings( '.rwmb-label' );
9
- $label.find( 'label' ).css( 'font-weight','bold' );
10
- $label.append( '<span class="required">*</span>' );
11
- }
12
  } );
13
 
14
  rwmb.validationOptions.invalidHandler = function( form, validator )
@@ -16,8 +14,9 @@ jQuery( document ).ready( function ( $ )
16
  // Re-enable the submit ( publish/update ) button and hide the ajax indicator
17
  $( '#publish' ).removeClass( 'button-primary-disabled' );
18
  $( '#ajax-loading' ).attr( 'style','' );
19
- $( 'form#post' ).siblings( '#message' ).remove();
20
- $( 'form#post' ).before( '<div id="message" class="error"><p>' + rwmb.summaryMessage + '</p></div>' );
21
  };
22
- $( 'form#post' ).validate( rwmb.validationOptions );
 
23
  } );
1
  jQuery( document ).ready( function ( $ )
2
  {
3
+ var $form = $( '#post' );
4
+
5
  // Required field styling
6
  $.each( rwmb.validationOptions.rules, function( k, v )
7
  {
8
  if ( v['required'] )
9
+ $( '#' + k ).parent().siblings( '.rwmb-label' ).addClass( 'required' ).append( '<span>*</span>' );
 
 
 
 
10
  } );
11
 
12
  rwmb.validationOptions.invalidHandler = function( form, validator )
14
  // Re-enable the submit ( publish/update ) button and hide the ajax indicator
15
  $( '#publish' ).removeClass( 'button-primary-disabled' );
16
  $( '#ajax-loading' ).attr( 'style','' );
17
+ $form.siblings( '#message' ).remove();
18
+ $form.before( '<div id="message" class="error"><p>' + rwmb.summaryMessage + '</p></div>' );
19
  };
20
+
21
+ $form.validate( rwmb.validationOptions );
22
  } );
meta-box.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Meta Box
4
  Plugin URI: http://www.deluxeblogtips.com/meta-box
5
  Description: Create meta box for editing pages in WordPress. Compatible with custom post types since WP 3.0
6
- Version: 4.1.11
7
  Author: Rilwis
8
  Author URI: http://www.deluxeblogtips.com
9
  License: GPL2+
@@ -13,7 +13,7 @@ License: GPL2+
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  // Script version, used to add version for scripts and styles
16
- define( 'RWMB_VER', '4.1.9' );
17
 
18
  // Define plugin URLs, for fast enqueuing scripts and styles
19
  if ( ! defined( 'RWMB_URL' ) )
3
  Plugin Name: Meta Box
4
  Plugin URI: http://www.deluxeblogtips.com/meta-box
5
  Description: Create meta box for editing pages in WordPress. Compatible with custom post types since WP 3.0
6
+ Version: 4.2
7
  Author: Rilwis
8
  Author URI: http://www.deluxeblogtips.com
9
  License: GPL2+
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  // Script version, used to add version for scripts and styles
16
+ define( 'RWMB_VER', '4.2' );
17
 
18
  // Define plugin URLs, for fast enqueuing scripts and styles
19
  if ( ! defined( 'RWMB_URL' ) )
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.deluxeblogtips.com/donate
4
  Tags: meta-box, custom-fields, custom-field, meta, meta-boxes
5
  Requires at least: 3.0
6
  Tested up to: 3.4.2
7
- Stable tag: 4.1.11
8
 
9
  Meta Box plugin helps you easily implement multiple meta boxes in editing pages in WordPress. Works with custom post types and various field types.
10
 
@@ -28,6 +28,7 @@ Meta Box plugin provides an API to easily implement custom meta boxes in editing
28
  - file
29
  - hidden
30
  - image
 
31
  - password
32
  - plupload_image
33
  - radio
@@ -58,13 +59,22 @@ To getting started with the plugin API, please read [this tutorial](http://www.d
58
 
59
  == Changelog ==
60
 
 
 
 
 
 
 
 
 
 
61
  = 4.1.11 =
62
  * Bug fix: helper function for getting `taxonomy` field type
63
  * Bug fix: `multiple` attribute for `select` field type
64
 
65
  = 4.1.10 =
66
  * Allow helper functions can be used in admin area
67
- * Allow cloned fields to have a uniquely indexed `name` attribute
68
  * Add Swedish translation
69
  * Allow hidden field has its own value
70
  * Taxonomy field now supported by `rwmb_meta` function
4
  Tags: meta-box, custom-fields, custom-field, meta, meta-boxes
5
  Requires at least: 3.0
6
  Tested up to: 3.4.2
7
+ Stable tag: 4.2
8
 
9
  Meta Box plugin helps you easily implement multiple meta boxes in editing pages in WordPress. Works with custom post types and various field types.
10
 
28
  - file
29
  - hidden
30
  - image
31
+ - number
32
  - password
33
  - plupload_image
34
  - radio
59
 
60
  == Changelog ==
61
 
62
+ = 4.2 =
63
+ * Bug fix: save only last element of `select` field with `multiple` values. [Link](http://wordpress.org/support/topic/plugin-meta-box-multiple-declaration-for-select-fields-no-longer-working?replies=5#post-3254534)
64
+ * Improvement: add `js_options` attribute for `date`, `datetime`, `time` fields to adjust jQuery date/datetime picker options. See `demo/demo.php` for usage
65
+ * Improvement: add `options` attribute for `wysiwyg`. You now can pass arguments same as for `wp_editor` function
66
+ * Improvement: clone feature now works with `checkbox_list` and `select` with `multiple` values
67
+ * Improvement: add `rwmb-{$field_type}-wrapper` class to field markup
68
+ * Improvement: Add [rwmb_meta meta_key="..."] shortcode. Attributes are the same as `rwmb_meta` function.
69
+ * Code refactored
70
+
71
  = 4.1.11 =
72
  * Bug fix: helper function for getting `taxonomy` field type
73
  * Bug fix: `multiple` attribute for `select` field type
74
 
75
  = 4.1.10 =
76
  * Allow helper functions can be used in admin area
77
+ * Allow cloned fields to have a uniquely indexed `name` attribute
78
  * Add Swedish translation
79
  * Allow hidden field has its own value
80
  * Taxonomy field now supported by `rwmb_meta` function
screenshot-1.png CHANGED
Binary file
screenshot-2.png DELETED
Binary file