1new Vue({ 2 3 name: 'pfy-register', 4 5 el: '#pfy-register', 6 7 data: { 8 9 // SSO 10 loggedIn: Portal.getData('pfySSOLoggedIn'), 11 12 // Reference 13 pfyServerURL: Portal.getData('pfyServerURL'), 14 loginURL: pfyRegisterData.loginURL, 15 forgotPasswordURL: pfyRegisterData.forgotPasswordURL, 16 accountURL: pfyRegisterData.accountURL, 17 returnURL: pfyRegisterData.returnURL, 18 vendorID: pfyRegisterData.vendorID, 19 siteContext: pfyRegisterData.siteContext, 20 studentRelationshipEntity: pfyRegisterData.studentRelationshipEntity, 21 studentJobFunctionCode: pfyRegisterData.studentJobFunctionCode, 22 studentJoinLink: pfyRegisterData.studentJoinLink, 23 programNoun: pfyRegisterData.programNoun, 24 jobFunctions: [], 25 relationshipTypes: [], 26 addressTypes: [], 27 countries: [], 28 states: [], 29 graduationYears: [], 30 genders: [], 31 ethnicities: [], 32 33 // Role 34 primaryRole: null, 35 studentInducted: null, 36 37 // Email 38 emailForm: { 39 email: '', 40 emailConfirm: '', 41 }, 42 43 emailSelected: false, 44 emailAlertExists: false, 45 46 // Password 47 passwordForm: { 48 // password: pfyRegisterData.defaultPassword, 49 password: '', 50 }, 51 52 // Personal information 53 personalForm: { 54 firstName: '', 55 lastName: '', 56 phone: '', 57 birthDate: '', 58 gender: null, 59 ethnicity: null, 60 }, 61 62 // School 63 schoolForm: { 64 relationshipType: null, 65 jobFunction: null, 66 graduationYear: null, 67 }, 68 69 // Address Search 70 addressSearchForm: { 71 method: 'search', 72 name: '', 73 city: '', 74 state: null, 75 country: 'USA', 76 schoolID: null, 77 }, 78 79 addressSearchResults: {}, 80 addressSearchSelected: null, 81 82 // Address Manual Entry 83 addressManualForm: { 84 type: null, 85 line1: '', 86 line2: '', 87 line3: '', 88 city: '', 89 state: null, 90 country: 'USA', 91 zip: '', 92 startDate: '', 93 endDate: '', 94 doNotValidate: false, 95 }, 96 97 addressAlertUnvalidated: false, 98 addressAlertUndeliverable: false, 99 100 consentForm: { 101 consent: false, 102 }, 103 104 // API responses 105 password: '', 106 107 // UI 108 step: 1 109 110 }, 111 112 computed: { 113 114 primaryRoleIsValid() { 115 return Boolean( 116 this.primaryRole === 'employee' 117 || 118 this.primaryRole === 'student' && this.studentInducted === 'yes' 119 || 120 this.primaryRole === 'other' 121 ); 122 }, 123 124 isStudentProgram() { 125 return Boolean( this.siteContext !== 'nassp' ); 126 }, 127 128 isStudent() { 129 return Boolean( this.primaryRole && this.primaryRole === 'student' ); 130 }, 131 132 isEmployee() { 133 return Boolean( this.primaryRole && this.primaryRole === 'employee' ); 134 }, 135 136 isOther() { 137 return Boolean( this.primaryRole && this.primaryRole === 'other' ); 138 }, 139 140 birthDateRequiresCOPPA() { 141 142 if ( !this.personalForm.birthDate.length ) return false; 143 144 var dateNow = new Date(); 145 dateNow.setHours( 0, 0, 0, 0 ); 146 147 var dateBirth = new Date( this.personalForm.birthDate ); 148 dateBirth.setHours( 0, 0, 0, 0 ); 149 150 var diff = dateNow - dateBirth; 151 var age = Math.floor( diff / 3.154e+10 ); 152 153 return ( age < 2 ); 154 155 }, 156 157 phoneDigits() { 158 159 if ( this.$v.personalForm.phone.$anyError ) return false; 160 161 return this.personalForm.phone.replace( /\D/g, ''); 162 163 }, 164 165 phoneAreaCode() { 166 167 if ( !this.phoneDigits ) return ''; 168 169 return this.phoneDigits.substr(0,3); 170 171 }, 172 173 phoneBody() { 174 175 if ( !this.phoneDigits ) return ''; 176 177 return this.phoneDigits.substr(3,7); 178 179 }, 180 181 phoneExtension() { 182 183 if ( !this.phoneDigits ) return ''; 184 185 return this.phoneDigits.substr(10); 186 187 }, 188 189 phonePreview() { 190 191 if ( !this.phoneDigits ) return ''; 192 193 let areaCode = this.phoneAreaCode, 194 body1 = this.phoneDigits.substr(3,3), 195 body2 = this.phoneDigits.substr(6,4), 196 extension = this.phoneExtension; 197 198 var phonePreview = '(' + areaCode + ') ' + body1 + '-' + body2; 199 200 if ( extension.length ) phonePreview += ' x' + extension; 201 202 return phonePreview; 203 204 }, 205 206 addressSearchResultsList() { 207 208 var addressSearchResultsList = []; 209 210 var addressIDs = Object.keys( this.addressSearchResults ); 211 212 for (let i = 0; i < addressIDs.length; i++) { 213 var id = addressIDs[i]; 214 var address = this.addressSearchResults[ id ]; 215 addressSearchResultsList.push( address ); 216 } 217 218 addressSearchResultsList = addressSearchResultsList.sort( (a,b) => { 219 return String( this.getAddressName(a) ).localeCompare( String( this.getAddressName(b) ) ); 220 }); 221 222 return addressSearchResultsList; 223 224 }, 225 226 addressSearchHasResults() { 227 228 return ( this.addressSearchResultsList.length > 0 ); 229 230 }, 231 232 derivedAddressType() { 233 234 switch ( this.primaryRole ) { 235 case 'student': 236 case 'employee': 237 return 'SCHOOL';
238 case 'other': 239 default: 240 return this.addressManualForm.type; 241 } 242 243 }, 244 245 employeeJobFunctionCodes() { 246 247 const whitelist = [ 248 'AA', 249 'ASSTHEADMAST', 250 'ASSTHEADMIST', 251 'ASSTPR', 252 'ASSTSUPER', 253 'ASSOCPRIN', 254 'ADMIN', 255 'COUNSELOR', 256 'CURRCOOR', 257 'DEAN', 258 'DEPTHEAD', 259 'DEPSUPER', 260 'DIRECTOR', 261 'DISTST', 262 'EDUC', 263 'HEADSCHOOL', 264 'HEADMASTER', 265 'HEADMISTRESS', 266 'PRESIDENT', 267 'PRIN', 268 'PROFESSOR', 269 'SUPER', 270 'SUPERVISOR', 271 'TEACHER', 272 'VICEPRIN', 273 ]; 274 275 let employeeJobFunctionCodes = structuredClone( this.jobFunctions ).filter( type => { 276 return whitelist.indexOf( type.Code ) !== -1; 277 }); 278 279 return employeeJobFunctionCodes; 280 281 }, 282 283 otherJobFunctionCodes() { 284 285 const employeeJobFunctionCodesList = this.employeeJobFunctionCodes.map( type => type.Code ); 286 287 let otherJobFunctionCodes = structuredClone( this.jobFunctions ).filter( type => { 288 289 return ( 290 employeeJobFunctionCodesList.indexOf( type.Code ) === -1 291 && 292 type.Code !== 'STUDENT' 293 ); 294 295 }); 296 297 return otherJobFunctionCodes; 298 299 }, 300 301 availableJobFunctionCodes() { 302 switch ( this.primaryRole ) { 303 case 'employee': 304 return this.employeeJobFunctionCodes; 305 case 'other': 306 return this.otherJobFunctionCodes; 307 default: 308 return []; 309 } 310 }, 311 312 derivedRelationshipType() { 313 if ( this.isStudent ) { 314 return this.studentRelationshipEntity; // FULL ENTITY 315 } else { 316 return this.schoolForm.relationshipType; 317 } 318 }, 319 320 derivedJobFunctionCode() { 321 if ( this.isStudent ) { 322 return this.studentJobFunctionCode; 323 } else { 324 return this.schoolForm.jobFunction; 325 } 326 }, 327 328 }, 329 330 /*html*/ 331 template: `<section id="pfy-register" class="pfy-register multi-step-form"> 332 333 <div class="progressBar"> 334 <div class="stepItemContainer"> 335 <div class="stepCircleContainer"> 336 <div class="stepCircle" :class="[{ active: step >= 1 }, { done: step >= 2 }]" data-id="account-info"> 337 <svg width="19" height="15" viewBox="0 0 19 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 338 <path d="M6.14645 13.5202L6.5 13.8738L6.85355 13.5202L17.4369 2.93691L17.7904 2.58335L17.4369 2.2298L16.2702 1.06313L15.9167 0.70958L15.5631 1.06313L6.5 10.1262L3.27022 6.89647L2.91667 6.54291L2.56311 6.89647L1.39645 8.06313L1.04289 8.41669L1.39645 8.77024L6.14645 13.5202Z" fill="white" stroke="white"/> 339 </svg> 340 </div> 341 <div class="stepLabel account" :class="{ active: step === 1 }" >Account info</div> 342 </div> 343 </div> 344 <div class="stepItemContainer"> 345 <div class="stepLine" :class="{ active: step >= 2 }" data-id="your-info"></div> 346 <div class="stepCircleContainer"> 347 <div class="stepCircle" :class="[{ active: step >= 2 }, { done: step >= 3 }]" data-id="your-info"> 348 <svg width="19" height="15" viewBox="0 0 19 15" fill="none" xmlns="http://www.w3.org/2000/svg"> 349 <path d="M6.14645 13.5202L6.5 13.8738L6.85355 13.5202L17.4369 2.93691L17.7904 2.58335L17.4369 2.2298L16.2702 1.06313L15.9167 0.70958L15.5631 1.06313L6.5 10.1262L3.27022 6.89647L2.91667 6.54291L2.56311 6.89647L1.39645 8.06313L1.04289 8.41669L1.39645 8.77024L6.14645 13.5202Z" fill="white" stroke="white"/> 350 </svg> 351 </div> 352 <div class="stepLabel" :class="{ active: step === 2 }">Your Info</div> 353 </div> 354 </div> 355 <div class="stepItemContainer"> 356 <div class="stepLine" :class="{ active: step >= 3 }" data-id="school-info"></div> 357 <div class="stepCircleContainer"> 358 <div class="stepCircle" :class="{ active: step >= 3 }" data-id="school-info"></div> 359 <div class="stepLabel school" :class="{ active: step === 3 }">School Info</div> 360 </div> 361 </div> 362 </div> 363 364 <div class="stepContainer" v-show="step === 1"> 365 366 <h1>Create an Account</h1> 367 368 <p>Follow the instructions below to create a username and password.</p> 369 370 <p><small>Already a member looking to renew your membership? <a :href="loginURL">Click here.</a></small></p> 371 372 <h2 class="mt-5">Role</h2> 373 374 <b-row id="pfy-register-primary-role"> 375 376 <b-col md="6"> 377 378 <b-button 379 class="mt-1" 380 block 381 :variant="primaryRole === 'student' ? 'primary' : 'outline-primary'" 382 v-if="isStudentProgram" 383 @click.prevent="setPrimaryRole('student')"> 384 Current Student 385 </b-button> 386 387 <b-button 388 class="mt-1" 389 block 390 :variant="primaryRole === 'employee' ? 'primary' : 'outline-primary'" 391 @click.prevent="setPrimaryRole('employee')"> 392 Current School Leader 393 </b-button> 394 395 <b-button 396 class="mt-1" 397 block 398 :variant="primaryRole === 'other' ? 'primary' : 'outline-primary'" 399 @click.prevent="setPrimaryRole('other')"> 400 Other 401 </b-button> 402 403 </b-col> 404 405 </b-row> 406 407 <p 408 class="small text-danger" 409 v-if="$v.primaryRole.$dirty && $v.primaryRole.$anyError"> 410 Please choose your primary role. 411 </p> 412 413 <b-form-group 414 v-if="primaryRole === 'student'" 415 :label="'Are you a current member of your ' + programNoun + '?'" 416 label-for="pfy-register-student-inducted" 417 :state="validateField('studentInducted')" 418 class="mt-5"> 419 420 <!-- RADIO_BUTTON --> 421 <b-form-radio-group 422 id="pfy-register-student-inducted" 423 v-model="$v.studentInducted.$model" 424 :state="validateField('studentInducted')" 425 size="sm"> 426 427 <b-form-radio 428 value="yes"> 429 Yes 430 </b-form-radio> 431 432 <b-form-radio 433 value="no"> 434 No 435 </b-form-radio> 436 437 </b-form-radio-group> 438 439 </b-form-group> 440 441 <b-modal 442 ref="modalStudentNotInducted" 443 id="pfy-register-student-not-inducted"> 444 445 <p>You must be a current member of your {{ programNoun }} to continue.</p> 446 447 <template v-slot:modal-footer> 448 <b-button 449 variant="primary" 450 :href="studentJoinLink.url"> 451 {{ studentJoinLink.title }} 452 </b-button> 453 </template> 454 455 </b-modal> 456 457 <b-form 458 id="pfy-register-email-form" 459 :class="getFormClass( 'pfy-register-email-form', primaryRoleIsValid )" 460 @submit.stop.prevent="submitEmail"> 461 462 <h2 class="mt-5">Email</h2> 463 464 <b-row> 465 466 <b-col md="6"> 467 468 <b-form-group 469 label="Email Address" 470 label-for="pfy-register-email"> 471 472 <b-form-input 473 id="pfy-register-email" 474 v-model="$v.emailForm.email.$model" 475 type="email" 476 :state="validateFormField('emailForm', 'email')" 477 :disabled="emailSelected"> 478 </b-form-input> 479 480 <b-form-invalid-feedback>Please enter a valid email address.</b-form-invalid-feedback> 481 482 <b-form-text v-if="!emailSelected"> 483 Use a non-school email address.<br> 484 </b-form-text> 485 486 </b-form-group> 487 488 </b-col> 489 490 <b-col md="6"> 491 492 <b-form-group 493 label="Confirm Email Address" 494 label-for="pfy-register-email-confirm"> 495 496 <b-form-input 497 id="pfy-register-email-confirm" 498 v-model="$v.emailForm.emailConfirm.$model" 499 type="email" 500 :state="validateFormField('emailForm', 'emailConfirm')" 501 :disabled="emailSelected"> 502 </b-form-input> 503 504 <b-form-invalid-feedback>The email addresses must match.</b-form-invalid-feedback> 505 506 </b-form-group> 507 508 </b-col> 509 510 </b-row> 511 512 <b-alert v-model="emailAlertExists" variant="danger" class="mt-3"> 513 An account already exists with this email address. Would you like to <a :href="loginURL">log in</a> or <a :href="forgotPasswordURL">reset your password</a>? 514 </b-alert> 515 516 </b-form> 517 518 <b-form 519 id="pfy-register-password-form" 520 :class="getFormClass( 'pfy-register-password-form', primaryRoleIsValid )"> 521 522 <b-row> 523 524 <b-col md="6"> 525 526 <b-form-group 527 label="Password" 528 label-for="pfy-register-password" 529 class="mt-3"> 530 531 <b-form-input 532 id="pfy-register-password" 533 v-model="$v.passwordForm.password.$model" 534 type="password" 535 :state="validateFormField('passwordForm', 'password')"> 536 </b-form-input> 537 538 <b-form-invalid-feedback>Your password must be at least 6 characters long.</b-form-invalid-feedback> 539 540 <b-form-text v-if="!emailSelected"> 541 Make sure to save your account password in a secure location.<br> 542 </b-form-text> 543 544 </b-form-group> 545 546 </b-col> 547 548 </b-row> 549 550 <div :class="getFormClass( 'progress-footer', primaryRoleIsValid )"> 551 <div class="button-container"> 552 <button id="next-step" type="submit" class="btn mt-1 btn-primary" @click.prevent="submitEmail"> 553 Next 554 </button> 555 </div>
556 </div> 557 558 </b-form> 559 560 </div> 561 562 <div class="stepContainer" v-show="step === 2"> 563 564 <b-form 565 id="pfy-register-personal-form" 566 class="pfy-register-personal-form"> 567 568 <h2 class="mt-5">Tell us about yourself</h2> 569 570 <b-row> 571 572 <b-col md="6"> 573 574 <!-- FIRST NAME --> 575 <b-form-group 576 label="First Name" 577 label-for="pfy-register-first-name"> 578 579 <b-form-input 580 id="pfy-register-first-name" 581 v-model="$v.personalForm.firstName.$model" 582 :state="validateFormField('personalForm', 'firstName')"> 583 </b-form-input> 584 585 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 586 587 </b-form-group> 588 589 </b-col> 590 591 <b-col md="6"> 592 593 <!-- LAST NAME --> 594 <b-form-group 595 label="Last Name" 596 label-for="pfy-register-last-name"> 597 598 <b-form-input 599 id="pfy-register-last-name" 600 v-model="$v.personalForm.lastName.$model" 601 :state="validateFormField('personalForm', 'lastName')"> 602 </b-form-input> 603 604 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 605 606 </b-form-group> 607 608 </b-col> 609 610 <b-col md="6"> 611 612 <!-- BIRTH DATE --> 613 <b-form-group 614 label="Date of Birth" 615 label-for="pfy-register-birthdate"> 616 617 <b-form-input 618 id="pfy-register-birthdate" 619 v-model="$v.personalForm.birthDate.$model" 620 type="date" 621 :state="validateFormField('personalForm', 'birthDate')"> 622 </b-form-input> 623 624 <b-form-invalid-feedback>Please enter your date of birth.</b-form-invalid-feedback> 625 626 </b-form-group> 627 628 <transition name="fade"> 629 <b-alert :show="birthDateRequiresCOPPA" variant="danger" class="mt-3"> 630 631 <p>Please ensure that your date of birth is correct.</p> 632 633 <!-- 634 <b-button 635 class="mb-2" 636 variant="primary" 637 href="/create-an-account/coppa-parental-consent-form/" 638 target="_blank"> 639 <i class="fas fa-file-pdf"></i> COPPA Parental Consent Form 640 </b-button> 641 642 <b-button 643 class="mb-2" 644 variant="outline-secondary" 645 href="/create-an-account/faq/" 646 target="_blank"> 647 Learn more <i class="fas fa-angle-right"></i> 648 </b-button> 649 --> 650 651 </b-alert> 652 </transition> 653 654 </b-col> 655 656 <b-col md="6"> 657 658 <!-- PHONE NUMBER --> 659 <b-form-group 660 label="Phone" 661 label-for="pfy-register-phone" 662 :class="getFormClass( 'pfy-register-phone', primaryRoleIsValid && !birthDateRequiresCOPPA )"> 663 664 <b-form-input 665 id="pfy-register-phone" 666 type="tel" 667 v-model="$v.personalForm.phone.$model" 668 :state="validateFormField('personalForm', 'phone')"> 669 </b-form-input> 670 671 <b-form-invalid-feedback>Please enter at least 10 digits.</b-form-invalid-feedback> 672 673 <b-form-valid-feedback>{{ phonePreview }}</b-form-valid-feedback> 674 675 </b-form-group> 676 677 </b-col> 678 679 <b-col md="6"> 680 681 <!-- GENDER --> 682 <b-form-group 683 label="Gender" 684 label-for="pfy-demographics-gender"> 685 686 <b-form-select 687 id="pfy-demographics-gender" 688 v-model="$v.personalForm.gender.$model" 689 :state="validateFormField('personalForm', 'gender')"> 690 691 <b-form-select-option 692 v-for="gender in genders" 693 :key="gender.Code" 694 :value="gender.Code"> 695 {{ gender.Description }} 696 </b-form-select-option> 697 698 </b-form-select> 699 700 <b-form-invalid-feedback>Please select an option.</b-form-invalid-feedback> 701 702 </b-form-group> 703 704 </b-col> 705 706 <b-col md="6"> 707 708 <!-- ETHNICITY --> 709 <b-form-group 710 label="Ethnicity" 711 label-for="pfy-register-ethnicity"> 712 713 <b-form-select 714 id="pfy-register-ethnicity" 715 v-model="$v.personalForm.ethnicity.$model" 716 :state="validateFormField('personalForm', 'ethnicity')"> 717 718 <b-form-select-option 719 v-for="ethnicity in ethnicities" 720 :key="ethnicity.Code" 721 :value="ethnicity.Code"> 722 {{ ethnicity.Description }} 723 </b-form-select-option> 724 725 </b-form-select> 726 727 <b-form-invalid-feedback>Please select an option.</b-form-invalid-feedback> 728 729 </b-form-group> 730 731 </b-col> 732 733 </b-row> 734 735 <div class="progress-footer"> 736 737 <div class="button-container"> 738 <button id="next-step" type="submit" class="btn mt-1 btn-outline-primary" @click.prevent="unsubmitEmail"> 739 Back 740 </button> 741 </div> 742 <div class="button-container"> 743 <button id="next-step" type="submit" class="btn mt-1 btn-primary" @click.prevent="submitPersonal"> 744 Next 745 </button> 746 </div>
747 </div> 748 749 </b-form> 750 751 </div> 752 753 <div class="stepContainer" v-show="step === 3"> 754 755 <b-form 756 id="pfy-register-school-role-form" 757 :class="getFormClass( 'pfy-register-school-role-form', primaryRoleIsValid && !birthDateRequiresCOPPA && !emailAlertExists )"> 758 759 <h2 class="mt-5">School</h2> 760 761 <b-row> 762 763 <b-col md="6" v-if="isEmployee"> 764 765 <!-- SCHOOL ROLE --> 766 <transition name="fade"> 767 <b-form-group 768 :label="'What is your role ' + ( isStudentProgram ? 'in the ' + programNoun : 'at your school' ) + '?'" 769 label-for="pfy-register-school-role"> 770 771 <b-form-select 772 id="pfy-register-school-role" 773 v-model="$v.schoolForm.relationshipType.$model" 774 :state="validateFormField( 'schoolForm', 'relationshipType' )"> 775 776 <b-form-select-option 777 v-for="relationshipType in relationshipTypes" 778 :key="relationshipType.RelationshipCode" 779 :value="relationshipType"> 780 {{ relationshipType.RelationshipCodeDescription }} 781 </b-form-select-option> 782 783 </b-form-select> 784 785 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 786 787 </b-form-group> 788 </transition> 789 790 </b-col> 791 792 <b-col md="6" v-if="isEmployee || isOther"> 793 794 <!-- JOB FUNCTION --> 795 <b-form-group 796 label="Job Description" 797 label-for="pfy-register-job-function" 798 :class="getFormClass( 'pfy-register-job-function', primaryRoleIsValid && !birthDateRequiresCOPPA )"> 799 800 <b-form-select 801 id="pfy-register-job-function" 802 v-model="$v.schoolForm.jobFunction.$model" 803 :state="validateFormField( 'schoolForm', 'jobFunction' )"> 804 805 <b-form-select-option 806 v-for="jobFunction in availableJobFunctionCodes" 807 :key="jobFunction.Code" 808 :value="jobFunction.Code"> 809 {{ jobFunction.Description }} 810 </b-form-select-option> 811 812 </b-form-select> 813 814 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 815 816 </b-form-group> 817 818 </b-col> 819 820 <b-col md="6" v-if="isStudent"> 821 822 <!-- GRADUATION YEAR --> 823 <b-form-group 824 label="Anticipated High School Graduation Year" 825 label-for="pfy-register-graduation-year"> 826 827 <b-form-select 828 id="pfy-register-graduation-year" 829 v-model="$v.schoolForm.graduationYear.$model" 830 :state="validateFormField( 'schoolForm', 'graduationYear' )"> 831 832 <b-form-select-option 833 v-for="graduationYear in graduationYears" 834 :key="graduationYear.Subcode" 835 :value="graduationYear.Subcode"> 836 {{ graduationYear.Description }} 837 </b-form-select-option> 838 839 </b-form-select> 840 841 </b-form-group> 842 843 </b-col> 844 845 </b-row> 846 847 </b-form> 848 849 <!-- SEARCH --> 850 <transition name="fade"> 851 <b-form 852 id="pfy-register-address-search-form" 853 :class="getFormClass( 'pfy-register-address-search-form', primaryRoleIsValid && !birthDateRequiresCOPPA && !emailAlertExists )" 854 v-show="isStudent || isEmployee" 855 @submit.stop.prevent="submitAddressSearch"> 856 857 <h3 class="mt-5">Find your school</h3> 858 859 <!-- METHOD --> 860 <b-form-group v-if="!addressSearchSelected"> 861 862 <b-form-radio-group 863 id="pfy-register-address-search-method" 864 name="pfy-register-address-search-method" 865 v-model="$v.addressSearchForm.method.$model"> 866 867 <b-form-radio 868 value="search" 869 plain> 870 <i class="fas fa-search"></i> Search for your school 871 </b-form-radio> 872 873 <b-form-radio 874 value="id" 875 plain> 876 <i class="fas fa-hashtag"></i> Enter School ID Number 877 </b-form-radio> 878 879 </b-form-radio-group> 880 881 </b-form-group> 882 883 <!-- BY SCHOOL ID --> 884 <template v-if="addressSearchForm.method == 'id' && !addressSearchSelected"> 885 886 <b-row> 887 888 <b-col md="6"> 889 890 <!-- SCHOOL ID --> 891 <b-form-group 892 label="School ID Number" 893 label-for="pfy-register-address-search-school-id"> 894 895 <b-form-input 896 id="pfy-register-address-search-name" 897 v-model="$v.addressSearchForm.schoolID.$model" 898 :state="validateFormField('addressSearchForm', 'schoolID')"> 899 </b-form-input> 900 901 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 902 903 </b-form-group> 904 905 </b-col> 906 907 </b-row> 908 909 </template> 910 911 <!-- BY NAME --> 912 <template v-if="addressSearchForm.method == 'search' && !addressSearchSelected"> 913 914 <b-row> 915 916 <b-col md="6"> 917 918 <!-- CITY --> 919 <b-form-group 920 label="City" 921 label-for="pfy-register-address-search-city"> 922 923 <b-form-input 924 id="pfy-register-address-search-city" 925 v-model="$v.addressSearchForm.city.$model"> 926 </b-form-input> 927 928 </b-form-group> 929 930 </b-col> 931 932 <b-col md="6"> 933 934 <!-- STATE --> 935 <b-form-group 936 label="State" 937 label-for="pfy-register-address-search-state" 938 v-if="addressSearchForm.country == 'USA'"> 939 940 <b-form-select 941 id="pfy-register-address-search-state" 942 v-model="$v.addressSearchForm.state.$model" 943 :state="validateFormField( 'addressSearchForm', 'state' )"> 944 945 <b-form-select-option 946 v-for="state in states" 947 :key="state.StateCode" 948 :value="state.StateCode"> 949 {{ state.StateDescription }} 950 </b-form-select-option> 951 952 </b-form-select> 953 954 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 955 956 </b-form-group> 957 958 </b-col> 959 960 <b-col md="6"> 961 962 <!-- COUNTRY --> 963 <b-form-group 964 label="Country" 965 label-for="pfy-register-address-search-country"> 966 967 <b-form-select 968 id="pfy-register-address-search-country" 969 v-model="$v.addressSearchForm.country.$model" 970 :state="validateFormField( 'addressSearchForm', 'country' )"> 971 972 <b-form-select-option 973 v-for="country in countries" 974 :key="country.CountryCode" 975 :value="country.CountryCode">
976 {{ country.CountryDescription }} 977 </b-form-select-option> 978 979 </b-form-select> 980 981 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 982 983 </b-form-group> 984 985 </b-col> 986 987 </b-row> 988 989 </template> 990 991 <b-card 992 v-if="addressSearchSelected" 993 class="my-3"> 994 995 <b-card-text> 996 <b>{{ getAddressName( addressSearchSelected ) }}</b><br> 997 <span v-html="formatHTML( addressSearchSelected.Address )"></span><br> 998 <small><span class="text-muted">School ID Number: #{{ addressSearchSelected.SchoolID }}</span></small> 999 </b-card-text> 1000 1001 </b-card> 1002 1003 <b-button 1004 v-if="!addressSearchSelected" 1005 type="submit" 1006 variant="primary" 1007 @click.prevent="submitAddressSearch"> 1008 Search for school 1009 </b-button> 1010 1011 <b-button 1012 v-if="addressSearchSelected" 1013 variant="outline-secondary" 1014 @click.prevent="resetSearch"> 1015 Change school 1016 </b-button> 1017 1018 <b-button 1019 v-if="!addressSearchSelected" 1020 variant="outline-secondary" 1021 @click.prevent="endSearch"> 1022 I can’t find my school 1023 </b-button> 1024 1025 </b-form> 1026 </transition> 1027 1028 <!-- SEARCH RESULTS --> 1029 <b-modal 1030 ref="modalAddressSearchResults" 1031 id="pfy-register-address-search-results" 1032 title="Search Results" 1033 ok-disabled 1034 cancel-disabled> 1035 1036 <b-card 1037 v-for="schoolAddress in addressSearchResultsList" 1038 :key="schoolAddress.CustomerAddressId" 1039 class="my-3"> 1040 1041 <b-card-text> 1042 1043 <b-form-checkbox 1044 v-model="addressSearchSelected" 1045 :value="schoolAddress"> 1046 <b>{{ getAddressName( schoolAddress ) }}</b> 1047 </b-form-checkbox> 1048 1049 <span v-html="formatHTML( schoolAddress.Address )"></span><br> 1050 <small><span class="text-muted">School ID Number: #{{ schoolAddress.SchoolID }}</span></small> 1051 </b-card-text> 1052 1053 </b-card> 1054 1055 <template v-if="!addressSearchHasResults"> 1056 1057 <h3 class="text-danger">No Search Results</h3> 1058 1059 <p>Your search did not match any schools. Try searching again with different information. If you are unable to find your school, you may also continue by entering a home or business address.</p> 1060 1061 </template> 1062 1063 <template v-slot:modal-footer> 1064 1065 <b-button 1066 variant="primary" 1067 @click.prevent="resetSearch" 1068 v-if="!addressSearchHasResults"> 1069 Search again 1070 </b-button> 1071 1072 <b-button 1073 variant="outline-secondary" 1074 @click="endSearch"> 1075 I can’t find my school 1076 </b-button> 1077 1078 </template> 1079 1080 </b-modal> 1081 1082 <b-modal 1083 ref="modalAddressSearchUnsuccessful" 1084 id="pfy-register-address-search-unsuccessful" 1085 ok-only> 1086 1087 <p>Current student and employee accounts must be affiliated with your school. If you are unable to find your school online, please contact <a href="mailto:[email protected]">NASSP Customer Care</a> with your school information to activate your account.</p> 1088 1089 </b-modal> 1090 1091 <!-- MANUAL ADDRESS FORM --> 1092 <b-form 1093 id="pfy-register-address-manual-form" 1094 :class="getFormClass( 'pfy-register-address-manual-form', primaryRoleIsValid && !birthDateRequiresCOPPA && !emailAlertExists )" 1095 v-show="isOther"> 1096 1097 <h2 class="mt-5">Address</h2> 1098 1099 <b-alert 1100 v-model="addressAlertUnvalidated" 1101 variant="danger"> 1102 We could not validate the address you submitted. Please make sure the information you have entered is correct. 1103 </b-alert> 1104 1105 <b-alert 1106 v-model="addressAlertUndeliverable" 1107 variant="danger"> 1108 The address you submitted is not valid. Please try another address. 1109 </b-alert> 1110 1111 <b-form-checkbox 1112 id="pfy-register-address-manual-novalidate" 1113 v-model="$v.addressManualForm.doNotValidate.$model" 1114 v-if="addressAlertUnvalidated" 1115 :value="true" 1116 :unchecked-value="false" 1117 class="mb-3"> 1118 Continue without validating my address. 1119 </b-form-checkbox> 1120 1121 <b-row> 1122 1123 <b-col md="6"> 1124 1125 <b-form-group 1126 label="Address Type" 1127 label-for="pfy-register-address-manual-type"> 1128 1129 <b-form-select 1130 id="pfy-register-address-manual-type" 1131 v-model="$v.addressManualForm.type.$model" 1132 :state="validateFormField( 'addressManualForm', 'type' )"> 1133 1134 <b-form-select-option 1135 v-for="addressType in addressTypes" 1136 v-if="addressType.Code != 'SCHOOL'" 1137 :key="addressType.Code" 1138 :value="addressType.Code"> 1139 {{ addressType.Description }} 1140 </b-form-select-option> 1141 1142 </b-form-select> 1143 1144 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 1145 1146 </b-form-group> 1147 1148 </b-col> 1149 1150 <b-col md="6"> 1151 1152 <!-- LINE 1 --> 1153 <b-form-group 1154 label="Address Line 1" 1155 label-for="pfy-register-address-manual-line1" 1156 required> 1157 1158 <b-form-input 1159 id="pfy-register-address-manual-line1" 1160 v-model="$v.addressManualForm.line1.$model" 1161 :state="validateFormField( 'addressManualForm', 'line1' )"> 1162 </b-form-input> 1163 1164 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 1165 1166 </b-form-group> 1167 1168 </b-col> 1169 1170 <b-col md="6"> 1171 1172 <!-- LINE 2 --> 1173 <b-form-group 1174 label="Address Line 2" 1175 label-for="pfy-register-address-manual-line2"> 1176 1177 <b-form-input 1178 id="pfy-register-address-manual-line2" 1179 v-model="$v.addressManualForm.line2.$model" 1180 :state="validateFormField( 'addressManualForm', 'line2' )"> 1181 </b-form-input> 1182 1183 </b-form-group> 1184 1185 </b-col> 1186 1187 <b-col md="6"> 1188 1189 <!-- LINE 3 --> 1190 <b-form-group 1191 label="Address Line 3" 1192 label-for="pfy-register-address-manual-line3"> 1193 1194 <b-form-input 1195 id="pfy-register-address-manual-line3" 1196 v-model="$v.addressManualForm.line3.$model" 1197 :state="validateFormField( 'addressManualForm', 'line3' )"> 1198 </b-form-input> 1199 1200 </b-form-group> 1201 1202 </b-col> 1203 1204 <b-col md="6"> 1205 1206 <!-- CITY --> 1207 <b-form-group 1208 label="City" 1209 label-for="pfy-register-address-manual-city"> 1210 1211 <b-form-input 1212 id="pfy-register-address-manual-city" 1213 v-model="$v.addressManualForm.city.$model" 1214 :state="validateFormField( 'addressManualForm', 'city' )"> 1215 </b-form-input> 1216 1217 </b-form-group> 1218 1219 </b-col> 1220 1221 <b-col md="6"> 1222 1223 <!-- STATE --> 1224 <b-form-group 1225 label="State" 1226 label-for="" 1227 v-if="addressManualForm.country == 'USA'"> 1228 1229 <b-form-select 1230 id="pfy-register-address-manual-state" 1231 v-model="$v.addressManualForm.state.$model" 1232 :state="validateFormField( 'addressManualForm', 'state' )"> 1233 1234 <b-form-select-option 1235 v-for="state in states" 1236 :key="state.StateCode" 1237 :value="state.StateCode"> 1238 {{ state.StateDescription }} 1239 </b-form-select-option> 1240 1241 </b-form-select> 1242 1243 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 1244 1245 </b-form-group> 1246 1247 </b-col> 1248 1249 <b-col md="6"> 1250 1251 <!-- ZIP CODE --> 1252 <b-form-group 1253 :label="addressManualForm.country == 'USA' ? 'ZIP Code' : 'Postal Code'" 1254 label-for="pfy-register-address-manual-zip"> 1255 1256 <b-form-input 1257 id="pfy-register-address-manual-zip" 1258 v-model="$v.addressManualForm.zip.$model" 1259 :state="validateFormField( 'addressManualForm', 'zip' )"> 1260 </b-form-input> 1261 1262 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 1263 1264 </b-form-group> 1265 1266 </b-col> 1267 1268 <b-col md="6"> 1269 1270 <!-- COUNTRY --> 1271 <b-form-group 1272 label="Country" 1273 label-for="pfy-register-address-manual-country"> 1274 1275 <b-form-select 1276 id="pfy-register-address-manual-country" 1277 v-model="$v.addressManualForm.country.$model" 1278 :state="validateFormField( 'addressManualForm', 'country' )"> 1279 1280 <b-form-select-option 1281 v-for="country in countries" 1282 :key="country.CountryCode" 1283 :value="country.CountryCode">
1284 {{ country.CountryDescription }} 1285 </b-form-select-option> 1286 1287 </b-form-select> 1288 1289 <b-form-invalid-feedback>This field is required.</b-form-invalid-feedback> 1290 1291 </b-form-group> 1292 1293 </b-col> 1294 1295 <b-col md="6"> 1296 1297 <!-- START DATE --> 1298 <b-form-group 1299 label="Start Date" 1300 label-for="pfy-register-start-date" 1301 v-if="derivedAddressType == 'SEASONAL'"> 1302 1303 <b-form-input 1304 id="pfy-register-start-date" 1305 v-model="$v.addressManualForm.startDate.$model" 1306 type="date" 1307 :state="validateFormField('addressManualForm', 'startDate')"> 1308 </b-form-input> 1309 1310 <b-form-invalid-feedback>This field is required for seasonal addresses.</b-form-invalid-feedback> 1311 1312 </b-form-group> 1313 1314 </b-col> 1315 1316 <b-col md="6"> 1317 1318 <!-- END DATE --> 1319 <b-form-group 1320 label="End Date" 1321 label-for="pfy-register-end-date" 1322 v-if="derivedAddressType == 'SEASONAL'"> 1323 1324 <b-form-input 1325 id="pfy-register-end-date" 1326 v-model="$v.addressManualForm.endDate.$model" 1327 type="date" 1328 :state="validateFormField('addressManualForm', 'endDate')"> 1329 </b-form-input> 1330 1331 <b-form-invalid-feedback>This field is required for seasonal addresses.</b-form-invalid-feedback> 1332 1333 </b-form-group> 1334 1335 </b-col> 1336 1337 </b-row> 1338 1339 </b-form> 1340 1341 <b-form 1342 id="pfy-register-consent-form" 1343 :class="getFormClass( 'pfy-register-consent-form', primaryRoleIsValid && !birthDateRequiresCOPPA && !emailAlertExists )" 1344 @submit.stop.prevent="submit"> 1345 1346 <h2 class="mt-5">Terms and Conditions</h2> 1347 1348 <p>By creating an account, you will have access to additional information, content, and resources concerning NASSP’s programs and activities, including information pertaining to the National Honor Society, National Junior Honor Society, National Elementary Honor Society, and National Association of Student Councils.</p> 1349 1350 <b-form-checkbox-group> 1351 1352 <b-form-checkbox 1353 id="pfy-register-consent" 1354 v-model="$v.consentForm.consent.$model" 1355 :value="true" 1356 :unchecked-value="null"> 1357 I certify that I have read and understand the website <a href="/privacy-policy" target="_blank">Privacy Policy</a> and <a href="/terms-of-use" target="_blank">Terms and Conditions</a>. 1358 </b-form-checkbox> 1359 1360 <b-form-invalid-feedback 1361 :state="validateFormField('consentForm', 'consent')"> 1362 You must accept the terms and conditions to create an account. 1363 </b-form-invalid-feedback> 1364 1365 </b-form-checkbox-group> 1366 1367 <div class="progress-footer"> 1368 <div class="button-container"> 1369 <button id="next-step" type="submit" class="btn mt-1 btn-primary" @click.prevent="submit"> 1370 Create my account 1371 </button> 1372 </div> 1373 <div class="button-container"> 1374 <button id="next-step" type="submit" class="btn mt-1 btn-outline-primary" @click.prevent="unsubmitPersonal"> 1375 Back 1376 </button> 1377 </div> 1378 </div> 1379 1380 </b-form> 1381 1382 </div> 1383 1384 <!-- SIDEBAR --> 1385 <!-- <portal to="pfySidebar"> 1386 <section class="widget"> 1387 1388 <h3 class="widget-title">Renew</h3> 1389 1390 <p>Already a member? Log in to renew your membership now.</p> 1391 1392 <b-button :href="loginURL" variant="primary" class="mb-2">Log in to renew</b-button> 1393 1394 </section> 1395 </portal> --> 1396 1397 </section>`, 1398 1399 mounted() { 1400 this.getInitialData(); 1401 }, 1402 1403 watch: { 1404 1405 // Hide the search results modal when the user selects a searched address. 1406 addressSearchSelected( newValue ) { 1407 if ( newValue ) this.$bvModal.hide('pfy-register-address-search-results'); 1408 }, 1409 1410 studentInducted( newValue ) { 1411 if ( newValue === 'no' ) this.$bvModal.show('pfy-register-student-not-inducted'); 1412 } 1413 1414 }, 1415 1416 methods: { 1417 1418 // INITIALIZE 1419 1420 getInitialData() { 1421 1422 var self = this; 1423 1424 var callConfig = { 1425 endpoint: 'personify/v1/register/get-initial-data', 1426 body: {}, 1427 callback: self.getInitialDataCallback, 1428 silent: true, 1429 } 1430 1431 var call = new PortalCall( callConfig ); 1432 1433 call.send(); 1434 1435 }, 1436 1437 getInitialDataCallback( call ) { 1438 1439 switch ( call.code ) { 1440 1441 case 'success': 1442 1443 this.addressTypes = call.response.addressTypes; 1444 this.countries = call.response.countries; 1445 this.states = call.response.states; 1446 this.jobFunctions = call.response.jobFunctions; 1447 this.relationshipTypes = call.response.relationshipTypes; 1448 this.graduationYears = call.response.graduationYears; 1449 this.genders = call.response.genders; 1450 this.ethnicities = call.response.ethnicities; 1451 1452 return; 1453 1454 default: return; 1455 1456 } 1457 1458 }, 1459 1460 // PRIMARY ROLE 1461 setPrimaryRole(role) { 1462 this.primaryRole = String( role ); 1463 }, 1464 1465 // EMAIL 1466 submitEmail() { 1467 1468 // Check primaryRole. 1469 this.$v.primaryRole.$touch(); 1470 if ( this.$v.primaryRole.$anyError ) { 1471 this.scrollTo('#pfy-register-primary-role'); 1472 return; 1473 } 1474 1475 this.$v.studentInducted.$touch(); 1476 if ( this.$v.studentInducted.$anyError || this.studentInducted === 'no' ) { 1477 this.scrollTo('#pfy-register-student-inducted'); 1478 this.$bvModal.show('pfy-register-student-not-inducted'); 1479 return; 1480 } 1481 1482 // Check password. 1483 this.$v.passwordForm.$touch(); 1484 if ( this.$v.passwordForm.$anyError ) { 1485 this.scrollTo('.pfy-register-password-form'); 1486 return; 1487 } 1488 1489 // Check email. 1490 if ( !this.emailSelected ) { 1491 1492 this.$v.emailForm.$touch(); 1493 if ( this.$v.$anyError ) return; 1494 1495 var self = this; 1496 1497 var callConfig = { 1498 endpoint: 'personify/v1/register/check-email', 1499 body: { 1500 email: this.emailForm.email, 1501 vendorID: this.vendorID, 1502 }, 1503 callback: self.submitEmailCallback, 1504 silent: false, 1505 } 1506 1507 var call = new PortalCall( callConfig ); 1508 1509 call.send(); 1510 1511 } 1512 1513 }, 1514 1515 submitEmailCallback( call ) { 1516 1517 var self = this; 1518 1519 switch ( call.code ) { 1520 1521 case 'success': 1522 1523 if ( call.response.emailAvailable ) { 1524 1525 this.emailSelected = true; 1526 this.emailAlertExists = false;
1527 1528 this.step = 2; 1529 1530 Vue.nextTick(function(){ 1531 self.scrollTo('.pfy-register-personal-form'); 1532 jQuery('#pfy-register-first-name').focus(); 1533 }); 1534 1535 } else { 1536 1537 this.emailAlertExists = true; 1538 1539 this.step = 1; 1540 1541 Vue.nextTick(function(){ 1542 self.scrollTo('.pfy-register-email-form'); 1543 }); 1544 1545 } 1546 1547 return; 1548 1549 default: 1550 1551 this.$bvToast.toast( call.response.message || call.message, { 1552 title: 'Error', 1553 autoHideDelay: 5000, 1554 variant: 'danger', 1555 toaster: 'b-toaster-top-center', 1556 appendToast: true 1557 }); 1558 1559 return; 1560 1561 } 1562 1563 }, 1564 1565 unsubmitEmail() { 1566 this.step = 1; 1567 this.emailSelected = false; 1568 }, 1569 1570 // PERSONAL INFO 1571 1572 submitPersonal() { 1573 1574 var self = this; 1575 1576 // Check personal info. 1577 this.$v.personalForm.$touch(); 1578 if ( this.$v.personalForm.$anyError ) { 1579 1580 this.step = 2; 1581 1582 Vue.nextTick(function(){ 1583 self.scrollTo('.pfy-register-personal-form'); 1584 }); 1585 1586 return; 1587 1588 } 1589 1590 this.step = 3; 1591 1592 Vue.nextTick(function(){ 1593 self.scrollTo('.pfy-register-school-role-form'); 1594 }); 1595 1596 }, 1597 1598 unsubmitPersonal() { 1599 this.step = 2; 1600 }, 1601 1602 // ADDRESS SEARCH 1603 1604 submitAddressSearch() { 1605 1606 // Don't repeat. 1607 if ( this.addressSearchSelected ) return; 1608 1609 // Check form. 1610 this.$v.addressSearchForm.$touch(); 1611 if ( this.$v.$anyError ) return; 1612 1613 var self = this; 1614 1615 var callConfig = { 1616 endpoint: 'personify/v1/register/search-schools', 1617 body: this.addressSearchForm, 1618 callback: self.submitAddressSearchCallback, 1619 silent: false, 1620 } 1621 1622 var call = new PortalCall( callConfig ); 1623 1624 call.send(); 1625 1626 }, 1627 1628 submitAddressSearchCallback( call ) { 1629 1630 switch ( call.code ) { 1631 1632 case 'success': 1633 1634 this.addressSearchResults = call.response.results; 1635 1636 this.$bvModal.show('pfy-register-address-search-results'); 1637 1638 return; 1639 1640 default: 1641 1642 this.$bvToast.toast( call.response.message || call.message, { 1643 title: 'Error', 1644 autoHideDelay: 5000, 1645 variant: 'danger', 1646 toaster: 'b-toaster-top-center', 1647 appendToast: true 1648 }); 1649 1650 return; 1651 1652 } 1653 1654 }, 1655 1656 getAddressName( address ) { 1657 1658 if ( address.SchoolName && address.SchoolName.length > 0 ) return address.SchoolName; 1659 1660 if ( address.CompanyName && address.CompanyName.length > 0 ) return address.CompanyName; 1661 1662 return address.CustomerAddressId; // default; 1663 1664 }, 1665 1666 resetSearch() { 1667 1668 this.addressSearchSelected = null; 1669 1670 this.$bvModal.hide('pfy-register-address-search-results'); 1671 1672 }, 1673 1674 endSearch() { 1675 1676 this.resetSearch() 1677 1678 this.$bvModal.show('pfy-register-address-search-unsuccessful'); 1679 1680 }, 1681 1682 // SUBMISSION 1683 submit() { 1684 1685 // Check school role info. 1686 this.$v.schoolForm.$touch(); 1687 if ( this.$v.schoolForm.$anyError ) { 1688 this.scrollTo('.pfy-register-school-role-form'); 1689 return; 1690 } 1691 1692 // Check address. 1693 if ( this.isStudent || this.isEmployee ) { 1694 1695 this.$v.addressSearchForm.$touch(); 1696 if ( this.$v.addressSearchForm.$anyError || !this.addressSearchSelected ) { 1697 this.scrollTo('.pfy-register-address-search-form'); 1698 return; 1699 } 1700 1701 } else { 1702 1703 this.$v.addressManualForm.$touch(); 1704 if ( this.$v.addressManualForm.$anyError ) { 1705 this.scrollTo('.pfy-register-address-manual-form'); 1706 return; 1707 } 1708 1709 } 1710 1711 // Check consent. 1712 this.$v.consentForm.$touch(); 1713 if ( this.$v.consentForm.$anyError ) { 1714 this.scrollTo('.pfy-register-consent-form'); 1715 return; 1716 } 1717 1718 // Clear alerts. 1719 this.addressAlertUnvalidated = false; 1720 this.addressAlertUndeliverable = false; 1721 1722 // Send. 1723 var self = this; 1724 1725 var callConfig = { 1726 endpoint: 'personify/v1/register/create-account', 1727 body: { 1728 primaryRole: this.primaryRole, 1729 email: this.emailForm.email, 1730 password: this.passwordForm.password, 1731 firstName: this.personalForm.firstName, 1732 lastName: this.personalForm.lastName, 1733 phoneAreaCode: this.phoneAreaCode, 1734 phoneBody: this.phoneBody, 1735 phoneExtension: this.phoneExtension, 1736 birthDate: this.personalForm.birthDate, 1737 gender: this.personalForm.gender, 1738 ethnicity: this.personalForm.ethnicity, 1739 addressType: this.derivedAddressType, 1740 relationshipType: this.derivedRelationshipType, 1741 jobFunction: this.derivedJobFunctionCode, 1742 graduationYear: this.schoolForm.graduationYear, 1743 schoolAddress: this.addressSearchSelected, 1744 manualName: this.addressManualForm.name, 1745 manualLine1: this.addressManualForm.line1, 1746 manualLine2: this.addressManualForm.line2, 1747 manualLine3: this.addressManualForm.line3, 1748 manualCity: this.addressManualForm.city, 1749 manualState: this.addressManualForm.state, 1750 manualCountry: this.addressManualForm.country, 1751 manualZip: this.addressManualForm.zip, 1752 manualStartDate: this.addressManualForm.startDate, 1753 manualEndDate: this.addressManualForm.endDate, 1754 manualDoNotValidate: this.addressManualForm.doNotValidate, 1755 consent: this.consentForm.consent, 1756 vendorID: this.vendorID, 1757 }, 1758 callback: self.submitCallback, 1759 silent: false, 1760 } 1761 1762 var call = new PortalCall( callConfig ); 1763 1764 call.send(); 1765 1766 }, 1767 1768 submitCallback( call ) { 1769 1770 switch ( call.code ) { 1771 1772 case 'success': 1773 1774 /* 1775 this.password = call.response.password; 1776 1777 // For third-party SSO integrations, skip the auto-login step and go straight to the provided return URL (usually the custom login page). 1778 if ( this.vendorID !== null ) { 1779 window.location = this.returnURL; 1780 return; 1781 } 1782 1783 this.submitLogin(); 1784 1785 return; 1786 */ 1787 1788 window.location = this.loginURL; 1789
1790 case 'address-unvalidated': 1791 1792 // NASSP prefers not to allow unvalidated addresses to proceed. 1793 1794 /* 1795 1796 this.addressAlertUnvalidated = true; 1797 1798 this.scrollTo('.pfy-register-address-manual-form'); 1799 1800 return; 1801 1802 */ 1803 1804 case 'address-not-found': 1805 case 'address-undeliverable': 1806 1807 this.addressAlertUndeliverable = true; 1808 1809 this.scrollTo('.pfy-register-address-manual-form'); 1810 1811 return; 1812 1813 default: 1814 1815 this.$bvToast.toast( call.response.message || call.message, { 1816 title: 'Error', 1817 variant: 'danger', 1818 toaster: 'b-toaster-top-center', 1819 appendToast: true 1820 }); 1821 1822 return; 1823 1824 } 1825 1826 }, 1827 1828 // LOGIN 1829 1830 submitLogin() { 1831 1832 var self = this; 1833 1834 var call = new PortalCall({ 1835 endpoint: 'personify/v1/login', 1836 body: { 1837 username: self.emailForm.email, 1838 password: self.password, 1839 vendorID: self.vendorID, 1840 returnURL: self.returnURL, 1841 }, 1842 callback: self.submitLoginCallback, 1843 silent: false, 1844 }); 1845 1846 call.send(); 1847 1848 }, 1849 1850 submitLoginCallback( call ) { 1851 1852 switch ( call.code ) { 1853 case 'success': 1854 1855 window.location = call.response.returnURL; 1856 return; 1857 1858 default: 1859 1860 this.$bvToast.toast( call.response.message || call.message, { 1861 title: 'Error', 1862 variant: 'danger', 1863 toaster: 'b-toaster-top-center', 1864 appendToast: true 1865 }); 1866 1867 return; 1868 1869 } 1870 1871 }, 1872 1873 // FORM VALIDATION 1874 1875 validateField( fieldName ) { 1876 const { $dirty, $error } = this.$v[fieldName]; 1877 return $dirty ? !$error : null; 1878 }, 1879 1880 validateFormField( formName, fieldName ) { 1881 const { $dirty, $error } = this.$v[formName][fieldName]; 1882 return $dirty ? !$error : null; 1883 }, 1884 1885 // HELPERS 1886 1887 getFormClass( mainClass, condition ) { 1888 1889 var formClass = mainClass; 1890 1891 if ( !condition ) { 1892 formClass += ' pfy-block-disabled'; 1893 } 1894 1895 return formClass; 1896 1897 }, 1898 1899 formatHTML( value ) { 1900 return value.replace("\n", '<br>'); 1901 }, 1902 1903 scrollTo( selector ) { 1904 1905 jQuery('html, body').animate({ 1906 scrollTop: jQuery(selector).offset().top - jQuery(window).height() / 3, 1907 }, 500); 1908 1909 } 1910 1911 }, 1912 1913 validations: { 1914 1915 primaryRole: { required }, 1916 studentInducted: { 1917 required: requiredIf( function( nestedModel ){ 1918 return Boolean( this.isStudent ); 1919 }) 1920 }, 1921 1922 emailForm: { 1923 email: { required, email }, 1924 emailConfirm: { 1925 required, 1926 email, 1927 matchEmail (val) { 1928 return Boolean( val === this.emailForm.email ) 1929 } 1930 }, 1931 }, 1932 1933 passwordForm: { 1934 password: { required, minLength: minLength(6) }, 1935 }, 1936 1937 personalForm: { 1938 firstName: { required }, 1939 lastName: { required }, 1940 birthDate: { 1941 required: requiredIf( function( nestedModel ){ 1942 return Boolean( this.isStudent || this.isEmployee ); 1943 }) 1944 }, 1945 phone: { required, minLength: minLength(10) }, 1946 gender: { required }, 1947 ethnicity: { required }, 1948 }, 1949 1950 schoolForm: { 1951 1952 relationshipType: { 1953 required: requiredIf( function( nestedModel ){ 1954 return this.isEmployee; 1955 }) 1956 }, 1957 1958 jobFunction: { 1959 required: requiredIf( function( nestedModel ){ 1960 return this.isEmployee; 1961 }) 1962 }, 1963 1964 graduationYear: { 1965 required: requiredIf( function( nestedModel ){ 1966 return this.isStudent; 1967 }) 1968 } 1969 1970 }, 1971 1972 addressSearchForm: { 1973 1974 method: { required }, 1975 1976 name: {}, 1977 1978 city: {}, 1979 1980 state: { 1981 required: requiredIf(function( nestedModel ) { 1982 return this.addressSearchForm.method == 'search' && this.addressSearchForm.country == 'USA'; 1983 }) 1984 }, 1985 1986 country: { 1987 required: requiredIf(function( nestedModel ) { 1988 return this.addressSearchForm.method == 'search' 1989 }) 1990 }, 1991 1992 schoolID: { 1993 required: requiredIf(function( nestedModel ) { 1994 return this.addressSearchForm.method == 'id' 1995 }) 1996 }, 1997 1998 }, 1999 2000 addressManualForm: { 2001 2002 type: { required }, 2003 2004 line1: { 2005 required, 2006 }, 2007 2008 line2: { 2009 2010 }, 2011 2012 line3: { 2013 2014 }, 2015 2016 city: { 2017 required, 2018 }, 2019 2020 state: { 2021 required: requiredIf( function( nestedModel ){ 2022 return this.addressManualForm.country == 'USA'; 2023 }), 2024 }, 2025 2026 country: { 2027 required, 2028 }, 2029 2030 zip: { 2031 required 2032 }, 2033 2034 startDate: { 2035 required: requiredIf( function( nestedModel ){ 2036 return this.addressManualForm.type == 'SEASONAL'; 2037 }), 2038 }, 2039 2040 endDate: { 2041 required: requiredIf( function( nestedModel ){ 2042 return this.addressManualForm.type == 'SEASONAL'; 2043 }), 2044 }, 2045 2046 doNotValidate: {}, 2047 2048 }, 2049 2050 consentForm: { 2051 consent: { arrayNotEmpty }, 2052 }, 2053 2054 }, 2055 2056});
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.