PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / 261001
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions v261001
261001 260927 260917 260913 260909 260829 260814 260805 110710 110731 110812 110815 110912 110913 110915 110926 110927 111002 111003 111011 111017 111029 111105 111206 111216 All 191 releases
s2member / src / includes / menu-pages / menu-pages-s.js

menu-pages-s.js in s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions 261001, at src/includes/menu-pages/menu-pages-s.js

1,354 lines 86.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Core JavaScript routines for s2Member menu pages.
3 *
4 * Copyright: © 2009-2011
5 * {@link http://websharks-inc.com/ WebSharks, Inc.}
6 * (coded in the USA)
7 *
8 * Released under the terms of the GNU General Public License.
9 * You should have received a copy of the GNU General Public License,
10 * along with this software. In the main directory, see: /licensing/
11 * If not, see: {@link http://www.gnu.org/licenses/}.
12 *
13 * @package s2Member\Menu_Pages
14 * @since 3.0
15 */
16 jQuery(document).ready(function($)
17 {
18 var esc_attr = esc_html = function(string/* Convert special characters. */)
19 {
20 if(/[&\<\>"']/.test(string = String(string)))
21 string = string.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'),
22 string = string.replace(/"/g, '&quot;').replace(/'/g, '&#039;');
23 return string;
24 };
25 ws_plugin__s2member_generateSecurityKey = /* Generates a unique Security Key. */ function(obj)
26 {
27 if(!obj) obj = '#ws-plugin--s2member-sec-encryption-key';
28
29 var mt_rand = /* The JS equivalent to mt_rand(). */ function(min, max)
30 {
31 min = (arguments.length < 1) ? 0 : min;
32 max = (arguments.length < 2) ? 2147483647 : max;
33
34 return Math.floor(Math.random() * (max-min+1))+min;
35 };
36 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#%^&*()';
37
38 for(var i = 0, key = ''; i < 64; i++)
39 key += chars.substr(mt_rand(0, chars.length-1), 1);
40
41 $(obj).val(key);
42
43 return false;
44 };
45 if(location.href.match /* Any & all s2Member pages. */(/page\=ws-plugin--s2member/))
46 {
47 $('input.ws-plugin--s2member-update-roles-button, input.ws-plugin--s2member-reset-roles-button').click(function()
48 {
49 var $this = /* Save $(this) into $this. */ $(this);
50 $this.val /* Indicate loading status (please wait). */('one moment please ...');
51
52 var levels = '<?php echo (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; ?>';
53 var resetUpdate = ($this.hasClass('ws-plugin--s2member-reset-roles-button')) ? 'Reset' : 'Update';
54
55 $.post(ajaxurl, {action: 'ws_plugin__s2member_update_roles_via_ajax', ws_plugin__s2member_update_roles_via_ajax: '<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-update-roles-via-ajax")); ?>'}, function(response)
56 {
57 if(response === '1')
58 alert('s2Member\'s Roles/Capabilities '+((resetUpdate.toLowerCase() === 'reset') ? 'have been successfully reset' : 'updated successfully')+'.\nYour installation of s2Member has Membership Levels 0-'+levels+'.'), $this.val(resetUpdate+' Roles/Capabilities');
59
60 else if(response === 'l' /* Locked? */)
61 alert('Sorry, your request failed.\ns2Member\'s Roles/Capabilities are locked by Filter:\nws_plugin__s2member_lock_roles_caps'), $this.val(resetUpdate+' Roles/Capabilities');
62
63 else // Default response message here.
64 alert('Sorry, your request failed.\nAccess denied. Do you have the ability to `create_users`?'), $this.val(resetUpdate+' Roles/Capabilities');
65 });
66 return false;
67 });
68 }
69 if(location.href.match(/page\=ws-plugin--s2member-logs/))
70 {
71 $('input#ws-plugin--s2member-gateway-debug-logs-extensive-1').click(function()
72 {
73 var $this = $(this), thisChecked = (this.checked) ? true : false;
74 if(thisChecked) $('input#ws-plugin--s2member-gateway-debug-logs-1').attr('checked', 'checked');
75 });
76 var $toggles = $('a.ws-plugin--s2member-log-file-viewport-toggle'); $toggles.click(function()
77 {
78 $('textarea#ws-plugin--s2member-log-file-viewer').each(function()
79 {
80 var $viewer = $(this); // There is only one viewer.
81
82 if($viewer.attr('data-state') !== 'expanded') // Not expanded yet?
83 {
84 $viewer.css({'height': ($viewer.prop('scrollHeight')+50)+'px', 'overflow-y':'auto'});
85 $toggles.html('&#8657; normalize viewport &#10073;');
86 $viewer.attr('data-state', 'expanded');
87 }
88 else // Already expanded. We need to toggle it back to a normalized state in this case.
89 {
90 $viewer.css({'height': 'auto', 'overflow-y':'scroll'});
91 $toggles.html('&#8659; expand viewport &#8659;');
92 $viewer.attr('data-state', 'scrolling');
93 }
94 });
95 return false; // Prevents location.hash jumps.
96 });
97 }
98 if(location.href.match(/page\=ws-plugin--s2member-mms-ops/))
99 {
100 $('select#ws-plugin--s2member-mms-registration-file').change(function()
101 {
102 if /* Expand/collapse relevant options; based on file selection. */($(this).val() === 'wp-signup')
103 {
104 var gv = $('select#ws-plugin--s2member-mms-registration-grants').val(), l0v = $('input#ws-plugin--s2member-mms-registration-blogs-level0').val();
105 $('div#ws-plugin--s2member-mms-registration-support-package-details-wrapper').show(), $('div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login').hide(), $('div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup').show();
106 $('div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0')[((gv === 'all') ? 'show' : 'hide')]();
107 $('input#ws-plugin--s2member-mms-registration-blogs-level0').val(((gv === 'all') ? ((l0v > 0) ? l0v : '1') : '0'));
108 }
109 else if /* Expand/collapse relevant options. */($(this).val() === 'wp-login')
110 {
111 var gv = $('select#ws-plugin--s2member-mms-registration-grants').val(), l0v = $('input#ws-plugin--s2member-mms-registration-blogs-level0').val();
112 $('div#ws-plugin--s2member-mms-registration-support-package-details-wrapper').hide(), $('div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login').show(), $('div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup').hide();
113 $('div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0').hide();
114 $('input#ws-plugin--s2member-mms-registration-blogs-level0').val('0');
115 }
116 }).trigger /* Fire on ready too. */('change');
117
118 $('select#ws-plugin--s2member-mms-registration-grants').change(function()
119 {
120 $('select#ws-plugin--s2member-mms-registration-file').trigger('change');
121 });
122 }
123 if(location.href.match(/page\=ws-plugin--s2member-gen-ops/))
124 {
125 ws_plugin__s2member_enableSecurityKey = /* Allow Security Key editing?? */ function()
126 {
127 //260810 Warn about the concrete effects of changing the configured encryption key.
128 if(confirm('Edit Security Encryption Key?\n\nChanging this key will invalidate existing data that was encrypted with the current effective key, which can include access links, registration/tracking cookies, pending transaction-return data, and values encrypted through s2Member\'s API.\n\nContinue only if you intend to change or recover the key. Keep the current key backed up; s2Member also retains a history of recent Security Encryption Keys configured in s2Member.'))
129 $('input#ws-plugin--s2member-sec-encryption-key').removeAttr('disabled');
130
131 return false;
132 };
133 ws_plugin__s2member_securityKeyHistory = /* Displays history of Keys. */ function()
134 {
135 $('div#ws-plugin--s2member-sec-encryption-key-history').toggle();
136
137 return false;
138 };
139 $('select#ws-plugin--s2member-new-user-emails-enabled').change(function()
140 {
141 var $pluggable = $('input#ws-plugin--s2member-pluggables-wp-new-user-notification'), $this = $(this), $newUserEmails = $('div#ws-plugin--s2member-new-user-emails');
142
143 if($pluggable.val() === '0' || $this.val() === '0')
144 {
145 ($pluggable.val() === '0') ? $this.attr('disabled', 'disabled') : $this.removeAttr('disabled');
146 $(':input', $newUserEmails).attr('disabled', 'disabled'), $newUserEmails.css('opacity', '0.5');
147 }
148 else // Else we allow the emails to be customized.
149 $this.removeAttr('disabled'), $(':input', $newUserEmails).removeAttr('disabled'), $newUserEmails.css('opacity', '');
150
151 }).trigger /* Fire on ready too. */('change');
152
153 $('select#ws-plugin--s2member-login-reg-design-enabled').change(function()
154 {
155 var $this = $(this), $loginRegDesign = $('div#ws-plugin--s2member-login-reg-design');
156
157 if($this.val() === '0') // Disable this section.
158 $(':input', $loginRegDesign).attr('disabled', 'disabled'), $loginRegDesign.css('opacity', '0.5'), $loginRegDesign.hide();
159
160 else // Else we allow login/registration design.
161 $(':input', $loginRegDesign).removeAttr('disabled'), $loginRegDesign.css('opacity', ''), $loginRegDesign.show();
162
163 }).trigger /* Fire on ready too. */('change');
164
165 $('select#ws-plugin--s2member-custom-reg-password').change(function()
166 {
167 var $this = $(this), $newUserNotification = $('div#ws-plugin--s2member-new-user-email-details');
168
169 if($this.val() === '1') // Disable this section.
170 $newUserNotification.css('opacity', '0.5');
171 else $newUserNotification.css('opacity', '');
172
173 }).trigger /* Fire on ready too. */('change');
174
175 if($('input#ws-plugin--s2member-custom-reg-fields').length && $('div#ws-plugin--s2member-custom-reg-field-configuration').length)
176 {
177 ( /* Wrap these routines inside a function to keep variables within relative scope. */function()
178 {
179 var i, fieldDefaults, tools, table, $tools, $table;
180 var $fields = $('input#ws-plugin--s2member-custom-reg-fields');
181 var $configuration = $('div#ws-plugin--s2member-custom-reg-field-configuration');
182 //260928.0402 Use the standard JSON API provided natively or by WordPress's JSON2 compatibility dependency.
183 var fields = ($fields.val()) ? JSON.parse($fields.val()) : [];
184
185 fields = /* Force fields to an array. */ (fields instanceof Array) ? fields : [];
186
187 fieldDefaults = {section: 'no', sectitle: '', id: '', label: '', type: 'text', deflt: '', options: '', expected: '', required: 'yes', levels: 'all', editable: 'yes', classes: '', styles: '', attrs: ''};
188
189 for(i = 0; i < fields.length; i++)
190 fields[i] = /* Extend, based on defaults (for future proofing). */ $.extend(true, {
191 }, fieldDefaults, fields[i]);
192
193 tools = '<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>', table = '<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';
194
195 $configuration.html /* Add tools div & table div to configuration div (i.e., div#ws-plugin--s2member-custom-reg-field-configuration). */(tools+table);
196
197 $tools = $('div#ws-plugin--s2member-custom-reg-field-configuration-tools'), $table = $('table#ws-plugin--s2member-custom-reg-field-configuration-table');
198
199 ws_plugin__s2member_customRegFieldSectionChange = function(select)
200 {
201 var section = /* Current selection (no|yes, selected by site owner). */ $(select).val();
202
203 var sectitle_trs = 'tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle';
204
205 (section === 'yes') ? $(sectitle_trs).css('display', '') : $(sectitle_trs).css('display', 'none');
206 };
207 ws_plugin__s2member_customRegFieldTypeChange = /* Handle change events here. */ function(select)
208 {
209 var type = /* Current selection (type of Field, selected by site owner). */ $(select).val();
210
211 var deflt_trs = 'tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt', options_trs = 'tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options', expected_trs = 'tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected';
212
213 (type.match(/^(text|textarea)$/)) ? $(deflt_trs).css('display', '') : $(deflt_trs).css('display', 'none');
214 (type.match(/^(select|selects|checkboxes|radios)$/)) ? $(options_trs).css('display', '') : $(options_trs).css('display', 'none');
215 (type.match(/^(text|textarea)$/)) ? $(expected_trs).css('display', '') : $(expected_trs).css('display', 'none');
216 };
217 ws_plugin__s2member_customRegFieldDelete = function(index)
218 {
219 var newFields = /* Build array. */ new Array();
220
221 for(var i = 0; i < fields.length; i++)
222 if /* Omit index. */(i !== index)
223 newFields.push(fields[i]);
224
225 fields = newFields, updateFields(), buildTable();
226 };
227 ws_plugin__s2member_customRegFieldMoveUp = function(index)
228 {
229 if(typeof fields[index] === 'object' && typeof fields[index-1] === 'object')
230 {
231 var prevFieldObj = fields[index-1], thisFieldObj = fields[index];
232
233 fields[index-1] = thisFieldObj, fields[index] = prevFieldObj;
234
235 updateFields(), buildTable();
236 }
237 };
238 ws_plugin__s2member_customRegFieldMoveDown = function(index)
239 {
240 if(typeof fields[index] === 'object' && typeof fields[index+1] === 'object')
241 {
242 var nextFieldObj = fields[index+1], thisFieldObj = fields[index];
243
244 fields[index+1] = thisFieldObj, fields[index] = nextFieldObj;
245
246 updateFields(), buildTable();
247 }
248 };
249 ws_plugin__s2member_customRegFieldCreate = function()
250 {
251 var $table = $('table#ws-plugin--s2member-custom-reg-field-configuration-tools-form'), field = {};
252
253 $(':input[property]', $table).each( /* Go through each property value. */function()
254 {
255 var $this = $(this), property = $this.attr('property'), val = $.trim($this.val());
256
257 field[property] = val;
258 });
259 if /* If it can be validated. */((field = validateField(field)))
260 {
261 fields.push(field), updateFields(), buildTools(), buildTable(), scrollReset();
262
263 setTimeout( /* A momentary delay here for usability. */function()
264 {
265 var row = 'tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-'+(fields.length-1);
266 alert('Field created successfully.\n* Remember to "Save All Changes".');
267 //$(row).effect('highlight');
268 }, 500);
269 }
270 };
271 ws_plugin__s2member_customRegFieldUpdate = function(index)
272 {
273 var $table = $('table#ws-plugin--s2member-custom-reg-field-configuration-tools-form'), field = {};
274
275 $(':input[property]', $table).each( /* Go through each property value. */function()
276 {
277 var $this = $(this), property = $this.attr('property'), val = $.trim($this.val());
278
279 field[property] = val;
280 });
281 if /* If it validates. */((field = validateField(field, index)))
282 {
283 fields[index] = field, updateFields(), buildTools(), buildTable(), scrollReset();
284
285 setTimeout( /* A momentary delay here for usability. */function()
286 {
287 var row = 'tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-'+index;
288 alert('Field updated successfully.\n* Remember to "Save All Changes".');
289 //$(row).effect('highlight');
290 }, 500);
291 }
292 };
293 ws_plugin__s2member_customRegFieldAdd = /* Add new field links. */ function()
294 {
295 buildTools /* No need to reset scroll position. */(true);
296 };
297 ws_plugin__s2member_customRegFieldEdit = /* Edit links. */ function(index)
298 {
299 buildTools(false, index), scrollReset();
300 };
301 ws_plugin__s2member_customRegFieldCancel = /* Cancel form. */ function()
302 {
303 buildTools(), scrollReset();
304 };
305 var validateField = function(field, index)
306 {
307 var editing = ( typeof index === 'number' && typeof fields[index] === 'object') ? true : false, errors = [], options, i;
308
309 if(typeof field !== 'object' || typeof (field = $.extend(true, {}, fieldDefaults, field)) !== 'object')
310 {
311 alert('Invalid field object. Please try again.');
312 return false;
313 }
314 field.sectitle = (field.section === 'yes') ? field.sectitle : '';
315 field.deflt = (field.type.match(/^(text|textarea)$/)) ? field.deflt : '';
316 field.deflt = (field.type.match(/^(text)$/)) ? field.deflt.replace(/[\r\n\t ]+/g, ' ') : field.deflt;
317 field.options = (field.type.match(/^(select|selects|checkboxes|radios)$/)) ? field.options : '';
318 field.expected = (field.type.match(/^(text|textarea)$/)) ? field.expected : '';
319
320 if /* Every Field must have a unique ID. */(!field.id)
321 {
322 errors.push('Unique Field ID:\nThis is required. Please try again.');
323 }
324 else if(fieldIdExists(field.id) && (!editing || field.id !== fields[index].id))
325 {
326 errors.push('Unique Field ID:\nThat Field ID already exists. Please try again.');
327 }
328
329 if /* Every Field must have a label. */(!field.label)
330 {
331 errors.push('Field Label/Description:\nThis is required. Please try again.');
332 }
333
334 if(field.type.match(/^(select|selects|checkboxes|radios)$/) && !field.options)
335 {
336 errors.push('Option Configuration File:\nThis is required. Please try again.');
337 }
338 else if(field.type.match(/^(select|selects|checkboxes|radios)$/))
339 {
340 for(i = 0; i < (options = field.options.split(/[\r\n]+/)).length; i++)
341 {
342 if(!(options[i] = $.trim(options[i])).match(/^([^\|]*)(\|)([^\|]*)(\|default)?$/))
343 {
344 errors.push('Option Configuration File:\nInvalid configuration at line #'+(i+1)+'.');
345 break; // Break now. There could potentially be lots of lines with errors.
346 }
347 }
348 field.options = /* Clean up. */ $.trim(options.join('\n'));
349 }
350
351 if(!(field.levels = field.levels.replace(/ /g, '')))
352 {
353 errors.push('Applicable Levels:\nThis is required. Please try again.');
354 }
355 else if(!field.levels.match(/^(all|[0-9,]+)$/))
356 {
357 errors.push('Applicable Levels:\nShould be comma-delimited Levels, or just type: all.\n(examples: 0,1,2,3,4 or type the word: all)');
358 }
359
360 if(field.classes && field.classes.match(/[^a-z 0-9 _ \-]/i))
361 {
362 errors.push('CSS Classes:\nContains invalid characters. Please try again.\n(only: alphanumerics, underscores, hyphens, spaces)');
363 }
364
365 if(field.styles && field.styles.match(/["\=\>\<]/))
366 {
367 errors.push('CSS Styles:\nContains invalid characters. Please try again.\n(do NOT use these characters: = " < >)');
368 }
369
370 if(field.attrs && field.attrs.match(/[\>\<]/))
371 {
372 errors.push('Other Attributes:\nContains invalid characters. Please try again.\n(do NOT use these characters: < >)');
373 }
374
375 if /* Errors? */(errors.length > 0)
376 {
377 alert(errors.join('\n\n'));
378 return false;
379 }
380 else // Return.
381 return field;
382 };
383 var updateFields = /* Update hidden input value. */ function()
384 {
385 $fields.val(((fields.length > 0) ? JSON.stringify(fields) : ''));
386 };
387 var fieldId2Var = /* Convert ids to variables. */ function(fieldId)
388 {
389 return ( typeof fieldId === 'string') ? $.trim(fieldId).toLowerCase().replace(/[^a-z0-9]/g, '_') : '';
390 };
391 var fieldTypeDesc = function(type)
392 {
393 var types = {text: 'Text (single line)', textarea: 'Textarea (multi-line)', select: 'Select Menu (drop-down)', selects: 'Select Menu (multi-option)', checkbox: 'Checkbox (single)', pre_checkbox: 'Checkbox (pre-checked)', checkboxes: 'Checkboxes (multi-option)', radios: 'Radio Buttons (multi-option)'};
394
395 if(typeof types[type] === 'string')
396 return types[type];
397
398 return /* Default. */ '';
399 };
400 var fieldIdExists = /* Already exists? */ function(fieldId)
401 {
402 for(var i = 0; i < fields.length; i++)
403 if(fields[i].id === fieldId)
404 return true;
405 };
406 var scrollReset = /* Return to Custom Fields section. */ function()
407 {
408 scrollTo(0, $('div.ws-plugin--s2member-custom-reg-fields-section').offset()['top']-100);
409 };
410 var buildTools = /* This builds tools into the configuration. */ function(adding, index)
411 {
412 var i = 0, html = '', form = '', w = 0, h = 0, editing = ( typeof index === 'number' && typeof fields[index] === 'object') ? true : false, displayForm = (adding || editing) ? true : false, field = (editing) ? $.extend(true, {
413 }, fieldDefaults, fields[index]) : fieldDefaults;
414
415 html += /* Click to add a new Custom Registration/Profile Field. */ '<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';
416
417 tb_remove /* Remove an existing thickbox. */(), $('div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form').remove();
418
419 if /* Do we need to display the adding/editing form at all? */(displayForm)
420 {
421 form += '<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';
422
423 form += '<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';
424 form += '<tbody>';
425
426 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';
427 form += '<td colspan="2">';
428 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">Starts A New Section?</label>';
429 form += '</td>';
430 form += '</tr>';
431
432 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';
433 form += '<td colspan="2">';
434 form += '<select property="section" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section" onchange="ws_plugin__s2member_customRegFieldSectionChange(this);">';
435 form += '<option value="no"'+((field.section === 'no') ? ' selected="selected"' : '')+'">No (this Field flows normally)</option>';
436 form += '<option value="yes"'+((field.section === 'yes') ? ' selected="selected"' : '')+'">Yes (this Field begins a new section)</option>';
437 form += '</select><br />';
438 form += '<small>Optional. Allows Fields to be grouped into sections.</small>';
439 form += '</td>';
440 form += '</tr>';
441
442 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section === 'yes') ? '' : ' style="display:none;"')+'><td colspan="2"><hr /></td></tr>';
443
444 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section === 'yes') ? '' : ' style="display:none;"')+'>';
445 form += '<td colspan="2">';
446 form += 'Title for this new section? (optional)<br />';
447 form += '<input type="text" property="sectitle" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle" value="'+esc_attr(field.sectitle)+'" /><br />';
448 form += '<small>If empty, a simple divider will be used by default.</small>';
449 form += '</td>';
450 form += '</tr>';
451
452 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-type"><td colspan="2">&nbsp;</td></tr>';
453
454 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';
455 form += '<td colspan="2">';
456 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';
457 form += '</td>';
458 form += '</tr>';
459
460 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';
461 form += '<td colspan="2">';
462 form += '<select property="type" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);">';
463 form += '<option value="text"'+((field.type === 'text') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('text'))+'</option>';
464 form += '<option value="textarea"'+((field.type === 'textarea') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('textarea'))+'</option>';
465 form += '<option value="select"'+((field.type === 'select') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('select'))+'</option>';
466 form += '<option value="selects"'+((field.type === 'selects') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('selects'))+'</option>';
467 form += '<option value="checkbox"'+((field.type === 'checkbox') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('checkbox'))+'</option>';
468 form += '<option value="pre_checkbox"'+((field.type === 'pre_checkbox') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('pre_checkbox'))+'</option>';
469 form += '<option value="checkboxes"'+((field.type === 'checkboxes') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('checkboxes'))+'</option>';
470 form += '<option value="radios"'+((field.type === 'radios') ? ' selected="selected"' : '')+'">'+esc_html(fieldTypeDesc('radios'))+'</option>';
471 form += '</select><br />';
472 form += '<small>The options below may change, based on the Field Type you choose here.</small>';
473 form += '</td>';
474 form += '</tr>';
475
476 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-label"><td colspan="2">&nbsp;</td></tr>';
477
478 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';
479 form += '<td colspan="2">';
480 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';
481 form += '</td>';
482 form += '</tr>';
483
484 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';
485 form += '<td colspan="2">';
486 form += '<input type="text" property="label" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" value="'+esc_attr(field.label)+'" /><br />';
487 form += '<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>';
488 form += '</td>';
489 form += '</tr>';
490
491 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-id"><td colspan="2">&nbsp;</td></tr>';
492
493 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';
494 form += '<td colspan="2">';
495 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';
496 form += '</td>';
497 form += '</tr>';
498
499 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';
500 form += '<td colspan="2">';
501 form += '<input type="text" property="id" maxlength="25" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" value="'+esc_attr(field.id)+'" /><br />';
502 form += '<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />';
503 form += '<small>e.g., <code>[s2Get user_field="country_code" /]</code></small>';
504 form += '</td>';
505 form += '</tr>';
506
507 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-required"><td colspan="2">&nbsp;</td></tr>';
508
509 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';
510 form += '<td colspan="2">';
511 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';
512 form += '</td>';
513 form += '</tr>';
514
515 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';
516 form += '<td colspan="2">';
517 form += '<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';
518 form += '<option value="yes"'+((field.required === 'yes') ? ' selected="selected"' : '')+'">Yes (required)</option>';
519 form += '<option value="no"'+((field.required === 'no') ? ' selected="selected"' : '')+'">No (optional)</option>';
520 form += '</select><br />';
521 form += '<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';
522 form += '<small>* Administrators are exempt from this requirement.</small>';
523 form += '</td>';
524 form += '</tr>';
525
526 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/)) ? '' : ' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';
527
528 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/)) ? '' : ' style="display:none;"')+'>';
529 form += '<td colspan="2">';
530 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">Default Text Value: (optional)</label>';
531 form += '</td>';
532 form += '</tr>';
533
534 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/)) ? '' : ' style="display:none;"')+'>';
535 form += '<td colspan="2">';
536 form += '<textarea property="deflt" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt" rows="1">'+esc_html(field.deflt)+'</textarea><br />';
537 form += '<small>Default value before user input is received.</small>';
538 form += '</td>';
539 form += '</tr>';
540
541 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/)) ? '' : ' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';
542
543 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/)) ? '' : ' style="display:none;"')+'>';
544 form += '<td colspan="2">';
545 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * (one option per line)</label><br />';
546 form += '<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>';
547 form += '</td>';
548 form += '</tr>';
549
550 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/)) ? '' : ' style="display:none;"')+'>';
551 form += '<td colspan="2">';
552 form += '<textarea property="options" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options" rows="3">'+esc_html(field.options)+'</textarea><br />';
553 form += 'Here is a quick example:<br />';
554 form += '<small>You can also specify a <em>default</em> option:</small><br />';
555 form += '<code>US|United States|default</code><br />';
556 form += '<code>CA|Canada</code><br />';
557 form += '<code>VI|Virgin Islands (U.S.)</code>';
558 form += '</td>';
559 form += '</tr>';
560
561 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/)) ? '' : ' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';
562
563 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/)) ? '' : ' style="display:none;"')+'>';
564 form += '<td colspan="2">';
565 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';
566 form += '</td>';
567 form += '</tr>';
568
569 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/)) ? '' : ' style="display:none;"')+'>';
570 form += '<td colspan="2">';
571 form += '<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';
572
573 form += '<option value=""'+((field.expected === '') ? ' selected="selected"' : '')+'">Anything Goes</option>';
574 form += '<option disabled="disabled"></option>';
575
576 form += '<optgroup label="Specific Input Types">';
577 form += '<option value="numeric-wp-commas"'+((field.expected === 'numeric-wp-commas') ? ' selected="selected"' : '')+'">Numeric (with or without decimals, commas allowed)</option>';
578 form += '<option value="numeric"'+((field.expected === 'numeric') ? ' selected="selected"' : '')+'">Numeric (with or without decimals, no commas)</option>';
579 form += '<option value="integer"'+((field.expected === 'integer') ? ' selected="selected"' : '')+'">Integer (whole number, without any decimals)</option>';
580 form += '<option value="integer-gt-0"'+((field.expected === 'integer-gt-0') ? ' selected="selected"' : '')+'">Integer > 0 (whole number, no decimals, greater than 0)</option>';
581 form += '<option value="float"'+((field.expected === 'float') ? ' selected="selected"' : '')+'">Float (floating point number, decimals required)</option>';
582 form += '<option value="float-gt-0"'+((field.expected === 'float-gt-0') ? ' selected="selected"' : '')+'">Float > 0 (floating point number, decimals required, greater than 0)</option>';
583 form += '<option value="date"'+((field.expected === 'date') ? ' selected="selected"' : '')+'">Date (required date format: dd/mm/yyyy)</option>';
584 form += '<option value="email"'+((field.expected === 'email') ? ' selected="selected"' : '')+'">Email (require valid email)</option>';
585 form += '<option value="url"'+((field.expected === 'url') ? ' selected="selected"' : '')+'">Full URL (starting with http or https)</option>';
586 form += '<option value="domain"'+((field.expected === 'domain') ? ' selected="selected"' : '')+'">Domain Name (domain name only, without http)</option>';
587 form += '<option value="phone"'+((field.expected === 'phone') ? ' selected="selected"' : '')+'">Phone # (10 digits w/possible hyphens,spaces,brackets)</option>';
588 form += '<option value="uszip"'+((field.expected === 'uszip') ? ' selected="selected"' : '')+'">US Zipcode (5-9 digits w/possible hyphen)</option>';
589 form += '<option value="cazip"'+((field.expected === 'cazip') ? ' selected="selected"' : '')+'">Canadian Zipcode (6 alpha-numerics w/possible space)</option>';
590 form += '<option value="uczip"'+((field.expected === 'uczip') ? ' selected="selected"' : '')+'">US/Canadian Zipcode (either a US or Canadian zipcode)</option>';
591 form += '<option value="ukpostcode"'+((field.expected === 'ukpostcode') ? ' selected="selected"' : '')+'">UK Postcode (valid UK postcode format)</option>';
592 form += '</optgroup>';
593
594 form += '<option disabled="disabled"></option>';
595
596 form += '<optgroup label="Any Character Combination">';
597 for(i = 1; i <= 25; i++)
598 {
599 form += '<option value="any-'+i+'"'+((field.expected === 'any-'+i) ? ' selected="selected"' : '')+'">Any Character Combination ('+i+' character minimum)</option>';
600 form += '<option value="any-'+i+'-e"'+((field.expected === 'any-'+i+'-e') ? ' selected="selected"' : '')+'">Any Character Combination (exactly '+i+' character'+((i > 1) ? 's' : '')+')</option>';
601 }
602 form += '</optgroup>';
603
604 form += '<option disabled="disabled"></option>';
605
606 form += '<optgroup label="Alphanumerics, Spaces &amp; Punctuation Only">';
607 for(i = 1; i <= 25; i++)
608 {
609 form += '<option value="alphanumerics-spaces-punctuation-'+i+'"'+((field.expected === 'alphanumerics-spaces-punctuation-'+i) ? ' selected="selected"' : '')+'">Alphanumerics, Spaces &amp; Punctuation ('+i+' character minimum)</option>';
610 form += '<option value="alphanumerics-spaces-punctuation-'+i+'-e"'+((field.expected === 'alphanumerics-spaces-punctuation-'+i+'-e') ? ' selected="selected"' : '')+'">Alphanumerics, Spaces &amp; Punctuation (exactly '+i+' character'+((i > 1) ? 's' : '')+')</option>';
611 }
612 form += '</optgroup>';
613
614 form += '<option disabled="disabled"></option>';
615
616 form += '<optgroup label="Alphanumerics &amp; Spaces Only">';
617 for(i = 1; i <= 25; i++)
618 {
619 form += '<option value="alphanumerics-spaces-'+i+'"'+((field.expected === 'alphanumerics-spaces-'+i) ? ' selected="selected"' : '')+'">Alphanumerics &amp; Spaces ('+i+' character minimum)</option>';
620 form += '<option value="alphanumerics-spaces-'+i+'-e"'+((field.expected === 'alphanumerics-spaces-'+i+'-e') ? ' selected="selected"' : '')+'">Alphanumerics &amp; Spaces (exactly '+i+' character'+((i > 1) ? 's' : '')+')</option>';
621 }
622 form += '</optgroup>';
623
624 form += '<option disabled="disabled"></option>';
625
626 form += '<optgroup label="Alphanumerics &amp; Punctuation Only">';
627 for(i = 1; i <= 25; i++)
628 {
629 form += '<option value="alphanumerics-punctuation-'+i+'"'+((field.expected === 'alphanumerics-punctuation-'+i) ? ' selected="selected"' : '')+'">Alphanumerics &amp; Punctuation ('+i+' character minimum)</option>';
630 form += '<option value="alphanumerics-punctuation-'+i+'-e"'+((field.expected === 'alphanumerics-punctuation-'+i+'-e') ? ' selected="selected"' : '')+'">Alphanumerics &amp; Punctuation (exactly '+i+' character'+((i > 1) ? 's' : '')+')</option>';
631 }
632 form += '</optgroup>';
633
634 form += '<option disabled="disabled"></option>';
635
636 form += '<optgroup label="Alphanumerics Only">';
637 for(i = 1; i <= 25; i++)
638 {
639 form += '<option value="alphanumerics-'+i+'"'+((field.expected === 'alphanumerics-'+i) ? ' selected="selected"' : '')+'">Alphanumerics ('+i+' character minimum)</option>';
640 form += '<option value="alphanumerics-'+i+'-e"'+((field.expected === 'alphanumerics-'+i+'-e') ? ' selected="selected"' : '')+'">Alphanumerics (exactly '+i+' character'+((i > 1) ? 's' : '')+')</option>';
641 }
642 form += '</optgroup>';
643
644 form += '<option disabled="disabled"></option>';
645
646 form += '<optgroup label="Alphabetics Only">';
647 for(i = 1; i <= 25; i++)
648 {
649 form += '<option value="alphabetics-'+i+'"'+((field.expected === 'alphabetics-'+i) ? ' selected="selected"' : '')+'">Alphabetics ('+i+' character minimum)</option>';
650 form += '<option value="alphabetics-'+i+'-e"'+((field.expected === 'alphabetics-'+i+'-e') ? ' selected="selected"' : '')+'">Alphabetics (exactly '+i+' character'+((i > 1) ? 's' : '')+')</option>';
651 }
652 form += '</optgroup>';
653
654 form += '<option disabled="disabled"></option>';
655
656 form += '<optgroup label="Numeric Digits Only">';
657 for(i = 1; i <= 25; i++)
658 {
659 form += '<option value="numerics-'+i+'"'+((field.expected === 'numerics-'+i) ? ' selected="selected"' : '')+'">Numeric Digits ('+i+' digit minimum)</option>';
660 form += '<option value="numerics-'+i+'-e"'+((field.expected === 'numerics-'+i+'-e') ? ' selected="selected"' : '')+'">Numeric Digits (exactly '+i+' digit'+((i > 1) ? 's' : '')+')</option>';
661 }
662 form += '</optgroup>';
663
664 form += '</select><br />';
665 form += '<small>Only Users/Members will be required to meet this criteria.</small><br />';
666 form += '<small>* Administrators are exempt from this.</small>';
667 form += '</td>';
668 form += '</tr>';
669
670 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels"><td colspan="2">&nbsp;</td></tr>';
671
672 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';
673 form += '<td colspan="2">';
674 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';
675 form += '</td>';
676 form += '</tr>';
677
678 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';
679 form += '<td colspan="2">';
680 form += '<input type="text" property="levels" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" value="'+esc_attr(field.levels)+'" /><br />';
681 form += '<small>Please use comma-delimited Level #\'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />';
682 form += '<small>This allows you to enable this field - only at specific Membership Levels.</small>';
683 form += '</td>';
684 form += '</tr>';
685
686 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable"><td colspan="2">&nbsp;</td></tr>';
687
688 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';
689 form += '<td colspan="2">';
690 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';
691 form += '</td>';
692 form += '</tr>';
693
694 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';
695 form += '<td colspan="2">';
696 form += '<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';
697 form += '<option value="yes"'+((field.editable === 'yes') ? ' selected="selected"' : '')+'">Yes (editable)</option>';
698 form += '<option value="no"'+((field.editable === 'no') ? ' selected="selected"' : '')+'">No (uneditable after registration)</option>';
699 form += '<option value="no-invisible"'+((field.editable === 'no-invisible') ? ' selected="selected"' : '')+'">No (uneditable &amp; totally invisible after registration)</option>';
700 form += '<option value="no-always-invisible"'+((field.editable === 'no-always-invisible') ? ' selected="selected"' : '')+'">No (uneditable &amp; totally invisible, both during &amp; after registration)</option>';
701 form += '<option value="yes-invisible"'+((field.editable === 'yes-invisible') ? ' selected="selected"' : '')+'">Yes (editable after registration / invisible during registration)</option>';
702 form += '</select><br />';
703 form += '<small>If <code>No</code>, this field will be un-editable after registration.</small><br />';
704 form += '<small>* Administrators are exempt from this.</small>';
705 form += '</td>';
706 form += '</tr>';
707
708 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes"><td colspan="2">&nbsp;</td></tr>';
709
710 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';
711 form += '<td colspan="2">';
712 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: (optional)</label>';
713 form += '</td>';
714 form += '</tr>';
715
716 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';
717 form += '<td colspan="2">';
718 form += '<input type="text" property="classes" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" value="'+esc_attr(field.classes)+'" /><br />';
719 form += '<small>Example: <code>my-style-1 my-style-2</code></small>';
720 form += '</td>';
721 form += '</tr>';
722
723 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles"><td colspan="2">&nbsp;</td></tr>';
724
725 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';
726 form += '<td colspan="2">';
727 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: (optional)</label>';
728 form += '</td>';
729 form += '</tr>';
730
731 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';
732 form += '<td colspan="2">';
733 form += '<input type="text" property="styles" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" value="'+esc_attr(field.styles)+'" /><br />';
734 form += '<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>';
735 form += '</td>';
736 form += '</tr>';
737
738 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs"><td colspan="2">&nbsp;</td></tr>';
739
740 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';
741 form += '<td colspan="2">';
742 form += '<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: (optional)</label>';
743 form += '</td>';
744 form += '</tr>';
745
746 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';
747 form += '<td colspan="2">';
748 form += '<input type="text" property="attrs" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" value="'+esc_attr(field.attrs)+'" /><br />';
749 form += '<small>Example: <code>onkeyup="" onblur=""</code></small>';
750 form += '</td>';
751 form += '</tr>';
752
753 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons"><td colspan="2">&nbsp;</td></tr>';
754
755 form += '<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';
756 form += '<td align="left">';
757 form += '<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';
758 form += '</td>';
759 form += '<td align="right">';
760 form += '<input type="button" value="'+((editing) ? 'Update This Field' : 'Create Registration Field')+'" onclick="'+((editing) ? 'ws_plugin__s2member_customRegFieldUpdate('+index+');' : 'ws_plugin__s2member_customRegFieldCreate();')+'" />';
761 form += '</td>';
762 form += '</tr>';
763
764 form += '</tbody>';
765 form += '</table>';
766
767 form += '<div>';
768
769 $('body').append(form);
770
771 tb_show(((editing) ? 'Editing Registration/Profile Field' : 'New Custom Registration/Profile Field'), '#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form');
772
773 $('table#ws-plugin--s2member-custom-reg-field-configuration-tools-form').show();
774 }
775 $tools.html(html);
776 };
777 var buildTable = /* This builds the table of existing fields. */ function()
778 {
779 var l = fields.length, i = 0, html = '', eo = 'o';
780
781 html += '<tbody>';
782
783 html += '<tr>';
784 html += '<th>Order</th>';
785 html += '<th>Field Type</th>';
786 html += '<th>Unique ID</th>';
787 html += '<th>Required</th>';
788 html += '<th>Levels</th>';
789 html += '<th>- Tools -</th>';
790 html += '</tr>';
791
792 if /* Any fields? */(fields.length > 0)
793 {
794 for(i = 0; i < fields.length; i++)
795 {
796 html += '<tr class="'+esc_attr((eo = (eo === 'o') ? 'e' : 'o'))+((fields[i].section === 'yes') ? ' s' : '')+' ws-plugin--s2member-custom-reg-field-configuration-table-row-'+i+'">'; // Odd/even + row identifier.
797 html += '<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+i+'); return false;"></a></td>';
798 html += '<td nowrap="nowrap">'+esc_html(fieldTypeDesc(fields[i].type))+'</td>';
799 html += '<td nowrap="nowrap">'+esc_html(fields[i].id)+'</td>';
800 html += '<td nowrap="nowrap">'+esc_html(fields[i].required)+'</td>';
801 html += '<td nowrap="nowrap">'+esc_html(fields[i].levels)+'</td>';
802 html += '<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+i+'); return false;"></a></td>';
803 html += '</tr>';
804 }
805 }
806 else // Otherwise, there are no fields configured yet.
807 {
808 html += /* There are no fields yet. */ '<tr>';
809 html += '<td colspan="6">No Custom Fields are configured.</td>';
810 html += '</tr>';
811 }
812
813 html += '</tbody>';
814
815 $table.html(html);
816 };
817 buildTools(), buildTable();
818 })();
819 }
820 }
821 if(location.href.match(/page\=ws-plugin--s2member-res-ops/))
822 {
823 $('input#ws-plugin--s2member-brute-force-restrictions-reset-button').click(function()
824 {
825 var $this = /* Save $(this) into $this. */ $(this);
826 $this.val /* Indicate loading status (please wait). */('one moment please ...');
827
828 $.post(ajaxurl, {action: 'ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax', ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax: '<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'}, function(response)
829 {
830 alert('s2Member\'s Brute Force Restriction Logs have all been reset.'), $this.val('Reset Brute Force Logs');
831 });
832
833 return false;
834 });
835 $('input#ws-plugin--s2member-ip-restrictions-reset-button').click(function()
836 {
837 var $this = /* Save $(this) into $this. */ $(this);
838 $this.val /* Indicate loading status (please wait). */('one moment please ...');
839
840 $.post(ajaxurl, {action: 'ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax', ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax: '<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'}, function(response)
841 {
842 alert('s2Member\'s IP Restriction Logs have all been reset.'), $this.val('Reset IP Restriction Logs');
843 });
844 return false;
845 });
846 $('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query\[\]"]').change(function()
847 {
848 var thisChange = /* Record value associated with change event. Allows for intutitive unchecking. */ $(this).val();
849
850 $('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query\[\]"]').each(function()
851 {
852 var $this = $(this), val = $this.val(), checkboxes = 'input[type="checkbox"]';
853
854 if /* All sub-items get checked/disabled. */(val === 'all' && this.checked)
855 $this.nextAll(checkboxes).attr({'checked': 'checked', 'disabled': 'disabled'});
856
857 else if(val === 'all' && !this.checked)
858 {
859 $this.nextAll(checkboxes).removeAttr('disabled');
860 (thisChange === 'all') ? $this.nextAll(checkboxes).removeAttr('checked') : null;
861 }
862 });
863 }).last().trigger('change');
864 }
865 if(location.href.match(/page\=ws-plugin--s2member-down-ops/))
866 {
867 var updateCloudFrontPrivateKey = /* Attaches to events below. */ function()
868 {
869 var $hiddenPrivateKey = $('input#ws-plugin--s2member-amazon-cf-files-private-key');
870 var $visiblePrivateKeyEntry = $('textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry');
871 var hiddenPrivateKeyValue = $.trim($hiddenPrivateKey.val()), visiblePrivateKeyEntryValue = $.trim($visiblePrivateKeyEntry.val());
872
873 if((hiddenPrivateKeyValue && !visiblePrivateKeyEntryValue) || visiblePrivateKeyEntryValue.match /* 9679.toString(16).toUpperCase() = 25CF. */(/[^\r\n\u25CF]/))
874 $hiddenPrivateKey.val(visiblePrivateKeyEntryValue), $visiblePrivateKeyEntry.val(visiblePrivateKeyEntryValue.replace(/[^\r\n]/g, String.fromCharCode(9679)));
875 };
876 $('form#ws-plugin--s2member-options-form').submit(updateCloudFrontPrivateKey);
877 $('textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry').change(updateCloudFrontPrivateKey).trigger('change');
878
879 var updateCloudFrontDistroCfgs = /* Attaches to events below. */ function()
880 {
881 var $hiddenPrivateKey = $('input#ws-plugin--s2member-amazon-cf-files-private-key');
882 var $visiblePrivateKeyId = $('input#ws-plugin--s2member-amazon-cf-files-private-key-id');
883
884 var $autoConfigDistros = $('input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros');
885 var $autoConfigDistrosStatus = $('input#ws-plugin--s2member-amazon-cf-files-distros-auto-config-status');
886
887 var autoConfigDistrosStatusValue = $.trim($autoConfigDistrosStatus.val());
888 var hiddenPrivateKeyValue = $.trim($hiddenPrivateKey.val()), visiblePrivateKeyIdValue = $.trim($visiblePrivateKeyId.val());
889 var hiddenPrivateKeyPrevConfigValue = $.trim($hiddenPrivateKey.attr('data-s-prev-config-value')), visiblePrivateKeyIdPrevConfigValue = $.trim($visiblePrivateKeyId.attr('data-s-prev-config-value'));
890
891 if(autoConfigDistrosStatusValue === 'configured' && ((visiblePrivateKeyIdPrevConfigValue && visiblePrivateKeyIdValue !== visiblePrivateKeyIdPrevConfigValue) || (hiddenPrivateKeyPrevConfigValue && hiddenPrivateKeyValue !== hiddenPrivateKeyPrevConfigValue)))
892 {
893 alert('s2Member will need to delete and re-configure your Amazon CloudFront distributions if you change this. When you\'re done editing, click (Save All Changes) below.');
894 $autoConfigDistros.attr /* Forcibly check. */('checked', 'checked');
895 }
896 else if(autoConfigDistrosStatusValue !== 'configured' && visiblePrivateKeyIdValue && hiddenPrivateKeyValue)
897 {
898 alert('s2Member will need to auto-configure your Amazon CloudFront distributions for you. When you\'re done editing, click (Save All Changes) below.');
899 $autoConfigDistros.attr /* Forcibly check. */('checked', 'checked');
900 }
901 };
902 $('input#ws-plugin--s2member-amazon-cf-files-private-key-id').change(updateCloudFrontDistroCfgs);
903 $('textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry').change(updateCloudFrontDistroCfgs);
904
905 $('input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames').change(function()
906 {
907 var $this = $(this), thisChecked = (this.checked) ? true : false;
908 var $autoConfigDistros = $('input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros');
909 var $autoConfigDistroCnames = $('div#ws-plugin--s2member-amazon-cf-files-auto-configure-distro-cnames');
910
911 (thisChecked) ? $autoConfigDistroCnames.show() : $autoConfigDistroCnames.hide();
912 (thisChecked) ? $autoConfigDistros.attr('checked', 'checked') : null;
913
914 }).trigger('change');
915 }
916 //260917.0108 Keep Demote-only options visibly inactive for Delete behavior, and update them immediately when the administrator changes the behavior selector.
917 $('select#ws-plugin--s2member-membership-eot-behavior').change(function()
918 {
919 var disabled = ($(this).val() === 'delete');
920 var $demotionRows = $('tr.ws-plugin--s2member-eot-demotion-option-row');
921 var $demotionInputs = $(':input', $demotionRows);
922 var $ccapsInput = $('#ws-plugin--s2member-eots-remove-ccaps');
923 var $ccapsRows = $('label[for="ws-plugin--s2member-eots-remove-ccaps"]').closest('tr').add($ccapsInput.closest('tr'));
924
925 $demotionInputs.add($ccapsInput).prop('disabled', disabled);
926 $demotionRows.add($ccapsRows).css('opacity', disabled ? '0.5' : '');
927 }).trigger('change');
928
929 //260917.0108 Custom Maximum Runtime is meaningful only in Custom mode; preserve its saved value while making the dependency obvious in the UI.
930 $('select#ws-plugin--s2member-auto-eot-system-runtime-mode').change(function()
931 {
932 var disabled = ($(this).val() !== 'custom');
933 var $runtimeInput = $('#ws-plugin--s2member-auto-eot-system-runtime-custom');
934 var $runtimeRows = $('label[for="ws-plugin--s2member-auto-eot-system-runtime-custom"]').closest('tr').add($runtimeInput.closest('tr'));
935
936 $runtimeInput.prop('disabled', disabled);
937 $runtimeRows.css('opacity', disabled ? '0.5' : '');
938 }).trigger('change');
939
940 if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/))
941 {
942 $('select#ws-plugin--s2member-auto-eot-system-enabled').change(function()
943 {
944 var $this = $(this), val = $this.val();
945 var $viaCron = $('p#ws-plugin--s2member-auto-eot-system-enabled-via-cron');
946
947 if /* Display Cron instructions. */(val == 2)
948 $viaCron.show()
949 else // Hide instructions.
950 $viaCron.hide();
951 });
952 }
953 if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/))
954 {
955 $('div.ws-menu-page select[id]').filter( /* Filter all select elements with an id. */function()
956 {
957 return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-term$/);
958 })
959 .change(function()
960 {
961 var button = this.id.replace(/^ws-plugin--s2member-(.+?)-term$/g, '$1');
962 var trialDisabled = ($(this).val().split('-')[2].replace(/[^0-1BN]/g, '') === 'BN') ? 1 : 0;
963
964 $('p#ws-plugin--s2member-'+button+'-trial-line').css('display', (trialDisabled ? 'none' : ''));
965 $('span#ws-plugin--s2member-'+button+'-trial-then').css('display', (trialDisabled ? 'none' : ''));
966 $('span#ws-plugin--s2member-'+button+'-20p-rule').css('display', (trialDisabled ? 'none' : ''));
967
968 (trialDisabled) ? $('input#ws-plugin--s2member-'+button+'-trial-period').val(0) : null;
969 (trialDisabled) ? $('input#ws-plugin--s2member-'+button+'-trial-amount').val('0.00') : null;
970 });
971 $('div.ws-menu-page input[id]').filter( /* Filter all input elements with an id. */function()
972 {
973 return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification|ccap)-ccaps$/);
974 })
975 .keyup(function()
976 {
977 var value = this.value.replace(/^(-all|-al|-a|-)[;,]*/gi, ''), _all = (this.value.match(/^(-all|-al|-a|-)[;,]*/i)) ? '-all,' : '';
978 if /* Only if there is a problem with the actual values; because this causes interruptions. */(value.match(/[^a-z_0-9,]/))
979 this.value = _all+$.trim($.trim(value).replace(/[ \-]/g, '_').replace(/[^a-z_0-9,]/gi, '').toLowerCase());
980 });
981 ws_plugin__s2member_paypalButtonGenerate = /* Handles PayPal Button Generation. */ function(button)
982 {
983 var shortCodeTemplate = '[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]', shortCodeTemplateAttrs = '', labels = {};
984
985 eval("<?php echo c_ws_plugin__s2member_utils_strings::esc_dq($labels); ?>");
986
987 var shortCode = $('input#ws-plugin--s2member-'+button+'-shortcode');
988 var code = $('textarea#ws-plugin--s2member-'+button+'-button');
989 var modLevel = $('select#ws-plugin--s2member-modification-level');
990
991 var level = (button === 'modification') ? modLevel.val().split(':', 2)[1] : button.replace(/^level/, '');
992 var label = /* Labels may NOT contain double-quotes. */ labels['level'+level].replace(/"/g, '');
993 var desc = $.trim($('input#ws-plugin--s2member-'+button+'-desc').val().replace(/"/g, ""));
994
995 var trialAmount = $('input#ws-plugin--s2member-'+button+'-trial-amount').val().replace(/[^0-9\.]/g, '');
996 var trialPeriod = $('input#ws-plugin--s2member-'+button+'-trial-period').val().replace(/[^0-9]/g, '');
997 var trialTerm = $('select#ws-plugin--s2member-'+button+'-trial-term').val().replace(/[^A-Z]/g, '');
998
999 var regAmount = $('input#ws-plugin--s2member-'+button+'-amount').val().replace(/[^0-9\.]/g, '');
1000 var regPeriod = $('select#ws-plugin--s2member-'+button+'-term').val().split('-')[0].replace(/[^0-9]/g, '');
1001 var regTerm = $('select#ws-plugin--s2member-'+button+'-term').val().split('-')[1].replace(/[^A-Z]/g, '');
1002 var regRecur = $('select#ws-plugin--s2member-'+button+'-term').val().split('-')[2].replace(/[^0-1BN]/g, '');
1003 var /* These options are NOT yet configurable. */ regRecurTimes = '', regRecurRetry = '1';
1004
1005 var /* NOT yet configurable. */ localeCode = '', digital = '0', noShipping = '1';
1006 var pageStyle = $.trim($('input#ws-plugin--s2member-'+button+'-page-style').val().replace(/"/g, ''));
1007 var currencyCode = $('select#ws-plugin--s2member-'+button+'-currency').val().replace(/[^A-Z]/g, '');
1008
1009 var cCaps = $.trim($.trim($('input#ws-plugin--s2member-'+button+'-ccaps').val()).replace(/^(-all|-al|-a|-)[;,]*/gi, '').replace(/[ \-]/g, '_').replace(/[^a-z_0-9,]/gi, '').toLowerCase());
1010 cCaps = ($.trim($('input#ws-plugin--s2member-'+button+'-ccaps').val()).match(/^(-all|-al|-a|-)[;,]*/i)) ? ((cCaps) ? '-all,' : '-all')+cCaps.toLowerCase() : cCaps.toLowerCase();
1011
1012 trialPeriod = /* Lifetime (1-L-BN) and Buy Now ( BN ) access is absolutely NOT compatible w/ Trial Periods. */ (regRecur === 'BN') ? '0' : trialPeriod;
1013 trialAmount = /* Validate Trial Amount. */ (!trialAmount || isNaN(trialAmount) || trialAmount < 0.01 || trialPeriod <= 0) ? '0' : trialAmount;
1014
1015 var levelCcapsPer = (regRecur === 'BN' && regTerm !== 'L') ? level+':'+cCaps+':'+regPeriod+' '+regTerm : level+':'+cCaps;
1016 levelCcapsPer = /* Clean any trailing separators from this string. */ levelCcapsPer.replace(/\:+$/g, '');
1017
1018 if(trialAmount !== '0' && (isNaN(trialAmount) || trialAmount < 0.00))
1019 {
1020 alert('— Oops, a slight problem: —\n\nWhen provided, Trial Amount must be >= 0.00');
1021 return false;
1022 }
1023 else if(trialAmount !== '0' && /* Maximum. */ trialAmount > 10000.00 && currencyCode.toUpperCase() === 'USD')
1024 {
1025 alert('— Oops, a slight problem: —\n\nMaximum Trial Amount is: 10000.00');
1026 return false;
1027 }
1028 else if(trialTerm === 'D' && /* Some validation on the Trial Period. Max days: 90. */ trialPeriod > 90)
1029 {
1030 alert('— Oops, a slight problem: —\n\nMaximum Trial Days is: 90.\nIf you want to offer more than 90 days, please choose Weeks or Months from the drop-down.');
1031 return false;
1032 }
1033 else if(trialTerm === 'W' && /* Some validation on the Trial Period. 52 max. */ trialPeriod > 52)
1034 {
1035 alert('— Oops, a slight problem: —\n\nMaximum Trial Weeks is: 52.\nIf you want to offer more than 52 weeks, please choose Months from the drop-down.');
1036 return false;
1037 }
1038 else if(trialTerm === 'M' && /* Some validation on the Trial Period. 24 max. */ trialPeriod > 24)
1039 {
1040 alert('— Oops, a slight problem: —\n\nMaximum Trial Months is: 24.\nIf you want to offer more than 24 months, please choose Years from the drop-down.');
1041 return false;
1042 }
1043 else if(trialTerm === 'Y' && /* 5 years max. */ trialPeriod > 5)
1044 {
1045 alert('— Oops, a slight problem: —\n\nMax Trial Period Years is: 5.');
1046 return false;
1047 }
1048 else if(!regAmount || isNaN(regAmount) || regAmount < 0.01)
1049 {
1050 alert('— Oops, a slight problem: —\n\nAmount must be >= 0.01');
1051 return false;
1052 }
1053 else if(regAmount > /* $10,000.00 maximum. */ 10000.00 && currencyCode.toUpperCase() === 'USD')
1054 {
1055 alert('— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00');
1056 return false;
1057 }
1058 else if /* Each Button should have a Description. */(!desc)
1059 {
1060 alert('— Oops, a slight problem: —\n\nPlease type a Description for this Button.');
1061 return false;
1062 }
1063 code.html(code.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g, " $1"));
1064 (parseInt(trialPeriod) <= 0) ? code.html(code.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
1065 (regRecur === 'BN') ? code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g, " $1_xclick$3")) : null;
1066 (regRecur === 'BN') ? code.html(code.val().replace(/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
1067 (regRecur !== 'BN') ? code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g, " $1_xclick-subscriptions$3")) : null;
1068 (regRecur !== 'BN') ? code.html(code.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
1069
1070 shortCodeTemplateAttrs += /* For Modification Buttons. */ (button === 'modification') ? 'modify="1" ' : '';
1071 shortCodeTemplateAttrs += 'level="'+esc_attr(level)+'" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';
1072 shortCodeTemplateAttrs += ' ta="'+esc_attr(trialAmount)+'" tp="'+esc_attr(trialPeriod)+'" tt="'+esc_attr(trialTerm)+'" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'" rrt="'+esc_attr(regRecurTimes)+'" rra="'+esc_attr(regRecurRetry)+'"';
1073 shortCode.val(shortCodeTemplate.replace(/%%attrs%%/, shortCodeTemplateAttrs));
1074
1075 code.html(code.val().replace(/ name\="lc" value\="(.*?)"/, ' name="lc" value="'+esc_attr(localeCode)+'"'));
1076 code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/, ' name="no_shipping" value="'+esc_attr(noShipping)+'"'));
1077 code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/, ' name="item_name" value="'+esc_attr(desc)+'"'));
1078 code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/, ' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));
1079 code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/, ' name="page_style" value="'+esc_attr(pageStyle)+'"'));
1080 code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/, ' name="currency_code" value="'+esc_attr(currencyCode)+'"'));
1081 code.html(code.val().replace(/ name\="custom" value\="(.*?)"/, ' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));
1082
1083 code.html(code.val().replace(/ name\="modify" value\="(.*?)"/, ' name="modify" value="'+((button === 'modification') ? '1' : '0')+'"'));
1084
1085 code.html(code.val().replace(/ name\="amount" value\="(.*?)"/, ' name="amount" value="'+esc_attr(regAmount)+'"'));
1086
1087 code.html(code.val().replace(/ name\="src" value\="(.*?)"/, ' name="src" value="'+esc_attr(regRecur)+'"'));
1088 code.html(code.val().replace(/ name\="srt" value\="(.*?)"/, ' name="srt" value="'+esc_attr(regRecurTimes)+'"'));
1089 code.html(code.val().replace(/ name\="sra" value\="(.*?)"/, ' name="sra" value="'+esc_attr(regRecurRetry)+'"'));
1090
1091 code.html(code.val().replace(/ name\="a1" value\="(.*?)"/, ' name="a1" value="'+esc_attr(trialAmount)+'"'));
1092 code.html(code.val().replace(/ name\="p1" value\="(.*?)"/, ' name="p1" value="'+esc_attr(trialPeriod)+'"'));
1093 code.html(code.val().replace(/ name\="t1" value\="(.*?)"/, ' name="t1" value="'+esc_attr(trialTerm)+'"'));
1094 code.html(code.val().replace(/ name\="a3" value\="(.*?)"/, ' name="a3" value="'+esc_attr(regAmount)+'"'));
1095 code.html(code.val().replace(/ name\="p3" value\="(.*?)"/, ' name="p3" value="'+esc_attr(regPeriod)+'"'));
1096 code.html(code.val().replace(/ name\="t3" value\="(.*?)"/, ' name="t3" value="'+esc_attr(regTerm)+'"'));
1097
1098 $('div#ws-plugin--s2member-'+button+'-button-prev').html(code.val().replace(/\<form/, '<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr (c_ws_plugin__s2member_utils_ip::current())); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1099
1100 (button === 'modification') ? alert('Your Modification Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Modification Buttons should be displayed to existing Users/Members, and they should be logged-in, BEFORE clicking this Button.') : alert('Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.');
1101
1102 shortCode.each( /* Focus and select the Shortcode. */function()
1103 {
1104 this.focus(), this.select();
1105 });
1106 return false;
1107 };
1108 ws_plugin__s2member_paypalCcapButtonGenerate = /* Handles PayPal Button Generation for Independent Capabilities. */ function()
1109 {
1110 var shortCodeTemplate = '[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]', shortCodeTemplateAttrs = '';
1111
1112 var shortCode = $('input#ws-plugin--s2member-ccap-shortcode');
1113 var code = $('textarea#ws-plugin--s2member-ccap-button');
1114
1115 var desc = $.trim($('input#ws-plugin--s2member-ccap-desc').val().replace(/"/g, ''));
1116
1117 var regAmount = $('input#ws-plugin--s2member-ccap-amount').val().replace(/[^0-9\.]/g, '');
1118 var regPeriod = $('select#ws-plugin--s2member-ccap-term').val().split('-')[0].replace(/[^0-9]/g, '');
1119 var regTerm = $('select#ws-plugin--s2member-ccap-term').val().split('-')[1].replace(/[^A-Z]/g, '');
1120 var regRecur = $('select#ws-plugin--s2member-ccap-term').val().split('-')[2].replace(/[^0-1BN]/g, '');
1121
1122 var /* NOT yet configurable. */ localeCode = '', digital = '0', noShipping = '1';
1123 var pageStyle = $.trim($('input#ws-plugin--s2member-ccap-page-style').val().replace(/"/g, ''));
1124 var currencyCode = $('select#ws-plugin--s2member-ccap-currency').val().replace(/[^A-Z]/g, '');
1125
1126 var cCaps = $.trim($.trim($('input#ws-plugin--s2member-ccap-ccaps').val()).replace(/^(-all|-al|-a|-)[;,]*/gi, '').replace(/[ \-]/g, '_').replace(/[^a-z_0-9,]/gi, '').toLowerCase());
1127 cCaps = ($.trim($('input#ws-plugin--s2member-ccap-ccaps').val()).match(/^(-all|-al|-a|-)[;,]*/i)) ? ((cCaps) ? '-all,' : '-all')+cCaps.toLowerCase() : cCaps.toLowerCase();
1128
1129 var levelCcapsPer = (regRecur === 'BN' && regTerm !== 'L') ? '*:'+cCaps+':'+regPeriod+' '+regTerm : '*:'+cCaps;
1130 levelCcapsPer = /* Clean any trailing separators from this string. */ levelCcapsPer.replace(/\:+$/g, '');
1131
1132 if /* Must have some Independent Custom Capabilities. */(!cCaps || cCaps === '-all')
1133 {
1134 alert('— Oops, a slight problem: —\n\nPlease provide at least one Custom Capability.');
1135 return false;
1136 }
1137 else if(!regAmount || isNaN(regAmount) || regAmount < 0.01)
1138 {
1139 alert('— Oops, a slight problem: —\n\nAmount must be >= 0.01');
1140 return false;
1141 }
1142 else if /* $10,000.00 maximum. */(regAmount > 10000.00 && currencyCode.toUpperCase() === 'USD')
1143 {
1144 alert('— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00');
1145 return false;
1146 }
1147 else if /* Each Button should have a Description. */(!desc)
1148 {
1149 alert('— Oops, a slight problem: —\n\nPlease type a Description for this Button.');
1150 return false;
1151 }
1152
1153 shortCodeTemplateAttrs += 'level="*" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';
1154 shortCodeTemplateAttrs += ' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'"';
1155 shortCode.val(shortCodeTemplate.replace(/%%attrs%%/, shortCodeTemplateAttrs));
1156
1157 code.html(code.val().replace(/ name\="lc" value\="(.*?)"/, ' name="lc" value="'+esc_attr(localeCode)+'"'));
1158 code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/, ' name="no_shipping" value="'+esc_attr(noShipping)+'"'));
1159 code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/, ' name="item_name" value="'+esc_attr(desc)+'"'));
1160 code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/, ' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));
1161 code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/, ' name="page_style" value="'+esc_attr(pageStyle)+'"'));
1162 code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/, ' name="currency_code" value="'+esc_attr(currencyCode)+'"'));
1163 code.html(code.val().replace(/ name\="custom" value\="(.*?)"/, ' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));
1164
1165 code.html(code.val().replace(/ name\="amount" value\="(.*?)"/, ' name="amount" value="'+esc_attr(regAmount)+'"'));
1166
1167 $('div#ws-plugin--s2member-ccap-button-prev').html(code.val().replace(/\<form/, '<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr (c_ws_plugin__s2member_utils_ip::current())); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1168
1169 alert('Your Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Independent Custom Capability Buttons should ONLY be displayed to existing Users/Members, and they MUST be logged-in, BEFORE clicking this Button.');
1170
1171 shortCode.each /* Focus and select the Shortcode. */(function()
1172 {
1173 this.focus(), this.select();
1174 });
1175 return false;
1176 };
1177 ws_plugin__s2member_paypalSpButtonGenerate = /* Handles PayPal Button Generation for Specific Post/Page Access. */ function()
1178 {
1179 var shortCodeTemplate = '[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]', shortCodeTemplateAttrs = '';
1180
1181 var shortCode = $('input#ws-plugin--s2member-sp-shortcode');
1182 var code = $('textarea#ws-plugin--s2member-sp-button');
1183
1184 var leading = $('select#ws-plugin--s2member-sp-leading-id').val().replace(/[^0-9]/g, '');
1185 var additionals = $('select#ws-plugin--s2member-sp-additional-ids').val() || [];
1186 var hours = $('select#ws-plugin--s2member-sp-hours').val().replace(/[^0-9]/g, '');
1187
1188 var regAmount = $('input#ws-plugin--s2member-sp-amount').val().replace(/[^0-9\.]/g, '');
1189 var desc = $.trim($('input#ws-plugin--s2member-sp-desc').val().replace(/"/g, ''));
1190
1191 var /* NOT yet configurable. */ localeCode = '', digital = '0', noShipping = '1';
1192 var pageStyle = $.trim($('input#ws-plugin--s2member-sp-page-style').val().replace(/"/g, ''));
1193 var currencyCode = $('select#ws-plugin--s2member-sp-currency').val().replace(/[^A-Z]/g, '');
1194
1195 if /* Must have a Leading Post/Page ID to work with. Otherwise, Link generation will fail. */(!leading)
1196 {
1197 alert('— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it\'s because you\'ve not configured s2Member for Specific Post/Page Access yet. See: s2Member → Restriction Options → Specific Post/Page Access.');
1198 return false;
1199 }
1200 else if(!regAmount || isNaN(regAmount) || regAmount < 0.01)
1201 {
1202 alert('— Oops, a slight problem: —\n\nAmount must be >= 0.01');
1203 return false;
1204 }
1205 else if /* $10,000.00 maximum. */(regAmount > 10000.00 && currencyCode.toUpperCase() === 'USD')
1206 {
1207 alert('— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00');
1208 return false;
1209 }
1210 else if /* Each Button should have a Description. */(!desc)
1211 {
1212 alert('— Oops, a slight problem: —\n\nPlease type a Description for this Button.');
1213 return false;
1214 }
1215 for(var i = 0, ids = leading; i < additionals.length; i++)
1216 if(additionals[i] && additionals[i] !== leading)
1217 ids += ','+additionals[i];
1218
1219 var /* Combined sp:ids:expiration hours. */ spIdsHours = 'sp:'+ids+':'+hours;
1220
1221 shortCodeTemplateAttrs += 'sp="1" ids="'+esc_attr(ids)+'" exp="'+esc_attr(hours)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';
1222 shortCodeTemplateAttrs += ' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'"';
1223 shortCode.val(shortCodeTemplate.replace(/%%attrs%%/, shortCodeTemplateAttrs));
1224
1225 code.html(code.val().replace(/ name\="lc" value\="(.*?)"/, ' name="lc" value="'+esc_attr(localeCode)+'"'));
1226 code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/, ' name="no_shipping" value="'+esc_attr(noShipping)+'"'));
1227 code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/, ' name="item_name" value="'+esc_attr(desc)+'"'));
1228 code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/, ' name="item_number" value="'+esc_attr(spIdsHours)+'"'));
1229 code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/, ' name="page_style" value="'+esc_attr(pageStyle)+'"'));
1230 code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/, ' name="currency_code" value="'+esc_attr(currencyCode)+'"'));
1231 code.html(code.val().replace(/ name\="custom" value\="(.*?)"/, ' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));
1232
1233 code.html(code.val().replace(/ name\="amount" value\="(.*?)"/, ' name="amount" value="'+esc_attr(regAmount)+'"'));
1234
1235 $('div#ws-plugin--s2member-sp-button-prev').html(code.val().replace(/\<form/, '<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr (c_ws_plugin__s2member_utils_ip::current())); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1236
1237 alert('Your Button has been generated.\nPlease copy/paste the Shortcode into your WordPress Editor.');
1238
1239 shortCode.each( /* Focus and select the Shortcode. */function()
1240 {
1241 this.focus(), this.select();
1242 });
1243 return false;
1244 };
1245 ws_plugin__s2member_paypalRegLinkGenerate = /* Handles PayPal Link Generation. */ function()
1246 {
1247 var level = $('select#ws-plugin--s2member-reg-link-level').val().replace(/[^0-9]/g, '');
1248 var subscrID = $.trim($('input#ws-plugin--s2member-reg-link-subscr-id').val());
1249 var custom = $.trim($('input#ws-plugin--s2member-reg-link-custom').val());
1250 var cCaps = $.trim($.trim($('input#ws-plugin--s2member-reg-link-ccaps').val()).replace(/[ \-]/g, '_').replace(/[^a-z_0-9,]/gi, '').toLowerCase());
1251 var fixedTerm = $.trim($('input#ws-plugin--s2member-reg-link-fixed-term').val().replace(/[^A-Z 0-9]/gi, '').toUpperCase());
1252 var $link = $('p#ws-plugin--s2member-reg-link'), $loading = $('img#ws-plugin--s2member-reg-link-loading');
1253
1254 var levelCcapsPer = (fixedTerm && !fixedTerm.match(/L$/)) ? level+':'+cCaps+':'+fixedTerm : level+':'+cCaps;
1255 levelCcapsPer = /* Clean any trailing separators from this string. */ levelCcapsPer.replace(/\:+$/g, '');
1256
1257 if /* We must have a Paid Subscr. ID value. */(!subscrID)
1258 {
1259 alert('— Oops, a slight problem: —\n\nPaid Subscr. ID is a required value.');
1260 return false;
1261 }
1262 else if(!custom || custom.indexOf('<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq ($_SERVER["HTTP_HOST"]); ?>') !== 0)
1263 {
1264 alert('— Oops, a slight problem: —\n\nThe Custom Value MUST start with your domain name.');
1265 return false;
1266 }
1267 else if /* Check format. */(fixedTerm && !fixedTerm.match(/^[1-9]+ (D|W|M|Y|L)$/))
1268 {
1269 alert('— Oops, a slight problem: —\n\nThe Fixed Term Length is not formatted properly.');
1270 return false;
1271 }
1272 $link.hide(), $loading.show(), $.post(ajaxurl, {action: 'ws_plugin__s2member_reg_access_link_via_ajax', ws_plugin__s2member_reg_access_link_via_ajax: '<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-reg-access-link-via-ajax")); ?>', s2member_reg_access_link_subscr_gateway: 'paypal', s2member_reg_access_link_subscr_id: subscrID, s2member_reg_access_link_custom: custom, s2member_reg_access_link_item_number: levelCcapsPer}, function(response)
1273 {
1274 $link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+'</a>'), $loading.hide();
1275 });
1276 return false;
1277 };
1278 ws_plugin__s2member_paypalSpLinkGenerate = /* Handles PayPal Link Generation. */ function()
1279 {
1280 var leading = $('select#ws-plugin--s2member-sp-link-leading-id').val().replace(/[^0-9]/g, '');
1281 var additionals = $('select#ws-plugin--s2member-sp-link-additional-ids').val() || [];
1282 var hours = $('select#ws-plugin--s2member-sp-link-hours').val().replace(/[^0-9]/g, '');
1283 var $link = $('p#ws-plugin--s2member-sp-link'), $loading = $('img#ws-plugin--s2member-sp-link-loading');
1284
1285 if /* Must have a Leading Post/Page ID to work with. Otherwise, Link generation will fail. */(!leading)
1286 {
1287 alert('— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it\'s because you\'ve not configured s2Member for Specific Post/Page Access yet. See: s2Member → Restriction Options → Specific Post/Page Access.');
1288 return false;
1289 }
1290 for(var i = 0, ids = leading; i < additionals.length; i++)
1291 if(additionals[i] && additionals[i] !== leading)
1292 ids += ','+additionals[i];
1293
1294 $link.hide(), $loading.show(), $.post(ajaxurl, {action: 'ws_plugin__s2member_sp_access_link_via_ajax', ws_plugin__s2member_sp_access_link_via_ajax: '<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-sp-access-link-via-ajax")); ?>', s2member_sp_access_link_ids: ids, s2member_sp_access_link_hours: hours}, function(response)
1295 {
1296 $link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+'</a>'), $loading.hide();
1297 });
1298 return false;
1299 };
1300 }
1301 if(location.href.match(/page\=ws-plugin--s2member-els-ops/))
1302 {
1303 $('select#ws-plugin--s2member-custom-reg-opt-in').change(function()
1304 {
1305 var $this = $(this), val = $this.val();
1306 var $rows = $('tr.ws-plugin--s2member-custom-reg-opt-in-label-row');
1307 var $prevImg = $('img.ws-plugin--s2member-custom-reg-opt-in-label-prev-img');
1308
1309 if /* Checkbox disabled. */(val <= 0)
1310 $rows.css('display', 'none'), $prevImg.attr('src', $prevImg.attr('src').replace(/\/checked\.png$/, '/unchecked.png'));
1311
1312 else if /* Enabled, checked by default. */(val == 1)
1313 $rows.css('display', ''), $prevImg.attr('src', $prevImg.attr('src').replace(/\/unchecked\.png$/, '/checked.png'));
1314
1315 else if /* Enabled, unchecked by default. */(val == 2)
1316 $rows.css('display', ''), $prevImg.attr('src', $prevImg.attr('src').replace(/\/checked\.png$/, '/unchecked.png'));
1317 });
1318 $('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs\[\]"]').change(function()
1319 {
1320 var /* Record value associated with change event. Also initialize checkedIndexes array. */ thisChange = $(this).val(), checkedIndexes = [];
1321
1322 $('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs\[\]"]').each(function()
1323 {
1324 var $this = $(this), val = $this.val(), checkboxes = 'input[type="checkbox"]';
1325
1326 if /* All sub-items get checked/disabled too. */(val === 'removal-deletion' && this.checked)
1327 $this.nextAll(checkboxes).slice(0, 2).attr({'checked': 'checked', 'disabled': 'disabled'});
1328
1329 else if(val === 'removal-deletion' && !this.checked)
1330 {
1331 $this.nextAll(checkboxes).slice(0, 2).removeAttr('disabled');
1332 (thisChange === 'removal-deletion') ? $this.nextAll(checkboxes).slice(0, 2).removeAttr('checked') : null;
1333 }
1334 else if /* All sub-items get checked/disabled too. */(val === 'modification' && this.checked)
1335 $this.nextAll(checkboxes).slice(0, 3).attr({'checked': 'checked', 'disabled': 'disabled'});
1336
1337 else if(val === 'modification' && !this.checked)
1338 {
1339 (thisChange === 'modification') ? $this.nextAll(checkboxes).slice(0, 3).removeAttr('checked') : null;
1340 $this.nextAll(checkboxes).slice(0, 3).removeAttr('disabled');
1341 }
1342 })
1343 .each( /* Now, which ones are checked? */function(index)
1344 {
1345 (this.checked) ? checkedIndexes.push(index) : null;
1346 });
1347 $('select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions').removeAttr('disabled');
1348 if($.inArray(3, checkedIndexes) === -1 && $.inArray(4, checkedIndexes) === -1 && $.inArray(5, checkedIndexes) === -1 && $.inArray(6, checkedIndexes) === -1)
1349 $('select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions').attr('disabled', 'disabled');
1350
1351 }).last().trigger('change');
1352 }
1353 });
1354