PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / 260927
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions v260927
260927 260917 260913 260909 260829 260814 260805 110710 110731 110812 110815 110912 110913 110915 110926 110927 111002 111003 111011 111017 111029 111105 111206 111216 111220 All 190 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 260927, at src/includes/menu-pages/menu-pages-s.js

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