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)
// 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

View file

@ -52,7 +52,7 @@
${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()}
@ -86,20 +86,26 @@
<div data-role="header">
${self.mobile_header_link()}
<h1>${base_meta.global_title()}</h1>
${self.mobile_header_feedback()}
</div>
</%def>
<%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>
<%def name="mobile_header_feedback()">
${h.link_to("Feedback", '#', id='feedback-button', data_role='button', data_icon='recycle')}
</%def>
<%def name="mobile_usermenu()">
<div id="usermenu" data-role="panel" data-display="overlay">
<ul data-role="listview">
@ -137,6 +143,15 @@
${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">
${self.mobile_header_link()}
</div>
@ -149,3 +164,45 @@
<h4>powered by ${h.link_to("Rattail", url('mobile.about'))}</h4>
</div>
</%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,
'referrer': referrer,
'image_url': image_url,
'dialog': mobile,
}
def authenticate_user(self, username, password):

View file

@ -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',