Add mobile support for basic "feedback" dialog

This commit is contained in:
Lance Edgar 2019-03-04 18:12:37 -06:00
parent 006a7096ed
commit ef7466e0d5
4 changed files with 120 additions and 8 deletions

View file

@ -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) // 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. // 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 // 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'); var newlink = ui.toPage.find('.replacement-header a');
link.text(newlink.text()); link.text(newlink.text());
link.attr('href', newlink.attr('href')); 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() { $(document).on('pagecreate', function() {
// setup any autocomplete fields // setup any autocomplete fields

View file

@ -52,7 +52,7 @@
${self.mobile_header()} ${self.mobile_header()}
<div data-role="page" data-url="${self.page_url()}"${' data-rel="dialog"' if dialog else ''|n}> <div data-role="page" data-url="${self.page_url()}">
${self.mobile_usermenu()} ${self.mobile_usermenu()}
@ -86,20 +86,26 @@
<div data-role="header"> <div data-role="header">
${self.mobile_header_link()} ${self.mobile_header_link()}
<h1>${base_meta.global_title()}</h1> <h1>${base_meta.global_title()}</h1>
${self.mobile_header_feedback()}
</div> </div>
</%def> </%def>
<%def name="mobile_header_link()"> <%def name="mobile_header_link()">
<% classes = 'ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all ui-btn-icon-left ' %> <% classes = 'ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all ui-btn-icon-left ' %>
% if request.user: % 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'): % 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: % 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 % endif
</%def> </%def>
<%def name="mobile_header_feedback()">
${h.link_to("Feedback", '#', id='feedback-button', data_role='button', data_icon='recycle')}
</%def>
<%def name="mobile_usermenu()"> <%def name="mobile_usermenu()">
<div id="usermenu" data-role="panel" data-display="overlay"> <div id="usermenu" data-role="panel" data-display="overlay">
<ul data-role="listview"> <ul data-role="listview">
@ -137,6 +143,15 @@
${self.body()} ${self.body()}
<div data-role="popup" data-overlay-theme="b" id="feedback-popup" class="ui-content">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
${self.mobile_feedback_form()}
</div>
<div data-role="popup" data-overlay-theme="b" id="feedback-thanks" class="ui-content">
Thank you for your feedback.
</div>
<div class="replacement-header"> <div class="replacement-header">
${self.mobile_header_link()} ${self.mobile_header_link()}
</div> </div>
@ -149,3 +164,45 @@
<h4>powered by ${h.link_to("Rattail", url('mobile.about'))}</h4> <h4>powered by ${h.link_to("Rattail", url('mobile.about'))}</h4>
</div> </div>
</%def> </%def>
<%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)}
<p>
Questions, suggestions, comments, complaints, etc. <span class="red">regarding this website</span>
are welcome and may be submitted below.
</p>
<div class="field-wrapper referrer">
<label for="referrer">Referring URL</label>
<div class="field"></div>
${h.hidden('referrer')}
</div>
% if request.user:
${h.hidden('user_name', value=six.text_type(request.user))}
% else:
<div class="field-wrapper user_name">
<label for="user_name">Your Name</label>
<div class="field">
${h.text('user_name')}
</div>
</div>
% endif
<div class="field-wrapper message">
<label for="message">Message</label>
<div class="field">
${h.textarea('message', cols=45, rows=15)}
</div>
</div>
<div class="buttons" id="feedback-form-buttons">
<button type="button" data-inline="true" class="submit" data-theme="b">Send Note</button>
<button type="button" data-inline="true" class="cancel">Cancel</button>
</div>
${h.end_form()}
</%def>

View file

@ -125,7 +125,6 @@ class AuthenticationView(View):
'form': form, 'form': form,
'referrer': referrer, 'referrer': referrer,
'image_url': image_url, 'image_url': image_url,
'dialog': mobile,
} }
def authenticate_user(self, username, password): def authenticate_user(self, username, password):

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2018 Lance Edgar # Copyright © 2010-2019 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -144,7 +144,7 @@ class CommonView(View):
def feedback(self): 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) form = forms.Form(schema=Feedback(), request=self.request)
if form.validate(newstyle=True): if form.validate(newstyle=True):
@ -156,6 +156,12 @@ class CommonView(View):
return {'ok': True} return {'ok': True}
return {'error': "Form did not validate!"} 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): def consume_batch_id(self):
""" """
Consume next batch ID from the PG sequence, and display via flash message. Consume next batch ID from the PG sequence, and display via flash message.
@ -214,6 +220,8 @@ class CommonView(View):
# feedback # feedback
config.add_route('feedback', '/feedback', request_method='POST') config.add_route('feedback', '/feedback', request_method='POST')
config.add_view(cls, attr='feedback', route_name='feedback', renderer='json') 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 # consume batch ID
config.add_tailbone_permission('common', 'common.consume_batch_id', config.add_tailbone_permission('common', 'common.consume_batch_id',