Added hosting page for confrence city residents

This commit is contained in:
Godwin
2016-06-05 08:01:14 -07:00
parent 633219b003
commit 2003028a15
12 changed files with 338 additions and 69 deletions
+21
View File
@@ -76,4 +76,25 @@
_input.addEventListener('change', function(event) { setRequired(); });
});
});
Array.prototype.forEach.call(document.querySelectorAll('[data-toggles]'), function(checkbox) {
var toggles = document.getElementById(checkbox.dataset.toggles);
toggles.classList.add('toggleable');
var form = checkbox.parentNode;
while (form && form.nodeName != 'FORM') {
form = form.parentNode;
}
var toggle = function() {
toggles.classList[checkbox.checked ? 'add' : 'remove']('open');
if (form) {
if (checkbox.checked) {
form.removeAttribute('novalidate');
} else {
form.setAttribute('novalidate', 'novalidate');
}
}
};
toggle();
checkbox.addEventListener('change', function(event) { toggle(); });
});
})();
+84 -33
View File
@@ -239,7 +239,7 @@ textarea, .textarea {
}
input {
&[type="text"], &[type="password"], &[type="telephone"], &[type="search"], &[type="email"], &[type="url"] {
&[type="text"], &[type="password"], &[type="tel"], &[type="search"], &[type="email"], &[type="url"], &[type="number"] {
display: block;
font-size: 1.25em;
outline: 0;
@@ -249,10 +249,15 @@ input {
padding: 0.25em 0.5em;
border-bottom: 0.15em solid transparent;
}
&[type="number"], &[type="tel"] {
@include font-family(secondary);
}
}
.number-field,
.email-field,
.telephone-field,
.text-field {
position: relative;
margin-bottom: 2em;
@@ -321,6 +326,10 @@ input {
}
}
.telephone-field {
max-width: 15em;
}
@include keyframes(bend) {
to {
@include _(transform, skewX(-5deg));
@@ -530,6 +539,10 @@ input {
font-size: 0.75em;
}
.check-box-field.inline {
display: inline-block;
}
.radio-button-field {
label {
width: 7em;
@@ -582,11 +595,11 @@ form {
}
&.mini-flex-form {
display: flex;
align-items: flex-start;
@include _-(display, flex);
@include _(align-items, flex-start);
.input-field {
flex: 1;
@include _(flex, 1);
}
button, .button {
@@ -597,8 +610,27 @@ form {
}
fieldset {
margin: 0;
padding: 0;
border: 0;
&.centered {
margin-top: 3em;
text-align: center;
}
}
.fieldgroup {
@include _-(display, flex);
@include _-(display, inline-flex);
@include _(align-items, flex-end);
@include _(flex-wrap, wrap);
margin: 0 0 3em 1em;
> .input-field {
margin-right: 1em;
@include _(flex, 1);
}
}
.view-object {
@@ -645,9 +677,9 @@ fieldset {
}
&.next-prev {
display: flex;
flex-wrap: wrap;
flex-direction: row-reverse;
@include _-(display, flex);
@include _(flex-wrap, wrap);
@include _(flex-direction, row-reverse);
margin: 0;
button, .button {
@@ -893,6 +925,7 @@ ul.warnings li,
a {
color: inherit;
position: static;
@include before {
content: '';
@@ -1152,15 +1185,15 @@ $header-tilt: 8deg;
padding: 1em;
footer {
display: flex;
flex-flow: row wrap;
@include _-(display, flex);
@include _(flex-flow, row wrap);
font-size: 4.1vw;
}
.github,
ul.locales {
flex: 1;
flex-basis: 50%;
@include _(flex, 1);
@include _(flex-basis, 50%);
}
.copy {
@@ -1174,7 +1207,7 @@ $header-tilt: 8deg;
}
.facebook {
flex: none;
@include _(flex, none);
margin: 0.5em;
a {
@@ -1255,16 +1288,17 @@ input[type="submit"]:focus {
}
.check-box-field input:focus + label,
.radio-button-field input:focus + label {
@include before {
background-color: $colour-2;
@include _(animation, colour-out ease-in-out 500ms infinite alternate both);
}
.radio-button-field input:focus + label,
.select-field select:focus {
outline: 0.25rem solid $colour-2;
outline-offset: 0.2rem;
z-index: 1;
}
body {
input:focus,
textarea:focus,
select:focus,
.textarea {
@include _(animation, none);
}
@@ -2177,15 +2211,31 @@ html[data-lingua-franca-example="html"] {
select {
display: block;
width: 100%;
height: 2.1em;
height: 1.75em;
font-family: inherit;
font-size: 1.5em;
padding: 0.25em;
padding: 0 0.5em;
border: 0.1em solid #333;
cursor: pointer;
@include default-box-shadow(top, 1.5, false);
}
}
.toggleable {
@include _(transition, 'transform 250ms ease-in-out, max-height 250ms ease-in-out, visibility 0s linear 250ms');
@include _(transform, scaleY(0));
@include _(transform-origin, 0 0);
max-height: 0;
visibility: hidden;
&.open {
@include _(transition, 'transform 250ms ease-in-out, max-height 250ms ease-in-out');
max-height: 100em;
visibility: visible;
@include _(transform, scaleX(1));
}
}
@include breakpoint(medium) {
body {
padding-bottom: 0;
@@ -2201,11 +2251,11 @@ html[data-lingua-franca-example="html"] {
form {
&.flex-form {
display: flex;
align-items: flex-start;
@include _-(display, flex);
@include _(align-items, flex-start);
.input-field {
flex: 1;
@include _(flex, 1);
}
button, .button {
@@ -2217,6 +2267,7 @@ html[data-lingua-franca-example="html"] {
.number-field,
.email-field,
.telephone-field,
.text-field {
&.big input {
font-size: 2em;
@@ -2224,8 +2275,8 @@ html[data-lingua-franca-example="html"] {
}
.flex-column {
display: flex;
align-items: flex-start;
@include _-(display, flex);
@include _(align-items, flex-start);
margin-top: 1em;
p:first-child {
@@ -2233,7 +2284,7 @@ html[data-lingua-franca-example="html"] {
}
.stretch-item {
flex: 1;
@include _(flex, 1);
margin-right: 1em;
}
}
@@ -2537,8 +2588,8 @@ html[data-lingua-franca-example="html"] {
}
.github {
flex: none;
flex-basis: auto;
@include _(flex, none);
@include _(flex-basis, auto);
bottom: 0.5em;
float: left;
margin-right: 1em;
@@ -2548,18 +2599,18 @@ html[data-lingua-franca-example="html"] {
margin: 0;
}
ul.locales {
flex: none;
flex-basis: auto;
flex-grow: 1;
@include _(flex, none);
@include _(flex-basis, auto);
@include _(flex-grow, 1);
}
}
.check-box-field,
.radio-button-field {
display: flex;
@include _-(display, flex);
label {
flex: 1;
@include _(flex, 1);
border: 0.1em solid;
border-left: 0;
text-align: left;
+45 -7
View File
@@ -578,6 +578,20 @@ class ConferencesController < ApplicationController
end
current_user.save! unless @errors.present?
when :hosting
@registration.can_provide_housing = params[:can_provide_housing].present?
@registration.housing_data = {
address: params[:address],
phone: params[:phone],
space: {
bed_space: params[:bed_space],
floor_space: params[:floor_space],
tent_space: params[:tent_space],
},
considerations: params[:considerations].keys,
availability: [ params[:first_day], params[:last_day] ],
notes: params[:notes]
}
end
if @errors.present?
@@ -743,11 +757,13 @@ class ConferencesController < ApplicationController
:bike => nil,
:other => ''
);
@languages = [I18n.locale.to_sym]
@languages = current_user.languages
if @registration.languages
@languages = JSON.parse(@registration.languages).map &:to_sym
if @languages.blank? && @registration.languages.present?
@languages = (@registration.languages.is_a?(String) ? JSON.parse(@registration.languages) : @registration.languages).map &:to_sym
end
@languages ||= [I18n.locale.to_sym]
when :workshops
@page_title = 'articles.conference_registration.headings.Workshops'
@workshops = Workshop.where(conference_id: @this_conference.id)
@@ -758,6 +774,12 @@ class ConferencesController < ApplicationController
@workshops_in_need = Workshop.where(conference_id: @this_conference.id, needs_facilitators: true)
when :contact_info
@page_title = 'articles.conference_registration.headings.Contact_Info'
when :hosting
@page_title = 'articles.conference_registration.headings.Hosting'
@hosting_data = @registration.housing_data || {}
@hosting_data['space'] ||= Hash.new
@hosting_data['availability'] ||= Array.new
@hosting_data['considerations'] ||= Array.new
when :policy
@page_title = 'articles.conference_registration.headings.Policy_Agreement'
when :done
@@ -1447,10 +1469,14 @@ class ConferencesController < ApplicationController
def registration_steps(conference = nil)
conference ||= @this_conference || @conference
{
pre: [:policy, :contact_info, :workshops],
open: [:policy, :contact_info, :questions, :payment, :workshops]
}[conference.registration_status]
status = conference.registration_status
return [] unless status == :pre || status == :open
steps = [:policy, :contact_info, :questions, :hosting, :payment, :workshops]
steps -= [:questions, :payment] unless status == :open
steps -= [:hosting] unless @registration.present? && view_context.same_city?(@registration.city, @conference.location)
return steps
end
def required_steps(conference = nil)
@@ -1508,11 +1534,23 @@ class ConferencesController < ApplicationController
def set_or_create_conference_registration
set_conference_registration
return @registration if @registration.present?
@registration ||= ConferenceRegistration.new(
conference: @this_conference,
user_id: current_user.id,
steps_completed: []
)
last_registration_data = ConferenceRegistration.where(user_id: current_user.id).order(created_at: :desc).limit(1).first
if last_registration_data.present?
if last_registration_data['languages'].present? && current_user.languages.blank?
current_user.languages = JSON.parse(last_registration_data['languages'])
current_user.save!
end
@registration.city = last_registration_data.city if last_registration_data.city.present?
end
end
# Only allow a trusted parameter "white list" through.
+114 -18
View File
@@ -611,6 +611,13 @@ module ApplicationHelper
return hash.length > 1 ? _("geography.formats.#{hash.keys.join('_')}", vars: hash) : hash.values.first
end
def same_city?(location1, location2)
location1 = location(location1) unless location1.is_a?(String)
location2 = location(location2) unless location2.is_a?(String)
location1.eql? location2
end
def show_errors(field)
return '' unless @errors && @errors[field].present?
@@ -665,6 +672,38 @@ module ApplicationHelper
_!((p * 10000).to_i.to_s.gsub(/^(.*)(\d\d)$/, '\1.\2%'))
end
def conference_housing_options(conference = nil)
conference ||= @this_conference || @conference
return [] unless conference
dates = []
day = conference.start_date - 7.days
last_day = conference.end_date + 7.days
while day <= last_day
dates << day
day += 1.day
end
return dates
end
def conference_housing_options_list(period, conference = nil)
conference ||= @this_conference || @conference
return [] unless conference
days = []
conference_housing_options(conference).each do |day|
belongs_to_periods = []
belongs_to_periods << :before if day <= conference.start_date
belongs_to_periods << :after if day >= conference.end_date
belongs_to_periods << :during if day >= conference.start_date && day <= conference.end_date
days << [date(day.to_date, :span_same_year_date_1), day] if belongs_to_periods.include?(period)
end
return days
end
def richtext(text, reduce_headings = 2)
return '' unless text.present?
return _!(text).
@@ -704,26 +743,75 @@ module ApplicationHelper
return html.html_safe
end
def fieldset(name, options = {}, &block)
html = ''
label_id = nil
description_id = nil
if options[:heading].present?
label_id ||= "#{name.to_s}-label"
html += content_tag(:h3, _(options[:heading], :t), id: label_id)
end
if options[:help].present?
description_id ||= "#{name.to_s}-desc"
html += content_tag(:div, _(options[:help], :s, 2), class: 'input-field-help', id: description_id)
end
(html + content_tag(:fieldset, content_tag(:div, class: :fieldgroup, &block).html_safe,
aria: {
labeledby: label_id,
describedby: description_id
}
)
).html_safe
end
def selectfield(name, value, select_options, options = {})
textfield(name, value, options.merge({type: :select, options: select_options}))
end
def telephonefield(name, value, options = {})
textfield(name, value, options.merge({type: :telephone}))
end
def numberfield(name, value, options = {})
textfield(name, value, options.merge({type: :number}))
end
def textfield(name, value, options = {})
html = ''
description_id = nil
if options[:heading].present?
description_id ||= "#{name.to_s}-desc"
html += content_tag(:h3, _(options[:heading]), id: description_id)
html += content_tag(:h3, _(options[:heading], :t), id: description_id)
end
if options[:help].present?
description_id ||= "#{name.to_s}-desc"
html += content_tag(:div, _(options[:help], :s, 2), class: 'input-field-help', id: description_id)
end
html += show_errors name
html += label_tag name
html += text_field_tag(name, value,
input_options = {
required: options[:required],
lang: options[:lang],
min: options[:min],
max: options[:max],
aria: { describedby: description_id }
)
}
case options[:type]
when :select
html += select_tag(name, options_for_select(options[:options], value), input_options)
else
html += send("#{(options[:type] || :text).to_s}_field_tag", name, value, input_options)
end
html = content_tag(:div, html.html_safe,
class: [
'text-field',
"#{(options[:type] || :text).to_s}-field",
'input-field',
options[:big] ? 'big' : nil,
(@errors || {})[name].present? ? 'has-error' : nil
@@ -738,6 +826,10 @@ module ApplicationHelper
checkboxes(name, boxes, [value], label_key, options.merge({radiobuttons: true}))
end
def checkbox(name, value, label_key, options = {})
checkboxes(name, [true], value, label_key, options)
end
def checkboxes(name, boxes, values, label_key, options = {})
html = ''
@@ -746,7 +838,7 @@ module ApplicationHelper
if options[:heading].present?
label_id ||= "#{name.to_s}-label"
html += content_tag(:h3, _(options[:heading]), id: label_id)
html += content_tag(:h3, _(options[:heading], :t), id: label_id)
end
if options[:help].present?
@@ -756,23 +848,24 @@ module ApplicationHelper
boxes_html = ''
values = values.present? ? values.map(&:to_s) : []
is_single = !values.is_a?(Array)
values = values.present? ? values.map(&:to_s) : [] unless is_single
boxes = boxes.map(&:to_s)
boxes.each do | box |
checked = values.include?(box)
values -= [box] if checked
checked = (is_single ? values.present? : values.include?(box))
values -= [box] if checked && !is_single
id = nil
if options[:radiobuttons].present?
id = "#{name.to_s}_#{box}"
boxes_html += radio_button_tag(name, box, checked)
else
id = "#{name.to_s}[#{box}]"
boxes_html += check_box_tag(id, 1, checked)
id = (is_single ? name : "#{name.to_s}[#{box}]")
boxes_html += check_box_tag(id, 1, checked, data: { toggles: options[:toggles] }.compact)
end
boxes_html += label_tag(id, _("#{label_key.to_s}.#{box}"))
boxes_html += label_tag(id, _(is_single ? label_key.to_s : "#{label_key.to_s}.#{box}"))
end
if options[:other].present?
if options[:other].present? && !is_single
id = nil
if options[:radiobuttons].present?
id = "#{name.to_s}_other"
@@ -787,16 +880,19 @@ module ApplicationHelper
class: 'other')
end
html += content_tag(:fieldset, boxes_html.html_safe,
html += content_tag(:fieldset, content_tag(:div, boxes_html.html_safe,
class: [
'check-box-field',
'input-field',
options[:vertical] ? 'vertical' : nil,
options[:inline] ? 'inline' : nil
]).html_safe,
aria: {
labeledby: label_id,
describedby: description_id
},
class: [
'check-box-field',
'input-field',
options[:vertical] ? 'vertical' : nil
])
class: options[:centered] ? 'centered' : nil
)
return html.html_safe
end
@@ -3,16 +3,9 @@
%p=_'articles.conference_registration.paragraphs.Contact_Info', :s, 2
= columns(medium: 12) do
= form_tag register_path(@this_conference.slug) do
= textfield :name, @name, required: true, heading: 'articles.conference_registration.headings.name'
= textfield :name, @name, required: true, heading: 'articles.conference_registration.headings.name', big: true
= textfield :location, (@registration.city || location(lookup_ip_location)), required: true, heading: 'articles.conference_registration.headings.location'
%h3=_'articles.conference_registration.headings.languages','Which languages do you speak?'
- puts @errors.to_json.to_s
.check-box-field.input-field{class: @errors[:languages].present? ? 'has-error' : nil}
- [:en, :es, :fr].each do |language|
= check_box_tag "languages[#{language}]", 1, (@registration.languages || [I18n.locale.to_s]).include?(language.to_s)
= label_tag "languages_#{language}" do
= _"languages.#{language}"
= show_errors :languages
= checkboxes :languages, [:en, :es, :fr], current_user.languages, 'languages', heading: 'articles.conference_registration.headings.languages'
.actions.next-prev
= button_tag (params[:step] == :save ? :save : :next), value: :contact_info
= button_tag :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true
+24
View File
@@ -0,0 +1,24 @@
- add_stylesheet :editor
- add_inline_script :pen
- add_inline_script :markdown
- add_inline_script :editor
= columns(medium: 12) do
%h2=_(@page_title)
= columns(medium: 12) do
= form_tag register_path(@this_conference.slug) do
= checkbox :can_provide_housing, @registration.can_provide_housing, 'articles.conference_registration.can_provide_housing', heading: 'articles.conference_registration.headings.can_provide_housing', help: 'articles.conference_registration.paragraphs.can_provide_housing', inline: true, toggles: 'hosting-options', centered: true
#hosting-options
= textfield :address, @hosting_data['address'], required: true, heading: 'articles.conference_registration.headings.host.address', help: 'articles.conference_registration.paragraphs.host.address'
= telephonefield :phone, @hosting_data['phone'], required: true
= fieldset :space, heading: 'articles.conference_registration.headings.host.space', help: 'articles.conference_registration.paragraphs.host.space' do
- [:bed_space, :floor_space, :tent_space].each do | space |
= numberfield space, @hosting_data['space'][space.to_s] || 0, min: 0, required: true
= fieldset :hosting_dates, heading: 'articles.conference_registration.headings.host.availability', help: 'articles.conference_registration.paragraphs.host.availability' do
= selectfield :first_day, @hosting_data['availability'][0] || @this_conference.start_date, conference_housing_options_list(:before)
= selectfield :last_day, @hosting_data['availability'][1] || @this_conference.start_date, conference_housing_options_list(:after)
= checkboxes :considerations, [:vegan, :smoking, :quiet], @hosting_data['considerations'], 'articles.conference_registration.host.considerations', heading: 'articles.conference_registration.headings.host.considerations', help: 'articles.conference_registration.paragraphs.host.considerations', vertical: true
= textarea :notes, @hosting_data['notes'], heading: 'articles.conference_registration.headings.host.notes', help: 'articles.conference_registration.paragraphs.host.notes'
.actions.next-prev
= button_tag (params[:step] == :save ? :save : :next), value: :hosting
= button_tag :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true
+1 -1
View File
@@ -1,5 +1,5 @@
= render :partial => 'page_header', :locals => {:page_key => 'Conference_Registration'}
- if (steps = current_registration_steps)
- if (steps = current_registration_steps(@registration))
= row id: 'registration-steps', class: 'flow-steps' do
= columns do
%ul