Verified Commit 04884e61 authored by Kaspar Vollenweider's avatar Kaspar Vollenweider 👻
Browse files

button that commits xhr put request and renders the response data in template

- it doesn't reload the page
- it shows model save errors as list
- it renders json response from the xhr action to template passed to api_button
  - using lodash tmplate
parent f917a73d
$(() => {
$('.api-button').click(({target}) => {
const { method, url, template } = $(target).data()
const tableCell = target.closest('td')
$.ajax({ method, url, dataType: 'json' })
.done(data => {
if (data.errors) {
$(tableCell).append(`<p class="text-danger">Es gab einen Fehler: ${data.errors.join('; ')}</p>`)
} else {
const compiled = _.template(template, { 'variable': 'data', 'imports': { 'data': data } })
target.remove()
$(tableCell).append(compiled(data))
}
})
})
})
\ No newline at end of file
......@@ -51,18 +51,29 @@ class FeedbacksController < ApplicationController
end
def mark_as_done
if @feedback.update(reviewer: current_user)
redirect_to(@redirect_back_path, notice: 'Halbjahres-Rapport quittiert.')
else
redirect_to(@redirect_back_path, notice: 'Fehler: Quittieren fehlgeschlagen.')
respond_to do |format|
if @feedback.update(reviewer: current_user)
format.html { redirect_to(@redirect_back_path, notice: 'Halbjahres-Rapport quittiert.') }
format.json { render json: { link: polymorphic_path([@feedback.volunteer, @feedback.feedbackable, @feedback]) }, status: :ok }
else
format.html { redirect_to(@redirect_back_path, notice: 'Fehler: Quittieren fehlgeschlagen.') }
format.json { render json: { errors: @feedback.errors.messages }, status: :unprocessable_entity }
end
end
end
def take_responsibility
if @feedback.update(responsible: current_user)
redirect_to(@redirect_back_path, notice: 'Halbjahres-Rapport übernommen.')
else
redirect_to(@redirect_back_path, notice: 'Fehler: Übernehmen fehlgeschlagen.')
respond_to do |format|
if @feedback.update(responsible: current_user)
format.html { redirect_to(@redirect_back_path, notice: 'Halbjahres-Rapport übernommen.') }
format.json do
render json: { link: url_for(@feedback.responsible), at: I18n.l(@feedback.responsible_at.to_date),
email: @feedback.responsible.email }, status: :ok
end
else
format.html { redirect_to(@redirect_back_path, notice: 'Fehler: Übernehmen fehlgeschlagen.') }
format.json { render json: { errors: @feedback.errors.messages }, status: :unprocessable_entity }
end
end
end
......
module ApiButtonHelper
# api_button helper
#
# params:
# text - the links text (required)
# subject - polymorphic object array or single object (required) - [volunteer, assignment, feedback]
# action - the controller action for the subject (optional) - skip if its intended for update action
# class - additional classes to the bootstrap btn classes (optional) - string with space separated
# size - the bootstrap button size class (optional) - default 'btn-xs'
# button_type - bootstrap button type (optional) - default 'btn-default'
# data - hash containing extra data attributes
# template - string for being rendered with the data in the response - https://lodash.com/docs/4.17.10#template
def api_button(text, params)
tag.button(
text,
class: api_button_class(params),
data: api_button_data(params)
)
end
def api_button_class(params)
extra_classes = params[:class]&.split(' ') || []
button_type = params[:button_type] || 'btn-default'
size = params[:size] || 'btn-xs'
(['api-button', 'btn', size, button_type] + extra_classes).join(' ')
end
def api_button_data(params)
{
template: params[:template],
method: params[:method]&.to_s&.upcase || :PUT,
url: polymorphic_url(api_button_subject(params), action: params[:action] || nil)
}.merge(params[:data] || {})
end
def api_button_subject(params)
subject = params.fetch(:subject) || []
if subject.is_a?(Array)
subject
else
[subject]
end
end
end
......@@ -66,16 +66,15 @@ table.table.table-striped.list-responses-table
= link_to record.responsible.email, record.responsible
= " am #{l(record.responsible_at.to_date)}"
- else
= link_to 'Übernehmen', polymorphic_path([record.volunteer, record.feedbackable, record],
action: :take_responsibility, q: search_parameters, page: params[:page]),
{ method: :put, class: 'btn btn-default btn-xs m-t-10' }
= api_button('Übernehmen', subject: [record.volunteer, record.feedbackable, record],
action: :take_responsibility, extra_class: 'm-t-10',
template: 'Übernommen durch <a href="<%= data.link %>"><%= data.email %></a> am <%= data.at %>')
td.index-action-cell.hidden-print
- if record.reviewer.present?
= link_to 'Anzeigen', polymorphic_path([record.volunteer, record.feedbackable, record])
- else
= link_to 'Quittieren', polymorphic_path([record.volunteer, record.feedbackable, record],
action: :mark_as_done, q: search_parameters),
{ method: :put, class: 'btn btn-default btn-xs m-t-10' }
= api_button 'Quittieren', subject: [record.volunteer, record.feedbackable, record],
action: :mark_as_done, extra_class: 'm-t-10',
template: '<a href="<%= data.link %>">Anzeigen</a>'
= bootstrap_paginate(@feedbacks)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment