Version Description
Export entries to a CSV, file uploads, and various bug fixes.
Download this release
Release Info
Developer | mmuro |
Plugin | Visual Form Builder |
Version | 1.4 |
Comparing to | |
See all releases |
Code changes from version 1.3.1 to 1.4
- class-entries-detail.php +99 -0
- class-entries-list.php +174 -8
- css/sprite.png +0 -0
- css/visual-form-builder-admin.css +2 -0
- css/visual-form-builder.css +26 -1
- js/js_quicktags.js +544 -0
- js/visual-form-builder.js +2 -2
- readme.txt +33 -2
- visual-form-builder.php +103 -24
class-entries-detail.php
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Class that builds our Entries detail page
|
4 |
+
*
|
5 |
+
* @since 1.4
|
6 |
+
*/
|
7 |
+
class VisualFormBuilder_Entries_Detail{
|
8 |
+
public function __construct(){
|
9 |
+
global $wpdb;
|
10 |
+
|
11 |
+
/* Setup global database table names */
|
12 |
+
$this->field_table_name = $wpdb->prefix . 'visual_form_builder_fields';
|
13 |
+
$this->form_table_name = $wpdb->prefix . 'visual_form_builder_forms';
|
14 |
+
$this->entries_table_name = $wpdb->prefix . 'visual_form_builder_entries';
|
15 |
+
|
16 |
+
add_action( 'admin_init', array( &$this, 'entries_detail' ) );
|
17 |
+
}
|
18 |
+
|
19 |
+
public function entries_detail(){
|
20 |
+
global $wpdb;
|
21 |
+
|
22 |
+
$entry_id = absint( $_REQUEST['entry'] );
|
23 |
+
|
24 |
+
$query = "SELECT forms.form_title, entries.* FROM $this->form_table_name AS forms INNER JOIN $this->entries_table_name AS entries ON entries.form_id = forms.form_id WHERE entries.entries_id = $entry_id;";
|
25 |
+
|
26 |
+
$entries = $wpdb->get_results( $query );
|
27 |
+
|
28 |
+
echo '<p>' . sprintf( '<a href="?page=%s&view=%s" class="view-entry">« Back to Entries</a>', $_REQUEST['page'], $_REQUEST['view'] ) . '</p>';
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
/* Loop trough the entries and setup the data to be displayed for each row */
|
33 |
+
foreach ( $entries as $entry ) {
|
34 |
+
$data = unserialize( $entry->data );
|
35 |
+
|
36 |
+
echo '<div id="poststuff" class="metabox-holder has-right-sidebar">
|
37 |
+
<div id="side-info-column" class="inner-sidebar">
|
38 |
+
<div id="side-sortables">
|
39 |
+
<div id="submitdiv" class="postbox">
|
40 |
+
<h3><span>Details</span></h3>
|
41 |
+
<div class="inside">
|
42 |
+
<div id="submitbox" class="submitbox">
|
43 |
+
<div id="minor-publishing">
|
44 |
+
<div id="misc-publishing-actions">
|
45 |
+
<div class="misc-pub-section">
|
46 |
+
<span><strong>Form Title: </strong>' . stripslashes( $entry->form_title ) . '</span>
|
47 |
+
</div>
|
48 |
+
<div class="misc-pub-section">
|
49 |
+
<span><strong>Date Submitted: </strong>' . $entry->date_submitted . '</span>
|
50 |
+
</div>
|
51 |
+
<div class="misc-pub-section">
|
52 |
+
<span><strong>IP Address: </strong>' . $entry->ip_address . '</span>
|
53 |
+
</div>
|
54 |
+
<div class="misc-pub-section">
|
55 |
+
<span><strong>Email Subject: </strong>' . stripslashes( $entry->subject ) . '</span>
|
56 |
+
</div>
|
57 |
+
<div class="misc-pub-section">
|
58 |
+
<span><strong>Sender Name: </strong>' . stripslashes( $entry->sender_name ) . '</span>
|
59 |
+
</div>
|
60 |
+
<div class="misc-pub-section">
|
61 |
+
<span><strong>Sender Email: </strong><a href="mailto:' . stripslashes( $entry->sender_email ) . '">' . stripslashes( $entry->sender_email ) . '</a></span>
|
62 |
+
</div>
|
63 |
+
<div class="misc-pub-section misc-pub-section-last">
|
64 |
+
<span><strong>Emailed To: </strong>' . preg_replace('/\b([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b/i', '<a href="mailto:$1">$1</a>', implode( ',', unserialize( stripslashes( $entry->emails_to ) ) ) ) . '</span>
|
65 |
+
</div>
|
66 |
+
<div class="clear"></div>
|
67 |
+
</div>
|
68 |
+
</div>
|
69 |
+
|
70 |
+
<div id="major-publishing-actions">
|
71 |
+
<div id="delete-action">'
|
72 |
+
. sprintf( '<a class="submitdelete deletion" href="?page=%s&view=%s&action=%s&entry=%s">Delete</a>', $_REQUEST['page'], $_REQUEST['view'], 'delete', $entry_id ) .
|
73 |
+
'</div>
|
74 |
+
<div class="clear"></div>
|
75 |
+
</div>
|
76 |
+
</div>
|
77 |
+
</div>
|
78 |
+
</div>
|
79 |
+
</div>
|
80 |
+
</div>';
|
81 |
+
echo '<div>
|
82 |
+
<div id="post-body-content">
|
83 |
+
<div class="postbox">
|
84 |
+
<h3><span>' . $entry->form_title . ' : Entry #' . $entry->entries_id . '</span></h3>
|
85 |
+
<div class="inside">';
|
86 |
+
|
87 |
+
foreach ( $data as $k => $v ) {
|
88 |
+
echo '<h4>' . ucwords( $k ) . '</h4>';
|
89 |
+
//echo '<pre>' . $v . '</pre>';
|
90 |
+
echo $v;
|
91 |
+
}
|
92 |
+
|
93 |
+
echo '</div></div></div></div>';
|
94 |
+
}
|
95 |
+
|
96 |
+
echo '<br class="clear"></div>';
|
97 |
+
}
|
98 |
+
}
|
99 |
+
?>
|
class-entries-list.php
CHANGED
@@ -25,9 +25,9 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
25 |
'singular' => 'entry',
|
26 |
'plural' => 'entries',
|
27 |
'ajax' => false
|
28 |
-
) );
|
29 |
}
|
30 |
-
|
31 |
/**
|
32 |
* Display column names. We'll handle the Form column separately.
|
33 |
*
|
@@ -55,7 +55,7 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
55 |
|
56 |
/* Build row actions */
|
57 |
$actions = array(
|
58 |
-
'view' => sprintf( '<a href="
|
59 |
'delete' => sprintf( '<a href="?page=%s&view=%s&action=%s&entry=%s">Delete</a>', $_REQUEST['page'], $_REQUEST['view'], 'delete', $item['entry_id'] ),
|
60 |
);
|
61 |
|
@@ -107,7 +107,7 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
107 |
* @since 1.2
|
108 |
* @returns array() $cols SQL results
|
109 |
*/
|
110 |
-
function get_entries( $orderby = 'date', $order = '
|
111 |
global $wpdb;
|
112 |
|
113 |
switch ( $orderby ) {
|
@@ -126,9 +126,9 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
126 |
}
|
127 |
|
128 |
$where = '';
|
129 |
-
|
130 |
/* If the form filter dropdown is used */
|
131 |
-
if ( $this->current_filter_action() )
|
132 |
$where = 'WHERE forms.form_id = ' . $this->current_filter_action();
|
133 |
|
134 |
|
@@ -166,7 +166,9 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
166 |
*/
|
167 |
function get_bulk_actions() {
|
168 |
$actions = array(
|
169 |
-
'delete' => 'Delete'
|
|
|
|
|
170 |
);
|
171 |
|
172 |
return $actions;
|
@@ -190,6 +192,166 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
190 |
}
|
191 |
}
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
/**
|
194 |
* Adds our forms filter dropdown
|
195 |
*
|
@@ -241,6 +403,10 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
241 |
/* Get screen options from the wp_options table */
|
242 |
$options = get_option( 'visual-form-builder-screen-options' );
|
243 |
|
|
|
|
|
|
|
|
|
244 |
/* How many to show per page */
|
245 |
$per_page = $options['per_page'];
|
246 |
|
@@ -276,7 +442,7 @@ class VisualFormBuilder_Entries_List extends WP_List_Table {
|
|
276 |
'sender_name' => stripslashes( $entry->sender_name ),
|
277 |
'sender_email' => stripslashes( $entry->sender_email ),
|
278 |
'emails_to' => implode( ',', unserialize( stripslashes( $entry->emails_to ) ) ),
|
279 |
-
'date' => $entry->date_submitted,
|
280 |
'ip_address' => $entry->ip_address,
|
281 |
'data' => unserialize( $entry->data )
|
282 |
);
|
25 |
'singular' => 'entry',
|
26 |
'plural' => 'entries',
|
27 |
'ajax' => false
|
28 |
+
) );
|
29 |
}
|
30 |
+
|
31 |
/**
|
32 |
* Display column names. We'll handle the Form column separately.
|
33 |
*
|
55 |
|
56 |
/* Build row actions */
|
57 |
$actions = array(
|
58 |
+
'view' => sprintf( '<a href="?page=%s&view=%s&action=%s&entry=%s" id="%4$s" class="view-entry">View</a>', $_REQUEST['page'], $_REQUEST['view'], 'view', $item['entry_id'] ),
|
59 |
'delete' => sprintf( '<a href="?page=%s&view=%s&action=%s&entry=%s">Delete</a>', $_REQUEST['page'], $_REQUEST['view'], 'delete', $item['entry_id'] ),
|
60 |
);
|
61 |
|
107 |
* @since 1.2
|
108 |
* @returns array() $cols SQL results
|
109 |
*/
|
110 |
+
function get_entries( $orderby = 'date', $order = 'ASC' ){
|
111 |
global $wpdb;
|
112 |
|
113 |
switch ( $orderby ) {
|
126 |
}
|
127 |
|
128 |
$where = '';
|
129 |
+
|
130 |
/* If the form filter dropdown is used */
|
131 |
+
if ( $this->current_filter_action() && absint( $this->current_filter_action ) )
|
132 |
$where = 'WHERE forms.form_id = ' . $this->current_filter_action();
|
133 |
|
134 |
|
166 |
*/
|
167 |
function get_bulk_actions() {
|
168 |
$actions = array(
|
169 |
+
'delete' => 'Delete',
|
170 |
+
'export-all' => 'Export All',
|
171 |
+
'export-selected' => 'Export Selected'
|
172 |
);
|
173 |
|
174 |
return $actions;
|
192 |
}
|
193 |
}
|
194 |
|
195 |
+
/**
|
196 |
+
* Handle the entries CSV export
|
197 |
+
*
|
198 |
+
* @since 1.4
|
199 |
+
*/
|
200 |
+
function export_entries( $selected = NULL ) {
|
201 |
+
global $wpdb;
|
202 |
+
|
203 |
+
/* Setup our query to accept selected entry IDs */
|
204 |
+
if ( is_array( $selected ) && !empty( $selected ) )
|
205 |
+
$selected = " WHERE entries.entries_id IN (" . implode( ',', $selected ) . ")";
|
206 |
+
|
207 |
+
$entries = $wpdb->get_results( "SELECT entries.*, forms.form_title FROM $this->entries_table_name AS entries JOIN $this->form_table_name AS forms USING(form_id) $selected ORDER BY entries_id DESC" );
|
208 |
+
|
209 |
+
/* If there's entries returned, do our CSV stuff */
|
210 |
+
if ( $entries ) :
|
211 |
+
|
212 |
+
/* Setup our default columns */
|
213 |
+
$cols = array(
|
214 |
+
'entries_id' => array(
|
215 |
+
'header' => 'Entries ID',
|
216 |
+
'data' => array()
|
217 |
+
),
|
218 |
+
'form_title' => array(
|
219 |
+
'header' => 'Form',
|
220 |
+
'data' => array()
|
221 |
+
),
|
222 |
+
'date_submitted' => array(
|
223 |
+
'header' => 'Date Submitted',
|
224 |
+
'data' => array()
|
225 |
+
),
|
226 |
+
'ip_address' => array(
|
227 |
+
'header' => 'IP Address',
|
228 |
+
'data' => array()
|
229 |
+
),
|
230 |
+
'subject' => array(
|
231 |
+
'header' => 'Email Subject',
|
232 |
+
'data' => array()
|
233 |
+
),
|
234 |
+
'sender_name' => array(
|
235 |
+
'header' => 'Sender Name',
|
236 |
+
'data' => array()
|
237 |
+
),
|
238 |
+
'sender_email' => array(
|
239 |
+
'header' => 'Sender Email',
|
240 |
+
'data' => array()
|
241 |
+
),
|
242 |
+
'emails_to' => array(
|
243 |
+
'header' => 'Emailed To',
|
244 |
+
'data' => array()
|
245 |
+
)
|
246 |
+
);
|
247 |
+
|
248 |
+
/* Initialize row index at 0 */
|
249 |
+
$row = 0;
|
250 |
+
|
251 |
+
/* Loop through all entries */
|
252 |
+
foreach ( $entries as $entry ) {
|
253 |
+
/* Loop through each entry and its fields */
|
254 |
+
foreach ( $entry as $key => $value ) {
|
255 |
+
/* Handle each column in the entries table */
|
256 |
+
switch ( $key ) {
|
257 |
+
case 'entries_id':
|
258 |
+
case 'form_title':
|
259 |
+
case 'date_submitted':
|
260 |
+
case 'ip_address':
|
261 |
+
case 'subject':
|
262 |
+
case 'sender_name':
|
263 |
+
case 'sender_email':
|
264 |
+
$cols[$key]['data'][$row] = $value;
|
265 |
+
break;
|
266 |
+
|
267 |
+
case 'emails_to':
|
268 |
+
$cols[$key]['data'][$row] = implode( ',', maybe_unserialize( $value ) );
|
269 |
+
break;
|
270 |
+
|
271 |
+
case 'data':
|
272 |
+
/* Unserialize value only if it was serialized */
|
273 |
+
$fields = maybe_unserialize( $value );
|
274 |
+
|
275 |
+
/* Loop through our submitted data */
|
276 |
+
foreach ( $fields as $field_key => $field_value ) {
|
277 |
+
|
278 |
+
/* Replace quotes for the header */
|
279 |
+
$header = str_replace( '"', '""', ucwords( $field_key ) );
|
280 |
+
|
281 |
+
/* Replace all spaces for each form field name */
|
282 |
+
$field_key = preg_replace( '/(\s)/i', '', $field_key );
|
283 |
+
|
284 |
+
/* Find new field names and make a new column with a header */
|
285 |
+
if ( !array_key_exists( $field_key, $cols ) ) {
|
286 |
+
$cols[$field_key] = array(
|
287 |
+
'header' => $header,
|
288 |
+
'data' => array()
|
289 |
+
);
|
290 |
+
}
|
291 |
+
|
292 |
+
/* Get rid of single quote entity */
|
293 |
+
$field_value = str_replace( ''', "'", $field_value );
|
294 |
+
|
295 |
+
/* Load data, row by row */
|
296 |
+
$cols[$field_key]['data'][$row] = str_replace( '"', '""', stripslashes( html_entity_decode( $field_value ) ) );
|
297 |
+
}
|
298 |
+
break;
|
299 |
+
}
|
300 |
+
|
301 |
+
}
|
302 |
+
|
303 |
+
$row++;
|
304 |
+
}
|
305 |
+
|
306 |
+
/* Setup our CSV vars */
|
307 |
+
$csv_headers = NULL;
|
308 |
+
$csv_rows = array();
|
309 |
+
|
310 |
+
/* Loop through each column */
|
311 |
+
foreach ( $cols as $data ) {
|
312 |
+
/* End our header row, if needed */
|
313 |
+
if ( $csv_headers )
|
314 |
+
$csv_headers .= ',';
|
315 |
+
|
316 |
+
/* Build our headers */
|
317 |
+
$csv_headers .= "{$data['header']}";
|
318 |
+
|
319 |
+
/* Loop through each row of data and add to our CSV */
|
320 |
+
for ( $i = 0; $i < $row; $i++ ) {
|
321 |
+
/* End our row of data, if needed */
|
322 |
+
if ( $csv_rows[$i] )
|
323 |
+
$csv_rows[$i] .= ',';
|
324 |
+
|
325 |
+
/* Add a starting quote for this row's data */
|
326 |
+
$csv_rows[$i] .= '"';
|
327 |
+
|
328 |
+
/* If there's data at this point, add it to the row */
|
329 |
+
if ( array_key_exists( $i, $data['data'] ) )
|
330 |
+
$csv_rows[$i] .= $data['data'][$i];
|
331 |
+
|
332 |
+
/* Add a closing quote for this row's data */
|
333 |
+
$csv_rows[$i] .= '"';
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
/* Change our header so the browser spits out a CSV file to download */
|
338 |
+
header('Content-type: text/csv');
|
339 |
+
header('Content-Disposition: attachment; filename="' . date( 'Y-m-d' ) . '-entries.csv"');
|
340 |
+
ob_clean();
|
341 |
+
|
342 |
+
/* Print headers for the CSV */
|
343 |
+
echo $csv_headers . "\n";
|
344 |
+
|
345 |
+
/* Print each row of data for the CSV */
|
346 |
+
foreach ( $csv_rows as $row ) {
|
347 |
+
echo $row . "\n";
|
348 |
+
}
|
349 |
+
|
350 |
+
die();
|
351 |
+
|
352 |
+
endif;
|
353 |
+
}
|
354 |
+
|
355 |
/**
|
356 |
* Adds our forms filter dropdown
|
357 |
*
|
403 |
/* Get screen options from the wp_options table */
|
404 |
$options = get_option( 'visual-form-builder-screen-options' );
|
405 |
|
406 |
+
/* Get the date/time format that is saved in the options table */
|
407 |
+
$date_format = get_option('date_format');
|
408 |
+
$time_format = get_option('time_format');
|
409 |
+
|
410 |
/* How many to show per page */
|
411 |
$per_page = $options['per_page'];
|
412 |
|
442 |
'sender_name' => stripslashes( $entry->sender_name ),
|
443 |
'sender_email' => stripslashes( $entry->sender_email ),
|
444 |
'emails_to' => implode( ',', unserialize( stripslashes( $entry->emails_to ) ) ),
|
445 |
+
'date' => date( "$date_format $time_format", strtotime( $entry->date_submitted ) ),
|
446 |
'ip_address' => $entry->ip_address,
|
447 |
'data' => unserialize( $entry->data )
|
448 |
);
|
css/sprite.png
CHANGED
Binary file
|
css/visual-form-builder-admin.css
CHANGED
@@ -31,6 +31,8 @@ label.error{color:red;display:block;}
|
|
31 |
#form-element-digits{background:url(sprite.png) 0 -452px no-repeat transparent;}
|
32 |
#form-element-time{background:url(sprite.png) 0 -489px no-repeat transparent;}
|
33 |
#form-element-phone{background:url(sprite.png) 0 -529px no-repeat transparent;}
|
|
|
|
|
34 |
#form-details-nav{font-size:1.0em;font-weight:bold;padding-top:10px;}
|
35 |
#form-details-nav a{padding:5px 10px;text-decoration:none;}
|
36 |
#form-details-nav a.current{
|
31 |
#form-element-digits{background:url(sprite.png) 0 -452px no-repeat transparent;}
|
32 |
#form-element-time{background:url(sprite.png) 0 -489px no-repeat transparent;}
|
33 |
#form-element-phone{background:url(sprite.png) 0 -529px no-repeat transparent;}
|
34 |
+
#form-element-html{background:url(sprite.png) 0 -559px no-repeat transparent;}
|
35 |
+
#form-element-file{background:url(sprite.png) 0 -587px no-repeat transparent;}
|
36 |
#form-details-nav{font-size:1.0em;font-weight:bold;padding-top:10px;}
|
37 |
#form-details-nav a{padding:5px 10px;text-decoration:none;}
|
38 |
#form-details-nav a.current{
|
css/visual-form-builder.css
CHANGED
@@ -74,6 +74,7 @@ input.text, textarea.textarea, select.select{
|
|
74 |
input.medium, select.medium{width:50%;}
|
75 |
input.large, select.large, textarea.textarea{width:100%;}
|
76 |
textarea.medium{height:10em;}
|
|
|
77 |
.submit{font-size:1.1em;}
|
78 |
input.checkbox, input.radio{
|
79 |
font-size:1.1em;
|
@@ -92,4 +93,28 @@ p#form_success{
|
|
92 |
color:green;
|
93 |
font-weight:bold;
|
94 |
}
|
95 |
-
#ui-datepicker-div { display: none; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
input.medium, select.medium{width:50%;}
|
75 |
input.large, select.large, textarea.textarea{width:100%;}
|
76 |
textarea.medium{height:10em;}
|
77 |
+
textarea.large{height:20em;}
|
78 |
.submit{font-size:1.1em;}
|
79 |
input.checkbox, input.radio{
|
80 |
font-size:1.1em;
|
93 |
color:green;
|
94 |
font-weight:bold;
|
95 |
}
|
96 |
+
#ui-datepicker-div { display: none; }
|
97 |
+
.ed_button{
|
98 |
+
font-family:Arial,"Bitstream Vera Sans",Helvetica,Verdana,sans-serif;
|
99 |
+
font-size:12px;
|
100 |
+
background-image: -moz-linear-gradient(top, #fcfcfc 0%, #e9e8e8 100%);
|
101 |
+
background-image: -o-linear-gradient(top, #fcfcfc 0%, #e9e8e8 100%);
|
102 |
+
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fcfcfc), color-stop(1, #e9e8e8));
|
103 |
+
background-image: linear-gradient(top, #fcfcfc 0%, #e9e8e8 100%);
|
104 |
+
min-width:26px;
|
105 |
+
margin:3px 1px 4px;
|
106 |
+
padding:2px 4px;
|
107 |
+
box-shadow:0 1px 0 #e3e3e3;
|
108 |
+
border-radius:3px 3px 3px 3px;
|
109 |
+
border:#C3C3C3 1px solid;
|
110 |
+
text-transform:lowercase;
|
111 |
+
}
|
112 |
+
.ed_button:hover{
|
113 |
+
background:none repeat scroll 0 0 #dddddd;
|
114 |
+
border-color:#aaaaaa;
|
115 |
+
cursor:pointer;
|
116 |
+
}
|
117 |
+
.ed_button.ed_bold{font-weight:bold;}
|
118 |
+
.ed_button.ed_italic{font-style:italic;}
|
119 |
+
.ed_button.ed_link{color:#0000FF;text-decoration:underline;}
|
120 |
+
.ed_button.ed_del{text-decoration:line-through;}
|
js/js_quicktags.js
ADDED
@@ -0,0 +1,544 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// JS QuickTags version 1.3.1
|
2 |
+
//
|
3 |
+
// Copyright (c) 2002-2008 Alex King
|
4 |
+
// http://alexking.org/projects/js-quicktags
|
5 |
+
//
|
6 |
+
// Thanks to Greg Heo <greg@node79.com> for his changes
|
7 |
+
// to support multiple toolbars per page.
|
8 |
+
//
|
9 |
+
// Licensed under the LGPL license
|
10 |
+
// http://www.gnu.org/copyleft/lesser.html
|
11 |
+
//
|
12 |
+
// **********************************************************************
|
13 |
+
// This program is distributed in the hope that it will be useful, but
|
14 |
+
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
16 |
+
// **********************************************************************
|
17 |
+
//
|
18 |
+
// This JavaScript will insert the tags below at the cursor position in IE and
|
19 |
+
// Gecko-based browsers (Mozilla, Camino, Firefox, Netscape). For browsers that
|
20 |
+
// do not support inserting at the cursor position (older versions of Safari,
|
21 |
+
// OmniWeb) it appends the tags to the end of the content.
|
22 |
+
//
|
23 |
+
// Pass the ID of the <textarea> element to the edToolbar and function.
|
24 |
+
//
|
25 |
+
// Example:
|
26 |
+
//
|
27 |
+
// <script type="text/javascript">edToolbar('canvas');</script>
|
28 |
+
// <textarea id="canvas" rows="20" cols="50"></textarea>
|
29 |
+
//
|
30 |
+
|
31 |
+
var dictionaryUrl = 'http://www.ninjawords.com/';
|
32 |
+
|
33 |
+
// other options include:
|
34 |
+
//
|
35 |
+
// var dictionaryUrl = 'http://www.answers.com/';
|
36 |
+
// var dictionaryUrl = 'http://www.dictionary.com/';
|
37 |
+
|
38 |
+
var edButtons = new Array();
|
39 |
+
var edLinks = new Array();
|
40 |
+
var edOpenTags = new Array();
|
41 |
+
|
42 |
+
function edButton(id, display, tagStart, tagEnd, access, open) {
|
43 |
+
this.id = id; // used to name the toolbar button
|
44 |
+
this.display = display; // label on button
|
45 |
+
this.tagStart = tagStart; // open tag
|
46 |
+
this.tagEnd = tagEnd; // close tag
|
47 |
+
this.access = access; // set to -1 if tag does not need to be closed
|
48 |
+
this.open = open; // set to -1 if tag does not need to be closed
|
49 |
+
}
|
50 |
+
|
51 |
+
edButtons.push(
|
52 |
+
new edButton(
|
53 |
+
'ed_bold'
|
54 |
+
,'B'
|
55 |
+
,'<strong>'
|
56 |
+
,'</strong>'
|
57 |
+
,'b'
|
58 |
+
)
|
59 |
+
);
|
60 |
+
|
61 |
+
edButtons.push(
|
62 |
+
new edButton(
|
63 |
+
'ed_italic'
|
64 |
+
,'I'
|
65 |
+
,'<em>'
|
66 |
+
,'</em>'
|
67 |
+
,'i'
|
68 |
+
)
|
69 |
+
);
|
70 |
+
|
71 |
+
edButtons.push(
|
72 |
+
new edButton(
|
73 |
+
'ed_link'
|
74 |
+
,'Link'
|
75 |
+
,''
|
76 |
+
,'</a>'
|
77 |
+
,'a'
|
78 |
+
)
|
79 |
+
); // special case
|
80 |
+
|
81 |
+
edButtons.push(
|
82 |
+
new edButton(
|
83 |
+
'ed_block'
|
84 |
+
,'B-QUOTE'
|
85 |
+
,'<blockquote>'
|
86 |
+
,'</blockquote>'
|
87 |
+
,'q'
|
88 |
+
)
|
89 |
+
);
|
90 |
+
|
91 |
+
edButtons.push(
|
92 |
+
new edButton(
|
93 |
+
'ed_img'
|
94 |
+
,'IMG'
|
95 |
+
,''
|
96 |
+
,''
|
97 |
+
,'m'
|
98 |
+
,-1
|
99 |
+
)
|
100 |
+
); // special case
|
101 |
+
|
102 |
+
edButtons.push(
|
103 |
+
new edButton(
|
104 |
+
'ed_ul'
|
105 |
+
,'UL'
|
106 |
+
,'<ul>\n'
|
107 |
+
,'</ul>\n\n'
|
108 |
+
,'u'
|
109 |
+
)
|
110 |
+
);
|
111 |
+
|
112 |
+
edButtons.push(
|
113 |
+
new edButton(
|
114 |
+
'ed_ol'
|
115 |
+
,'OL'
|
116 |
+
,'<ol>\n'
|
117 |
+
,'</ol>\n\n'
|
118 |
+
,'o'
|
119 |
+
)
|
120 |
+
);
|
121 |
+
|
122 |
+
edButtons.push(
|
123 |
+
new edButton(
|
124 |
+
'ed_li'
|
125 |
+
,'LI'
|
126 |
+
,'\t<li>'
|
127 |
+
,'</li>\n'
|
128 |
+
,'l'
|
129 |
+
)
|
130 |
+
);
|
131 |
+
|
132 |
+
edButtons.push(
|
133 |
+
new edButton(
|
134 |
+
'ed_code'
|
135 |
+
,'CODE'
|
136 |
+
,'<code>'
|
137 |
+
,'</code>'
|
138 |
+
,'c'
|
139 |
+
)
|
140 |
+
);
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
|
145 |
+
|
146 |
+
var extendedStart = edButtons.length;
|
147 |
+
|
148 |
+
function edLink(display, URL, newWin) {
|
149 |
+
this.display = display;
|
150 |
+
this.URL = URL;
|
151 |
+
if (!newWin) {
|
152 |
+
newWin = 0;
|
153 |
+
}
|
154 |
+
this.newWin = newWin;
|
155 |
+
}
|
156 |
+
|
157 |
+
|
158 |
+
edLinks[edLinks.length] = new edLink('alexking.org'
|
159 |
+
,'http://www.alexking.org/'
|
160 |
+
);
|
161 |
+
|
162 |
+
function edShowButton(which, button, i) {
|
163 |
+
if (button.access) {
|
164 |
+
var accesskey = ' accesskey = "' + button.access + '"'
|
165 |
+
}
|
166 |
+
else {
|
167 |
+
var accesskey = '';
|
168 |
+
}
|
169 |
+
switch (button.id) {
|
170 |
+
case 'ed_img':
|
171 |
+
document.write('<input type="button" id="' + button.id + '_' + which + '" ' + accesskey + ' class="ed_button ' + button.id + '" onclick="edInsertImage(\'' + which + '\');" value="' + button.display + '" />');
|
172 |
+
break;
|
173 |
+
case 'ed_link':
|
174 |
+
document.write('<input type="button" id="' + button.id + '_' + which + '" ' + accesskey + ' class="ed_button ' + button.id + '" onclick="edInsertLink(\'' + which + '\', ' + i + ');" value="' + button.display + '" />');
|
175 |
+
break;
|
176 |
+
case 'ed_ext_link':
|
177 |
+
document.write('<input type="button" id="' + button.id + '_' + which + '" ' + accesskey + ' class="ed_button ' + button.id + '" onclick="edInsertExtLink(\'' + which + '\', ' + i + ');" value="' + button.display + '" />');
|
178 |
+
break;
|
179 |
+
case 'ed_footnote':
|
180 |
+
document.write('<input type="button" id="' + button.id + '_' + which + '" ' + accesskey + ' class="ed_button ' + button.id + '" onclick="edInsertFootnote(\'' + which + '\');" value="' + button.display + '" />');
|
181 |
+
break;
|
182 |
+
case 'ed_via':
|
183 |
+
document.write('<input type="button" id="' + button.id + '_' + which + '" ' + accesskey + ' class="ed_button ' + button.id + '" onclick="edInsertVia(\'' + which + '\');" value="' + button.display + '" />');
|
184 |
+
break;
|
185 |
+
default:
|
186 |
+
document.write('<input type="button" id="' + button.id + '_' + which + '" ' + accesskey + ' class="ed_button ' + button.id + '" onclick="edInsertTag(\'' + which + '\', ' + i + ');" value="' + button.display + '" />');
|
187 |
+
break;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
function edShowLinks() {
|
192 |
+
var tempStr = '<select onchange="edQuickLink(this.options[this.selectedIndex].value, this);"><option value="-1" selected>(Quick Links)</option>';
|
193 |
+
for (i = 0; i < edLinks.length; i++) {
|
194 |
+
tempStr += '<option value="' + i + '">' + edLinks[i].display + '</option>';
|
195 |
+
}
|
196 |
+
tempStr += '</select>';
|
197 |
+
document.write(tempStr);
|
198 |
+
}
|
199 |
+
|
200 |
+
function edAddTag(which, button) {
|
201 |
+
if (edButtons[button].tagEnd != '') {
|
202 |
+
edOpenTags[which][edOpenTags[which].length] = button;
|
203 |
+
document.getElementById(edButtons[button].id + '_' + which).value = '/' + document.getElementById(edButtons[button].id + '_' + which).value;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
function edRemoveTag(which, button) {
|
208 |
+
for (i = 0; i < edOpenTags[which].length; i++) {
|
209 |
+
if (edOpenTags[which][i] == button) {
|
210 |
+
edOpenTags[which].splice(i, 1);
|
211 |
+
document.getElementById(edButtons[button].id + '_' + which).value = document.getElementById(edButtons[button].id + '_' + which).value.replace('/', '');
|
212 |
+
}
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
function edCheckOpenTags(which, button) {
|
217 |
+
var tag = 0;
|
218 |
+
for (i = 0; i < edOpenTags[which].length; i++) {
|
219 |
+
if (edOpenTags[which][i] == button) {
|
220 |
+
tag++;
|
221 |
+
}
|
222 |
+
}
|
223 |
+
if (tag > 0) {
|
224 |
+
return true; // tag found
|
225 |
+
}
|
226 |
+
else {
|
227 |
+
return false; // tag not found
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
function edCloseAllTags(which) {
|
232 |
+
var count = edOpenTags[which].length;
|
233 |
+
for (o = 0; o < count; o++) {
|
234 |
+
edInsertTag(which, edOpenTags[which][edOpenTags[which].length - 1]);
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
function edQuickLink(i, thisSelect) {
|
239 |
+
if (i > -1) {
|
240 |
+
var newWin = '';
|
241 |
+
if (edLinks[i].newWin == 1) {
|
242 |
+
newWin = ' target="_blank"';
|
243 |
+
}
|
244 |
+
var tempStr = '<a href="' + edLinks[i].URL + '"' + newWin + '>'
|
245 |
+
+ edLinks[i].display
|
246 |
+
+ '</a>';
|
247 |
+
thisSelect.selectedIndex = 0;
|
248 |
+
edInsertContent(edCanvas, tempStr);
|
249 |
+
}
|
250 |
+
else {
|
251 |
+
thisSelect.selectedIndex = 0;
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
function edSpell(which) {
|
256 |
+
myField = document.getElementById(which);
|
257 |
+
var word = '';
|
258 |
+
if (document.selection) {
|
259 |
+
myField.focus();
|
260 |
+
var sel = document.selection.createRange();
|
261 |
+
if (sel.text.length > 0) {
|
262 |
+
word = sel.text;
|
263 |
+
}
|
264 |
+
}
|
265 |
+
else if (myField.selectionStart || myField.selectionStart == '0') {
|
266 |
+
var startPos = myField.selectionStart;
|
267 |
+
var endPos = myField.selectionEnd;
|
268 |
+
if (startPos != endPos) {
|
269 |
+
word = myField.value.substring(startPos, endPos);
|
270 |
+
}
|
271 |
+
}
|
272 |
+
if (word == '') {
|
273 |
+
word = prompt('Enter a word to look up:', '');
|
274 |
+
}
|
275 |
+
if (word != '') {
|
276 |
+
window.open(dictionaryUrl + escape(word));
|
277 |
+
}
|
278 |
+
}
|
279 |
+
|
280 |
+
function edToolbar(which) {
|
281 |
+
document.write('<div id="ed_toolbar_' + which + '"><span>');
|
282 |
+
for (i = 0; i < extendedStart; i++) {
|
283 |
+
edShowButton(which, edButtons[i], i);
|
284 |
+
}
|
285 |
+
if (edShowExtraCookie()) {
|
286 |
+
document.write(
|
287 |
+
'<input type="button" id="ed_close_' + which + '" class="ed_button ed_closetags" onclick="edCloseAllTags(\'' + which + '\');" value="Close Tags" />'
|
288 |
+
+ '<input type="button" id="ed_spell_' + which + '" class="ed_button ed_spell" onclick="edSpell(\'' + which + '\');" value="Lookup" />'
|
289 |
+
);
|
290 |
+
}
|
291 |
+
else {
|
292 |
+
document.write(
|
293 |
+
'<input type="button" id="ed_close_' + which + '" class="ed_button ed_closetags" onclick="edCloseAllTags(\'' + which + '\');" value="Close Tags" />'
|
294 |
+
+ '<input type="button" id="ed_spell_' + which + '" class="ed_button ed_spell" onclick="edSpell(\'' + which + '\');" value="Lookup" />'
|
295 |
+
);
|
296 |
+
}
|
297 |
+
for (i = extendedStart; i < edButtons.length; i++) {
|
298 |
+
//edShowButton(which, edButtons[i], i);
|
299 |
+
}
|
300 |
+
document.write('</span>');
|
301 |
+
// edShowLinks();
|
302 |
+
document.write('</div>');
|
303 |
+
edOpenTags[which] = new Array();
|
304 |
+
}
|
305 |
+
|
306 |
+
function edShowExtra(which) {
|
307 |
+
document.getElementById('ed_extra_show_' + which).style.visibility = 'hidden';
|
308 |
+
document.getElementById('ed_extra_buttons_' + which).style.display = 'block';
|
309 |
+
edSetCookie(
|
310 |
+
'js_quicktags_extra'
|
311 |
+
, 'show'
|
312 |
+
, new Date("December 31, 2100")
|
313 |
+
);
|
314 |
+
}
|
315 |
+
|
316 |
+
function edHideExtra(which) {
|
317 |
+
document.getElementById('ed_extra_buttons_' + which).style.display = 'none';
|
318 |
+
document.getElementById('ed_extra_show_' + which).style.visibility = 'visible';
|
319 |
+
edSetCookie(
|
320 |
+
'js_quicktags_extra'
|
321 |
+
, 'hide'
|
322 |
+
, new Date("December 31, 2100")
|
323 |
+
);
|
324 |
+
}
|
325 |
+
|
326 |
+
// insertion code
|
327 |
+
|
328 |
+
function edInsertTag(which, i) {
|
329 |
+
myField = document.getElementById(which);
|
330 |
+
//IE support
|
331 |
+
if (document.selection) {
|
332 |
+
myField.focus();
|
333 |
+
sel = document.selection.createRange();
|
334 |
+
if (sel.text.length > 0) {
|
335 |
+
sel.text = edButtons[i].tagStart + sel.text + edButtons[i].tagEnd;
|
336 |
+
}
|
337 |
+
else {
|
338 |
+
if (!edCheckOpenTags(which, i) || edButtons[i].tagEnd == '') {
|
339 |
+
sel.text = edButtons[i].tagStart;
|
340 |
+
edAddTag(which, i);
|
341 |
+
}
|
342 |
+
else {
|
343 |
+
sel.text = edButtons[i].tagEnd;
|
344 |
+
edRemoveTag(which, i);
|
345 |
+
}
|
346 |
+
}
|
347 |
+
myField.focus();
|
348 |
+
}
|
349 |
+
//MOZILLA/NETSCAPE support
|
350 |
+
else if (myField.selectionStart || myField.selectionStart == '0') {
|
351 |
+
var startPos = myField.selectionStart;
|
352 |
+
var endPos = myField.selectionEnd;
|
353 |
+
var cursorPos = endPos;
|
354 |
+
var scrollTop = myField.scrollTop;
|
355 |
+
if (startPos != endPos) {
|
356 |
+
myField.value = myField.value.substring(0, startPos)
|
357 |
+
+ edButtons[i].tagStart
|
358 |
+
+ myField.value.substring(startPos, endPos)
|
359 |
+
+ edButtons[i].tagEnd
|
360 |
+
+ myField.value.substring(endPos, myField.value.length);
|
361 |
+
cursorPos += edButtons[i].tagStart.length + edButtons[i].tagEnd.length;
|
362 |
+
}
|
363 |
+
else {
|
364 |
+
if (!edCheckOpenTags(which, i) || edButtons[i].tagEnd == '') {
|
365 |
+
myField.value = myField.value.substring(0, startPos)
|
366 |
+
+ edButtons[i].tagStart
|
367 |
+
+ myField.value.substring(endPos, myField.value.length);
|
368 |
+
edAddTag(which, i);
|
369 |
+
cursorPos = startPos + edButtons[i].tagStart.length;
|
370 |
+
}
|
371 |
+
else {
|
372 |
+
myField.value = myField.value.substring(0, startPos)
|
373 |
+
+ edButtons[i].tagEnd
|
374 |
+
+ myField.value.substring(endPos, myField.value.length);
|
375 |
+
edRemoveTag(which, i);
|
376 |
+
cursorPos = startPos + edButtons[i].tagEnd.length;
|
377 |
+
}
|
378 |
+
}
|
379 |
+
myField.focus();
|
380 |
+
myField.selectionStart = cursorPos;
|
381 |
+
myField.selectionEnd = cursorPos;
|
382 |
+
myField.scrollTop = scrollTop;
|
383 |
+
}
|
384 |
+
else {
|
385 |
+
if (!edCheckOpenTags(which, i) || edButtons[i].tagEnd == '') {
|
386 |
+
myField.value += edButtons[i].tagStart;
|
387 |
+
edAddTag(which, i);
|
388 |
+
}
|
389 |
+
else {
|
390 |
+
myField.value += edButtons[i].tagEnd;
|
391 |
+
edRemoveTag(which, i);
|
392 |
+
}
|
393 |
+
myField.focus();
|
394 |
+
}
|
395 |
+
}
|
396 |
+
|
397 |
+
function edInsertContent(which, myValue) {
|
398 |
+
myField = document.getElementById(which);
|
399 |
+
//IE support
|
400 |
+
if (document.selection) {
|
401 |
+
myField.focus();
|
402 |
+
sel = document.selection.createRange();
|
403 |
+
sel.text = myValue;
|
404 |
+
myField.focus();
|
405 |
+
}
|
406 |
+
//MOZILLA/NETSCAPE support
|
407 |
+
else if (myField.selectionStart || myField.selectionStart == '0') {
|
408 |
+
var startPos = myField.selectionStart;
|
409 |
+
var endPos = myField.selectionEnd;
|
410 |
+
var scrollTop = myField.scrollTop;
|
411 |
+
myField.value = myField.value.substring(0, startPos)
|
412 |
+
+ myValue
|
413 |
+
+ myField.value.substring(endPos, myField.value.length);
|
414 |
+
myField.focus();
|
415 |
+
myField.selectionStart = startPos + myValue.length;
|
416 |
+
myField.selectionEnd = startPos + myValue.length;
|
417 |
+
myField.scrollTop = scrollTop;
|
418 |
+
} else {
|
419 |
+
myField.value += myValue;
|
420 |
+
myField.focus();
|
421 |
+
}
|
422 |
+
}
|
423 |
+
|
424 |
+
function edInsertLink(which, i, defaultValue) {
|
425 |
+
myField = document.getElementById(which);
|
426 |
+
if (!defaultValue) {
|
427 |
+
defaultValue = 'http://';
|
428 |
+
}
|
429 |
+
if (!edCheckOpenTags(which, i)) {
|
430 |
+
var URL = prompt('Enter the URL' ,defaultValue);
|
431 |
+
if (URL) {
|
432 |
+
edButtons[i].tagStart = '<a href="' + URL + '">';
|
433 |
+
edInsertTag(which, i);
|
434 |
+
}
|
435 |
+
}
|
436 |
+
else {
|
437 |
+
edInsertTag(which, i);
|
438 |
+
}
|
439 |
+
}
|
440 |
+
|
441 |
+
function edInsertExtLink(which, i, defaultValue) {
|
442 |
+
myField = document.getElementById(which);
|
443 |
+
if (!defaultValue) {
|
444 |
+
defaultValue = 'http://';
|
445 |
+
}
|
446 |
+
if (!edCheckOpenTags(which, i)) {
|
447 |
+
var URL = prompt('Enter the URL' ,defaultValue);
|
448 |
+
if (URL) {
|
449 |
+
edButtons[i].tagStart = '<a href="' + URL + '" rel="external">';
|
450 |
+
edInsertTag(which, i);
|
451 |
+
}
|
452 |
+
}
|
453 |
+
else {
|
454 |
+
edInsertTag(which, i);
|
455 |
+
}
|
456 |
+
}
|
457 |
+
|
458 |
+
function edInsertImage(which) {
|
459 |
+
myField = document.getElementById(which);
|
460 |
+
var myValue = prompt('Enter the URL of the image', 'http://');
|
461 |
+
if (myValue) {
|
462 |
+
myValue = '<img src="'
|
463 |
+
+ myValue
|
464 |
+
+ '" alt="' + prompt('Enter a description of the image', '')
|
465 |
+
+ '" />';
|
466 |
+
edInsertContent(which, myValue);
|
467 |
+
}
|
468 |
+
}
|
469 |
+
|
470 |
+
function edInsertFootnote(which) {
|
471 |
+
myField = document.getElementById(which);
|
472 |
+
var note = prompt('Enter the footnote:', '');
|
473 |
+
if (!note || note == '') {
|
474 |
+
return false;
|
475 |
+
}
|
476 |
+
var now = new Date;
|
477 |
+
var fnId = 'fn' + now.getTime();
|
478 |
+
var fnStart = myField.value.indexOf('<ol class="footnotes">');
|
479 |
+
if (fnStart != -1) {
|
480 |
+
var fnStr1 = myField.value.substring(0, fnStart)
|
481 |
+
var fnStr2 = myField.value.substring(fnStart, myField.value.length)
|
482 |
+
var count = countInstances(fnStr2, '<li id="') + 1;
|
483 |
+
}
|
484 |
+
else {
|
485 |
+
var count = 1;
|
486 |
+
}
|
487 |
+
var count = '<sup><a href="#' + fnId + 'n" id="' + fnId + '" class="footnote">' + count + '</a></sup>';
|
488 |
+
edInsertContent(which, count);
|
489 |
+
if (fnStart != -1) {
|
490 |
+
fnStr1 = myField.value.substring(0, fnStart + count.length)
|
491 |
+
fnStr2 = myField.value.substring(fnStart + count.length, myField.value.length)
|
492 |
+
}
|
493 |
+
else {
|
494 |
+
var fnStr1 = myField.value;
|
495 |
+
var fnStr2 = "\n\n" + '<ol class="footnotes">' + "\n"
|
496 |
+
+ '</ol>' + "\n";
|
497 |
+
}
|
498 |
+
var footnote = ' <li id="' + fnId + 'n">' + note + ' [<a href="#' + fnId + '">back</a>]</li>' + "\n"
|
499 |
+
+ '</ol>';
|
500 |
+
myField.value = fnStr1 + fnStr2.replace('</ol>', footnote);
|
501 |
+
}
|
502 |
+
|
503 |
+
function countInstances(string, substr) {
|
504 |
+
var count = string.split(substr);
|
505 |
+
return count.length - 1;
|
506 |
+
}
|
507 |
+
|
508 |
+
function edInsertVia(which) {
|
509 |
+
myField = document.getElementById(which);
|
510 |
+
var myValue = prompt('Enter the URL of the source link', 'http://');
|
511 |
+
if (myValue) {
|
512 |
+
myValue = '(Thanks <a href="' + myValue + '" rel="external">'
|
513 |
+
+ prompt('Enter the name of the source', '')
|
514 |
+
+ '</a>)';
|
515 |
+
edInsertContent(which, myValue);
|
516 |
+
}
|
517 |
+
}
|
518 |
+
|
519 |
+
|
520 |
+
function edSetCookie(name, value, expires, path, domain) {
|
521 |
+
document.cookie= name + "=" + escape(value) +
|
522 |
+
((expires) ? "; expires=" + expires.toGMTString() : "") +
|
523 |
+
((path) ? "; path=" + path : "") +
|
524 |
+
((domain) ? "; domain=" + domain : "");
|
525 |
+
}
|
526 |
+
|
527 |
+
function edShowExtraCookie() {
|
528 |
+
var cookies = document.cookie.split(';');
|
529 |
+
for (var i=0;i < cookies.length; i++) {
|
530 |
+
var cookieData = cookies[i];
|
531 |
+
while (cookieData.charAt(0) ==' ') {
|
532 |
+
cookieData = cookieData.substring(1, cookieData.length);
|
533 |
+
}
|
534 |
+
if (cookieData.indexOf('js_quicktags_extra') == 0) {
|
535 |
+
if (cookieData.substring(19, cookieData.length) == 'show') {
|
536 |
+
return true;
|
537 |
+
}
|
538 |
+
else {
|
539 |
+
return false;
|
540 |
+
}
|
541 |
+
}
|
542 |
+
}
|
543 |
+
return false;
|
544 |
+
}
|
js/visual-form-builder.js
CHANGED
@@ -59,14 +59,14 @@ jQuery(document).ready(function($) {
|
|
59 |
});
|
60 |
|
61 |
/* Display entries form data */
|
62 |
-
|
63 |
|
64 |
var id = $( e.target ).attr( 'id' );
|
65 |
|
66 |
$( e.target ).closest( 'td' ).children( '#entry-' + id ).slideToggle( 'fast' );
|
67 |
|
68 |
return false;
|
69 |
-
})
|
70 |
|
71 |
/* Hide entries form data */
|
72 |
$( '.visual-form-builder-inline-edit-cancel' ).click( function( e ){
|
59 |
});
|
60 |
|
61 |
/* Display entries form data */
|
62 |
+
/*$( '.view-entry' ).click( function( e ){
|
63 |
|
64 |
var id = $( e.target ).attr( 'id' );
|
65 |
|
66 |
$( e.target ).closest( 'td' ).children( '#entry-' + id ).slideToggle( 'fast' );
|
67 |
|
68 |
return false;
|
69 |
+
});*/
|
70 |
|
71 |
/* Hide entries form data */
|
72 |
$( '.visual-form-builder-inline-edit-cancel' ).click( function( e ){
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: mmuro
|
|
3 |
Tags: form, forms, form to email, email form, email, input, validation, jquery, shortcode
|
4 |
Requires at least: 3.1
|
5 |
Tested up to: 3.2.1
|
6 |
-
Stable tag: 1.
|
7 |
|
8 |
Dynamically build forms using a simple interface. Forms include jQuery validation, a basic logic-based verification system, and entry tracking.
|
9 |
|
@@ -16,12 +16,14 @@ Dynamically build forms using a simple interface. Forms include jQuery validatio
|
|
16 |
* Setup and organize your form using a drag-and-drop interface
|
17 |
* Automatically includes a basic logic-based verification system
|
18 |
* Store form entries in your WordPress database and can manage them via the dashboard.
|
|
|
19 |
* Send form submissions to multiple emails
|
20 |
* Utilizes jQuery Form Validation
|
21 |
* Customized Confirmation Messages
|
22 |
* Redirect to a WordPress Page or a URL
|
23 |
* Standard and Advanced Fields
|
24 |
* Easy date fields using the jQuery UI Date Picker
|
|
|
25 |
|
26 |
== Installation ==
|
27 |
|
@@ -36,7 +38,7 @@ Dynamically build forms using a simple interface. Forms include jQuery validatio
|
|
36 |
= How do I build my form? =
|
37 |
|
38 |
1. Click on the + tab, give your form a name and click Create Form.
|
39 |
-
1.
|
40 |
1. Edit the information for each form field by clicking on the down arrow.
|
41 |
1. Drag and drop the elements to put them in order.
|
42 |
1. Click Save Form to save your changes.
|
@@ -75,6 +77,23 @@ To use the more complex features of the Date Picker plugin, you will need to:
|
|
75 |
1. Using the above example ID, paste the following into your javascript file: `$( '#start-date' ).datepicker();`
|
76 |
1. Add and customize the [jQuery UI Date Picker configuration options](http://jqueryui.com/demos/datepicker)
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
== Screenshots ==
|
79 |
|
80 |
1. Visual Form Builder page
|
@@ -83,6 +102,15 @@ To use the more complex features of the Date Picker plugin, you will need to:
|
|
83 |
|
84 |
== Changelog ==
|
85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
**Version 1.3.1**
|
87 |
|
88 |
* Fix bug where new Confirmation screen was not being installed
|
@@ -121,6 +149,9 @@ To use the more complex features of the Date Picker plugin, you will need to:
|
|
121 |
|
122 |
== Upgrade Notice ==
|
123 |
|
|
|
|
|
|
|
124 |
= 1.3.1 =
|
125 |
Recommended update immediately! Fix for bug where confirmation screen does not install.
|
126 |
|
3 |
Tags: form, forms, form to email, email form, email, input, validation, jquery, shortcode
|
4 |
Requires at least: 3.1
|
5 |
Tested up to: 3.2.1
|
6 |
+
Stable tag: 1.4
|
7 |
|
8 |
Dynamically build forms using a simple interface. Forms include jQuery validation, a basic logic-based verification system, and entry tracking.
|
9 |
|
16 |
* Setup and organize your form using a drag-and-drop interface
|
17 |
* Automatically includes a basic logic-based verification system
|
18 |
* Store form entries in your WordPress database and can manage them via the dashboard.
|
19 |
+
* Export entries to a CSV file
|
20 |
* Send form submissions to multiple emails
|
21 |
* Utilizes jQuery Form Validation
|
22 |
* Customized Confirmation Messages
|
23 |
* Redirect to a WordPress Page or a URL
|
24 |
* Standard and Advanced Fields
|
25 |
* Easy date fields using the jQuery UI Date Picker
|
26 |
+
* File uploads
|
27 |
|
28 |
== Installation ==
|
29 |
|
38 |
= How do I build my form? =
|
39 |
|
40 |
1. Click on the + tab, give your form a name and click Create Form.
|
41 |
+
1. Click the form fields from the box on the left to add it to your form.
|
42 |
1. Edit the information for each form field by clicking on the down arrow.
|
43 |
1. Drag and drop the elements to put them in order.
|
44 |
1. Click Save Form to save your changes.
|
77 |
1. Using the above example ID, paste the following into your javascript file: `$( '#start-date' ).datepicker();`
|
78 |
1. Add and customize the [jQuery UI Date Picker configuration options](http://jqueryui.com/demos/datepicker)
|
79 |
|
80 |
+
= How do I export my entries to a CSV? =
|
81 |
+
|
82 |
+
There are two ways to export your entries to a CSV: Export All or Export Selected.
|
83 |
+
|
84 |
+
To Export All:
|
85 |
+
|
86 |
+
1. Go to the Entries screen
|
87 |
+
1. Select the `Export All` option under the `Bulk Actions` dropdown
|
88 |
+
1. Click Apply and save the file
|
89 |
+
|
90 |
+
To Export Selected:
|
91 |
+
|
92 |
+
1. Go to the Entries screen
|
93 |
+
1. Check boxes next to the entries you wish to export
|
94 |
+
1. Select the `Export Selected` option under the `Bulk Actions` dropdown
|
95 |
+
1. CLick Apply and save the file
|
96 |
+
|
97 |
== Screenshots ==
|
98 |
|
99 |
1. Visual Form Builder page
|
102 |
|
103 |
== Changelog ==
|
104 |
|
105 |
+
**Version 1.4**
|
106 |
+
|
107 |
+
* Fix bug where database charset wasn't being set and causing character encoding issues
|
108 |
+
* Fix date submitted to match local date and time settings
|
109 |
+
* Fix Textarea CSS to respond to large size
|
110 |
+
* Add File Upload and HTML Form Items
|
111 |
+
* Add Entries Export feature
|
112 |
+
* Update View Entries to full page view instead of jQuery show/hide quick view
|
113 |
+
|
114 |
**Version 1.3.1**
|
115 |
|
116 |
* Fix bug where new Confirmation screen was not being installed
|
149 |
|
150 |
== Upgrade Notice ==
|
151 |
|
152 |
+
= 1.4 =
|
153 |
+
Export entries to a CSV, file uploads, and various bug fixes.
|
154 |
+
|
155 |
= 1.3.1 =
|
156 |
Recommended update immediately! Fix for bug where confirmation screen does not install.
|
157 |
|
visual-form-builder.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Visual Form Builder
|
4 |
Description: Dynamically build forms using a simple interface. Forms include jQuery validation, a basic logic-based verification system, and entry tracking.
|
5 |
Author: Matthew Muro
|
6 |
-
Version: 1.
|
7 |
*/
|
8 |
|
9 |
/*
|
@@ -27,7 +27,7 @@ $visual_form_builder = new Visual_Form_Builder();
|
|
27 |
/* Restrict Categories class */
|
28 |
class Visual_Form_Builder{
|
29 |
|
30 |
-
public $vfb_db_version = '1.
|
31 |
|
32 |
public function __construct(){
|
33 |
global $wpdb;
|
@@ -44,7 +44,8 @@ class Visual_Form_Builder{
|
|
44 |
add_action( 'admin_menu', array( &$this, 'save' ) );
|
45 |
add_action( 'wp_ajax_visual_form_builder_process_sort', array( &$this, 'visual_form_builder_process_sort_callback' ) );
|
46 |
add_action( 'admin_init', array( &$this, 'add_visual_form_builder_contextual_help' ) );
|
47 |
-
|
|
|
48 |
/* Load the includes files */
|
49 |
add_action( 'plugins_loaded', array( &$this, 'includes' ) );
|
50 |
|
@@ -91,8 +92,11 @@ class Visual_Form_Builder{
|
|
91 |
* @since 1.2
|
92 |
*/
|
93 |
public function includes(){
|
94 |
-
/* Load the Entries class */
|
95 |
require_once( trailingslashit( plugin_dir_path( __FILE__ ) ) . 'class-entries-list.php' );
|
|
|
|
|
|
|
96 |
}
|
97 |
|
98 |
/**
|
@@ -191,6 +195,24 @@ class Visual_Form_Builder{
|
|
191 |
update_option( 'visual-form-builder-screen-options', $updated_options );
|
192 |
}
|
193 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
|
195 |
|
196 |
/**
|
@@ -205,6 +227,10 @@ class Visual_Form_Builder{
|
|
205 |
$form_table_name = $wpdb->prefix . 'visual_form_builder_forms';
|
206 |
$entries_table_name = $wpdb->prefix . 'visual_form_builder_entries';
|
207 |
|
|
|
|
|
|
|
|
|
208 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
209 |
|
210 |
$field_sql = "CREATE TABLE $field_table_name (
|
@@ -220,9 +246,8 @@ class Visual_Form_Builder{
|
|
220 |
field_required VARCHAR(25),
|
221 |
field_size VARCHAR(25),
|
222 |
UNIQUE KEY (field_id)
|
223 |
-
);";
|
224 |
-
|
225 |
-
|
226 |
$form_sql = "CREATE TABLE $form_table_name (
|
227 |
form_id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
228 |
form_key TINYTEXT NOT NULL,
|
@@ -236,7 +261,7 @@ class Visual_Form_Builder{
|
|
236 |
form_success_type VARCHAR(25) DEFAULT 'text',
|
237 |
form_success_message TEXT,
|
238 |
UNIQUE KEY (form_id)
|
239 |
-
);";
|
240 |
|
241 |
$entries_sql = "CREATE TABLE $entries_table_name (
|
242 |
entries_id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
@@ -249,7 +274,7 @@ class Visual_Form_Builder{
|
|
249 |
date_submitted VARCHAR(25),
|
250 |
ip_address VARCHAR(25),
|
251 |
UNIQUE KEY (entries_id)
|
252 |
-
);";
|
253 |
|
254 |
/* Create or Update database tables */
|
255 |
dbDelta( $field_sql );
|
@@ -287,6 +312,7 @@ class Visual_Form_Builder{
|
|
287 |
wp_enqueue_script( 'jquery-form-validation', 'http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8/jquery.validate.min.js', array( 'jquery' ), '', true );
|
288 |
wp_enqueue_script( 'jquery-ui-core ', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js', array( 'jquery' ), '', true );
|
289 |
wp_enqueue_script( 'visual-form-builder-validation', plugins_url( 'visual-form-builder' ) . '/js/visual-form-builder-validate.js' , array( 'jquery', 'jquery-form-validation' ), '', true );
|
|
|
290 |
}
|
291 |
|
292 |
/**
|
@@ -500,7 +526,7 @@ class Visual_Form_Builder{
|
|
500 |
$form_id = absint( $_REQUEST['form_id'] );
|
501 |
$field_key = sanitize_title( $_REQUEST['field_name'] );
|
502 |
$field_name = esc_html( $_REQUEST['field_type'] );
|
503 |
-
$field_type = strtolower(
|
504 |
|
505 |
/* Set defaults for validation */
|
506 |
switch ( $field_type ) {
|
@@ -611,12 +637,18 @@ class Visual_Form_Builder{
|
|
611 |
if ( isset( $_REQUEST['view'] ) && in_array( $_REQUEST['view'], array( 'entries' ) ) ) :
|
612 |
|
613 |
$entries_list = new VisualFormBuilder_Entries_List();
|
614 |
-
$
|
|
|
|
|
|
|
|
|
|
|
615 |
?>
|
616 |
<form id="entries-filter" method="post" action="">
|
617 |
<?php $entries_list->display(); ?>
|
618 |
</form>
|
619 |
<?php
|
|
|
620 |
/* Display the Forms */
|
621 |
else:
|
622 |
echo ( isset( $this->message ) ) ? $this->message : ''; ?>
|
@@ -654,6 +686,8 @@ class Visual_Form_Builder{
|
|
654 |
<li><input type="submit" id="form-element-digits" class="button-secondary" name="field_type" value="Number"<?php echo $disabled; ?> /></li>
|
655 |
<li><input type="submit" id="form-element-time" class="button-secondary" name="field_type" value="Time"<?php echo $disabled; ?> /></li>
|
656 |
<li><input type="submit" id="form-element-phone" class="button-secondary" name="field_type" value="Phone"<?php echo $disabled; ?> /></li>
|
|
|
|
|
657 |
</ul>
|
658 |
</div>
|
659 |
</div>
|
@@ -868,8 +902,8 @@ class Visual_Form_Builder{
|
|
868 |
<li id="form_item_<?php echo $field->field_id; ?>" class="form-item">
|
869 |
<dl class="menu-item-bar">
|
870 |
<dt class="menu-item-handle<?php echo ( $field->field_type == 'fieldset' ) ? ' fieldset' : ''; ?>">
|
871 |
-
<span class="item-title"><?php echo stripslashes( $field->field_name ); ?><?php echo ( $field->field_required == 'yes' ) ? ' <span class="is-field-required">*</span>' : ''; ?></span> <span class="item-controls">
|
872 |
-
<span class="item-type"><?php echo strtoupper( $field->field_type ); ?></span>
|
873 |
<a href="#" title="Edit Field Item" id="edit-<?php echo $field->field_id; ?>" class="item-edit">Edit Field Item</a>
|
874 |
</span>
|
875 |
</dt>
|
@@ -886,7 +920,7 @@ class Visual_Form_Builder{
|
|
886 |
<p class="description description-wide">
|
887 |
<label for="edit-form-item-name-<?php echo $field->field_id; ?>">
|
888 |
Name<br />
|
889 |
-
<input type="text" value="<?php echo stripslashes( $field->field_name ); ?>" name="field_name-<?php echo $field->field_id; ?>" class="widefat" id="edit-form-item-name-<?php echo $field->field_id; ?>" />
|
890 |
</label>
|
891 |
</p>
|
892 |
<p class="description description-wide">
|
@@ -922,7 +956,7 @@ class Visual_Form_Builder{
|
|
922 |
<p class="description description-thin">
|
923 |
<label for="edit-form-item-validation">
|
924 |
Validation<br />
|
925 |
-
<select name="field_validation-<?php echo $field->field_id; ?>" class="widefat" id="edit-form-item-validation-<?php echo $field->field_id; ?>"<?php echo ( in_array( $field->field_type, array( 'radio', 'select', 'checkbox', 'address', 'date', 'textarea' ) ) ) ? ' disabled="disabled"' : ''; ?>>
|
926 |
<?php if ( $field->field_type == 'time' ) : ?>
|
927 |
<option value="time-12" <?php selected( $field->field_validation, 'time-12' ); ?>>12 Hour Format</option>
|
928 |
<option value="time-24" <?php selected( $field->field_validation, 'time-24' ); ?>>24 Hour Format</option>
|
@@ -1066,7 +1100,7 @@ class Visual_Form_Builder{
|
|
1066 |
|
1067 |
foreach ( $forms as $form ) :
|
1068 |
|
1069 |
-
$output = '<form id="' . $form->form_key . '" class="visual-form-builder" method="post">
|
1070 |
<input type="hidden" name="form_id" value="' . $form->form_id . '" />';
|
1071 |
$output .= wp_nonce_field( 'visual-form-builder-nonce', '_wpnonce', false, false );
|
1072 |
|
@@ -1100,13 +1134,14 @@ class Visual_Form_Builder{
|
|
1100 |
$output .= '<span><input type="text" name="vfb-' . esc_html( $field->field_key ) . '" id="vfb-' . esc_html( $field->field_key ) . '" value="" class="text ' . $field->field_size . $required . $validation . '" /><label>' . $field->field_description . '</label></span>';
|
1101 |
else
|
1102 |
$output .= '<input type="text" name="vfb-' . esc_html( $field->field_key ) . '" id="vfb-' . esc_html( $field->field_key ) . '" value="" class="text ' . $field->field_size . $required . $validation . '" />';
|
|
|
1103 |
break;
|
1104 |
|
1105 |
case 'textarea' :
|
1106 |
|
1107 |
if ( !empty( $field->field_description ) )
|
1108 |
$output .= '<span><label>' . stripslashes( $field->field_description ) . '</label></span>';
|
1109 |
-
|
1110 |
$output .= '<textarea name="vfb-'. $field->field_key . '" id="vfb-'. $field->field_key . '" class="textarea ' . $field->field_size . $required . '"></textarea>';
|
1111 |
|
1112 |
break;
|
@@ -1255,7 +1290,28 @@ class Visual_Form_Builder{
|
|
1255 |
/* AM/PM */
|
1256 |
if ( $time_format == '12' )
|
1257 |
$output .= '<span class="time"><select name="vfb-'. $field->field_key . '[ampm]" id="vfb-'. $field->field_key . '" class="select' . $required . '"><option value="AM">AM</option><option value="PM">PM</option></select><label>AM/PM</label></span>';
|
1258 |
-
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1259 |
}
|
1260 |
|
1261 |
$output .= '</li>';
|
@@ -1355,12 +1411,12 @@ class Visual_Form_Builder{
|
|
1355 |
$form_from = $_POST[ 'vfb-' . $email->field_key ];
|
1356 |
}
|
1357 |
|
1358 |
-
|
1359 |
/* Prepare the beginning of the content */
|
1360 |
$message = '<html><body><table rules="all" style="border-color: #666;" cellpadding="10">';
|
1361 |
|
1362 |
/* Loop through each form field and build the body of the message */
|
1363 |
foreach ( $_POST as $key => $value ) {
|
|
|
1364 |
/* Remove prefix, dashes and lowercase */
|
1365 |
$key = str_replace( 'vfb-', '', $key );
|
1366 |
$key = strtolower( str_replace( '-', ' ', $key ) );
|
@@ -1382,9 +1438,32 @@ class Visual_Form_Builder{
|
|
1382 |
}
|
1383 |
}
|
1384 |
|
1385 |
-
/*
|
1386 |
-
|
1387 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1388 |
|
1389 |
/* Setup our entries data */
|
1390 |
$entry = array(
|
@@ -1394,7 +1473,7 @@ class Visual_Form_Builder{
|
|
1394 |
'sender_name' => $form_from_name,
|
1395 |
'sender_email' => $form_from,
|
1396 |
'emails_to' => serialize( $form_to ),
|
1397 |
-
'date_submitted' =>
|
1398 |
'ip_address' => $_SERVER['REMOTE_ADDR']
|
1399 |
);
|
1400 |
|
@@ -1411,7 +1490,7 @@ class Visual_Form_Builder{
|
|
1411 |
|
1412 |
/* Send the mail */
|
1413 |
foreach ( $form_to as $email ) {
|
1414 |
-
$mail_sent = wp_mail( $email, esc_html( $form_subject ), $message, $headers );
|
1415 |
}
|
1416 |
elseif ( isset( $_REQUEST['visual-form-builder-submit'] ) ) :
|
1417 |
/* If any of the security checks fail, provide some user feedback */
|
3 |
Plugin Name: Visual Form Builder
|
4 |
Description: Dynamically build forms using a simple interface. Forms include jQuery validation, a basic logic-based verification system, and entry tracking.
|
5 |
Author: Matthew Muro
|
6 |
+
Version: 1.4
|
7 |
*/
|
8 |
|
9 |
/*
|
27 |
/* Restrict Categories class */
|
28 |
class Visual_Form_Builder{
|
29 |
|
30 |
+
public $vfb_db_version = '1.4';
|
31 |
|
32 |
public function __construct(){
|
33 |
global $wpdb;
|
44 |
add_action( 'admin_menu', array( &$this, 'save' ) );
|
45 |
add_action( 'wp_ajax_visual_form_builder_process_sort', array( &$this, 'visual_form_builder_process_sort_callback' ) );
|
46 |
add_action( 'admin_init', array( &$this, 'add_visual_form_builder_contextual_help' ) );
|
47 |
+
add_action( 'admin_init', array( &$this, 'export_entries' ) );
|
48 |
+
|
49 |
/* Load the includes files */
|
50 |
add_action( 'plugins_loaded', array( &$this, 'includes' ) );
|
51 |
|
92 |
* @since 1.2
|
93 |
*/
|
94 |
public function includes(){
|
95 |
+
/* Load the Entries List class */
|
96 |
require_once( trailingslashit( plugin_dir_path( __FILE__ ) ) . 'class-entries-list.php' );
|
97 |
+
|
98 |
+
/* Load the Entries Details class */
|
99 |
+
require_once( trailingslashit( plugin_dir_path( __FILE__ ) ) . 'class-entries-detail.php' );
|
100 |
}
|
101 |
|
102 |
/**
|
195 |
update_option( 'visual-form-builder-screen-options', $updated_options );
|
196 |
}
|
197 |
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Runs the export_entries function in the class-entries-list.php file
|
201 |
+
*
|
202 |
+
* @since 1.4
|
203 |
+
*/
|
204 |
+
public function export_entries() {
|
205 |
+
$entries = new VisualFormBuilder_Entries_List();
|
206 |
+
|
207 |
+
/* If exporting all, don't pass the IDs */
|
208 |
+
if ( 'export-all' === $entries->current_action() )
|
209 |
+
$entries->export_entries();
|
210 |
+
/* If exporting selected, pick up the ID array and pass them */
|
211 |
+
elseif ( 'export-selected' === $entries->current_action() ) {
|
212 |
+
$entry_id = ( is_array( $_REQUEST['entry'] ) ) ? $_REQUEST['entry'] : array( $_REQUEST['entry'] );
|
213 |
+
$entries->export_entries( $entry_id );
|
214 |
+
}
|
215 |
+
}
|
216 |
|
217 |
|
218 |
/**
|
227 |
$form_table_name = $wpdb->prefix . 'visual_form_builder_forms';
|
228 |
$entries_table_name = $wpdb->prefix . 'visual_form_builder_entries';
|
229 |
|
230 |
+
/* Explicitly set the character set and collation when creating the tables */
|
231 |
+
$charset = ( defined( 'DB_CHARSET' && '' !== DB_CHARSET ) ) ? DB_CHARSET : 'utf8';
|
232 |
+
$collate = ( defined( 'DB_COLLATE' && '' !== DB_COLLATE ) ) ? DB_COLLATE : 'utf8_general_ci';
|
233 |
+
|
234 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
235 |
|
236 |
$field_sql = "CREATE TABLE $field_table_name (
|
246 |
field_required VARCHAR(25),
|
247 |
field_size VARCHAR(25),
|
248 |
UNIQUE KEY (field_id)
|
249 |
+
) DEFAULT CHARACTER SET $charset COLLATE $collate;";
|
250 |
+
|
|
|
251 |
$form_sql = "CREATE TABLE $form_table_name (
|
252 |
form_id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
253 |
form_key TINYTEXT NOT NULL,
|
261 |
form_success_type VARCHAR(25) DEFAULT 'text',
|
262 |
form_success_message TEXT,
|
263 |
UNIQUE KEY (form_id)
|
264 |
+
) DEFAULT CHARACTER SET $charset COLLATE $collate;";
|
265 |
|
266 |
$entries_sql = "CREATE TABLE $entries_table_name (
|
267 |
entries_id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
274 |
date_submitted VARCHAR(25),
|
275 |
ip_address VARCHAR(25),
|
276 |
UNIQUE KEY (entries_id)
|
277 |
+
) DEFAULT CHARACTER SET $charset COLLATE $collate;";
|
278 |
|
279 |
/* Create or Update database tables */
|
280 |
dbDelta( $field_sql );
|
312 |
wp_enqueue_script( 'jquery-form-validation', 'http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8/jquery.validate.min.js', array( 'jquery' ), '', true );
|
313 |
wp_enqueue_script( 'jquery-ui-core ', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js', array( 'jquery' ), '', true );
|
314 |
wp_enqueue_script( 'visual-form-builder-validation', plugins_url( 'visual-form-builder' ) . '/js/visual-form-builder-validate.js' , array( 'jquery', 'jquery-form-validation' ), '', true );
|
315 |
+
wp_enqueue_script( 'visual-form-builder-quicktags', plugins_url( 'visual-form-builder' ) . '/js/js_quicktags.js' );
|
316 |
}
|
317 |
|
318 |
/**
|
526 |
$form_id = absint( $_REQUEST['form_id'] );
|
527 |
$field_key = sanitize_title( $_REQUEST['field_name'] );
|
528 |
$field_name = esc_html( $_REQUEST['field_type'] );
|
529 |
+
$field_type = strtolower( sanitize_title( $_REQUEST['field_type'] ) );
|
530 |
|
531 |
/* Set defaults for validation */
|
532 |
switch ( $field_type ) {
|
637 |
if ( isset( $_REQUEST['view'] ) && in_array( $_REQUEST['view'], array( 'entries' ) ) ) :
|
638 |
|
639 |
$entries_list = new VisualFormBuilder_Entries_List();
|
640 |
+
$entries_detail = new VisualFormBuilder_Entries_Detail();
|
641 |
+
|
642 |
+
if ( isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array( 'view' ) ) ) :
|
643 |
+
$entries_detail->entries_detail();
|
644 |
+
else :
|
645 |
+
$entries_list->prepare_items();
|
646 |
?>
|
647 |
<form id="entries-filter" method="post" action="">
|
648 |
<?php $entries_list->display(); ?>
|
649 |
</form>
|
650 |
<?php
|
651 |
+
endif;
|
652 |
/* Display the Forms */
|
653 |
else:
|
654 |
echo ( isset( $this->message ) ) ? $this->message : ''; ?>
|
686 |
<li><input type="submit" id="form-element-digits" class="button-secondary" name="field_type" value="Number"<?php echo $disabled; ?> /></li>
|
687 |
<li><input type="submit" id="form-element-time" class="button-secondary" name="field_type" value="Time"<?php echo $disabled; ?> /></li>
|
688 |
<li><input type="submit" id="form-element-phone" class="button-secondary" name="field_type" value="Phone"<?php echo $disabled; ?> /></li>
|
689 |
+
<li><input type="submit" id="form-element-html" class="button-secondary" name="field_type" value="HTML"<?php echo $disabled; ?> /></li>
|
690 |
+
<li><input type="submit" id="form-element-file" class="button-secondary" name="field_type" value="File Upload"<?php echo $disabled; ?> /></li>
|
691 |
</ul>
|
692 |
</div>
|
693 |
</div>
|
902 |
<li id="form_item_<?php echo $field->field_id; ?>" class="form-item">
|
903 |
<dl class="menu-item-bar">
|
904 |
<dt class="menu-item-handle<?php echo ( $field->field_type == 'fieldset' ) ? ' fieldset' : ''; ?>">
|
905 |
+
<span class="item-title"><?php echo stripslashes( htmlspecialchars( $field->field_name ) ); ?><?php echo ( $field->field_required == 'yes' ) ? ' <span class="is-field-required">*</span>' : ''; ?></span> <span class="item-controls">
|
906 |
+
<span class="item-type"><?php echo strtoupper( str_replace( '-', ' ', $field->field_type ) ); ?></span>
|
907 |
<a href="#" title="Edit Field Item" id="edit-<?php echo $field->field_id; ?>" class="item-edit">Edit Field Item</a>
|
908 |
</span>
|
909 |
</dt>
|
920 |
<p class="description description-wide">
|
921 |
<label for="edit-form-item-name-<?php echo $field->field_id; ?>">
|
922 |
Name<br />
|
923 |
+
<input type="text" value="<?php echo stripslashes( htmlspecialchars( $field->field_name ) ); ?>" name="field_name-<?php echo $field->field_id; ?>" class="widefat" id="edit-form-item-name-<?php echo $field->field_id; ?>" />
|
924 |
</label>
|
925 |
</p>
|
926 |
<p class="description description-wide">
|
956 |
<p class="description description-thin">
|
957 |
<label for="edit-form-item-validation">
|
958 |
Validation<br />
|
959 |
+
<select name="field_validation-<?php echo $field->field_id; ?>" class="widefat" id="edit-form-item-validation-<?php echo $field->field_id; ?>"<?php echo ( in_array( $field->field_type, array( 'radio', 'select', 'checkbox', 'address', 'date', 'textarea', 'html', 'file-upload' ) ) ) ? ' disabled="disabled"' : ''; ?>>
|
960 |
<?php if ( $field->field_type == 'time' ) : ?>
|
961 |
<option value="time-12" <?php selected( $field->field_validation, 'time-12' ); ?>>12 Hour Format</option>
|
962 |
<option value="time-24" <?php selected( $field->field_validation, 'time-24' ); ?>>24 Hour Format</option>
|
1100 |
|
1101 |
foreach ( $forms as $form ) :
|
1102 |
|
1103 |
+
$output = '<form id="' . $form->form_key . '" class="visual-form-builder" method="post" enctype="multipart/form-data">
|
1104 |
<input type="hidden" name="form_id" value="' . $form->form_id . '" />';
|
1105 |
$output .= wp_nonce_field( 'visual-form-builder-nonce', '_wpnonce', false, false );
|
1106 |
|
1134 |
$output .= '<span><input type="text" name="vfb-' . esc_html( $field->field_key ) . '" id="vfb-' . esc_html( $field->field_key ) . '" value="" class="text ' . $field->field_size . $required . $validation . '" /><label>' . $field->field_description . '</label></span>';
|
1135 |
else
|
1136 |
$output .= '<input type="text" name="vfb-' . esc_html( $field->field_key ) . '" id="vfb-' . esc_html( $field->field_key ) . '" value="" class="text ' . $field->field_size . $required . $validation . '" />';
|
1137 |
+
|
1138 |
break;
|
1139 |
|
1140 |
case 'textarea' :
|
1141 |
|
1142 |
if ( !empty( $field->field_description ) )
|
1143 |
$output .= '<span><label>' . stripslashes( $field->field_description ) . '</label></span>';
|
1144 |
+
|
1145 |
$output .= '<textarea name="vfb-'. $field->field_key . '" id="vfb-'. $field->field_key . '" class="textarea ' . $field->field_size . $required . '"></textarea>';
|
1146 |
|
1147 |
break;
|
1290 |
/* AM/PM */
|
1291 |
if ( $time_format == '12' )
|
1292 |
$output .= '<span class="time"><select name="vfb-'. $field->field_key . '[ampm]" id="vfb-'. $field->field_key . '" class="select' . $required . '"><option value="AM">AM</option><option value="PM">PM</option></select><label>AM/PM</label></span>';
|
1293 |
+
break;
|
1294 |
+
|
1295 |
+
case 'html' :
|
1296 |
+
|
1297 |
+
if ( !empty( $field->field_description ) )
|
1298 |
+
$output .= '<span><label>' . stripslashes( $field->field_description ) . '</label></span>';
|
1299 |
+
|
1300 |
+
$output .= '<script type="text/javascript">edToolbar("vfb-' . $field->field_key . '");</script>';
|
1301 |
+
$output .= '<textarea name="vfb-'. $field->field_key . '" id="vfb-'. $field->field_key . '" class="textarea vfbEditor ' . $field->field_size . $required . '"></textarea>';
|
1302 |
+
|
1303 |
+
break;
|
1304 |
+
|
1305 |
+
case 'file-upload' :
|
1306 |
+
|
1307 |
+
if ( !empty( $field->field_description ) )
|
1308 |
+
$output .= '<span><input type="file" size="35" name="vfb-' . esc_html( $field->field_key ) . '" id="vfb-' . esc_html( $field->field_key ) . '" value="" class="text ' . $field->field_size . $required . $validation . '" /><label>' . $field->field_description . '</label></span>';
|
1309 |
+
else
|
1310 |
+
$output .= '<input type="file" size="35" name="vfb-' . esc_html( $field->field_key ) . '" id="vfb-' . esc_html( $field->field_key ) . '" value="" class="text ' . $field->field_size . $required . $validation . '" />';
|
1311 |
+
|
1312 |
+
|
1313 |
+
break;
|
1314 |
+
|
1315 |
}
|
1316 |
|
1317 |
$output .= '</li>';
|
1411 |
$form_from = $_POST[ 'vfb-' . $email->field_key ];
|
1412 |
}
|
1413 |
|
|
|
1414 |
/* Prepare the beginning of the content */
|
1415 |
$message = '<html><body><table rules="all" style="border-color: #666;" cellpadding="10">';
|
1416 |
|
1417 |
/* Loop through each form field and build the body of the message */
|
1418 |
foreach ( $_POST as $key => $value ) {
|
1419 |
+
|
1420 |
/* Remove prefix, dashes and lowercase */
|
1421 |
$key = str_replace( 'vfb-', '', $key );
|
1422 |
$key = strtolower( str_replace( '-', ' ', $key ) );
|
1438 |
}
|
1439 |
}
|
1440 |
|
1441 |
+
/* Prepare the attachments */
|
1442 |
+
if ( isset( $_FILES ) ) {
|
1443 |
+
foreach ( $_FILES as $k => $v ) {
|
1444 |
+
if ( $v['size'] > 0 ) {
|
1445 |
+
/* Options array for the wp_handle_upload function. 'test_upload' => false */
|
1446 |
+
$upload_overrides = array( 'test_form' => false );
|
1447 |
+
|
1448 |
+
/* We need to include the file that runs the wp_handle_upload function */
|
1449 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
1450 |
+
|
1451 |
+
/* Handle the upload using WP's wp_handle_upload function. Takes the posted file and an options array */
|
1452 |
+
$uploaded_file = wp_handle_upload( $v, $upload_overrides );
|
1453 |
+
|
1454 |
+
/* If the wp_handle_upload call returned a local path for the image */
|
1455 |
+
if ( isset( $uploaded_file['file'] ) ) {
|
1456 |
+
$attachments[$k] = $uploaded_file['file'];
|
1457 |
+
|
1458 |
+
$key = str_replace( 'vfb-', '', $k );
|
1459 |
+
$key = strtolower( str_replace( '-', ' ', $key ) );
|
1460 |
+
$fields[$key] = $uploaded_file['url'];
|
1461 |
+
|
1462 |
+
$message .= '<tr><td><strong>' . ucwords( $key ) . ': </strong></td><td><a href="' . $uploaded_file['url'] . '">' . $uploaded_file['url'] . '</a></td></tr>';
|
1463 |
+
}
|
1464 |
+
}
|
1465 |
+
}
|
1466 |
+
}
|
1467 |
|
1468 |
/* Setup our entries data */
|
1469 |
$entry = array(
|
1473 |
'sender_name' => $form_from_name,
|
1474 |
'sender_email' => $form_from,
|
1475 |
'emails_to' => serialize( $form_to ),
|
1476 |
+
'date_submitted' => date_i18n( 'Y-m-d G:i:s' ),
|
1477 |
'ip_address' => $_SERVER['REMOTE_ADDR']
|
1478 |
);
|
1479 |
|
1490 |
|
1491 |
/* Send the mail */
|
1492 |
foreach ( $form_to as $email ) {
|
1493 |
+
$mail_sent = wp_mail( $email, esc_html( $form_subject ), $message, $headers, $attachments );
|
1494 |
}
|
1495 |
elseif ( isset( $_REQUEST['visual-form-builder-submit'] ) ) :
|
1496 |
/* If any of the security checks fail, provide some user feedback */
|