1/** 2 * Javascript: RSVP Events Calendar 3 * @version 2.8.3 4 */ 5jQuery(document).ready(function($){ 6 7 8 var JDATA = {}; 9 var submit_open = false; 10 11 12 // load JSON DATA for event's rsvp into local object 13 function load_json_to_local(O){ 14 JDATA = O.closest('.evo_metarow_rsvp').find('.evors_jdata').data('j'); 15 } 16 17 // RSVP form function 18 $.fn.evors_form = function (opt){ 19 var form = this; 20 const form_holder = form.closest('.evors_forms'); 21 22 var formtype = form.find('input[name=formtype]').val(); 23 24 works = { 25 reset_notifications: function(elm){ 26 $('.evors_lightbox_body').removeClass('error'); 27 $( elm ).removeClass('err'); 28 $('.evors_lightbox_body').find('.notification').hide(); 29 }, 30 interaction: function(){ 31 // capacity check 32 form.on('change','input[name="count"]', function(){ 33 O = $(this); 34 35 // reset 36 works.reset_notifications( $(this) ); 37 38 CAP = JDATA.cap; 39 PERCAP = JDATA.precap; 40 form = O.closest('.evors_submission_form'); 41 42 VAL = parseInt(O.val()); 43 passedVAL = parseInt(O.data('passed')); 44 45 ERROR = false; 46 47 48 // change RSVP form 49 if( formtype == 'update'){ 50 // no space left but waitlist 51 if(CAP == 'wl' && VAL> passedVAL){ 52 $(this).addClass('err'); 53 works.show_msg('err9'); 54 ERROR = true; 55 } 56 57 changeVAL = VAL - passedVAL; 58 59 // increasing count 60 if(CAP != 'wl' && changeVAL>0 && changeVAL> parseInt(CAP) ){ 61 $(this).addClass('err'); 62 works.show_msg('err9'); 63 ERROR = true; 64 } 65 }else{ 66 // check avialable space vs party size 67 if(VAL > parseInt(CAP) && CAP!= 'na'){ 68 $(this).addClass('err'); 69 works.show_msg('err9'); 70 ERROR = true; 71 } 72 // check per each rsvp capacity vs party size 73 if(VAL > parseInt(PERCAP) && PERCAP!= 'na'){ 74 $(this).addClass('err'); 75 works.show_msg('err10'); 76 ERROR = true; 77 } 78 } 79 80 // if valid capacity add additional guests 81 if(!ERROR){ 82 83 guestNames = form.find('.form_guest_names'); 84 maskField = '<input class="regular input" name="names[]" type="text">'; 85 inputHolder = guestNames.find('.form_guest_names_list'); 86 87 if(VAL>1){ 88 89 ExistInputCount = inputHolder.find('input').length; 90 91 // add or remove input fields 92 if( (VAL-1) > ExistInputCount){ // add 93 fieldsNeed = VAL-1-ExistInputCount; 94 appender =''; 95 for(x=0; x<fieldsNeed; x++){ 96 appender += maskField; 97 } 98 inputHolder.append(appender); 99 }else{ 100 fieldsNeed = VAL-2; 101 inputHolder.find('input').each(function(index){ 102 if(index> fieldsNeed) $(this).remove(); 103 });
104 } 105 guestNames.show(); 106 }else{ 107 guestNames.hide(); 108 inputHolder.html( maskField); 109 } 110 } 111 }); 112 113 // change RSVP status within the form 114 form.on('click', 'span.evors_choices', function(){ 115 OBJ = $(this); 116 117 VAL = OBJ.attr('data-val'); 118 form.attr('class','evors_gen_form evors_submission_form rsvp_'+VAL); 119 OBJ.siblings().removeClass('set'); 120 OBJ.addClass('set'); 121 122 OBJ.siblings('input').val( VAL ); 123 }); 124 125 // close RSVP form from incard close button 126 form.on('click','.evors_incard_close',function(){ 127 $(this).closest('.evors_incard_form').hide(); 128 // reset any selected RSVP choices 129 $(this).closest('.evo_metarow_rsvp').find('.evors_choices').removeClass('set'); 130 }); 131 // checkbox field 132 form.on('click', '.evors_checkbox_field', function(){ 133 O = $(this); 134 if(O.hasClass('checked')){ 135 O.removeClass('checked'); O.siblings('input').val('no'); 136 }else{ 137 O.addClass('checked'); O.siblings('input').val('yes'); 138 } 139 }); 140 }, 141 142 // show form message 143 show_msg: function (code, type, message){ 144 145 if(message == '' || message === undefined){ 146 var C = form_holder.find('.evors_msg_').data('j'); 147 var classN = (type== undefined || type=='error' || type == '')? 'err':type; 148 message = C.codes[code] 149 } 150 form_holder.find('.notification').addClass(classN).show().find('p').html(message); 151 form_holder.parent().addClass('error'); 152 form.addClass('error'); 153 } 154 } 155 156 works.interaction(); 157 } 158 159 160 // open RSVP form from anywhere @since 2.8.3 161 $('body').on('click','.evors_trig_open_rsvp_form', function(event){ 162 event.preventDefault(); 163 event.stopPropagation(); 164 165 show_rsvp_form( $(this), $(this).attr('data-val'), 'submit'); 166 }); 167 $('body').on('click','.evoRS_status_option_selection span',function(){ 168 show_rsvp_form( $(this), $(this).attr('data-val'), 'submit'); 169 }); 170 171 // RSVP from eventtop 172 $('body').on('click', '.evors_rsvpiable span.evors_choices', function(event){ 173 event.preventDefault(); 174 event.stopPropagation(); 175 176 load_json_to_local( $(this) ); 177 178 179 var obj = $(this), 180 rsvp = obj.parent(), 181 ajaxdataa = {}; 182 183 ajaxdataa['rsvp']= obj.data('val'); 184 ajaxdataa['lang']= rsvp.data('lang'); 185 ajaxdataa['uid']= rsvp.data('uid'); 186 ajaxdataa['updates']= 'no'; 187 ajaxdataa['action']='the_ajax_evors_a7'; 188 ajaxdataa['repeat_interval']=rsvp.data('ri'); 189 ajaxdataa['e_id']= parseInt(rsvp.data('eid')); 190 191 192 var event_uid = 'event_'+ ajaxdataa.e_id +'_'+ ajaxdataa.repeat_interval; 193 194 $.ajax({ 195 beforeSend: function(){ rsvp.addClass('loading'); }, 196 type: 'POST', 197 url:evors_ajax_script.ajaxurl, 198 data: ajaxdataa, 199 dataType:'json', 200 success:function(data){ 201 if(data.status=='0'){ 202 $('body').trigger('evors_new_rsvp_eventtop'); 203 204 // update events eventwhere 205 $('body').find('.eventon_list_event.'+event_uid).each(function(){ 206 $(this).find('.evors_rsvpiable').html(data.message).addClass('success'); 207 $(this).find('.evors_eventtop_section_data').replaceWith(data.content); 208 209 // update event card 210 if( data.card_content !== undefined){ 211 $(this).find('.evors_eventcard_content').html( data.card_content); 212 } 213 }); 214 215 }else{ 216 rsvp.append('<span class="error">'+data.message+'</span>'); 217 } 218 },complete:function(){ 219 rsvp.removeClass('loading'); 220 } 221 }); 222 }); 223 224 // RSVP form submissions & update existing 225 $('body').on('click', '.evors_submit_rsvpform_btn', function(){ 226 227 var obj = O = $(this), 228 ajaxdataa = { }, 229 form = obj.closest('form.evors_submission_form'), 230 FORMPAR = form.parent(), 231 formSection = form.parent(), 232 error = 0, 233 formType = form.find('input[name="formtype"]').val(); 234 235 236 // reset form error messages 237 rsvp_hide_notifications(); 238 FORMPAR.parent().removeClass('error'); 239 240 // validation 241 // run through each rsvp field 242 form.find('.form_row.req').each(function(index){ 243
244 const row = $(this); 245 row.removeClass('err'); 246 247 iO = $(this).find('input'); 248 249 if( iO.length < 1) return; 250 251 $.each(iO, function(){ 252 ioo = $(this); 253 254 // required checkbox field 255 if( ioo.hasClass('checkbox') && ioo.val()=='no'){ 256 error = 1; 257 row.addClass('err'); 258 } 259 260 // check required fields filled 261 if( ioo.val()=='' && ioo.is(":visible")){ 262 error = 1; 263 row.addClass('err'); 264 } 265 266 if( $(this).val() == '' ) return true; 267 268 }); 269 270 271 }); 272 273 // validate email 274 if(error==0){ 275 var thisemail = form.find('input[name=email]'); 276 if(!is_email(thisemail.val().trim() )){ 277 thisemail.addClass('err'); 278 rsvp_error('err2','','', form); // invalid email address 279 error = 2; 280 } 281 } 282 // capacity check 283 if(error==0){ 284 if(formType=='update'){ 285 pastVal = parseInt(form.find('input[name=count]').attr('data-pastval')); 286 newVal = parseInt(form.find('input[name=count]').val()); 287 compareCount = (pastVal>newVal)? 0: newVal-pastVal; 288 }else{ 289 compareCount = parseInt(form.find('input[name=count]').val()); 290 } 291 292 if(form.find('.rsvp_status span.set').data('val')!='n' 293 && JDATA.cap 294 && JDATA.cap !='na' 295 && compareCount > parseInt(JDATA.cap) 296 ){ 297 error=4; 298 form.find('input[name=count]').addClass('err'); 299 rsvp_error('err9','','',form); 300 } 301 // max count limit 302 if( JDATA.precap!='na' && 303 (parseInt(form.find('input[name=count]').val()) > parseInt(JDATA.precap) ) 304 ){ 305 error=4; 306 form.find('input[name=count]').addClass('err'); 307 rsvp_error('err10','','',form); 308 } 309 } 310 // validate human 311 if(error==0){ 312 var human = rsvp_validate_human( form.find('input.captcha') ); 313 if(!human){ 314 error=3; 315 rsvp_error('err6','','',form); 316 } 317 } 318 319 // if form type is wl-remove 320 if(formType == 'wl-remove') error = 0; 321 322 // if no errors proceed 323 if(error==0){ 324 var updates = form.find('.updates input').attr('checked'); 325 updates = (updates=='checked')? 'yes':'no'; 326 327 ajaxdataa['action']='the_ajax_evors'; 328 form.ajaxSubmit({ 329 //$.ajax({ 330 beforeSend: function(){ form.parent().addClass('loading'); }, 331 type: 'POST',url:evors_ajax_script.ajaxurl,data: ajaxdataa,dataType:'json', 332 success:function(data){ 333 if(data.status=='0'){ 334 335 336 FORMPAR.parent().html(data.message); 337 EVENTCARD = $('body').find('.event_'+data.e_id+'_'+ data.ri ); 338 339 // if lightbox event 340 lb_eventcard = $('body').find('.evo_lightbox_body.event_'+ data.e_id+'_'+ data.ri); 341 342 // update event top data 343 if( 'data_content_eventtop' in data){ 344 // lightbox 345 if(lb_eventcard.find('.evors_eventtop_section_data').length>0){ 346 lb_eventcard.find('.evors_eventtop_section_data').replaceWith( data.data_content_eventtop ); 347 } 348 349 // calednar 350 if(EVENTCARD.find('.evors_eventtop_section_data').length>0){ 351 EVENTCARD.find('.evors_eventtop_section_data').replaceWith( data.data_content_eventtop ); 352 } 353 } 354 if('data_content_eventtop_your' in data){ 355 // lightbox 356 if(lb_eventcard.find('.evors_eventop_rsvped_data').length>0){ 357 lb_eventcard.find('.evors_eventop_rsvped_data').replaceWith( data.data_content_eventtop_your ); 358 } 359 // calendar 360 if(EVENTCARD.find('.evors_eventop_rsvped_data').length>0){ 361 EVENTCARD.find('.evors_eventop_rsvped_data').replaceWith( data.data_content_eventtop_your ); 362 } 363 } 364 365 // update Event Card 366 if(data.e_id){ 367 if(data.data_content_eventcard != ''){ 368 const incard_form_html = EVENTCARD.find('.evors_incard_form').html(); 369 370 EVENTCARD.find('.evors_eventcard_content').html( data.data_content_eventcard); 371 lb_eventcard.find('.evors_eventcard_content').html( data.data_content_eventcard); 372 373 // update incard rsvp form @since 2.8.4 374 if( EVENTCARD.find('.evors_incard_form').is(":visible") ){ 375 EVENTCARD.find('.evors_incard_form').html( incard_form_html ).show(); 376 } 377 378 } 379 } 380 // update event manager stuff 381 if( $('body').find('#rsvp_event_'+data.e_id).length>0 && data.new_rsvp_text){ 382 STATUS = $('#rsvp_event_'+data.e_id).find('span.rsvpstatus'); 383 STATUS.html( data.new_rsvp_text); 384 STATUS.attr('class','rsvpstatus status_'+data.new_rsvp_text); 385 } 386 387 // update virtual event information 388 if( $('body').find('.evo_vir_data').length>0){ 389 const vir_data_box = $('body').find('.evo_vir_data'); 390 391 if( vir_data_box.data('single') !== undefined 392 && vir_data_box.data('single') == 'y' && 393 vir_data_box.data('refresh') 394 ){ 395 extra_data = {}; 396 extra_data['refresh_main'] = 'yy'; 397 $('body').trigger('evo_refresh_designated_elm',[ vir_data_box,'evo_vir_data', extra_data]); 398 } 399 } 400 401 402 }else{
403 var passedRsvppd = (data.status)? 'err'+data.status:'err7'; 404 rsvp_error(passedRsvppd, '', data.message,form); 405 } 406 },complete:function(){ form.parent().removeClass('loading'); } 407 }); 408 }else if(error==1){ rsvp_error('err','','',form); } 409 }); 410 411 // CHANGE RSVP 412 // change a RSVP 413 $("body").on('click','.evors_change_rsvp_trig',function(){ 414 OBJ = $(this); 415 PAR = OBJ.parent(); 416 show_rsvp_form(OBJ, '','update'); 417 }); 418 419 // from successful rsvped page 420 $('body').on('click','#call_change_rsvp_form',function(){ 421 OBJ = $(this); 422 PAR = OBJ.parent(); 423 show_rsvp_form(OBJ, '','update'); 424 }); 425 // From rsvp manager 426 $('.eventon_rsvp_rsvplist').on('click','.update_rsvp',function(){ 427 OBJ = $(this); 428 PAR = OBJ.parent(); 429 430 // load Json data 431 JDATA = OBJ.parent().siblings('.evors_jdata').data('j'); 432 433 show_rsvp_form(OBJ, '','update'); 434 }); 435 436 // Show RSVP lightbox form 437 function show_rsvp_form(OBJ, RSVP,formtype, extra_data){ 438 var ajaxdataa = {}; 439 ajaxdataa['action']='evors_get_rsvp_form'; 440 441 ROW = OBJ.closest('.evo_metarow_rsvp'); 442 if(OBJ.closest('.evo_metarow_rsvp').length) load_json_to_local( OBJ); 443 444 if(JDATA){ 445 $.each(JDATA, function(index, val){ 446 ajaxdataa[index] = val; 447 }); 448 } 449 450 if( extra_data && extra_data !== undefined){ 451 $.each(extra_data, function(ind, vall){ 452 ajaxdataa[ ind ] = vall; 453 }); 454 } 455 456 ajaxdataa['rsvp'] = RSVP; 457 ajaxdataa['formtype'] = formtype; 458 FORMNEST = OBJ.closest('.evors_forms').parent(); 459 460 $.ajax({ 461 beforeSend: function(){ loading(OBJ); }, 462 url: evors_ajax_script.ajaxurl,data: ajaxdataa, dataType:'json', type: 'POST', 463 success:function(data){ 464 if(data.status=='good'){ 465 // show form inside eventcard 466 if( ajaxdataa.incard =='yes'){ 467 ROW.find('.evors_incard_form') 468 .removeClass('error') 469 .html( data.content ) 470 .slideDown('fast'); 471 }else{ 472 $('.evors_lightbox') 473 .find('.evo_lightbox_body') 474 .removeClass('error') 475 .html( data.content ); 476 $('.evors_lightbox.evo_lightbox').addClass('show'); 477 $('body').trigger('evolightbox_show'); 478 } 479 480 $('body').find('form.evors_gen_form').evors_form(); 481 482 }else{ 483 // error notice *** 484 } 485 },complete:function(){ 486 completeloading(OBJ); 487 FORMNEST.closest('.evorow').removeClass('loading'); 488 } 489 }); 490 } 491 492 // during ajax eventcard loading 493 function loading(obj){ 494 obj.closest('.evorow').addClass('loading'); 495 obj.closest('.trig_evo_loading').addClass('evoloading'); 496 obj.closest('p.rsvpmanager_event').addClass('loading'); 497 } 498 function completeloading(obj){ 499 obj.closest('.evorow').removeClass('loading'); 500 obj.closest('.trig_evo_loading').removeClass('evoloading'); 501 obj.closest('p.rsvpmanager_event').removeClass('loading'); 502 } 503 504 // Find RSVP 505 $('body').on('click','.evors_findrsvp_form_btn', function(){ 506 var obj = $(this); 507 var form = obj.closest('form.evors_findrsvp_form'); 508 var error = 0; 509 510 // get form data 511 var formdata = form.serializeArray().reduce(function(obj, item) { 512 obj[item.name] = item.value; 513 return obj; 514 }, {}); 515 516 f_holder = obj.closest('.evors_forms'); 517 518 // run through each rsvp field 519 form.find('.input').each(function(index){ 520 // check required fields filled 521 if( $(this).hasClass('req') && $(this).val()=='' ){ 522 error = 1; 523 } 524 }); 525 if(error=='1'){ 526 rsvp_error('err','','',form); 527 }else{ 528 var ajaxdataa = {}; 529 ajaxdataa['action']='evors_find_rsvp_form'; 530 form.ajaxSubmit({ 531 beforeSend: function(){ f_holder.addClass('loading'); }, 532 url: evors_ajax_script.ajaxurl, 533 data: ajaxdataa, dataType:'json', type: 'POST', 534 success:function(data){ 535 if(data.status=='good'){ 536 537 if( formdata.incard == 'yes'){ 538 539 }else{ 540 541 } 542 543 f_holder.parent().removeClass('error').addClass('t'); 544 f_holder.parent().html( data.content ); 545 546 $('body').find('form.evors_gen_form').evors_form(); 547 548 }else{ 549 rsvp_error('err5','','',form); 550 } 551 },complete:function(){ f_holder.removeClass('loading'); } 552 });
553 } 554 }); 555 556 // hover over guests list icons 557 $('body').on('mouseover','.evors_whos_coming span.initials', function(){ 558 OBJ = $(this); 559 EM = OBJ.parent().find('em.tooltip'); 560 TEXT = OBJ.data('name'); 561 562 POS = OBJ.position(); 563 564 EM.css({'left':(POS.left+20), 'top':(POS.top-30)}).html(TEXT).show(); 565 566 }); 567 $('body').on('mouseout','.evors_whos_coming span', function(){ 568 OBJ = $(this); 569 EM = OBJ.parent().find('em.tooltip'); 570 EM.hide(); 571 }); 572 573 // Buddypress profile linking 574 $('body').on('click','.evors_whos_coming span',function(){ 575 LINK = $(this).data('link'); 576 577 if(LINK != 'na') 578 window.open(LINK, '_blank'); 579 }); 580 581 582 583// ADDONS 584 // action user event manager 585 // show rsvp stats for events 586 $('#evoau_event_manager').on('click','a.load_rsvp_stats',function(event){ 587 event.preventDefault(); 588 O = $(this); 589 590 var data_arg = { 591 eid: O.data('eid'), 592 ri: O.data('ri'), 593 data: O.closest('.evoau_manager').find('.evoau_manager_json').data('js') 594 }; 595 596 load_rsvp_stats( O , data_arg); 597 }); 598 // refresh rsvp data 599 $(document).on('click','.evorsau_refresh_data',function(){ 600 O = $(this); 601 var data_arg = { 602 eid: O.closest('.evoau_manager_continer').data('eid'), 603 ri: O.closest('.evoau_manager_continer').data('ri'), 604 data: O.closest('.evoau_manager').find('.evoau_manager_json').data('js') 605 }; 606 607 load_rsvp_stats( O , data_arg, true); 608 }); 609 610 function load_rsvp_stats(O, data_arg, refresh){ 611 data_arg['action'] = 'evors_ajax_get_auem_stats'; 612 MANAGER = O.closest('.evoau_manager'); 613 $.ajax({
614 beforeSend: function(){ 615 MANAGER.find('.trig_evo_loading').addClass('evoloading'); 616 MANAGER.find('.eventon_actionuser_eventslist').addClass('evoloading'); 617 }, 618 type: 'POST', 619 url:evors_ajax_script.ajaxurl, 620 data: data_arg, 621 dataType:'json', 622 success:function(data){ 623 if( refresh){ 624 MANAGER.find('.evoau_manager_event_content').html( data.html ); 625 }else{ 626 $('body').trigger('evoau_show_eventdata',[MANAGER, data.html, true]); 627 } 628 629 },complete:function(){ 630 MANAGER.find('.eventon_actionuser_eventslist').removeClass('evoloading'); 631 MANAGER.find('.trig_evo_loading').removeClass('evoloading'); 632 } 633 }); 634 } 635 636 // find an attendee 637 $(document).on('click','.evorsau_trig_find_attendee',function(){ 638 $(this).parent().siblings('.evorsau_find_rsvp').toggle(); 639 }); 640 $(document).on('change paste keyup','input.evorsau_find_attendee',function(){ 641 var O = $(this); 642 var val = O.val(); 643 const section = O.closest('.evorsau_attendee_list'); 644 645 section.find('li').each(function(){ 646 var show = false; 647 // if rsvp id typed and it matches 648 if( val == $(this).data('rsvpid')) show = true; 649 if( val == $(this).data('e')) show = true; 650 if( $(this).data('e').includes( val)) show = true; 651 if( val == '') show = true; 652 653 (show) ? $(this).show(): $(this).hide(); 654 }); 655 }); 656 657 // register attendee on the spot 658 $('body').on('click','.evorsau_trig_rsvp_form',function(){ 659 OBJ = $(this); 660 // load Json data 661 JDATA = OBJ.siblings('.evors_jdata').data('j'); 662 663 var extra_data = {}; 664 extra_data['loginuser'] = 'no'; 665 show_rsvp_form(OBJ, '','submit', extra_data); 666 }); 667 668 // checkin guests 669 $('.evoau_manager_event').on('click','span.checkin',function(){ 670 var obj = $(this); 671 var PAR = obj.closest('.evorsau_attendee_list'); 672 673 if(!PAR.hasClass('checkable')) return false; 674 675 var status = obj.attr('data-status'); 676 677 status = (status=='' || status=='check-in')? 'checked':'check-in'; 678 679 var data_arg = { 680 action: 'the_ajax_evors_f4', 681 rsvp_id: obj.attr('data-id'), 682 status: status, 683 nonce: PAR.find('input#evors_nonce').val() 684 }; 685 $.ajax({
686 beforeSend: function(){ 687 obj.html( obj.html()+'...'); 688 }, 689 type: 'POST', 690 url:evors_ajax_script.ajaxurl, 691 data: data_arg, 692 dataType:'json', 693 success:function(data){ 694 //alert(data); 695 obj.attr({'data-status':status}).html(data.new_status_lang) 696 .removeAttr('class') 697 .addClass(status+' checkin'); 698 } 699 }); 700 }); 701 // waitlist 702 // Remove from waitlist 703 $('body').on('click','.evorsw_remove_wl',function(){ 704 705 FORM = $(this).closest('form'); 706 707 // update form values to remove from waitlist 708 FORM.find('input[name="formtype"]').val('wl-remove'); 709 710 // submit form 711 FORM.find('.evors_submit_rsvpform_btn').trigger('click'); 712 713 }); 714 715// Supporting functions 716 // show error messages 717 function rsvp_error(code, type, message, O){ 718 FORM = O.closest('.evors_forms'); 719 F = FORM.find('form'); 720 721 if(message == '' || message === undefined){ 722 var C = FORM.find('.evors_msg_').data('j'); 723 var classN = (type== undefined || type=='error' || type == '')? 'err':type; 724 message = C.codes[code] 725 } 726 FORM.find('.notification').addClass(classN).show().find('p').html(message); 727 FORM.parent().addClass('error'); 728 F.addClass('error'); 729 } 730 731 // hide form messages 732 function rsvp_hide_notifications(){ 733 $('.evors_lightbox_body').find('.notification').hide(); 734 } 735 // validate humans 736 function rsvp_validate_human(field){ 737 if(field==undefined){ 738 return true; 739 }else{ 740 var numbers = ['11', '3', '6', '3', '8']; 741 if(numbers[field.attr('data-cal')] == field.val() ){ 742 return true; 743 }else{ return false;} 744 } 745 } 746 747 function is_email(email){ 748 var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; 749 return regex.test(email); 750 } 751});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.