Commit 2470072a by AlasdairSwan

Merge pull request #10830 from edx/alasdair/ECOM-2824-fa-form

ECOM-2824 Financial Assistance Form
parents e9a32340 56ba7850
......@@ -522,15 +522,15 @@ class ViewsTestCase(ModuleStoreTestCase):
effort = "I'm done, okay? You just give me my money, and you and I, we're done."
data = {
'username': username,
'course_id': course,
'legal_name': legal_name,
'course': course,
'name': legal_name,
'email': self.user.email,
'country': country,
'income': income,
'reason_for_applying': reason_for_applying,
'goals': goals,
'effort': effort,
'marketing_permission': False,
'mktg-permission': False,
}
response = self._submit_financial_assistance_form(data)
self.assertEqual(response.status_code, 204)
......@@ -560,15 +560,15 @@ class ViewsTestCase(ModuleStoreTestCase):
def test_zendesk_submission_failed(self, _mock_record_feedback):
response = self._submit_financial_assistance_form({
'username': self.user.username,
'course_id': '',
'legal_name': '',
'course': '',
'name': '',
'email': '',
'country': '',
'income': '',
'reason_for_applying': '',
'goals': '',
'effort': '',
'marketing_permission': False,
'mktg-permission': False,
})
self.assertEqual(response.status_code, 500)
......
......@@ -1460,15 +1460,15 @@ def financial_assistance_request(request):
if request.user.username != username:
return HttpResponseForbidden()
course_id = data['course_id']
legal_name = data['legal_name']
course_id = data['course']
legal_name = data['name']
email = data['email']
country = data['country']
income = data['income']
reason_for_applying = data['reason_for_applying']
goals = data['goals']
effort = data['effort']
marketing_permission = data['marketing_permission']
marketing_permission = data['mktg-permission']
ip_address = get_ip(request)
except ValueError:
# Thrown if JSON parsing fails
......
;(function (define) {
'use strict';
define([
'js/financial-assistance/views/financial_assistance_form_view'
],
function (FinancialAssistanceFormView) {
return function (options) {
var formView = new FinancialAssistanceFormView({
el: '.financial-assistance-wrapper',
context: options
});
return formView;
};
});
}).call(this, define || RequireJS.define);
/**
* Model for Financial Assistance.
*/
(function (define) {
'use strict';
define(['backbone'], function (Backbone) {
var FinancialAssistance = Backbone.Model.extend({
initialize: function(options) {
this.url = options.url;
}
});
return FinancialAssistance;
});
}).call(this, define || RequireJS.define);
<h1><%- gettext('Financial Assistance Application') %></h1>
<div class="intro">
<% _.each(header_text, function(copy) { %>
<p class="copy"><%- copy %></p>
<% }); %>
</div>
<form class="financial-assistance-form">
<div class="status submission-error hidden" aria-live="polite">
<h4 class="message-title"><%- gettext('Application not submitted') %></h4>
<ul class="message-copy"></ul>
</div>
<div class="user-info">
<h2><%- gettext('About You') %></h2>
<p><%- interpolate_text(
gettext('The following information is already a part of your {platform} profile. We\'ve included it here for your application.'),
{platform: platform_name}
) %></p>
<div class="info-column">
<div class="title"><%- gettext('Username') %></div>
<div class="data"><%- username %></div>
</div>
<div class="info-column">
<div class="title"><%- gettext('Email address') %></div>
<div class="data"><%- email %></div>
</div>
<div class="info-column">
<div class="title"><%- gettext('Legal name') %></div>
<div class="data"><%- name %></div>
</div>
<div class="info-column">
<div class="title"><%- gettext('Country of residence') %></div>
<div class="data"><%- country %></div>
</div>
</div>
<%= fields %>
<div class="cta-wrapper clearfix">
<a href="<%- student_faq_url %>" class="nav-link"><%- interpolate_text(
gettext('Back to {platform} FAQs'),
{platform: platform_name}
) %></a>
<button type="submit" class="action action-primary action-update js-submit-form submit-form"><%- gettext("Submit Application") %></button>
</div>
</form>
<h1><%- gettext('Financial Assistance Application') %></h1>
<p class="js-success-message success-message" tabindex="-1"><%- interpolate_text(
gettext('Thank you for submitting your financial assistance application for {course_name}! You can expect a response in 2-4 business days.'), {course_name: course}
) %>
</p>
<div class="cta-wrapper clearfix">
<a href="<%- dashboard_url %>" class="btn btn-blue btn-dashboard"><%- gettext('Go to Dashboard') %></a>
</div>
;(function (define) {
'use strict';
define(['backbone',
'jquery',
'underscore',
'gettext',
'js/financial-assistance/models/financial_assistance_model',
'text!js/financial-assistance/templates/financial_assessment_form.underscore',
'text!js/financial-assistance/templates/financial_assessment_submitted.underscore',
'js/student_account/views/FormView',
'text!templates/student_account/form_field.underscore'
],
function(Backbone, $, _, gettext, FinancialAssistanceModel, formViewTpl, successTpl, FormView, formFieldTpl) {
return FormView.extend({
el: '.financial-assistance-wrapper',
events: {
'click .js-submit-form': 'submitForm'
},
tpl: formViewTpl,
fieldTpl: formFieldTpl,
formType: 'financial-assistance',
requiredStr: '',
submitButton: '.js-submit-form',
initialize: function(data) {
var context = data.context,
fields = context.fields;
// Add default option to array
if ( fields[0].options.length > 1 ) {
fields[0].options.unshift({
name: '- ' + gettext('Choose one') + ' -',
value: '',
default: true
});
}
// Set non-form data needed to render the View
this.context = {
dashboard_url: context.dashboard_url,
header_text: context.header_text,
platform_name: context.platform_name,
student_faq_url: context.student_faq_url
};
// Make the value accessible to this View
this.user_details = context.user_details;
// Initialize the model and set user details
this.model = new FinancialAssistanceModel({
url: context.submit_url
});
this.model.set( context.user_details );
this.listenTo( this.model, 'error', this.saveError );
this.model.on('sync', this.renderSuccess, this);
// Build the form
this.buildForm( fields );
},
render: function(html) {
var data = _.extend( this.model.toJSON(), this.context, {
fields: html || '',
});
this.$el.html(_.template(this.tpl, data));
this.postRender();
return this;
},
renderSuccess: function() {
this.$el.html(_.template(successTpl, {
course: this.model.get('course'),
dashboard_url: this.context.dashboard_url
}));
$('.js-success-message').focus();
},
saveError: function(error) {
/*jslint maxlen: 500 */
var txt = [
'An error has occurred. Wait a few minutes and then try to submit the application again.',
'If you continue to have issues please contact support.'
],
msg = gettext(txt.join(' '));
if (error.status === 0) {
msg = gettext('An error has occurred. Check your Internet connection and try again.');
}
this.errors = ['<li>' + msg + '</li>'];
this.setErrors();
this.element.hide( this.$resetSuccess );
this.toggleDisableButton(false);
},
setExtraData: function(data) {
return _.extend(data, this.user_details);
}
});
}
);
}).call(this, define || RequireJS.define);
define([
'backbone',
'jquery',
'js/financial-assistance/views/financial_assistance_form_view'
], function (Backbone, $, FinancialAssistanceFormView) {
'use strict';
describe('Financial Assistance View', function () {
var view = null,
context = {
fields: [{
defaultValue: '',
form: 'financial-assistance',
instructions: 'select a course',
label: 'Course',
name: 'course',
options: [
{'name': 'Verified with Audit', 'value': 'course-v1:HCFA+VA101+2015'},
{'name': 'Something Else', 'value': 'course-v1:SomethingX+SE101+215'},
{'name': 'Test Course', 'value': 'course-v1:TestX+T101+2015'}
],
placeholder: '',
required: true,
requiredStr: '',
type: 'select'
}],
user_details: {
country: 'UK',
email: 'xsy@edx.org',
name: 'xsy',
username: 'xsy4ever'
},
header_text: ['Line one.', 'Line two.'],
student_faq_url: '/faqs',
dashboard_url: '/dashboard',
platform_name: 'edx',
submit_url: '/api/financial/v1/assistance'
};
beforeEach(function() {
setFixtures('<div class="financial-assistance-wrapper"></div>');
view = new FinancialAssistanceFormView({
el: '.financial-assistance-wrapper',
context: context
});
});
afterEach(function() {
view.undelegateEvents();
view.remove();
});
it('should exist', function() {
expect(view).toBeDefined();
});
});
}
);
......@@ -213,6 +213,13 @@
this.focusFirstError();
},
/* Allows extended views to add non-form attributes
* to the data before saving it to model
*/
setExtraData: function( data ) {
return data;
},
submitForm: function( event ) {
var data = this.getFormData();
......@@ -223,6 +230,7 @@
this.toggleDisableButton(true);
if ( !_.compact(this.errors).length ) {
data = this.setExtraData( data );
this.model.set( data );
this.model.save();
this.toggleErrorMsg( false );
......
%fa-copy {
@extend %t-copy-base;
padding: ($baseline/2) 0;
margin: 0;
color: $m-gray-d2;
};
.financial-assistance-wrapper {
margin: auto;
padding: $baseline 0;
padding: $baseline ($baseline/2);
max-width: 1180px;
.financial-assistance {
border-bottom: 4px solid $gray-l5;
h1 {
@extend %t-title4;
@include text-align(left);
......@@ -23,12 +27,14 @@
}
p {
@extend %t-copy-base;
padding: ($baseline/2) 0;
margin: 0;
color: $m-gray-d2;
@extend %fa-copy;
font-size: 0.875em;
}
.financial-assistance {
padding-bottom: ($baseline/2);
border-bottom: 4px solid $gray-l5;
.apply-form-list {
padding: 0;
list-style: none;
......@@ -73,4 +79,165 @@
border-radius: 2px;
}
}
// Application form View
.intro {
border-bottom: 4px solid $gray-l5;
p {
margin: 10px 0;
}
}
.success-message {
p {
margin: 10px 0;
}
}
.btn-dashboard {
@include float(right);
color: $white;
&:hover,
&:active,
&:focus {
color: $white;
}
}
.user-info {
@include clearfix();
border-bottom: 2px solid $gray-l5;
padding: 20px 0;
margin-bottom: 20px;
.info-column {
@include float(left);
width: 100%;
margin: 10px 0;
}
.title {
@extend %fa-copy;
padding: 0;
}
.data {
@extend %fa-copy;
padding: 0;
color: $black;
font-size: 1.125em;
}
}
.financial-assistance-form {
@extend .login-register;
.action-primary {
@include float(left);
width: auto;
margin-top: 0;
}
.nav-link {
margin: 15px 0;
display: block;
}
form {
border: none;
}
.form-field {
select,
input {
width: 320px;
}
input {
border: {
top: none;
right: none;
bottom: 3px solid $gray-l1;
left: none;
};
box-shadow: none;
}
textarea {
height: 125px;
}
.checkbox {
height: auto;
position: absolute;
top: 5px;
& + label {
@include margin-left(30px);
display: inline-block;
}
}
}
}
.cta-wrapper {
border-top: 4px solid $gray-l5;
padding: 20px 0;
}
@include media($bp-medium) {
.user-info {
.info-column {
width: 50%;
}
}
.financial-assistance-form {
.action-primary {
@include float(right);
}
.nav-link {
display: inline-block;
}
}
}
@include media($bp-large) {
.user-info {
.info-column {
width: 25%;
}
}
.financial-assistance-form {
.action-primary {
@include float(right);
}
.nav-link {
display: inline-block;
}
}
}
@include media($bp-huge) {
.user-info {
.info-column {
width: 25%;
}
}
.financial-assistance-form {
.action-primary {
@include float(right);
}
.nav-link {
display: inline-block;
}
}
}
}
......@@ -21,6 +21,7 @@
<option value="<%= el.value%>"<% if ( el.default ) { %> data-isdefault="true"<% } %>><%= el.name %></option>
<% }); %>
</select>
<% if ( instructions ) { %> <span class="tip tip-input" id="<%= form %>-<%= name %>-desc"><%= instructions %></span><% } %>
<% } else if ( type === 'textarea' ) { %>
<textarea id="<%= form %>-<%= name %>"
type="<%= type %>"
......@@ -35,6 +36,7 @@
<% });
} %>
<% if ( required ) { %> aria-required="true" required<% } %> ></textarea>
<% if ( instructions ) { %> <span class="tip tip-input" id="<%= form %>-<%= name %>-desc"><%= instructions %></span><% } %>
<% } else { %>
<input id="<%= form %>-<%= name %>"
type="<%= type %>"
......@@ -52,15 +54,14 @@
<% if ( placeholder ) { %> placeholder="<%= placeholder %>"<% } %>
value="<%- defaultValue %>"
/>
<% if ( instructions ) { %> <span class="tip tip-input" id="<%= form %>-<%= name %>-desc"><%= instructions %></span><% } %>
<% } %>
<% if ( type === 'checkbox' ) { %>
<label for="<%= form %>-<%= name %>">
<%= label %>
<% if ( required && requiredStr ) { %> <%= requiredStr %><% } %>
</label>
<% } %>
<% if ( instructions ) { %> <span class="tip tip-input" id="<%= form %>-<%= name %>-desc"><%= instructions %></span><% } %>
<% } %>
<% if( form === 'login' && name === 'password' ) { %>
<a href="#" class="forgot-password field-link"><%- gettext("Forgot password?") %></a>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment