diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index ee10e21..530b0dc 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -152,9 +152,9 @@ } window.initNodeFunctions = [ function(node) { - forEachElement('.number-field,.email-field,.text-field,.password-field', function(field) { + forEachElement('.number-field,.email-field,.text-field,.password-field,.search-field', function(field) { var input = field.querySelector('input'); - var positionLabel = function(input) { + var positionLabel = function(input) { field.classList[input.value ? 'remove' : 'add']('empty'); } positionLabel(input); diff --git a/app/assets/javascripts/registrations.js b/app/assets/javascripts/registrations.js new file mode 100644 index 0000000..e950adb --- /dev/null +++ b/app/assets/javascripts/registrations.js @@ -0,0 +1,23 @@ +(function() { + var searchControl = document.getElementById('search'); + + function filterTable() { + forEach(document.getElementById('search-rows').getElementsByTagName('tr'), function(tr) { + tr.classList.remove('hidden'); + + var value = searchControl.value; + if (value) { + var words = value.split(/\s+/); + for (var i = 0; i < words.length; i++) { + var word = new RegExp(words[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), "i"); + if (tr.innerHTML.search(word) == -1) { + tr.classList.add('hidden'); + } + } + } + }); + } + + searchControl.addEventListener('keyup', filterTable); + searchControl.addEventListener('search', filterTable); +})(); diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss index 625e6a4..8da841b 100644 --- a/app/assets/stylesheets/_application.scss +++ b/app/assets/stylesheets/_application.scss @@ -166,6 +166,10 @@ table, .table { } } } + + &.bold { + @include font-family(secondary); + } } tbody th { @@ -175,6 +179,14 @@ table, .table { &.admin-edit { width: 100%; } + + tr.hidden { + display: none; + } +} + +.table-scroller { + overflow: auto; } .table { @@ -376,6 +388,7 @@ input { .number-field, .email-field, +.search-field, .telephone-field, .password-field, .text-field { @@ -449,6 +462,7 @@ input { .email-field, .password-field, .telephone-field, +.search-field, .text-field, .text-area-field { text-align: left; diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 1259d3e..0f86c0e 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -134,7 +134,7 @@ class ConferencesController < ApplicationController else @registration.is_attending = 'y' end - + @registration.housing_data = { address: params[:address], phone: params[:phone], @@ -336,95 +336,96 @@ class ConferencesController < ApplicationController end end when :stats - if request.format.xlsx? - @registrations = ConferenceRegistration.where(:conference_id => @this_conference.id).sort { |a,b| (a.user.present? ? (a.user.firstname || '') : '').downcase <=> (b.user.present? ? (b.user.firstname || '') : '').downcase } - logger.info "Generating stats.xls" - @excel_data = { - columns: [ - :name, - :email, - :status, - :registration_fees_paid, - :date, - :city, - :preferred_language, - :languages, - :arrival, - :departure, - :housing, - :bike, - :food, - :companion, - :allergies - ], - column_types: { - name: :bold, - date: :datetime, - arrival: [:date, :day], - departure: [:date, :day], - registration_fees_paid: :money - }, - keys: { - name: 'forms.labels.generic.name', - email: 'forms.labels.generic.email', - status: 'forms.labels.generic.registration_status', - city: 'forms.labels.generic.location', - date: 'articles.conference_registration.terms.Date', - languages: 'articles.conference_registration.terms.Languages', - preferred_language: 'articles.conference_registration.terms.Preferred_Languages', - arrival: 'forms.labels.generic.arrival', - departure: 'forms.labels.generic.departure', - housing: 'forms.labels.generic.housing', - bike: 'forms.labels.generic.bike', - food: 'forms.labels.generic.food', - companion: 'articles.conference_registration.terms.companion', - allergies: 'forms.labels.generic.allergies', - registration_fees_paid: 'articles.conference_registration.headings.fees_paid' - }, - data: [] - } - @registrations.each do | r | - user = r.user_id ? User.where(id: r.user_id).first : nil - if user.present? - companion = '' - if r.housing_data.present? && r.housing_data['companions'].present? - companion_user = User.find_by_email(r.housing_data['companions'].first) - companion = view_context._'articles.conference_registration.terms.registration_status.unregistered' - - if companion_user.present? - cr = ConferenceRegistration.where(user_id: companion_user.id).order(created_at: :desc).limit(1).first - - if cr.present? && ((cr.steps_completed || []).include? 'questions') - companion = companion_user.named_email - end + @registrations = ConferenceRegistration.where(:conference_id => @this_conference.id).sort { |a,b| (a.user.present? ? (a.user.firstname || '') : '').downcase <=> (b.user.present? ? (b.user.firstname || '') : '').downcase } + @excel_data = { + columns: [ + :name, + :email, + :status, + :registration_fees_paid, + :date, + :city, + :preferred_language, + :languages, + :arrival, + :departure, + :housing, + :bike, + :food, + :companion, + :allergies + ], + column_types: { + name: :bold, + date: :datetime, + arrival: [:date, :day], + departure: [:date, :day], + registration_fees_paid: :money + }, + keys: { + name: 'forms.labels.generic.name', + email: 'forms.labels.generic.email', + status: 'forms.labels.generic.registration_status', + city: 'forms.labels.generic.location', + date: 'articles.conference_registration.terms.Date', + languages: 'articles.conference_registration.terms.Languages', + preferred_language: 'articles.conference_registration.terms.Preferred_Languages', + arrival: 'forms.labels.generic.arrival', + departure: 'forms.labels.generic.departure', + housing: 'forms.labels.generic.housing', + bike: 'forms.labels.generic.bike', + food: 'forms.labels.generic.food', + companion: 'articles.conference_registration.terms.companion', + allergies: 'forms.labels.generic.allergies', + registration_fees_paid: 'articles.conference_registration.headings.fees_paid' + }, + data: [] + } + @registrations.each do | r | + user = r.user_id ? User.where(id: r.user_id).first : nil + if user.present? + companion = '' + if r.housing_data.present? && r.housing_data['companions'].present? + companion_user = User.find_by_email(r.housing_data['companions'].first) + companion = view_context._'articles.conference_registration.terms.registration_status.unregistered' + + if companion_user.present? + cr = ConferenceRegistration.where(user_id: companion_user.id).order(created_at: :desc).limit(1).first + + if cr.present? && ((cr.steps_completed || []).include? 'questions') + companion = companion_user.named_email end end - steps = r.steps_completed || [] - - @excel_data[:data] << { - name: user.firstname || '', - email: user.email || '', - status: (view_context._"articles.conference_registration.terms.registration_status.#{(steps.include? 'questions') ? 'registered' : ((steps.include? 'contact_info') ? 'preregistered' : 'unregistered')}"), - date: r.created_at ? r.created_at.strftime("%F %T") : '', - city: r.city || '', - preferred_language: user.locale.present? ? (view_context.language_name user.locale) : '', - languages: ((r.languages || []).map { |x| view_context.language_name x }).join(', ').to_s, - arrival: r.arrival ? r.arrival.strftime("%F %T") : '', - departure: r.departure ? r.departure.strftime("%F %T") : '', - housing: r.housing || '', - bike: r.bike.present? ? (view_context._"articles.conference_registration.questions.bike.#{r.bike}") : '', - food: r.food.present? ? (view_context._"articles.conference_registration.questions.food.#{r.food}") : '', - companion: companion, - allergies: r.allergies, - registration_fees_paid: r.registration_fees_paid - } end + steps = r.steps_completed || [] + + @excel_data[:data] << { + name: user.firstname || '', + email: user.email || '', + status: (view_context._"articles.conference_registration.terms.registration_status.#{(steps.include? 'questions') ? 'registered' : ((steps.include? 'contact_info') ? 'preregistered' : 'unregistered')}"), + date: r.created_at ? r.created_at.strftime("%F %T") : '', + city: r.city || '', + preferred_language: user.locale.present? ? (view_context.language_name user.locale) : '', + languages: ((r.languages || []).map { |x| view_context.language_name x }).join(', ').to_s, + arrival: r.arrival ? r.arrival.strftime("%F %T") : '', + departure: r.departure ? r.departure.strftime("%F %T") : '', + housing: r.housing || '', + bike: r.bike.present? ? (view_context._"articles.conference_registration.questions.bike.#{r.bike}") : '', + food: r.food.present? ? (view_context._"articles.conference_registration.questions.food.#{r.food}") : '', + companion: companion, + allergies: r.allergies, + registration_fees_paid: r.registration_fees_paid + } end + end + + if request.format.xlsx? + logger.info "Generating stats.xls" return respond_to do | format | format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" } end else - @registrations = ConferenceRegistration.where(:conference_id => @this_conference.id) + # @registrations = ConferenceRegistration.where(:conference_id => @this_conference.id) @registration_count = @registrations.size @completed_registrations = 0 @bikes = 0 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a1bca27..4839d64 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1288,6 +1288,10 @@ module ApplicationHelper textfield(name, value, options.merge({type: :number})) end + def searchfield(name, value, options = {}) + textfield(name, value, options.merge({type: :search})) + end + def emailfield(name, value, options = {}) textfield(name, value, options.merge({type: :email})) end @@ -1345,7 +1349,7 @@ module ApplicationHelper when :phone input_options[:autocomplete] = 'tel' when :paypal_email_address, :paypal_username, :paypal_password, :paypal_signature - input_options[:autocomplete] = 'false' + input_options[:autocomplete] = 'off' end case options[:type] @@ -1358,6 +1362,7 @@ module ApplicationHelper end html += select_tag(name, option_list, input_options) else + input_options[:autocomplete] = 'off' if options[:type] == :search html += send("#{(options[:type] || :text).to_s}_field_tag", name, value, input_options) end @@ -1544,8 +1549,6 @@ module ApplicationHelper format 'td.bold', font_name: 'Calibri', fg_color: '333333', b: true end - key = excel_data[:key] || 'excel.columns' - content_tag(:table) do (content_tag(:thead) do content_tag(:tr, excel_header_columns(excel_data)) diff --git a/app/views/conferences/admin/_stats.html.haml b/app/views/conferences/admin/_stats.html.haml index c9d0444..15ef688 100644 --- a/app/views/conferences/admin/_stats.html.haml +++ b/app/views/conferences/admin/_stats.html.haml @@ -1,3 +1,4 @@ +- add_inline_script :registrations .details = data_set(:h4, 'articles.admin.stats.headings.completed_registrations') do = (@completed_registrations || 0).to_s @@ -18,3 +19,10 @@ .actions = link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, :stats, :format => :xlsx), class: [:button, :download] = link_to (_'links.download.Organizations_Excel'), administration_step_path(@this_conference.slug, :organizations, :format => :xlsx), class: [:button, :download, :subdued] +%h4 Registrations += searchfield :search, nil, big: true +.table-scroller + %table.registrations.admin-edit + %thead + %tr=excel_header_columns(@excel_data) + %tbody#search-rows=excel_rows(@excel_data) diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index bf4b408..5357f42 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -8,4 +8,4 @@ Rails.application.config.assets.version = '1.0' # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. -Rails.application.config.assets.precompile += %w( user-mailer.css map.js pen.js time.js editor.js markdown.js html2canvas.js main.js housing.js schedule.js favicon.ico ) +Rails.application.config.assets.precompile += %w( user-mailer.css map.js pen.js time.js editor.js markdown.js html2canvas.js main.js registrations.js housing.js schedule.js favicon.ico )