mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-02 11:58:10 -05:00
Add required district field to teacher trial request forms
School now optional N/A placeholder on district field and don't save it if it's n/a Updating required field error UI a bit, and there is some larger refactoring needed here later. NCES phone number for district only entries will currently be a child school, will fix later. Closes #3818
This commit is contained in:
parent
f4c0e4144e
commit
6f08d5e422
18 changed files with 630 additions and 426 deletions
|
@ -45,7 +45,7 @@ module.exports.applyErrorsToForm = (el, errors, warning=false) ->
|
||||||
for error in errors
|
for error in errors
|
||||||
if error.code is tv4.errorCodes.OBJECT_REQUIRED
|
if error.code is tv4.errorCodes.OBJECT_REQUIRED
|
||||||
prop = _.last(_.string.words(error.message)) # hack
|
prop = _.last(_.string.words(error.message)) # hack
|
||||||
message = 'Required field'
|
message = $.i18n.t('common.required_field')
|
||||||
|
|
||||||
else if error.dataPath
|
else if error.dataPath
|
||||||
prop = error.dataPath[1..]
|
prop = error.dataPath[1..]
|
||||||
|
|
|
@ -356,7 +356,7 @@
|
||||||
submit_patch: "Submit Patch"
|
submit_patch: "Submit Patch"
|
||||||
submit_changes: "Submit Changes"
|
submit_changes: "Submit Changes"
|
||||||
save_changes: "Save Changes"
|
save_changes: "Save Changes"
|
||||||
required_field: "Required field"
|
required_field: "required" # {change}
|
||||||
|
|
||||||
general:
|
general:
|
||||||
and: "and"
|
and: "and"
|
||||||
|
@ -885,7 +885,9 @@
|
||||||
evaluate_recommend: "Evaluate/Recommend"
|
evaluate_recommend: "Evaluate/Recommend"
|
||||||
approve_funds: "Approve Funds"
|
approve_funds: "Approve Funds"
|
||||||
no_purchaser_role: "No role in purchase decisions"
|
no_purchaser_role: "No role in purchase decisions"
|
||||||
organization_label: "Name of School/District"
|
district_label: "District"
|
||||||
|
district_na: "Enter N/A if not applicable"
|
||||||
|
organization_label: "School" # {change}
|
||||||
city: "City"
|
city: "City"
|
||||||
state: "State"
|
state: "State"
|
||||||
country: "Country"
|
country: "Country"
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
@import "app/styles/mixins"
|
|
||||||
@import "app/styles/bootstrap/variables"
|
|
||||||
|
|
||||||
#request-quote-view
|
|
||||||
#site-content-area
|
|
||||||
margin: 50px 0 100px
|
|
||||||
.row
|
|
||||||
margin: 20px 0
|
|
||||||
|
|
||||||
#conversion-warning
|
|
||||||
margin-top: 20px
|
|
||||||
|
|
||||||
.form-group
|
|
||||||
label
|
|
||||||
margin-bottom: 0
|
|
||||||
|
|
||||||
label.checkbox
|
|
||||||
font-weight: normal
|
|
||||||
|
|
||||||
.help-block
|
|
||||||
margin: -4px 0 2px
|
|
||||||
|
|
||||||
p
|
|
||||||
margin: 0 0 20px
|
|
||||||
|
|
||||||
.checkbox, .checkbox-inline
|
|
||||||
input
|
|
||||||
margin-top: 8px
|
|
||||||
|
|
||||||
#other-education-level-input
|
|
||||||
label
|
|
||||||
display: inline-block
|
|
||||||
display: inline-block
|
|
||||||
width: 200px
|
|
||||||
margin-left: 5px
|
|
||||||
|
|
||||||
#submit-request-btn
|
|
||||||
margin-left: 10px
|
|
||||||
|
|
||||||
// After submit (anonymous)
|
|
||||||
|
|
||||||
h5
|
|
||||||
margin-top: 50px
|
|
||||||
|
|
||||||
#social-network-signups
|
|
||||||
margin: 20px 0
|
|
||||||
button
|
|
||||||
margin-left: 10px
|
|
||||||
|
|
||||||
.text-h1
|
|
||||||
margin: 40px 0 30px
|
|
||||||
|
|
||||||
|
|
||||||
.algolia-autocomplete
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.aa-input
|
|
||||||
width: 100%
|
|
||||||
|
|
||||||
.aa-hint
|
|
||||||
color: #999
|
|
||||||
width: 100%
|
|
||||||
|
|
||||||
.aa-dropdown-menu
|
|
||||||
background-color: #fff
|
|
||||||
border: 1px solid #999
|
|
||||||
border-top: none
|
|
||||||
width: 100%
|
|
||||||
|
|
||||||
.aa-suggestion
|
|
||||||
cursor: pointer
|
|
||||||
padding: 5px 4px
|
|
||||||
border-top: 1px solid #ccc
|
|
||||||
|
|
||||||
.school
|
|
||||||
font-family: Open Sans
|
|
||||||
font-size: 14px
|
|
||||||
line-height: 20px
|
|
||||||
font-weight: bold
|
|
||||||
|
|
||||||
.district
|
|
||||||
font-family: Open Sans
|
|
||||||
font-size: 14px
|
|
||||||
line-height: 20px
|
|
||||||
|
|
||||||
span
|
|
||||||
white-space: nowrap
|
|
||||||
|
|
||||||
|
|
||||||
.aa-suggestion.aa-cursor
|
|
||||||
background-color: #B2D7FF
|
|
||||||
|
|
||||||
em
|
|
||||||
font-weight: bold
|
|
||||||
font-style: normal
|
|
||||||
|
|
81
app/styles/teachers/teacher-trial-requests.sass
Normal file
81
app/styles/teachers/teacher-trial-requests.sass
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#create-teacher-account-view, #convert-to-teacher-account-view, #request-quote-view
|
||||||
|
.algolia-autocomplete
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.aa-input
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.aa-hint
|
||||||
|
color: #999
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.aa-dropdown-menu
|
||||||
|
background-color: #fff
|
||||||
|
border: 1px solid #999
|
||||||
|
border-top: none
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.aa-suggestion
|
||||||
|
cursor: pointer
|
||||||
|
padding: 5px 4px
|
||||||
|
border-top: 1px solid #ccc
|
||||||
|
|
||||||
|
.school
|
||||||
|
font-family: Open Sans
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 20px
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
.district
|
||||||
|
font-family: Open Sans
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 20px
|
||||||
|
|
||||||
|
span
|
||||||
|
white-space: nowrap
|
||||||
|
|
||||||
|
|
||||||
|
.aa-suggestion.aa-cursor
|
||||||
|
background-color: #B2D7FF
|
||||||
|
|
||||||
|
em
|
||||||
|
font-weight: bold
|
||||||
|
font-style: normal
|
||||||
|
|
||||||
|
// TODO: update form validation instead of overwriting these styles
|
||||||
|
|
||||||
|
.control-label
|
||||||
|
font-weight: bold
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.error-help-block
|
||||||
|
margin-top: inherit
|
||||||
|
margin-bottom: 0px
|
||||||
|
float: right
|
||||||
|
font-size: 13px
|
||||||
|
font-style: italic
|
||||||
|
font-weight: normal
|
||||||
|
|
||||||
|
.text-muted
|
||||||
|
float: right
|
||||||
|
font-size: 13px
|
||||||
|
font-style: italic
|
||||||
|
font-weight: normal
|
||||||
|
|
||||||
|
.nullify-form-control
|
||||||
|
display: inherit
|
||||||
|
width: inherit
|
||||||
|
height: inherit
|
||||||
|
padding: inherit
|
||||||
|
font-size: inherit
|
||||||
|
line-height: inherit
|
||||||
|
color: inherit
|
||||||
|
vertical-align: inherit
|
||||||
|
background-color: inherit
|
||||||
|
background-image: inherit
|
||||||
|
border: inherit
|
||||||
|
border-radius: inherit
|
||||||
|
-webkit-box-shadow: inherit
|
||||||
|
box-shadow: inherit
|
||||||
|
-webkit-transition: inherit
|
||||||
|
transition: inherit
|
|
@ -30,8 +30,8 @@ block content
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th Created
|
th Created
|
||||||
th NCES District
|
|
||||||
th School Name
|
th School Name
|
||||||
|
th School District
|
||||||
th.number NCES District Schools
|
th.number NCES District Schools
|
||||||
th.number NCES District Students
|
th.number NCES District Students
|
||||||
th.number NCES School Students
|
th.number NCES School Students
|
||||||
|
@ -44,8 +44,8 @@ block content
|
||||||
- continue;
|
- continue;
|
||||||
tr
|
tr
|
||||||
td.created= trialRequest.get('created').substring(0, 10)
|
td.created= trialRequest.get('created').substring(0, 10)
|
||||||
td= trialRequest.get('properties').nces_district || ''
|
td= trialRequest.get('properties').nces_name || trialRequest.get('properties').organization || ''
|
||||||
td= trialRequest.get('properties').organization || ''
|
td= trialRequest.get('properties').nces_district || trialRequest.get('properties').district || ''
|
||||||
td= trialRequest.get('properties').nces_district_schools || ''
|
td= trialRequest.get('properties').nces_district_schools || ''
|
||||||
td= trialRequest.get('properties').nces_district_students || ''
|
td= trialRequest.get('properties').nces_district_students || ''
|
||||||
td= trialRequest.get('properties').nces_students || ''
|
td= trialRequest.get('properties').nces_students || ''
|
||||||
|
|
|
@ -28,40 +28,36 @@ block content
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.username")
|
span.control-label(data-i18n="general.username")
|
||||||
input.form-control(disabled=true value=me.get('name'))
|
input.form-control(disabled=true value=me.get('name'))
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
#email-form-group.form-group
|
#email-form-group.form-group
|
||||||
label.control-label(data-i18n="general.email")
|
span.control-label(data-i18n="general.email")
|
||||||
input.form-control(name='email' disabled=true value=me.get('email'))
|
input.form-control(name='email' disabled=true value=me.get('email'))
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.first_name")
|
span.control-label(data-i18n="general.first_name")
|
||||||
input.form-control(name="firstName" value=me.get('firstName') || '')
|
input.form-control(name="firstName" value=me.get('firstName') || '')
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.last_name")
|
span.control-label(data-i18n="general.last_name")
|
||||||
input.form-control(name="lastName" value=me.get('lastName') || '')
|
input.form-control(name="lastName" value=me.get('lastName') || '')
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="teachers_quote.phone_number")
|
span(data-i18n="teachers_quote.phone_number")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
.help-block.small
|
input.form-control(name="phoneNumber", data-i18n="[placeholder]teachers_quote.phone_number_help")
|
||||||
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
|
||||||
input.form-control(name="phoneNumber")
|
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.primary_role_label")
|
span.control-label(data-i18n="teachers_quote.primary_role_label")
|
||||||
.help-block.small
|
|
||||||
em.text-info(data-i18n="teachers_quote.role_help")
|
|
||||||
select.form-control(name="role")
|
select.form-control(name="role")
|
||||||
option(data-i18n="teachers_quote.role_default", , value='')
|
option(data-i18n="teachers_quote.role_default", , value='')
|
||||||
option(data-i18n="courses.teacher", value="Teacher")
|
option(data-i18n="courses.teacher", value="Teacher")
|
||||||
|
@ -75,30 +71,40 @@ block content
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.organization_label")
|
span.control-label
|
||||||
|
span(data-i18n="teachers_quote.organization_label")
|
||||||
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
input.form-control#organization-control(name="organization")
|
input.form-control#organization-control(name="organization")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.city")
|
//- TODO: algolia and form errors both change form-control
|
||||||
input.form-control(name="city")
|
//- TODO: District not red on validation error
|
||||||
|
span.control-label.form-control.nullify-form-control(data-i18n="teachers_quote.district_label")
|
||||||
|
input.form-control#district-control(name="district", data-i18n="[placeholder]teachers_quote.district_na")
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.state")
|
span.control-label(data-i18n="teachers_quote.city")
|
||||||
input.form-control(name="state")
|
input.form-control(name="city")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-labellabel.control-label(data-i18n="teachers_quote.country")
|
span.control-label(data-i18n="teachers_quote.state")
|
||||||
|
input.form-control(name="state")
|
||||||
|
|
||||||
|
.row.m-y-2
|
||||||
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
|
.form-group
|
||||||
|
span.control-labelspan.control-label(data-i18n="teachers_quote.country")
|
||||||
input.form-control(name="country")
|
input.form-control(name="country")
|
||||||
|
|
||||||
#form-students-info
|
#form-students-info
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4
|
.col-md-offset-2.col-md-4
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="courses.number_programming_students")
|
span.control-label(data-i18n="courses.number_programming_students")
|
||||||
.help-block.small
|
.help-block.small
|
||||||
em.text-info(data-i18n="teachers_quote.num_students_help")
|
em.text-info(data-i18n="teachers_quote.num_students_help")
|
||||||
select.form-control(name="numStudents")
|
select.form-control(name="numStudents")
|
||||||
|
@ -113,7 +119,7 @@ block content
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="courses.number_total_students")
|
span(data-i18n="courses.number_total_students")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
select.form-control(name="numStudentsTotal")
|
select.form-control(name="numStudentsTotal")
|
||||||
|
@ -126,11 +132,10 @@ block content
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-10
|
.col-md-offset-2.col-md-4
|
||||||
label.control-label(data-i18n="teachers_quote.education_level_label")
|
span.control-label(data-i18n="teachers_quote.education_level_label")
|
||||||
.help-block.small
|
.help-block.small
|
||||||
em.text-info(data-i18n="teachers_quote.education_level_help")
|
em.text-info(data-i18n="teachers_quote.education_level_help")
|
||||||
.col-md-offset-2.col-md-5
|
|
||||||
.checkbox
|
.checkbox
|
||||||
label
|
label
|
||||||
input(type="checkbox" name="educationLevel" value="Elementary")
|
input(type="checkbox" name="educationLevel" value="Elementary")
|
||||||
|
@ -156,7 +161,7 @@ block content
|
||||||
|
|
||||||
#anything-else-row.row.m-y-2
|
#anything-else-row.row.m-y-2
|
||||||
.col-md-offset-2.col-md-8
|
.col-md-offset-2.col-md-8
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="teachers_quote.anything_else")
|
span(data-i18n="teachers_quote.anything_else")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
textarea.form-control(rows=8, name="notes")
|
textarea.form-control(rows=8, name="notes")
|
||||||
|
|
|
@ -34,49 +34,47 @@ block content
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.username")
|
span.control-label(data-i18n="general.username")
|
||||||
input.form-control(name="name")
|
input.form-control(name="name")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
#email-form-group.form-group
|
#email-form-group.form-group
|
||||||
label.control-label(data-i18n="general.email")
|
span.control-label(data-i18n="general.email")
|
||||||
input.form-control(name="email")
|
input.form-control(name="email")
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.first_name")
|
span.control-label(data-i18n="general.first_name")
|
||||||
input.form-control(name="firstName")
|
input.form-control(name="firstName")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.last_name")
|
span.control-label(data-i18n="general.last_name")
|
||||||
input.form-control(name="lastName")
|
input.form-control(name="lastName")
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.password")
|
span.control-label(data-i18n="general.password")
|
||||||
input.form-control(name="password1", type="password")
|
input.form-control(name="password1", type="password")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.confirm_password")
|
span.control-label(data-i18n="general.confirm_password")
|
||||||
input.form-control(name="password2", type="password")
|
input.form-control(name="password2", type="password")
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="teachers_quote.phone_number")
|
span(data-i18n="teachers_quote.phone_number")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
.help-block.small
|
input.form-control(name="phoneNumber", data-i18n="[placeholder]teachers_quote.phone_number_help")
|
||||||
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
|
||||||
input.form-control(name="phoneNumber")
|
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.primary_role_label")
|
span.control-label(data-i18n="teachers_quote.primary_role_label")
|
||||||
select.form-control(name="role")
|
select.form-control(name="role")
|
||||||
option(data-i18n="teachers_quote.role_default", , value='')
|
option(data-i18n="teachers_quote.role_default", , value='')
|
||||||
option(data-i18n="courses.teacher", value="Teacher")
|
option(data-i18n="courses.teacher", value="Teacher")
|
||||||
|
@ -90,30 +88,40 @@ block content
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.organization_label")
|
span.control-label
|
||||||
|
span(data-i18n="teachers_quote.organization_label")
|
||||||
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
input.form-control#organization-control(name="organization")
|
input.form-control#organization-control(name="organization")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.city")
|
//- TODO: algolia and form errors both change form-control
|
||||||
input.form-control(name="city")
|
//- TODO: District not red on validation error
|
||||||
|
span.control-label.form-control.nullify-form-control(data-i18n="teachers_quote.district_label")
|
||||||
|
input.form-control#district-control(name="district", data-i18n="[placeholder]teachers_quote.district_na")
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.state")
|
span.control-label(data-i18n="teachers_quote.city")
|
||||||
input.form-control(name="state")
|
input.form-control(name="city")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-labellabel.control-label(data-i18n="teachers_quote.country")
|
span.control-label(data-i18n="teachers_quote.state")
|
||||||
|
input.form-control(name="state")
|
||||||
|
|
||||||
|
.row.m-y-2
|
||||||
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
|
.form-group
|
||||||
|
span.control-label(data-i18n="teachers_quote.country")
|
||||||
input.form-control(name="country")
|
input.form-control(name="country")
|
||||||
|
|
||||||
#form-students-info
|
#form-students-info
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4
|
.col-md-offset-2.col-md-4
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="courses.number_programming_students")
|
span.control-label(data-i18n="courses.number_programming_students")
|
||||||
.help-block.small
|
.help-block.small
|
||||||
em.text-info(data-i18n="teachers_quote.num_students_help")
|
em.text-info(data-i18n="teachers_quote.num_students_help")
|
||||||
select.form-control(name="numStudents")
|
select.form-control(name="numStudents")
|
||||||
|
@ -128,7 +136,7 @@ block content
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="courses.number_total_students")
|
span(data-i18n="courses.number_total_students")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
select.form-control(name="numStudentsTotal")
|
select.form-control(name="numStudentsTotal")
|
||||||
|
@ -140,14 +148,11 @@ block content
|
||||||
option 10,000+
|
option 10,000+
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
|
|
||||||
.row.m-y-2
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-10
|
.col-md-offset-2.col-md-4
|
||||||
label.control-label(data-i18n="teachers_quote.education_level_label")
|
span.control-label(data-i18n="teachers_quote.education_level_label")
|
||||||
.help-block.small
|
.help-block.small
|
||||||
em.text-info(data-i18n="teachers_quote.education_level_help")
|
em.text-info(data-i18n="teachers_quote.education_level_help")
|
||||||
|
|
||||||
.col-md-offset-2.col-md-5
|
|
||||||
.checkbox
|
.checkbox
|
||||||
label
|
label
|
||||||
input(type="checkbox" name="educationLevel" value="Elementary")
|
input(type="checkbox" name="educationLevel" value="Elementary")
|
||||||
|
@ -173,7 +178,7 @@ block content
|
||||||
|
|
||||||
#anything-else-row.row.m-y-2
|
#anything-else-row.row.m-y-2
|
||||||
.col-md-offset-2.col-md-8
|
.col-md-offset-2.col-md-8
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="teachers_quote.anything_else")
|
span(data-i18n="teachers_quote.anything_else")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ block content
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="general.username")
|
span(data-i18n="general.username")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
- var name = me.get('name') || '';
|
- var name = me.get('name') || '';
|
||||||
|
@ -44,20 +44,20 @@ block content
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="share_progress_modal.form_label")
|
span.control-label(data-i18n="share_progress_modal.form_label")
|
||||||
- var email = me.get('email') || '';
|
- var email = me.get('email') || '';
|
||||||
input.form-control(name="email" value=email, disabled=!!email)
|
input.form-control(name="email" value=email, disabled=!!email)
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.first_name")
|
span.control-label(data-i18n="general.first_name")
|
||||||
- var firstName = me.get('firstName') || '';
|
- var firstName = me.get('firstName') || '';
|
||||||
input.form-control(name="firstName" value=firstName, disabled=!!firstName)
|
input.form-control(name="firstName" value=firstName, disabled=!!firstName)
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.last_name")
|
span.control-label(data-i18n="general.last_name")
|
||||||
- var lastName = me.get('lastName') || '';
|
- var lastName = me.get('lastName') || '';
|
||||||
input.form-control(name="lastName" value=lastName, disabled=!!lastName)
|
input.form-control(name="lastName" value=lastName, disabled=!!lastName)
|
||||||
|
|
||||||
|
@ -65,23 +65,20 @@ block content
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label
|
span.control-label(data-i18n="teachers_quote.phone_number")
|
||||||
span(data-i18n="teachers_quote.phone_number")
|
input.form-control(name="phoneNumber", data-i18n="[placeholder]teachers_quote.phone_number_help")
|
||||||
.help-block.small
|
|
||||||
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
|
||||||
input.form-control(name="phoneNumber")
|
|
||||||
|
|
||||||
if me.isAnonymous()
|
if me.isAnonymous()
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
#email-form-group.form-group
|
#email-form-group.form-group
|
||||||
label.control-label(data-i18n="general.email")
|
span.control-label(data-i18n="general.email")
|
||||||
- var email = me.get('email') || '';
|
- var email = me.get('email') || '';
|
||||||
input.form-control(name="email" type="email", value=email, disabled=!!email)
|
input.form-control(name="email" type="email", value=email, disabled=!!email)
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="teachers_quote.phone_number")
|
span(data-i18n="teachers_quote.phone_number")
|
||||||
.help-block.small
|
.help-block.small
|
||||||
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
||||||
|
@ -91,7 +88,7 @@ block content
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.primary_role_label")
|
span.control-label(data-i18n="teachers_quote.primary_role_label")
|
||||||
select.form-control(name="role")
|
select.form-control(name="role")
|
||||||
option(data-i18n="teachers_quote.primary_role_default", , value='')
|
option(data-i18n="teachers_quote.primary_role_default", , value='')
|
||||||
option(data-i18n="courses.teacher", value="Teacher")
|
option(data-i18n="courses.teacher", value="Teacher")
|
||||||
|
@ -103,7 +100,7 @@ block content
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.purchaser_role_label")
|
span.control-label(data-i18n="teachers_quote.purchaser_role_label")
|
||||||
select.form-control(name="purchaserRole")
|
select.form-control(name="purchaserRole")
|
||||||
option(data-i18n="teachers_quote.purchaser_role_default", , value='')
|
option(data-i18n="teachers_quote.purchaser_role_default", , value='')
|
||||||
option(data-i18n="teachers_quote.influence_advocate", value="Influence/Advocate")
|
option(data-i18n="teachers_quote.influence_advocate", value="Influence/Advocate")
|
||||||
|
@ -112,33 +109,43 @@ block content
|
||||||
option(data-i18n="teachers_quote.no_purchaser_role", value="No role in purchase decisions")
|
option(data-i18n="teachers_quote.no_purchaser_role", value="No role in purchase decisions")
|
||||||
|
|
||||||
#form-school-info
|
#form-school-info
|
||||||
.row
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.organization_label")
|
span.control-label
|
||||||
|
span(data-i18n="teachers_quote.organization_label")
|
||||||
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
input.form-control#organization-control(name="organization")
|
input.form-control#organization-control(name="organization")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.city")
|
//- TODO: algolia and form errors both change form-control
|
||||||
input.form-control(name="city")
|
//- TODO: District not red on validation error
|
||||||
|
span.control-label.form-control.nullify-form-control(data-i18n="teachers_quote.district_label")
|
||||||
|
input.form-control#district-control(name="district", data-i18n="[placeholder]teachers_quote.district_na")
|
||||||
|
|
||||||
.row
|
.row.m-y-2
|
||||||
.col-md-offset-2.col-md-4.col-sm-6
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="teachers_quote.state")
|
span.control-label(data-i18n="teachers_quote.city")
|
||||||
input.form-control(name="state")
|
input.form-control(name="city")
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-labellabel.control-label(data-i18n="teachers_quote.country")
|
span.control-label(data-i18n="teachers_quote.state")
|
||||||
|
input.form-control(name="state")
|
||||||
|
|
||||||
|
.row.m-y-2
|
||||||
|
.col-md-offset-2.col-md-4.col-sm-6
|
||||||
|
.form-group
|
||||||
|
span.control-labelspan.control-label(data-i18n="teachers_quote.country")
|
||||||
input.form-control(name="country")
|
input.form-control(name="country")
|
||||||
|
|
||||||
#form-students-info
|
#form-students-info
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4
|
.col-md-offset-2.col-md-4
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="courses.number_programming_students")
|
span.control-label(data-i18n="courses.number_programming_students")
|
||||||
.help-block.small
|
.help-block.small
|
||||||
em.text-info(data-i18n="teachers_quote.num_students_help")
|
em.text-info(data-i18n="teachers_quote.num_students_help")
|
||||||
select.form-control(name="numStudents")
|
select.form-control(name="numStudents")
|
||||||
|
@ -153,7 +160,7 @@ block content
|
||||||
|
|
||||||
.col-md-4.col-sm-6
|
.col-md-4.col-sm-6
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="courses.number_total_students")
|
span.control-label(data-i18n="courses.number_total_students")
|
||||||
select.form-control(name="numStudentsTotal")
|
select.form-control(name="numStudentsTotal")
|
||||||
option(data-i18n="teachers_quote.num_students_default", value='')
|
option(data-i18n="teachers_quote.num_students_default", value='')
|
||||||
option 1-500
|
option 1-500
|
||||||
|
@ -163,14 +170,11 @@ block content
|
||||||
option 10,000+
|
option 10,000+
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
|
.row.m-y-2
|
||||||
.row
|
.col-md-offset-2.col-md-4
|
||||||
.col-md-offset-2.col-md-10
|
span.control-label(data-i18n="teachers_quote.education_level_label")
|
||||||
label.control-label(data-i18n="teachers_quote.education_level_label")
|
|
||||||
.help-block.small
|
.help-block.small
|
||||||
em.text-info(data-i18n="teachers_quote.education_level_help")
|
em.text-info(data-i18n="teachers_quote.education_level_help")
|
||||||
|
|
||||||
.col-md-offset-2.col-md-5
|
|
||||||
.checkbox
|
.checkbox
|
||||||
label
|
label
|
||||||
input(type="checkbox" name="educationLevel" value="Elementary")
|
input(type="checkbox" name="educationLevel" value="Elementary")
|
||||||
|
@ -196,7 +200,7 @@ block content
|
||||||
|
|
||||||
#anything-else-row.row
|
#anything-else-row.row
|
||||||
.col-md-offset-2.col-md-8
|
.col-md-offset-2.col-md-8
|
||||||
label.control-label
|
span.control-label
|
||||||
span(data-i18n="teachers_quote.anything_else")
|
span(data-i18n="teachers_quote.anything_else")
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
|
|
||||||
|
@ -210,7 +214,7 @@ block content
|
||||||
input(type="hidden" name="nces_students")
|
input(type="hidden" name="nces_students")
|
||||||
input(type="hidden" name="nces_phone")
|
input(type="hidden" name="nces_phone")
|
||||||
|
|
||||||
#buttons-row.row.text-center
|
#buttons-row.row.m-y-2.text-center
|
||||||
input#submit-request-btn.btn.btn-lg.btn-primary(type="submit" data-i18n="[value]teachers_quote.title")
|
input#submit-request-btn.btn.btn-lg.btn-primary(type="submit" data-i18n="[value]teachers_quote.title")
|
||||||
|
|
||||||
#form-submit-success.text-center(class=showDone ? '' : 'hide')
|
#form-submit-success.text-center(class=showDone ? '' : 'hide')
|
||||||
|
@ -244,17 +248,17 @@ block content
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4
|
.col-md-offset-2.col-md-4
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.username")
|
span.control-label(data-i18n="general.username")
|
||||||
input.form-control(name="name")
|
input.form-control(name="name")
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.col-md-offset-2.col-md-4
|
.col-md-offset-2.col-md-4
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.password")
|
span.control-label(data-i18n="general.password")
|
||||||
input.form-control(name="password1", type="password")
|
input.form-control(name="password1", type="password")
|
||||||
.col-md-4
|
.col-md-4
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(data-i18n="general.confirm_password")
|
span.control-label(data-i18n="general.confirm_password")
|
||||||
input.form-control(name="password2", type="password")
|
input.form-control(name="password2", type="password")
|
||||||
|
|
||||||
.text-center
|
.text-center
|
||||||
|
|
|
@ -7,9 +7,9 @@ errors = require 'core/errors'
|
||||||
User = require 'models/User'
|
User = require 'models/User'
|
||||||
ConfirmModal = require 'views/editor/modal/ConfirmModal'
|
ConfirmModal = require 'views/editor/modal/ConfirmModal'
|
||||||
algolia = require 'core/services/algolia'
|
algolia = require 'core/services/algolia'
|
||||||
NCES_KEYS = ['id', 'name', 'district', 'district_id', 'district_schools', 'district_students', 'students', 'phone']
|
|
||||||
|
|
||||||
FORM_KEY = 'request-quote-form'
|
DISTRICT_NCES_KEYS = ['district', 'district_id', 'district_schools', 'district_students', 'phone']
|
||||||
|
SCHOOL_NCES_KEYS = DISTRICT_NCES_KEYS.concat(['id', 'name', 'students'])
|
||||||
|
|
||||||
module.exports = class ConvertToTeacherAccountView extends RootView
|
module.exports = class ConvertToTeacherAccountView extends RootView
|
||||||
id: 'convert-to-teacher-account-view'
|
id: 'convert-to-teacher-account-view'
|
||||||
|
@ -40,7 +40,7 @@ module.exports = class ConvertToTeacherAccountView extends RootView
|
||||||
return 'Your account has not been updated! If you continue, your changes will be lost.'
|
return 'Your account has not been updated! If you continue, your changes will be lost.'
|
||||||
|
|
||||||
invalidateNCES: ->
|
invalidateNCES: ->
|
||||||
for key in NCES_KEYS
|
for key in SCHOOL_NCES_KEYS
|
||||||
@$('input[name="nces_' + key + '"]').val ''
|
@$('input[name="nces_' + key + '"]').val ''
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
|
@ -75,16 +75,34 @@ module.exports = class ConvertToTeacherAccountView extends RootView
|
||||||
"<div class='school'> #{hr.name.value} </div>" +
|
"<div class='school'> #{hr.name.value} </div>" +
|
||||||
"<div class='district'>#{hr.district.value}, " +
|
"<div class='district'>#{hr.district.value}, " +
|
||||||
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
||||||
|
|
||||||
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
||||||
|
@$('input[name="district"]').val suggestion.district
|
||||||
@$('input[name="city"]').val suggestion.city
|
@$('input[name="city"]').val suggestion.city
|
||||||
@$('input[name="state"]').val suggestion.state
|
@$('input[name="state"]').val suggestion.state
|
||||||
@$('input[name="district"]').val suggestion.district
|
|
||||||
@$('input[name="country"]').val 'USA'
|
@$('input[name="country"]').val 'USA'
|
||||||
|
for key in SCHOOL_NCES_KEYS
|
||||||
for key in NCES_KEYS
|
|
||||||
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
||||||
|
@onChangeForm()
|
||||||
|
|
||||||
|
$("#district-control").algolia_autocomplete({hint: false}, [
|
||||||
|
source: (query, callback) ->
|
||||||
|
algolia.schoolsIndex.search(query, { hitsPerPage: 5, aroundLatLngViaIP: false }).then (answer) ->
|
||||||
|
callback answer.hits
|
||||||
|
, ->
|
||||||
|
callback []
|
||||||
|
displayKey: 'district',
|
||||||
|
templates:
|
||||||
|
suggestion: (suggestion) ->
|
||||||
|
hr = suggestion._highlightResult
|
||||||
|
"<div class='district'>#{hr.district.value}, " +
|
||||||
|
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
||||||
|
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
||||||
|
@$('input[name="organization"]').val '' # TODO: does not persist on tabbing: back to school, back to district
|
||||||
|
@$('input[name="city"]').val suggestion.city
|
||||||
|
@$('input[name="state"]').val suggestion.state
|
||||||
|
@$('input[name="country"]').val 'USA'
|
||||||
|
for key in DISTRICT_NCES_KEYS
|
||||||
|
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
||||||
@onChangeForm()
|
@onChangeForm()
|
||||||
|
|
||||||
onChangeForm: ->
|
onChangeForm: ->
|
||||||
|
@ -97,28 +115,35 @@ module.exports = class ConvertToTeacherAccountView extends RootView
|
||||||
|
|
||||||
form = @$('form')
|
form = @$('form')
|
||||||
attrs = forms.formToObject(form)
|
attrs = forms.formToObject(form)
|
||||||
|
trialRequestAttrs = _.cloneDeep(attrs)
|
||||||
|
|
||||||
|
# Don't save n/a district entries, but do validate required district client-side
|
||||||
|
trialRequestAttrs = _.omit(trialRequestAttrs, 'district') if trialRequestAttrs.district?.replace(/\s/ig, '').match(/n\/a/ig)
|
||||||
|
|
||||||
if @$('#other-education-level-checkbox').is(':checked')
|
if @$('#other-education-level-checkbox').is(':checked')
|
||||||
val = @$('#other-education-level-input').val()
|
val = @$('#other-education-level-input').val()
|
||||||
attrs.educationLevel.push(val) if val
|
trialRequestAttrs.educationLevel.push(val) if val
|
||||||
|
|
||||||
forms.clearFormAlerts(form)
|
forms.clearFormAlerts(form)
|
||||||
|
|
||||||
result = tv4.validateMultiple(attrs, formSchema)
|
result = tv4.validateMultiple(trialRequestAttrs, formSchema)
|
||||||
error = false
|
error = false
|
||||||
if not result.valid
|
if not result.valid
|
||||||
forms.applyErrorsToForm(form, result.errors)
|
forms.applyErrorsToForm(form, result.errors)
|
||||||
error = true
|
error = true
|
||||||
if not _.size(attrs.educationLevel)
|
if not _.size(trialRequestAttrs.educationLevel)
|
||||||
forms.setErrorToProperty(form, 'educationLevel', 'Include at least one.')
|
forms.setErrorToProperty(form, 'educationLevel', 'include at least one')
|
||||||
|
error = true
|
||||||
|
unless attrs.district
|
||||||
|
forms.setErrorToProperty(form, 'district', $.i18n.t('common.required_field'))
|
||||||
error = true
|
error = true
|
||||||
if error
|
if error
|
||||||
forms.scrollToFirstError()
|
forms.scrollToFirstError()
|
||||||
return
|
return
|
||||||
attrs['siteOrigin'] = 'convert teacher'
|
trialRequestAttrs['siteOrigin'] = 'convert teacher'
|
||||||
@trialRequest = new TrialRequest({
|
@trialRequest = new TrialRequest({
|
||||||
type: 'course'
|
type: 'course'
|
||||||
properties: attrs
|
properties: trialRequestAttrs
|
||||||
})
|
})
|
||||||
if me.get('role') is 'student' and not me.isAnonymous()
|
if me.get('role') is 'student' and not me.isAnonymous()
|
||||||
modal = new ConfirmModal({
|
modal = new ConfirmModal({
|
||||||
|
@ -151,15 +176,14 @@ module.exports = class ConvertToTeacherAccountView extends RootView
|
||||||
|
|
||||||
formSchema = {
|
formSchema = {
|
||||||
type: 'object'
|
type: 'object'
|
||||||
required: [
|
required: ['firstName', 'lastName', 'role', 'numStudents', 'city', 'state', 'country']
|
||||||
'firstName', 'lastName', 'organization', 'role', 'numStudents', 'city', 'state', 'country'
|
|
||||||
]
|
|
||||||
properties:
|
properties:
|
||||||
firstName: { type: 'string' }
|
firstName: { type: 'string' }
|
||||||
lastName: { type: 'string' }
|
lastName: { type: 'string' }
|
||||||
phoneNumber: { type: 'string' }
|
phoneNumber: { type: 'string' }
|
||||||
role: { type: 'string' }
|
role: { type: 'string' }
|
||||||
organization: { type: 'string' }
|
organization: { type: 'string' }
|
||||||
|
district: { type: 'string' }
|
||||||
city: { type: 'string' }
|
city: { type: 'string' }
|
||||||
state: { type: 'string' }
|
state: { type: 'string' }
|
||||||
country: { type: 'string' }
|
country: { type: 'string' }
|
||||||
|
@ -172,5 +196,5 @@ formSchema = {
|
||||||
notes: { type: 'string' }
|
notes: { type: 'string' }
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in NCES_KEYS
|
for key in SCHOOL_NCES_KEYS
|
||||||
formSchema['nces_' + key] = type: 'string'
|
formSchema['nces_' + key] = type: 'string'
|
||||||
|
|
|
@ -7,9 +7,9 @@ errors = require 'core/errors'
|
||||||
User = require 'models/User'
|
User = require 'models/User'
|
||||||
algolia = require 'core/services/algolia'
|
algolia = require 'core/services/algolia'
|
||||||
|
|
||||||
FORM_KEY = 'request-quote-form'
|
|
||||||
SIGNUP_REDIRECT = '/teachers/classes'
|
SIGNUP_REDIRECT = '/teachers/classes'
|
||||||
NCES_KEYS = ['id', 'name', 'district', 'district_id', 'district_schools', 'district_students', 'students', 'phone']
|
DISTRICT_NCES_KEYS = ['district', 'district_id', 'district_schools', 'district_students', 'phone']
|
||||||
|
SCHOOL_NCES_KEYS = DISTRICT_NCES_KEYS.concat(['id', 'name', 'students'])
|
||||||
|
|
||||||
module.exports = class CreateTeacherAccountView extends RootView
|
module.exports = class CreateTeacherAccountView extends RootView
|
||||||
id: 'create-teacher-account-view'
|
id: 'create-teacher-account-view'
|
||||||
|
@ -43,7 +43,7 @@ module.exports = class CreateTeacherAccountView extends RootView
|
||||||
super()
|
super()
|
||||||
|
|
||||||
invalidateNCES: ->
|
invalidateNCES: ->
|
||||||
for key in NCES_KEYS
|
for key in SCHOOL_NCES_KEYS
|
||||||
@$('input[name="nces_' + key + '"]').val ''
|
@$('input[name="nces_' + key + '"]').val ''
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
|
@ -72,16 +72,34 @@ module.exports = class CreateTeacherAccountView extends RootView
|
||||||
"<div class='school'> #{hr.name.value} </div>" +
|
"<div class='school'> #{hr.name.value} </div>" +
|
||||||
"<div class='district'>#{hr.district.value}, " +
|
"<div class='district'>#{hr.district.value}, " +
|
||||||
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
||||||
|
|
||||||
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
||||||
|
@$('input[name="district"]').val suggestion.district
|
||||||
@$('input[name="city"]').val suggestion.city
|
@$('input[name="city"]').val suggestion.city
|
||||||
@$('input[name="state"]').val suggestion.state
|
@$('input[name="state"]').val suggestion.state
|
||||||
@$('input[name="district"]').val suggestion.district
|
|
||||||
@$('input[name="country"]').val 'USA'
|
@$('input[name="country"]').val 'USA'
|
||||||
|
for key in SCHOOL_NCES_KEYS
|
||||||
for key in NCES_KEYS
|
|
||||||
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
||||||
|
@onChangeForm()
|
||||||
|
|
||||||
|
$("#district-control").algolia_autocomplete({hint: false}, [
|
||||||
|
source: (query, callback) ->
|
||||||
|
algolia.schoolsIndex.search(query, { hitsPerPage: 5, aroundLatLngViaIP: false }).then (answer) ->
|
||||||
|
callback answer.hits
|
||||||
|
, ->
|
||||||
|
callback []
|
||||||
|
displayKey: 'district',
|
||||||
|
templates:
|
||||||
|
suggestion: (suggestion) ->
|
||||||
|
hr = suggestion._highlightResult
|
||||||
|
"<div class='district'>#{hr.district.value}, " +
|
||||||
|
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
||||||
|
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
||||||
|
@$('input[name="organization"]').val '' # TODO: does not persist on tabbing: back to school, back to district
|
||||||
|
@$('input[name="city"]').val suggestion.city
|
||||||
|
@$('input[name="state"]').val suggestion.state
|
||||||
|
@$('input[name="country"]').val 'USA'
|
||||||
|
for key in DISTRICT_NCES_KEYS
|
||||||
|
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
||||||
@onChangeForm()
|
@onChangeForm()
|
||||||
|
|
||||||
onClickLoginLink: ->
|
onClickLoginLink: ->
|
||||||
|
@ -101,6 +119,9 @@ module.exports = class CreateTeacherAccountView extends RootView
|
||||||
allAttrs = forms.formToObject(form)
|
allAttrs = forms.formToObject(form)
|
||||||
trialRequestAttrs = _.omit(allAttrs, 'name', 'password1', 'password2')
|
trialRequestAttrs = _.omit(allAttrs, 'name', 'password1', 'password2')
|
||||||
|
|
||||||
|
# Don't save n/a district entries, but do validate required district client-side
|
||||||
|
trialRequestAttrs = _.omit(trialRequestAttrs, 'district') if trialRequestAttrs.district?.replace(/\s/ig, '').match(/n\/a/ig)
|
||||||
|
|
||||||
if @$('#other-education-level-checkbox').is(':checked')
|
if @$('#other-education-level-checkbox').is(':checked')
|
||||||
val = @$('#other-education-level-input').val()
|
val = @$('#other-education-level-input').val()
|
||||||
trialRequestAttrs.educationLevel.push(val) if val
|
trialRequestAttrs.educationLevel.push(val) if val
|
||||||
|
@ -112,18 +133,21 @@ module.exports = class CreateTeacherAccountView extends RootView
|
||||||
if not result.valid
|
if not result.valid
|
||||||
forms.applyErrorsToForm(form, result.errors)
|
forms.applyErrorsToForm(form, result.errors)
|
||||||
error = true
|
error = true
|
||||||
if not forms.validateEmail(trialRequestAttrs.email)
|
if not error and not forms.validateEmail(trialRequestAttrs.email)
|
||||||
forms.setErrorToProperty(form, 'email', 'Invalid email.')
|
forms.setErrorToProperty(form, 'email', 'invalid email')
|
||||||
error = true
|
error = true
|
||||||
if not _.size(trialRequestAttrs.educationLevel)
|
if not _.size(trialRequestAttrs.educationLevel)
|
||||||
forms.setErrorToProperty(form, 'educationLevel', 'Include at least one.')
|
forms.setErrorToProperty(form, 'educationLevel', 'include at least one')
|
||||||
|
error = true
|
||||||
|
unless allAttrs.district
|
||||||
|
forms.setErrorToProperty(form, 'district', $.i18n.t('common.required_field'))
|
||||||
error = true
|
error = true
|
||||||
unless @gplusAttrs or @facebookAttrs
|
unless @gplusAttrs or @facebookAttrs
|
||||||
if not allAttrs.password1
|
if not allAttrs.password1
|
||||||
forms.setErrorToProperty(form, 'password1', 'Required field')
|
forms.setErrorToProperty(form, 'password1', $.i18n.t('common.required_field'))
|
||||||
error = true
|
error = true
|
||||||
else if not allAttrs.password2
|
else if not allAttrs.password2
|
||||||
forms.setErrorToProperty(form, 'password2', 'Required field')
|
forms.setErrorToProperty(form, 'password2', $.i18n.t('common.required_field'))
|
||||||
error = true
|
error = true
|
||||||
else if allAttrs.password1 isnt allAttrs.password2
|
else if allAttrs.password1 isnt allAttrs.password2
|
||||||
forms.setErrorToProperty(form, 'password1', 'Password fields are not equivalent')
|
forms.setErrorToProperty(form, 'password1', 'Password fields are not equivalent')
|
||||||
|
@ -225,7 +249,6 @@ module.exports = class CreateTeacherAccountView extends RootView
|
||||||
@$('input[type="password"]').attr('disabled', true)
|
@$('input[type="password"]').attr('disabled', true)
|
||||||
@$('#gplus-logged-in-row, #social-network-signups').toggleClass('hide')
|
@$('#gplus-logged-in-row, #social-network-signups').toggleClass('hide')
|
||||||
|
|
||||||
|
|
||||||
# Facebook signup
|
# Facebook signup
|
||||||
|
|
||||||
onClickFacebookSignupButton: ->
|
onClickFacebookSignupButton: ->
|
||||||
|
@ -269,13 +292,9 @@ module.exports = class CreateTeacherAccountView extends RootView
|
||||||
@$('#facebook-logged-in-row, #social-network-signups').toggleClass('hide')
|
@$('#facebook-logged-in-row, #social-network-signups').toggleClass('hide')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
formSchema = {
|
formSchema = {
|
||||||
type: 'object'
|
type: 'object'
|
||||||
required: [
|
required: ['firstName', 'lastName', 'email', 'role', 'numStudents', 'city', 'state', 'country']
|
||||||
'firstName', 'lastName', 'email', 'organization', 'role', 'numStudents', 'city'
|
|
||||||
'state', 'country'
|
|
||||||
]
|
|
||||||
properties:
|
properties:
|
||||||
password1: { type: 'string' }
|
password1: { type: 'string' }
|
||||||
password2: { type: 'string' }
|
password2: { type: 'string' }
|
||||||
|
@ -286,6 +305,7 @@ formSchema = {
|
||||||
phoneNumber: { type: 'string' }
|
phoneNumber: { type: 'string' }
|
||||||
role: { type: 'string' }
|
role: { type: 'string' }
|
||||||
organization: { type: 'string' }
|
organization: { type: 'string' }
|
||||||
|
district: { type: 'string' }
|
||||||
city: { type: 'string' }
|
city: { type: 'string' }
|
||||||
state: { type: 'string' }
|
state: { type: 'string' }
|
||||||
country: { type: 'string' }
|
country: { type: 'string' }
|
||||||
|
@ -298,5 +318,5 @@ formSchema = {
|
||||||
notes: { type: 'string' }
|
notes: { type: 'string' }
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in NCES_KEYS
|
for key in SCHOOL_NCES_KEYS
|
||||||
formSchema['nces_' + key] = type: 'string'
|
formSchema['nces_' + key] = type: 'string'
|
||||||
|
|
|
@ -8,7 +8,8 @@ ConfirmModal = require 'views/editor/modal/ConfirmModal'
|
||||||
algolia = require 'core/services/algolia'
|
algolia = require 'core/services/algolia'
|
||||||
|
|
||||||
SIGNUP_REDIRECT = '/teachers'
|
SIGNUP_REDIRECT = '/teachers'
|
||||||
NCES_KEYS = ['id', 'name', 'district', 'district_id', 'district_schools', 'district_students', 'students', 'phone']
|
DISTRICT_NCES_KEYS = ['district', 'district_id', 'district_schools', 'district_students', 'phone']
|
||||||
|
SCHOOL_NCES_KEYS = DISTRICT_NCES_KEYS.concat(['id', 'name', 'students'])
|
||||||
|
|
||||||
module.exports = class RequestQuoteView extends RootView
|
module.exports = class RequestQuoteView extends RootView
|
||||||
id: 'request-quote-view'
|
id: 'request-quote-view'
|
||||||
|
@ -46,7 +47,7 @@ module.exports = class RequestQuoteView extends RootView
|
||||||
super()
|
super()
|
||||||
|
|
||||||
invalidateNCES: ->
|
invalidateNCES: ->
|
||||||
for key in NCES_KEYS
|
for key in SCHOOL_NCES_KEYS
|
||||||
@$('input[name="nces_' + key + '"]').val ''
|
@$('input[name="nces_' + key + '"]').val ''
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
|
@ -75,16 +76,34 @@ module.exports = class RequestQuoteView extends RootView
|
||||||
"<div class='school'> #{hr.name.value} </div>" +
|
"<div class='school'> #{hr.name.value} </div>" +
|
||||||
"<div class='district'>#{hr.district.value}, " +
|
"<div class='district'>#{hr.district.value}, " +
|
||||||
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
||||||
|
|
||||||
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
||||||
|
@$('input[name="district"]').val suggestion.district
|
||||||
@$('input[name="city"]').val suggestion.city
|
@$('input[name="city"]').val suggestion.city
|
||||||
@$('input[name="state"]').val suggestion.state
|
@$('input[name="state"]').val suggestion.state
|
||||||
@$('input[name="district"]').val suggestion.district
|
|
||||||
@$('input[name="country"]').val 'USA'
|
@$('input[name="country"]').val 'USA'
|
||||||
|
for key in SCHOOL_NCES_KEYS
|
||||||
for key in NCES_KEYS
|
|
||||||
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
||||||
|
@onChangeRequestForm()
|
||||||
|
|
||||||
|
$("#district-control").algolia_autocomplete({hint: false}, [
|
||||||
|
source: (query, callback) ->
|
||||||
|
algolia.schoolsIndex.search(query, { hitsPerPage: 5, aroundLatLngViaIP: false }).then (answer) ->
|
||||||
|
callback answer.hits
|
||||||
|
, ->
|
||||||
|
callback []
|
||||||
|
displayKey: 'district',
|
||||||
|
templates:
|
||||||
|
suggestion: (suggestion) ->
|
||||||
|
hr = suggestion._highlightResult
|
||||||
|
"<div class='district'>#{hr.district.value}, " +
|
||||||
|
"<span>#{hr.city?.value}, #{hr.state.value}</span></div>"
|
||||||
|
]).on 'autocomplete:selected', (event, suggestion, dataset) =>
|
||||||
|
@$('input[name="organization"]').val '' # TODO: does not persist on tabbing: back to school, back to district
|
||||||
|
@$('input[name="city"]').val suggestion.city
|
||||||
|
@$('input[name="state"]').val suggestion.state
|
||||||
|
@$('input[name="country"]').val 'USA'
|
||||||
|
for key in DISTRICT_NCES_KEYS
|
||||||
|
@$('input[name="nces_' + key + '"]').val suggestion[key]
|
||||||
@onChangeRequestForm()
|
@onChangeRequestForm()
|
||||||
|
|
||||||
onChangeRequestForm: ->
|
onChangeRequestForm: ->
|
||||||
|
@ -96,32 +115,39 @@ module.exports = class RequestQuoteView extends RootView
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
form = @$('#request-form')
|
form = @$('#request-form')
|
||||||
attrs = forms.formToObject(form)
|
attrs = forms.formToObject(form)
|
||||||
|
trialRequestAttrs = _.cloneDeep(attrs)
|
||||||
|
|
||||||
|
# Don't save n/a district entries, but do validate required district client-side
|
||||||
|
trialRequestAttrs = _.omit(trialRequestAttrs, 'district') if trialRequestAttrs.district?.replace(/\s/ig, '').match(/n\/a/ig)
|
||||||
|
|
||||||
# custom other input logic
|
# custom other input logic
|
||||||
if @$('#other-education-level-checkbox').is(':checked')
|
if @$('#other-education-level-checkbox').is(':checked')
|
||||||
val = @$('#other-education-level-input').val()
|
val = @$('#other-education-level-input').val()
|
||||||
attrs.educationLevel.push(val) if val
|
trialRequestAttrs.educationLevel.push(val) if val
|
||||||
|
|
||||||
forms.clearFormAlerts(form)
|
forms.clearFormAlerts(form)
|
||||||
requestFormSchema = if me.isAnonymous() then requestFormSchemaAnonymous else requestFormSchemaLoggedIn
|
requestFormSchema = if me.isAnonymous() then requestFormSchemaAnonymous else requestFormSchemaLoggedIn
|
||||||
result = tv4.validateMultiple(attrs, requestFormSchemaAnonymous)
|
result = tv4.validateMultiple(trialRequestAttrs, requestFormSchemaAnonymous)
|
||||||
error = false
|
error = false
|
||||||
if not result.valid
|
if not result.valid
|
||||||
forms.applyErrorsToForm(form, result.errors)
|
forms.applyErrorsToForm(form, result.errors)
|
||||||
error = true
|
error = true
|
||||||
if not forms.validateEmail(attrs.email)
|
if not error and not forms.validateEmail(trialRequestAttrs.email)
|
||||||
forms.setErrorToProperty(form, 'email', 'Invalid email.')
|
forms.setErrorToProperty(form, 'email', 'invalid email')
|
||||||
error = true
|
error = true
|
||||||
if not _.size(attrs.educationLevel)
|
if not _.size(trialRequestAttrs.educationLevel)
|
||||||
forms.setErrorToProperty(form, 'educationLevel', 'Include at least one.')
|
forms.setErrorToProperty(form, 'educationLevel', 'include at least one')
|
||||||
|
error = true
|
||||||
|
unless attrs.district
|
||||||
|
forms.setErrorToProperty(form, 'district', $.i18n.t('common.required_field'))
|
||||||
error = true
|
error = true
|
||||||
if error
|
if error
|
||||||
forms.scrollToFirstError()
|
forms.scrollToFirstError()
|
||||||
return
|
return
|
||||||
attrs['siteOrigin'] = 'demo request'
|
trialRequestAttrs['siteOrigin'] = 'demo request'
|
||||||
@trialRequest = new TrialRequest({
|
@trialRequest = new TrialRequest({
|
||||||
type: 'course'
|
type: 'course'
|
||||||
properties: attrs
|
properties: trialRequestAttrs
|
||||||
})
|
})
|
||||||
if me.get('role') is 'student' and not me.isAnonymous()
|
if me.get('role') is 'student' and not me.isAnonymous()
|
||||||
modal = new ConfirmModal({
|
modal = new ConfirmModal({
|
||||||
|
@ -262,7 +288,7 @@ module.exports = class RequestQuoteView extends RootView
|
||||||
requestFormSchemaAnonymous = {
|
requestFormSchemaAnonymous = {
|
||||||
type: 'object'
|
type: 'object'
|
||||||
required: [
|
required: [
|
||||||
'firstName', 'lastName', 'email', 'organization', 'role', 'purchaserRole', 'numStudents',
|
'firstName', 'lastName', 'email', 'role', 'purchaserRole', 'numStudents',
|
||||||
'numStudentsTotal', 'phoneNumber', 'city', 'state', 'country']
|
'numStudentsTotal', 'phoneNumber', 'city', 'state', 'country']
|
||||||
properties:
|
properties:
|
||||||
firstName: { type: 'string' }
|
firstName: { type: 'string' }
|
||||||
|
@ -273,6 +299,7 @@ requestFormSchemaAnonymous = {
|
||||||
role: { type: 'string' }
|
role: { type: 'string' }
|
||||||
purchaserRole: { type: 'string' }
|
purchaserRole: { type: 'string' }
|
||||||
organization: { type: 'string' }
|
organization: { type: 'string' }
|
||||||
|
district: { type: 'string' }
|
||||||
city: { type: 'string' }
|
city: { type: 'string' }
|
||||||
state: { type: 'string' }
|
state: { type: 'string' }
|
||||||
country: { type: 'string' }
|
country: { type: 'string' }
|
||||||
|
@ -285,7 +312,7 @@ requestFormSchemaAnonymous = {
|
||||||
notes: { type: 'string' },
|
notes: { type: 'string' },
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in NCES_KEYS
|
for key in SCHOOL_NCES_KEYS
|
||||||
requestFormSchemaAnonymous['nces_' + key] = type: 'string'
|
requestFormSchemaAnonymous['nces_' + key] = type: 'string'
|
||||||
|
|
||||||
# same form, but add username input
|
# same form, but add username input
|
||||||
|
|
|
@ -34,7 +34,8 @@ module.exports = class TeachersContactModal extends ModalView
|
||||||
message = """
|
message = """
|
||||||
Hi CodeCombat! I want to learn more about the Classroom experience and get licenses so that my students can access Computer Science 2 and on.
|
Hi CodeCombat! I want to learn more about the Classroom experience and get licenses so that my students can access Computer Science 2 and on.
|
||||||
|
|
||||||
Name of School/District: #{props.organization or ''}
|
Name of School #{props.nces_name or props.organization or ''}
|
||||||
|
Name of District: #{props.nces_district or props.district or ''}
|
||||||
Role: #{props.role or ''}
|
Role: #{props.role or ''}
|
||||||
Phone Number: #{props.phoneNumber or ''}
|
Phone Number: #{props.phoneNumber or ''}
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -16,7 +16,7 @@ if (process.argv.length !== 10) {
|
||||||
// TODO: Cleanup country/status lookup code
|
// TODO: Cleanup country/status lookup code
|
||||||
|
|
||||||
// Save as custom fields instead of user-specific lead notes (also saving nces_ props)
|
// Save as custom fields instead of user-specific lead notes (also saving nces_ props)
|
||||||
const commonTrialProperties = ['organization', 'city', 'state', 'country'];
|
const commonTrialProperties = ['organization', 'district', 'city', 'state', 'country'];
|
||||||
|
|
||||||
// Old properties which are deprecated or moved
|
// Old properties which are deprecated or moved
|
||||||
const customFieldsToRemove = [
|
const customFieldsToRemove = [
|
||||||
|
@ -327,7 +327,7 @@ function findCocoLeads(done) {
|
||||||
if (!trialRequest.properties || !trialRequest.properties.email) continue;
|
if (!trialRequest.properties || !trialRequest.properties.email) continue;
|
||||||
const email = trialRequest.properties.email.toLowerCase();
|
const email = trialRequest.properties.email.toLowerCase();
|
||||||
emails.push(email);
|
emails.push(email);
|
||||||
const name = trialRequest.properties.nces_name || trialRequest.properties.organization || trialRequest.properties.school || email;
|
const name = trialRequest.properties.nces_name || trialRequest.properties.organization || trialRequest.properties.school || trialRequest.properties.district || trialRequest.properties.nces_district || email;
|
||||||
if (!leads[name]) leads[name] = new CocoLead(name);
|
if (!leads[name]) leads[name] = new CocoLead(name);
|
||||||
leads[name].addTrialRequest(email, trialRequest);
|
leads[name].addTrialRequest(email, trialRequest);
|
||||||
emailLeadMap[email] = leads[name];
|
emailLeadMap[email] = leads[name];
|
||||||
|
|
|
@ -138,7 +138,7 @@ module.exports =
|
||||||
trialRequests = yield TrialRequest.find({$and: [{type: 'course'}, {applicant: {$in: userIDs}}]}, {applicant: 1, properties: 1}).lean()
|
trialRequests = yield TrialRequest.find({$and: [{type: 'course'}, {applicant: {$in: userIDs}}]}, {applicant: 1, properties: 1}).lean()
|
||||||
schoolPrepaidsMap = {}
|
schoolPrepaidsMap = {}
|
||||||
for trialRequest in trialRequests
|
for trialRequest in trialRequests
|
||||||
school = trialRequest.properties?.organization ? trialRequest.properties?.school
|
school = trialRequest.properties?.nces_name ? trialRequest.properties?.organization ? trialRequest.properties?.school
|
||||||
continue unless school
|
continue unless school
|
||||||
if userPrepaidsMap[trialRequest.applicant.valueOf()]?.length > 0
|
if userPrepaidsMap[trialRequest.applicant.valueOf()]?.length > 0
|
||||||
schoolPrepaidsMap[school] ?= []
|
schoolPrepaidsMap[school] ?= []
|
||||||
|
|
|
@ -184,6 +184,7 @@ module.exports = {
|
||||||
email: 'an@email.com'
|
email: 'an@email.com'
|
||||||
phoneNumber: '555-555-5555'
|
phoneNumber: '555-555-5555'
|
||||||
organization: 'Greendale'
|
organization: 'Greendale'
|
||||||
|
district: 'Green District'
|
||||||
}
|
}
|
||||||
}, attrs)
|
}, attrs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ describe 'ConvertToTeacherAccountView (/teachers/update-account)', ->
|
||||||
phoneNumber: '555-555-5555'
|
phoneNumber: '555-555-5555'
|
||||||
role: 'Teacher'
|
role: 'Teacher'
|
||||||
organization: 'School'
|
organization: 'School'
|
||||||
|
district: 'District'
|
||||||
city: 'Springfield'
|
city: 'Springfield'
|
||||||
state: 'AA'
|
state: 'AA'
|
||||||
country: 'asdf'
|
country: 'asdf'
|
||||||
|
@ -168,3 +169,48 @@ describe 'ConvertToTeacherAccountView (/teachers/update-account)', ->
|
||||||
})
|
})
|
||||||
expect(me.get('role')).toBe(successForm.role.toLowerCase())
|
expect(me.get('role')).toBe(successForm.role.toLowerCase())
|
||||||
|
|
||||||
|
describe 'submitting the form without school', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('form')
|
||||||
|
formData = _.omit(successForm, ['organization'])
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'submits a trial request, which does not include school setting', ->
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.url).toBe('/db/trial.request')
|
||||||
|
expect(request.method).toBe('POST')
|
||||||
|
attrs = JSON.parse(request.params)
|
||||||
|
expect(attrs.properties?.organization).toBeUndefined()
|
||||||
|
expect(attrs.properties?.district).toEqual('District')
|
||||||
|
|
||||||
|
describe 'submitting the form without district', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('form')
|
||||||
|
formData = _.omit(successForm, ['district'])
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'displays a validation error on district and not school', ->
|
||||||
|
expect(view.$('#organization-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
expect(view.$('#district-control').parent().hasClass('has-error')).toEqual(true)
|
||||||
|
|
||||||
|
describe 'submitting the form district set to n/a', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('form')
|
||||||
|
formData = _.omit(successForm, ['organization'])
|
||||||
|
formData.district = 'N/A'
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'submits a trial request, which does not include district setting', ->
|
||||||
|
expect(view.$('#organization-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
expect(view.$('#district-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.url).toBe('/db/trial.request')
|
||||||
|
expect(request.method).toBe('POST')
|
||||||
|
attrs = JSON.parse(request.params)
|
||||||
|
expect(attrs.properties?.district).toBeUndefined()
|
||||||
|
|
|
@ -33,6 +33,7 @@ describe 'CreateTeacherAccountView', ->
|
||||||
phoneNumber: '555-555-5555'
|
phoneNumber: '555-555-5555'
|
||||||
role: 'Teacher'
|
role: 'Teacher'
|
||||||
organization: 'School'
|
organization: 'School'
|
||||||
|
district: 'District'
|
||||||
city: 'Springfield'
|
city: 'Springfield'
|
||||||
state: 'AA'
|
state: 'AA'
|
||||||
country: 'asdf'
|
country: 'asdf'
|
||||||
|
@ -219,6 +220,8 @@ describe 'CreateTeacherAccountView', ->
|
||||||
expect(attrs.password2).toBeUndefined()
|
expect(attrs.password2).toBeUndefined()
|
||||||
expect(attrs.name).toBeUndefined()
|
expect(attrs.name).toBeUndefined()
|
||||||
expect(attrs.properties?.siteOrigin).toBe('create teacher')
|
expect(attrs.properties?.siteOrigin).toBe('create teacher')
|
||||||
|
expect(attrs.properties?.organization).toEqual('School')
|
||||||
|
expect(attrs.properties?.district).toEqual('District')
|
||||||
|
|
||||||
describe 'after saving the new trial request', ->
|
describe 'after saving the new trial request', ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
@ -267,4 +270,48 @@ describe 'CreateTeacherAccountView', ->
|
||||||
view.$('#email-form-group .login-link').click()
|
view.$('#email-form-group .login-link').click()
|
||||||
expect(view.openModalView).toHaveBeenCalled()
|
expect(view.openModalView).toHaveBeenCalled()
|
||||||
|
|
||||||
|
describe 'submitting the form without school', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('form')
|
||||||
|
formData = _.omit(successForm, ['organization'])
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'submits a trial request, which does not include school setting', ->
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.url).toBe('/db/trial.request')
|
||||||
|
expect(request.method).toBe('POST')
|
||||||
|
attrs = JSON.parse(request.params)
|
||||||
|
expect(attrs.properties?.organization).toBeUndefined()
|
||||||
|
expect(attrs.properties?.district).toEqual('District')
|
||||||
|
|
||||||
|
describe 'submitting the form without district', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('form')
|
||||||
|
formData = _.omit(successForm, ['district'])
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'displays a validation error on district and not school', ->
|
||||||
|
expect(view.$('#organization-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
expect(view.$('#district-control').parent().hasClass('has-error')).toEqual(true)
|
||||||
|
|
||||||
|
describe 'submitting the form district set to n/a', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('form')
|
||||||
|
formData = _.omit(successForm, ['organization'])
|
||||||
|
formData.district = 'N/A'
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'submits a trial request, which does not include district setting', ->
|
||||||
|
expect(view.$('#organization-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
expect(view.$('#district-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.url).toBe('/db/trial.request')
|
||||||
|
expect(request.method).toBe('POST')
|
||||||
|
attrs = JSON.parse(request.params)
|
||||||
|
expect(attrs.properties?.district).toBeUndefined()
|
||||||
|
|
|
@ -5,13 +5,14 @@ describe 'RequestQuoteView', ->
|
||||||
|
|
||||||
view = null
|
view = null
|
||||||
|
|
||||||
successFormValues = {
|
successForm = {
|
||||||
firstName: 'A'
|
firstName: 'A'
|
||||||
lastName: 'B'
|
lastName: 'B'
|
||||||
email: 'C@D.com'
|
email: 'C@D.com'
|
||||||
phoneNumber: '555-555-5555'
|
phoneNumber: '555-555-5555'
|
||||||
role: 'Teacher'
|
role: 'Teacher'
|
||||||
organization: 'School'
|
organization: 'School'
|
||||||
|
district: 'District'
|
||||||
city: 'Springfield'
|
city: 'Springfield'
|
||||||
state: 'AA'
|
state: 'AA'
|
||||||
country: 'asdf'
|
country: 'asdf'
|
||||||
|
@ -23,7 +24,7 @@ describe 'RequestQuoteView', ->
|
||||||
|
|
||||||
isSubmitRequest = (r) -> _.string.startsWith(r.url, '/db/trial.request') and r.method is 'POST'
|
isSubmitRequest = (r) -> _.string.startsWith(r.url, '/db/trial.request') and r.method is 'POST'
|
||||||
|
|
||||||
describe 'when user is anonymous and has an existing trial request', ->
|
describe 'when an anonymous user', ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
me.clear()
|
me.clear()
|
||||||
me.set('_id', '1234')
|
me.set('_id', '1234')
|
||||||
|
@ -32,7 +33,10 @@ describe 'RequestQuoteView', ->
|
||||||
view = new RequestQuoteView()
|
view = new RequestQuoteView()
|
||||||
view.render()
|
view.render()
|
||||||
jasmine.demoEl(view.$el)
|
jasmine.demoEl(view.$el)
|
||||||
|
_.defer done # Let SuperModel finish
|
||||||
|
|
||||||
|
describe 'has an existing trial request', ->
|
||||||
|
beforeEach (done) ->
|
||||||
request = jasmine.Ajax.requests.mostRecent()
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
request.respondWith({
|
request.respondWith({
|
||||||
status: 200
|
status: 200
|
||||||
|
@ -50,43 +54,8 @@ describe 'RequestQuoteView', ->
|
||||||
expect(view.$('#request-form').hasClass('hide')).toBe(true)
|
expect(view.$('#request-form').hasClass('hide')).toBe(true)
|
||||||
expect(view.$('#form-submit-success').hasClass('hide')).toBe(false)
|
expect(view.$('#form-submit-success').hasClass('hide')).toBe(false)
|
||||||
|
|
||||||
|
describe 'does NOT have an existing trial request', ->
|
||||||
describe 'when user is signed in and has an existing trial request', ->
|
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
me.clear()
|
|
||||||
me.set('_id', '1234')
|
|
||||||
me._revertAttributes = {}
|
|
||||||
spyOn(me, 'isAnonymous').and.returnValue(false)
|
|
||||||
view = new RequestQuoteView()
|
|
||||||
view.render()
|
|
||||||
jasmine.demoEl(view.$el)
|
|
||||||
|
|
||||||
request = jasmine.Ajax.requests.mostRecent()
|
|
||||||
request.respondWith({
|
|
||||||
status: 200
|
|
||||||
responseText: JSON.stringify([{
|
|
||||||
_id: '1'
|
|
||||||
properties: {
|
|
||||||
firstName: 'First'
|
|
||||||
lastName: 'Last'
|
|
||||||
}
|
|
||||||
}])
|
|
||||||
})
|
|
||||||
_.defer done # Let SuperModel finish
|
|
||||||
|
|
||||||
it 'shows form with data from the most recent request', ->
|
|
||||||
expect(view.$('input[name="firstName"]').val()).toBe('First')
|
|
||||||
|
|
||||||
describe 'when a user is anonymous and does NOT have an existing trial request', ->
|
|
||||||
beforeEach (done) ->
|
|
||||||
me.clear()
|
|
||||||
me.set('_id', '1234')
|
|
||||||
me._revertAttributes = {}
|
|
||||||
spyOn(me, 'isAnonymous').and.returnValue(true)
|
|
||||||
view = new RequestQuoteView()
|
|
||||||
view.render()
|
|
||||||
jasmine.demoEl(view.$el)
|
|
||||||
|
|
||||||
request = jasmine.Ajax.requests.mostRecent()
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
request.respondWith({
|
request.respondWith({
|
||||||
status: 200
|
status: 200
|
||||||
|
@ -108,12 +77,12 @@ describe 'RequestQuoteView', ->
|
||||||
describe 'on successful form submit', ->
|
describe 'on successful form submit', ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
forms.objectToForm(view.$el, successFormValues)
|
forms.objectToForm(view.$el, successForm)
|
||||||
view.$('#request-form').submit()
|
view.$('#request-form').submit()
|
||||||
@submitRequest = _.last(jasmine.Ajax.requests.filter(isSubmitRequest))
|
@submitRequest = _.last(jasmine.Ajax.requests.filter(isSubmitRequest))
|
||||||
@submitRequest.respondWith({
|
@submitRequest.respondWith({
|
||||||
status: 201
|
status: 201
|
||||||
responseText: JSON.stringify(_.extend({_id: 'a'}, successFormValues))
|
responseText: JSON.stringify(_.extend({_id: 'a'}, successForm))
|
||||||
})
|
})
|
||||||
|
|
||||||
it 'does not prevent navigating away', ->
|
it 'does not prevent navigating away', ->
|
||||||
|
@ -167,10 +136,9 @@ describe 'RequestQuoteView', ->
|
||||||
expect(request.method).toBe('PUT')
|
expect(request.method).toBe('PUT')
|
||||||
expect(request.url).toBe('/db/user/1234')
|
expect(request.url).toBe('/db/user/1234')
|
||||||
|
|
||||||
describe 'when an anonymous user tries to submit a request with an existing user\'s email', ->
|
describe 'tries to submit a request with an existing user\'s email', ->
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
forms.objectToForm(view.$el, successFormValues)
|
forms.objectToForm(view.$el, successForm)
|
||||||
view.$('#request-form').submit()
|
view.$('#request-form').submit()
|
||||||
@submitRequest = _.last(jasmine.Ajax.requests.filter(isSubmitRequest))
|
@submitRequest = _.last(jasmine.Ajax.requests.filter(isSubmitRequest))
|
||||||
@submitRequest.respondWith({
|
@submitRequest.respondWith({
|
||||||
|
@ -182,15 +150,86 @@ describe 'RequestQuoteView', ->
|
||||||
expect(view.$('#email-form-group').hasClass('has-error')).toBe(true)
|
expect(view.$('#email-form-group').hasClass('has-error')).toBe(true)
|
||||||
expect(view.$('#email-form-group .error-help-block').length).toBe(1)
|
expect(view.$('#email-form-group .error-help-block').length).toBe(1)
|
||||||
|
|
||||||
describe 'when user is signed in and has role "student"', ->
|
describe 'submits the form without school', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('#request-form')
|
||||||
|
formData = _.omit(successForm, ['organization'])
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'submits a trial request, which does not include school setting', ->
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.url).toBe('/db/trial.request')
|
||||||
|
expect(request.method).toBe('POST')
|
||||||
|
attrs = JSON.parse(request.params)
|
||||||
|
expect(attrs.properties?.organization).toBeUndefined()
|
||||||
|
expect(attrs.properties?.district).toEqual('District')
|
||||||
|
|
||||||
|
describe 'submits the form without district', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('#request-form')
|
||||||
|
formData = _.omit(successForm, ['district'])
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'displays a validation error on district and not school', ->
|
||||||
|
expect(view.$('#organization-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
expect(view.$('#district-control').parent().hasClass('has-error')).toEqual(true)
|
||||||
|
|
||||||
|
describe 'submits form with district set to n/a', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.$el.find('#request-form').trigger('change') # to confirm navigating away isn't prevented
|
||||||
|
form = view.$('#request-form')
|
||||||
|
formData = _.omit(successForm, ['organization'])
|
||||||
|
formData.district = 'N/A'
|
||||||
|
forms.objectToForm(form, formData)
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
it 'submits a trial request, which does not include district setting', ->
|
||||||
|
expect(view.$('#organization-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
expect(view.$('#district-control').parent().hasClass('has-error')).toEqual(false)
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.url).toBe('/db/trial.request')
|
||||||
|
expect(request.method).toBe('POST')
|
||||||
|
attrs = JSON.parse(request.params)
|
||||||
|
expect(attrs.properties?.district).toBeUndefined()
|
||||||
|
|
||||||
|
describe 'when a signed in user', ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
me.set('role', 'student')
|
me.clear()
|
||||||
me.set('name', 'Some User')
|
me.set('_id', '1234')
|
||||||
|
me._revertAttributes = {}
|
||||||
spyOn(me, 'isAnonymous').and.returnValue(false)
|
spyOn(me, 'isAnonymous').and.returnValue(false)
|
||||||
view = new RequestQuoteView()
|
view = new RequestQuoteView()
|
||||||
view.render()
|
view.render()
|
||||||
jasmine.demoEl(view.$el)
|
jasmine.demoEl(view.$el)
|
||||||
|
_.defer done # Let SuperModel finish
|
||||||
|
|
||||||
|
describe 'has an existing trial request', ->
|
||||||
|
beforeEach (done) ->
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
request.respondWith({
|
||||||
|
status: 200
|
||||||
|
responseText: JSON.stringify([{
|
||||||
|
_id: '1'
|
||||||
|
properties: {
|
||||||
|
firstName: 'First'
|
||||||
|
lastName: 'Last'
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
})
|
||||||
|
_.defer done # Let SuperModel finish
|
||||||
|
|
||||||
|
it 'shows form with data from the most recent request', ->
|
||||||
|
expect(view.$('input[name="firstName"]').val()).toBe('First')
|
||||||
|
|
||||||
|
describe 'has role "student"', ->
|
||||||
|
beforeEach (done) ->
|
||||||
|
me.clear()
|
||||||
|
me.set('role', 'student')
|
||||||
|
me.set('name', 'Some User')
|
||||||
request = jasmine.Ajax.requests.mostRecent()
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
request.respondWith({ status: 200, responseText: '[]'})
|
request.respondWith({ status: 200, responseText: '[]'})
|
||||||
_.defer done # Let SuperModel finish
|
_.defer done # Let SuperModel finish
|
||||||
|
@ -200,7 +239,7 @@ describe 'RequestQuoteView', ->
|
||||||
|
|
||||||
it 'requires confirmation to submit the form', ->
|
it 'requires confirmation to submit the form', ->
|
||||||
form = view.$('#request-form')
|
form = view.$('#request-form')
|
||||||
forms.objectToForm(form, successFormValues)
|
forms.objectToForm(form, successForm)
|
||||||
spyOn(view, 'openModalView')
|
spyOn(view, 'openModalView')
|
||||||
form.submit()
|
form.submit()
|
||||||
expect(view.openModalView).toHaveBeenCalled()
|
expect(view.openModalView).toHaveBeenCalled()
|
||||||
|
@ -211,5 +250,3 @@ describe 'RequestQuoteView', ->
|
||||||
confirmModal.trigger 'confirm'
|
confirmModal.trigger 'confirm'
|
||||||
submitRequest = _.last(jasmine.Ajax.requests.filter(isSubmitRequest))
|
submitRequest = _.last(jasmine.Ajax.requests.filter(isSubmitRequest))
|
||||||
expect(submitRequest).toBeTruthy()
|
expect(submitRequest).toBeTruthy()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue