From ef7466e0d5534858748c8329ca976af5765950bd Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 4 Mar 2019 18:12:37 -0600 Subject: [PATCH] Add mobile support for basic "feedback" dialog --- tailbone/static/js/tailbone.mobile.js | 50 ++++++++++++++++++++- tailbone/templates/mobile/base.mako | 65 +++++++++++++++++++++++++-- tailbone/views/auth.py | 1 - tailbone/views/common.py | 12 ++++- 4 files changed, 120 insertions(+), 8 deletions(-) diff --git a/tailbone/static/js/tailbone.mobile.js b/tailbone/static/js/tailbone.mobile.js index 15ac0cd4..432f3170 100644 --- a/tailbone/static/js/tailbone.mobile.js +++ b/tailbone/static/js/tailbone.mobile.js @@ -20,7 +20,7 @@ $(document).on('pagecontainerchange', function(event, ui) { // in some cases (i.e. when no user is logged in) we may want the (external) // header toolbar button to change between pages. here's how we do that. // note however that we do this *always* even when not technically needed - var link = $('[data-role="header"] a'); + var link = $('[data-role="header"] a:first'); var newlink = ui.toPage.find('.replacement-header a'); link.text(newlink.text()); link.attr('href', newlink.attr('href')); @@ -29,6 +29,54 @@ $(document).on('pagecontainerchange', function(event, ui) { }); +$(document).on('click', '#feedback-button', function() { + + // prepare and display 'feedback' popup dialog + var popup = $('.ui-page-active #feedback-popup'); + popup.find('.referrer .field').html(location.href); + popup.find('.referrer input').val(location.href); + popup.find('.user_name input').val(''); + popup.find('.message textarea').val(''); + popup.data('feedback-sent', false); + popup.popup('open'); +}); + + +$(document).on('click', '#feedback-popup .submit', function() { + + // send message when 'feedback' submit button pressed + var popup = $('.ui-page-active #feedback-popup'); + var form = popup.find('form'); + $.post(form.attr('action'), form.serializeArray(), function(data) { + if (data.ok) { + + // mark "feedback sent" flag, for popupafterclose + popup.data('feedback-sent', true); + popup.popup('close'); + } + }); + +}); + + +$(document).on('click', '#feedback-form-buttons .cancel', function() { + + // close 'feedback' popup when user clicks Cancel + var popup = $('.ui-page-active #feedback-popup'); + popup.popup('close'); +}); + + +$(document).on('popupafterclose', '#feedback-popup', function() { + + // thank the user for their feedback, after msg is sent + if ($(this).data('feedback-sent')) { + var popup = $('.ui-page-active #feedback-thanks'); + popup.popup('open'); + } +}); + + $(document).on('pagecreate', function() { // setup any autocomplete fields diff --git a/tailbone/templates/mobile/base.mako b/tailbone/templates/mobile/base.mako index 11ee47ef..c05c2100 100644 --- a/tailbone/templates/mobile/base.mako +++ b/tailbone/templates/mobile/base.mako @@ -52,7 +52,7 @@ ${self.mobile_header()} -
+
${self.mobile_usermenu()} @@ -86,20 +86,26 @@
${self.mobile_header_link()}

${base_meta.global_title()}

+ ${self.mobile_header_feedback()}
<%def name="mobile_header_link()"> <% classes = 'ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all ui-btn-icon-left ' %> % if request.user: - ${h.link_to(request.user.get_short_name(), '#usermenu', class_=classes + 'ui-icon-user' + (' root-user' if request.is_root else ''))} + ${h.link_to(request.user.get_short_name(), '#usermenu', data_role='button', data_icon='user', + class_=' root-user' if request.is_root else '')} % elif request.matched_route.name in ('mobile.login', 'mobile.about'): - ${h.link_to("Home", url('mobile.home'), class_=classes + 'ui-icon-home')} + ${h.link_to("Home", url('mobile.home'), data_role='button', data_icon='home')} % else: - ${h.link_to("Login", url('mobile.login'), class_=classes + 'ui-icon-user')} + ${h.link_to("Login", url('mobile.login'), data_role='button', data_icon='user')} % endif +<%def name="mobile_header_feedback()"> + ${h.link_to("Feedback", '#', id='feedback-button', data_role='button', data_icon='recycle')} + + <%def name="mobile_usermenu()">
    @@ -137,6 +143,15 @@ ${self.body()} +
    + Close + ${self.mobile_feedback_form()} +
    + +
    + Thank you for your feedback. +
    +
    ${self.mobile_header_link()}
    @@ -149,3 +164,45 @@

    powered by ${h.link_to("Rattail", url('mobile.about'))}

+ +<%def name="mobile_feedback_form()"> + ${h.form(url('mobile.feedback'))} + ${h.csrf_token(request)} + ${h.hidden('user', value=request.user.uuid if request.user else None)} + +

+ Questions, suggestions, comments, complaints, etc. regarding this website + are welcome and may be submitted below. +

+ +
+ +
+ ${h.hidden('referrer')} +
+ + % if request.user: + ${h.hidden('user_name', value=six.text_type(request.user))} + % else: +
+ +
+ ${h.text('user_name')} +
+
+ % endif + +
+ +
+ ${h.textarea('message', cols=45, rows=15)} +
+
+ +
+ + +
+ + ${h.end_form()} + diff --git a/tailbone/views/auth.py b/tailbone/views/auth.py index 86406aed..7e7713fc 100644 --- a/tailbone/views/auth.py +++ b/tailbone/views/auth.py @@ -125,7 +125,6 @@ class AuthenticationView(View): 'form': form, 'referrer': referrer, 'image_url': image_url, - 'dialog': mobile, } def authenticate_user(self, username, password): diff --git a/tailbone/views/common.py b/tailbone/views/common.py index 14370ad4..b5ad562a 100644 --- a/tailbone/views/common.py +++ b/tailbone/views/common.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2018 Lance Edgar +# Copyright © 2010-2019 Lance Edgar # # This file is part of Rattail. # @@ -144,7 +144,7 @@ class CommonView(View): def feedback(self): """ - Generic view to present/handle the user feedback form. + Generic view to handle the user feedback form. """ form = forms.Form(schema=Feedback(), request=self.request) if form.validate(newstyle=True): @@ -156,6 +156,12 @@ class CommonView(View): return {'ok': True} return {'error': "Form did not validate!"} + def mobile_feedback(self): + """ + Generic view to handle the user feedback form on mobile. + """ + return self.feedback() + def consume_batch_id(self): """ Consume next batch ID from the PG sequence, and display via flash message. @@ -214,6 +220,8 @@ class CommonView(View): # feedback config.add_route('feedback', '/feedback', request_method='POST') config.add_view(cls, attr='feedback', route_name='feedback', renderer='json') + config.add_route('mobile.feedback', '/mobile/feedback', request_method='POST') + config.add_view(cls, attr='mobile_feedback', route_name='mobile.feedback', renderer='json') # consume batch ID config.add_tailbone_permission('common', 'common.consume_batch_id',