]> git.agnieray.net Git - galette.git/commitdiff
Move batch actions buttons to dropdown
authorGuillaume AGNIERAY <dev@agnieray.net>
Tue, 31 Jan 2023 16:22:10 +0000 (17:22 +0100)
committerJohan Cwiklinski <johan@x-tnd.be>
Mon, 6 Feb 2023 17:49:31 +0000 (18:49 +0100)
Batch actions upward dropdown button style

Fix _bind_check()

Restore members batch actions modals

Rework members batch actions modals

Fix (almost) all members batch actions in dropdown

Fix twig CS

Get members list modals header from template

Rename "ajax" twig variable

Renamed to "mode" for consistency with other ajax templates.

Fix sendmail and attendance_sheet batch actions

Some comments and refactoring

Clean debug

Destroy multistep modals on cancel to reset steps

Fix mass contributions template

Clean comment

Remove useless code

Fix sendmail batch action

Use direct download on all needed batch actions

Remove more useless js code

Fix redirects after batch actions

Clean useless js

14 files changed:
galette/lib/Galette/Controllers/PdfController.php
galette/lib/Galette/Core/Galette.php
galette/templates/default/elements/js/removal.js.twig
galette/templates/default/elements/list.html.twig
galette/templates/default/macros.twig
galette/templates/default/modals/mass_add_contributions.html.twig
galette/templates/default/modals/mass_change_members.html.twig
galette/templates/default/modals/mass_choose_contributions_type.html.twig
galette/templates/default/modals/members_attendance_sheet.html.twig
galette/templates/default/pages/contribution_form.html.twig
galette/templates/default/pages/contributions_list.html.twig
galette/templates/default/pages/members_list.html.twig
ui/js/common.js
ui/semantic/galette/elements/button.overrides

index c3ac359af588792de6af621d845c8e13db4f30d2..95b50072112c272a5e9a3f1506881ee038ded19a 100644 (file)
@@ -320,18 +320,18 @@ class PdfController extends AbstractController
         $ajax = false;
         if (
             $request->isXhr()
-            || (isset($post['ajax'])
-            && $post['ajax'] == 'true')
+            || (isset($post['mode'])
+            && $post['mode'] == 'ajax')
         ) {
             $ajax = true;
 
             //retrieve selected members
-            $selection = $post['selection'] ?? array();
+            $data = $post['selection'] ?? array();
 
-            $filters->selected = $selection;
+            $filters->selected = $data;
             $this->session->filter_members = $filters;
         } else {
-            $selection = $filters->selected;
+            $data = $filters->selected;
         }
 
         // display page
@@ -340,8 +340,8 @@ class PdfController extends AbstractController
             'modals/members_attendance_sheet.html.twig',
             [
                 'page_title'    => _T("Attendance sheet configuration"),
-                'ajax'          => $ajax,
-                'selection'     => $selection
+                'mode'          => $ajax,
+                'data'          => $data
             ]
         );
         return $response;
index af114145bedcb3995b409feea6de44655b77ebc5..e039e3be6bc6fde4c8c4e717a1d730b5c35f1afa 100644 (file)
@@ -910,17 +910,17 @@ class Galette
                         'icon' => 'file alternate'
                     ],
                     [
-                        'name' => 'labels',
+                        'name' => 'labels__directdownload',
                         'label' => _T('Generate labels'),
                         'icon' => 'address card'
                     ],
                     [
-                        'name' => 'cards',
+                        'name' => 'cards__directdownload',
                         'label' => _T('Generate Member Cards'),
                         'icon' => 'id badge'
                     ],
                     [
-                        'name' => 'csv',
+                        'name' => 'csv__directdownload',
                         'label' => _T('Export as CSV'),
                         'icon' => 'file csv'
                     ],
index 7bc30c2c343f4f793631951129d48ccf17cd808a..c77f801b38a13159a072b15ea414eaf90ffbb49f 100644 (file)
@@ -2,10 +2,11 @@
     {% set selector = '.delete' %}
 {% endif %}
         //handle removals
+{% if single_action is defined %}
         $('{{ selector }}').off('click').on('click', function(event) {
             event.preventDefault();
             var _this = $(this);
-
+{% endif %}
 {% if extra_check is defined %}
             {{ extra_check }}
 {% endif %}
@@ -81,4 +82,6 @@
                     alert('{{ _T("An error occurred :(")|e("js") }}');
                 }
             });
+{% if single_action is defined %}
         });
+{% endif %}
index d3586ddc264c953f322f820d208e2b43cf5740c2..68487cb914ff139114cd0882db76f43edb7ed8d4 100644 (file)
     {% endblock %}
     <form action="{%  if form.route is defined %}{{ path_for(form.route.name, form.route.args|default([])) }}{% endif %}" method="post" id="listform" class="ui form">
         <div class="ui basic fitted segment">
-        <table class="listing ui celled table">
-            <thead>
-            <tr>
+
+        {% if batch_actions is defined and batch_actions|length > 0 %}
+            {{ macros.drawBatchActionsList(batch_actions) }}
+        {% endif %}
+
+            <table class="listing ui celled table">
+                <thead>
+                    <tr>
                 {% block header %}
                     {% for column in columns %}
                         <th class="left">
                         </th>
                     {% endfor %}
                     {% if mode != 'ajax' and no_action is not defined or no_action == false %}
-                    <th class="actions_row">{{ _T('Actions') }}</th>
+                        <th class="actions_row">{{ _T('Actions') }}</th>
                     {% endif %}
                 {% endblock %}
-            </tr>
-            </thead>
-            <tbody>
-                {% block body %}{% endblock %}
-            </tbody>
-            <tfoot>
-                {% block footer %}{% endblock %}
-            </tfoot>
-        </table>
-        </div>
+                    </tr>
+                </thead>
+                <tbody>
+                    {% block body %}{% endblock %}
+                </tbody>
+                <tfoot>
+                    {% block footer %}{% endblock %}
+                </tfoot>
+            </table>
 
         {% if batch_actions is defined and batch_actions|length > 0 %}
-            <div class="ui bottom attached segment screen-only selection_menu">
-                <div class="ui horizontal list">
-                    <span class="ui primary ribbon label">{{ _T('For the selection:') }}</span>
-                    {% for batch_action in batch_actions %}
-                        {{ macros.drawBatchAction(batch_action.name, batch_action.label, batch_action.icon, batch_action.title ?? null) }}
-                    {% endfor %}
-                </div>
-            </div>
+            {{ macros.drawBatchActionsList(batch_actions) }}
         {% endif %}
 
+        </div>
+
         {% if is_paginated %}
-            <div class="ui basic center aligned fitted segment">
-                <div class="ui inverted pagination menu">
-                    <div class="header item">
-                        {{ _T('Pages:') }}
-                    </div>
-                    {{ pagination|raw }}
+        <div class="ui basic center aligned fitted segment">
+            <div class="ui inverted pagination menu">
+                <div class="header item">
+                    {{ _T('Pages:') }}
                 </div>
+                {{ pagination|raw }}
             </div>
+        </div>
         {% endif %}
 
         {% block extra_form %}{% endblock %}
     {% if batch is defined and batch_actions is defined and batch_actions|length > 0 %}
             var _init_page = function(res){
         {% if login.isAdmin() or login.isStaff() %}
-                {# Use of Javascript to draw specific elements that are not relevant is JS is inactive #}
-                var _checklinks = '<div class="checkboxes ui basic horizontal segments"><div class="ui basic fitted segment">' +
-                    '<a href="#" class="checkall ui blue tertiary button">{{ _T("(Un)Check all")|e('js') }}</a>' +
-                    ' | <a href="#" class="checkinvert ui blue tertiary button">{{ _T("Invert selection")|e('js') }}</a></div>';
+                {# Use of Javascript to draw specific elements that are not relevant if JS is inactive #}
+                var _checklinks = '<a href="#" class="checkall ui blue tertiary button">{{ _T("(Un)Check all")|e('js') }}</a>' +
+                    ' | <a href="#" class="checkinvert ui blue tertiary button">{{ _T("Invert selection")|e('js') }}</a> | ';
             {% if _legend_block is not empty %}
-                _checklinks += '<div class="ui basic right aligned fitted segment"><a href="#" class="show_legend ui blue tertiary button">{{ _T("Show legend")|e('js') }}</a></div></div>';
+                var _legendlink = '<div class="ui basic right aligned fitted segment"><a href="#" class="show_legend ui blue tertiary button">{{ _T("Show legend")|e('js') }}</a></div></div>';
             {% endif %}
-
-                $('.listing').before(_checklinks);
-                $('.listing').after(_checklinks);
-                _bind_check('entries_sel');
-        {% endif %}
-
-                $('.selection_menu *[type="submit"], .selection_menu *[type="button"]').click(function(event) {
-                    //mass removal is handled from 2 steps removal
-                    {% set batch_excludes = ['delete']|merge(batch_excludes|default([])) %}
-                    if (
-                        {% for batch_exclude in batch_excludes %}
-                            {% if not loop.first %} || {% endif %}this.id == '{{ batch_exclude }}'
-                        {% endfor %}
-                    ) {
-                        return;
-                    }
-
-                    if (!_checkselection()) {
-                        return false;
-                    } else {
+                $('.batch-select-action').before(_checklinks);
+                $('.batch-select-action').dropdown({
+                    onChange: function(value, text, $selectedItem) {
+                        if (!_checkselection()) {
+                            return false;
+                        }
+                        // Handle direct download actions.
+                        if (value.endsWith('__directdownload')) {
+                            const _value = value.split('__');
+                            var value = _value[0];
+                            var _form = $('#listform');
+                                _form.append($('<input type="hidden" name="' + value + '" value="true"/>'));
+                            _form.submit();
+                        // Handle delete.
+                        } else if (value == 'delete') {
+                            {% include "elements/js/removal.js.twig" with {
+                                selector: ".batch-delete",
+                                deleteurl: path_for(batch.route.name, batch.route.args|default([])),
+                                extra_data: "delete: true, entries_sel: $('#listform input[type=\"checkbox\"]:checked').map(function(){ return $(this).val(); }).get()",
+                                method: "POST",
+                                loader: "button",
+                                loader_parent: ".batch-select-action"
+                            } %}
+                        }
+                        // Handle other custom list actions.
+                {% if batch_selection is defined %}
                         {% block batch_selection %}{% endblock %}
+                {% endif %}
                     }
                 });
+                $('.batch-selection').after(_legendlink);
+                _bind_check('entries_sel');
+        {% endif %}
             }
             _init_page();
-
-            {% include "elements/js/removal.js.twig" with {
-                selector: "#delete",
-                deleteurl: path_for(batch.route.name, batch.route.args|default([])),
-                extra_check: "if (!_checkselection()) { return false; }",
-                extra_data: "delete: true, entries_sel: $('#listform input[type=\"checkbox\"]:checked').map(function(){ return $(this).val(); }).get()",
-                method: "POST",
-                loader: "button"
-            } %}
     {% endif %}
     {% if _legend_block is not empty %}
             _bind_legend();
     {% endif %}
-            {% include "elements/js/removal.js.twig" %}
+            {% include "elements/js/removal.js.twig" with {
+                single_action: "true"
+            } %}
         });
     </script>
 {% endblock %}
index 57428af349ff39cfdc5851d5e842d36f59869e1e..76cca3362e76df2688a122f8ec107ff102d55504 100644 (file)
     </a>
 {% endmacro %}
 
-{% macro drawBatchAction(name, label, icon, title) %}
-    <div class="item">
-        <button type="submit" id="{{ name }}" name="{{ name }}" class="ui labeled icon tiny button"{% if title %} title="{{ title }}"{% endif %}>
-            <i class="{{ icon }} icon"></i> {{ label }}
-        </button>
+{% macro drawBatchActionsList(batch_actions) %}
+    <div class="checkboxes ui basic horizontal segments">
+        <div class="ui basic fitted segment batch-selection">
+            <div class="ui blue tertiary dropdown icon button batch-select-action">
+                <i class="tasks icon"></i>
+                {{ _T('For the selection:') }}
+                <i class="dropdown icon"></i>
+                <div class="menu">
+                {% for batch_action in batch_actions %}
+                    {{ _self.drawBatchAction(batch_action.name, batch_action.label, batch_action.icon, batch_action.title ?? null) }}
+                {% endfor %}
+                </div>
+            </div>
+        </div>
     </div>
 {% endmacro %}
+
+{% macro drawBatchAction(name, label, icon, title) %}
+    <span class="ui item batch-action batch-{{ name }}" data-value="{{ name }}"{% if title %} title="{{ title }}"{% endif %}>
+        <i class="{{ icon }} icon"></i> {{ label }}
+    </span>
+{% endmacro %}
index 747f984f7866c9abd536c7c83124d461cbc8c047..e9bc1cff3b780f35c48e72d09c640e69d90290cc 100644 (file)
@@ -1,16 +1,26 @@
 {% extends 'pages/contribution_form.html.twig' %}
 
 {% block content %}
-    <div id="mass_contributions"{% if mode != 'ajax' %} class="center"{% else %} class="ui modal" title="{{ page_title }}"{% endif %}>
+    <div id="mass_contributions"{% if mode != 'ajax' %} class="center"{% else %} class="ui modal"{% endif %}>
     {% if mode == 'ajax' %}
-        <div class="fullscreen content scrolling">
+        <div class="header">
+    {% else %}
+        <h2>
     {% endif %}
-            <form action="{{ form_url }}" method="post">
-                {% if mode != 'ajax' %}<h2>{{ page_title }}</h2>{% endif %}
+            {{ page_title }}
+    {% if mode != 'ajax' %}
+        </h2>
+    {% else %}
+        </div>
+        <div class="content scrolling">
+    {% endif %}
+            <form action="{{ form_url }}" method="post" class="ui form">
+                {{ parent() }}
                 <div class="button-container">
-                    {{ parent() }}
-                    <input type="submit" id="masschange" class="button" value="{% if changes is not defined %}{{ _T("Edit") }}{% else %}{{ _T("OK") }}{% endif %}"/>
-                    <a href="{{ cancel_uri }}" class="button" id="btncancel">{{ _T("Cancel") }}</a>
+                    {% if mode != 'ajax' %}
+                        <input type="submit" id="masschange" class="ui button" value="{% if changes is not defined %}{{ _T("Edit") }}{% else %}{{ _T("OK") }}{% endif %}"/>
+                        <a href="{{ cancel_uri }}" class="ui button" id="btncancel">{{ _T("Cancel") }}</a>
+                    {% endif %}
                     <input type="hidden" name="confirm" value="1"/>
                     {% if mode == 'ajax' %}<input type="hidden" name="ajax" value="true"/>{% endif %}
                     {% for key, value in data %}
index ec27ecb93db7725a11c483b9a5f4bd5a813d6287..0a221eb40482cc72f105867032fd271f2fe08386 100644 (file)
@@ -1,12 +1,20 @@
 {% extends (mode == 'ajax') ? "ajax.html.twig" : "page.html.twig" %}
 
 {% block content %}
-    <div id="mass_change"{% if mode != 'ajax' %} class="center"{% else %} class="ui modal" title="{{ page_title }}"{% endif %}>
+    <div id="mass_change"{% if mode != 'ajax' %} class="center"{% else %} class="ui modal"{% endif %}>
     {% if mode == 'ajax' %}
+        <div class="header">
+    {% else %}
+        <h2>
+    {% endif %}
+            {{ page_title }}
+    {% if mode != 'ajax' %}
+        </h2>
+    {% else %}
+        </div>
         <div class="content scrolling">
     {% endif %}
             <form action="{{ form_url }}" method="post" class="ui form">
-                {% if mode != 'ajax' %}<h2>{{ page_title }}</h2>{% endif %}
             {% if changes is not defined %}
                 <p>{{ _T("Only checked fields will be updated.") }}</p>
                 {# Form entries #}
                 </ul>
             {% endif %}
                 <div class="button-container">
-                    <input type="submit" id="masschange" class="ui button" value="{% if changes is not defined %}{{ _T("Edit") }}{% else %}{{ _T("OK") }}{% endif %}"/>
-                    <a href="{{ cancel_uri }}" class="ui button" id="btncancel">{{ _T("Cancel") }}</a>
+                    {% if mode != 'ajax' %}
+                        <input type="submit" id="masschange" class="ui button" value="{% if changes is not defined %}{{ _T("Edit") }}{% else %}{{ _T("OK") }}{% endif %}"/>
+                        <a href="{{ cancel_uri }}" class="ui button" id="btncancel">{{ _T("Cancel") }}</a>
+                    {% endif %}
                     <input type="hidden" name="confirm" value="1"/>
                     {% if mode == 'ajax' %}<input type="hidden" name="ajax" value="true"/>{% endif %}
                     {% for key, value in data %}
index 3a62d40e204975e0226e71d64be0321f06220ac8..d6bd3dff68cc17336d2598a5382f98ddc95a4c49 100644 (file)
@@ -1,29 +1,47 @@
 {% extends (mode == 'ajax') ? "ajax.html.twig" : "page.html.twig" %}
 
 {% block content %}
-    <div id="mass_contributions"{% if mode != 'ajax' %} class="center"{% else %} title="{{ page_title }}"{% endif %}>
-    <form action="{{ form_url }}" method="post">
-        {% if mode != 'ajax' %}<h2>{{ page_title }}</h2>{% endif %}
-        <label for="type">{{ _T("Contribution type") }}</label>
-        <select name="type" id="type">
-            <option value="{{ constant('Galette\\Entity\\Contribution::TYPE_FEE') }}">{{ _T("Membership") }}</option>
-            <option value="{{ constant('Galette\\Entity\\Contribution::TYPE_DONATION') }}">{{ _T("Donation") }}</option>
-        </select>
-        <div class="button-container">
-            <input type="submit" id="masschange" class="button" value="{{ _T("OK") }}"/>
-            <a href="{{ cancel_uri }}" class="button" id="btncancel">{{ _T("Cancel") }}</a>
-            {% if mode == 'ajax' %}<input type="hidden" name="ajax" value="true"/>{% endif %}
-            {% for key, value in data %}
-                {% if value is iterable %}
-                    {% for val in value %}
-                <input type="hidden" name="{{ key }}[]" value="{{ val }}"/>
+    <div id="mass_contributions"{% if mode != 'ajax' %} class="center"{% else %} class="ui modal"{% endif %}>
+    {% if mode == 'ajax' %}
+        <div class="header">
+    {% else %}
+        <h2>
+    {% endif %}
+            {{ page_title }}
+    {% if mode != 'ajax' %}
+        </h2>
+    {% else %}
+        </div>
+        <div class="content scrolling">
+    {% endif %}
+            <form action="{{ form_url }}" method="post" class="ui form">
+                <div class="inline field">
+                    <label for="type">{{ _T("Contribution type") }}</label>
+                    <select name="type" id="type" class="ui dropdown">
+                        <option value="{{ constant('Galette\\Entity\\Contribution::TYPE_FEE') }}">{{ _T("Membership") }}</option>
+                        <option value="{{ constant('Galette\\Entity\\Contribution::TYPE_DONATION') }}">{{ _T("Donation") }}</option>
+                    </select>
+                </div>
+                <div class="button-container">
+                    {% if mode != 'ajax' %}
+                        <input type="submit" id="masschange" class="ui button" value="{{ _T("OK") }}"/>
+                        <a href="{{ cancel_uri }}" class="ui button" id="btncancel">{{ _T("Cancel") }}</a>
+                    {% endif %}
+                    {% if mode == 'ajax' %}<input type="hidden" name="ajax" value="true"/>{% endif %}
+                    {% for key, value in data %}
+                        {% if value is iterable %}
+                            {% for val in value %}
+                        <input type="hidden" name="{{ key }}[]" value="{{ val }}"/>
+                            {% endfor %}
+                        {% else %}
+                        <input type="hidden" name="{{ key }}" value="{{ value }}"/>
+                        {% endif %}
                     {% endfor %}
-                {% else %}
-                <input type="hidden" name="{{ key }}" value="{{ value }}"/>
-                {% endif %}
-            {% endfor %}
-            {% include "components/forms/csrf.html.twig" %}
+                    {% include "components/forms/csrf.html.twig" %}
+                </div>
+            </form>
+    {% if mode == 'ajax' %}
         </div>
-    </form>
+    {% endif %}
     </div>
 {% endblock %}
index 691a33aecd007a1ddc62ad24b84bf4caeaef2c05..9cdeb0de0ab609843897b10705e55aa9c1aa0102 100644 (file)
@@ -1,47 +1,64 @@
-{% extends (ajax) ? "ajax.html.twig" : "page.html.twig" %}
+{% extends (mode == 'ajax') ? "ajax.html.twig" : "page.html.twig" %}
 
 {% block content %}
-    <form action="{{ path_for('attendance_sheet') }}" id="sheet_details_form" method="POST" class="ui form">
-        <div class="ui top attached accordion-styled header">
-            {{ _T("Some details about your attendance sheet...") }} - <span>{{ _T("%s attendees")|replace({'%s': selection|length}) }}</span>
+    <div id="attendance_sheet_details"{% if mode != 'ajax' %} class="center"{% else %} class="ui modal"{% endif %}>
+    {% if mode == 'ajax' %}
+        <div class="header">
+    {% else %}
+        <h2>
+    {% endif %}
+            {{ page_title }}
+    {% if mode != 'ajax' %}
+        </h2>
+    {% else %}
         </div>
-        <div class="ui bottom attached accordion-styled segment">
-            <div class="active content field">
-                <div class="inline field">
-                    <label for="sheet_type">{{ _T("Sheet type") }}</label>
-                    <input type="text" name="sheet_type" id="sheet_type" value="{{ _T("Attendance sheet") }}" required/>
+        <div class="content scrolling">
+    {% endif %}
+            <form action="{{ path_for('attendance_sheet') }}" id="sheet_details_form" method="POST" class="ui form">
+                <div class="ui top attached accordion-styled header">
+                    {{ _T("Some details about your attendance sheet...") }} - <span>{{ _T("%s attendees")|replace({'%s': data|length}) }}</span>
                 </div>
-                <div class="inline field">
-                    <label for="sheet_title">{{ _T("Title") }}</label>
-                    <input type="text" name="sheet_title" id="sheet_title"/>
+                <div class="ui bottom attached accordion-styled segment">
+                    <div class="active content field">
+                        <div class="inline field">
+                            <label for="sheet_type">{{ _T("Sheet type") }}</label>
+                            <input type="text" name="sheet_type" id="sheet_type" value="{{ _T("Attendance sheet") }}" required/>
+                        </div>
+                        <div class="inline field">
+                            <label for="sheet_title">{{ _T("Title") }}</label>
+                            <input type="text" name="sheet_title" id="sheet_title"/>
+                        </div>
+                        <div class="inline field">
+                            <label for="sheet_sub_title">{{ _T("Subtitle") }}</label>
+                            <input type="text" name="sheet_sub_title" id="sheet_sub_title"/>
+                        </div>
+                        <div class="inline field">
+                            <label for="sheet_date">{{ _T("Date") }}</label>
+                            <input type="text" name="sheet_date" id="sheet_date"/>
+                            <span class="exemple">{{ _T("(yyyy-mm-dd format)") }}</span>
+                        </div>
+                        <div class="inline field">
+                            <label for="sheet_photos">{{ _T("With photos?") }}</label>
+                            <input type="checkbox" name="sheet_photos" id="sheet_photos" value="1"/>
+    {% for key, value in data %}
+                            <input type="hidden" name="selection[]" value="{{ value }}"/>
+    {% endfor %}
+                            {% include 'components/forms/csrf.html.twig' %}
+                        </div>
+                    </div>
                 </div>
-                <div class="inline field">
-                    <label for="sheet_sub_title">{{ _T("Subtitle") }}</label>
-                    <input type="text" name="sheet_sub_title" id="sheet_sub_title"/>
+    {% if mode != 'ajax' %}
+                <div class="ui basic center aligned segment">
+                    <button type="submit" class="ui labeled icon primary button">
+                        <i class="file pdf icon" aria-hidden="true"></i>
+                        {{ _T("Generate") }}
+                    </button>
                 </div>
-                <div class="inline field">
-                    <label for="sheet_date">{{ _T("Date") }}</label>
-                    <input type="text" name="sheet_date" id="sheet_date"/>
-                    <span class="exemple">{{ _T("(yyyy-mm-dd format)") }}</span>
-                </div>
-                <div class="inline field">
-                    <label for="sheet_photos">{{ _T("With photos?") }}</label>
-                    <input type="checkbox" name="sheet_photos" id="sheet_photos" value="1"/>
-{% for member in selection %}
-                    <input type="hidden" name="selection[]" value="{{ member }}"/>
-{% endfor %}
-                {% include 'components/forms/csrf.html.twig' %}
-                </div>
-            </div>
-        </div>
-{% if not ajax %}
-        <div class="ui basic center aligned segment">
-            <button type="submit" class="ui labeled icon primary button">
-                <i class="file pdf icon" aria-hidden="true"></i>
-                {{ _T("Generate") }}
-            </button>
-        </div>
-{% endif %}
+    {% endif %}
 
-    </form>
+            </form>
+    {% if mode == 'ajax' %}
+        </div>
+    {% endif %}
+    </div>
 {% endblock %}
index 13b560b18402692bf4f7b2f2d01c2694db5baa3b..eba1fdf200e8ec8465a8902ee11bde86d1e2759e 100644 (file)
@@ -2,7 +2,9 @@
 
 {% block content %}
 {% if members.list is defined or require_mass %}
+    {% if mode != 'ajax' %}
         <form action="{% if contribution.id %}{{ path_for("doEditContribution", {"type": type, "id": contribution.id}) }}{% else %}{{ path_for("doAddContribution", {"type": type}) }}{% endif %}" enctype="multipart/form-data" method="post" class="ui form">
+    {% endif %}
     {% if contribution.isTransactionPart() %}
         {% set mid = contribution.transaction.member %}
             <div class="ui top attached accordion-styled header">
@@ -70,8 +72,8 @@
                     </a>
     {% endif %}
                 </div>
-    {% if not require_mass %}
                 <div class="active content">
+    {% if not require_mass %}
                     <div class="field inline">
                         <label for="id_adh">{{ _T("Contributor:") }}</label>
                         <div id="id_adh" class="jsonly search-dropdown ui input nochosen">
             <input type="hidden" name="trans_id" value="{% if contribution.transaction != NULL %}{{ contribution.transaction.id }}{% endif %}"/>
         </div>
     {% endif %}
+    {% if mode != 'ajax' %}
             {% include "components/forms/csrf.html.twig" %}
         </form>
-{% else %} {# No members #}
+    {% endif %}
+{% elseif mode != 'ajax' %} {# No members #}
     <div class="ui warning message" id="warningbox">
         <h3>{{ _T("No member registered!") }}</h3>
         <p>
index ea30cadd65a5c413c87299934d1bc474eb42caa2..350feacb5ab889d120ade6f1b3902257b50287a2 100644 (file)
@@ -29,7 +29,7 @@
             'icon': 'trash red'
         },
         {
-            'name': 'csv',
+            'name': 'csv__directdownload',
             'label': _T("Export as CSV"),
             'icon': 'file csv'
         }
index 464d1ab2d59d40030dab3e4692e67f17087218c0..adae24c24cb0c74d2ddc5e4e0f8d9f65039e3def 100644 (file)
 {% endif %}
 
 {% block batch_selection %}
+                    else if (value == 'sendmail') {
     {% if existing_mailing == true %}
-                    if (this.id == 'sendmail') {
-                        $('body').modal({
-                            title: '{{ _T("Existing mailing")|e('js') }}',
-                            class: 'tiny',
-                            content: '{{ _T("A mailing already exists. Do you want to create a new one or resume the existing?")|e('js') }}',
-                            actions: [{
-                                text    : '{{ _T("Resume")|e('js') }}',
-                                class   : 'blue cancel',
-                                click   : function() {
-                                    location.href = '{{ path_for('mailing') }}';
-                                }
-                            }, {
-                                text    : '{{ _T("New")|e('js') }}',
-                                class   : 'green approve',
-                                click   : function() {
-                                    //add required controls to the form, change its action URI, and send it.
-                                    var _form = $('#listform');
-                                    _form.append($('<input type="hidden" name="mailing_new" value="true"/>'));
-                                    _form.append($('<input type="hidden" name="mailing" value="true"/>'));
-                                    _form.submit();
-                                }
-                            }]
-                        }).modal('show');
-                        return false;
-                    }
+                        _sendmail(true);
+    {% else %}
+                        _sendmail();
     {% endif %}
-                    if (this.id == 'attendance_sheet') {
+                    }
+                    else if (value == 'attendance_sheet') {
                         _attendance_sheet_details();
-                        return false;
                     }
 
-                    if (this.id == 'masscontributions') {
-                        event.preventDefault();
-                        $.ajax({
-                            url: '{{ path_for('batch-memberslist') }}',
-                            type: "POST",
-                            data: {
-                                ajax: true,
-                                masscontributions: true,
-                                entries_sel: $('#listform input[type=\"checkbox\"]:checked').map(function(){
-                                    return $(this).val();
-                                }).get()
-                            },
-                            datatype: 'json',
-                            {% include "elements/js/loader.js.twig" %},
-                            success: function(res){
-                                var _res = $(res);
-                                _bindmassres(_res);
-                                $('body').append(_res);
-
-                                _massCheckboxes('#mass_contributions');
-
-                                $('#mass_contributions').modal({
-                                    actions: [{
-                                        text    : '{{ _T("Close")|e('js') }}',
-                                        class   : 'cancel'
-                                    }]
-                                }).modal('show');
-                            },
-                            error: function() {
-                                alert("{{ _T("An error occurred :(")|e('js') }}");
-                            }
-                        });
+                    else if (value == 'masscontributions') {
+                        _masscontributions();
                     }
 
-                    return true;
+                    else if (value == 'masschange') {
+                        _masschange();
+                    }
 {% endblock %}
 
 {% block javascripts %}
-    {% set batch_excludes = ['masschange'] %}
+    {% set batch_selection = ['masschange', 'masscontributions', 'sendmail', 'attendance_sheet_details'] %}
     {{ parent() }}
     <script type="text/javascript">
         {# Use of Javascript to draw specific elements that are not relevant is JS is inactive #}
         $(function(){
-            if ( _shq = $('#showhideqry') ) {
-                _shq.click(function(){
-                    $('#sql_qry').toggleClass('hidden');
-                    return false;
-                });
-            }
-
             $('#savesearch').on('click', function(e) {
                 e.preventDefault();
 
 
         });
 {% if nb_members != 0 %}
-        var _bindmassres = function(res) {
-            res.find('#btncancel')
-                .on('click', function(e) {
-                    e.preventDefault();
-                    res.modal('hide');
-                });
+        var _sendmail = function(existing){
+            var _form = $('#listform');
+                _form.append($('<input type="hidden" name="sendmail" value="true"/>'));
+                _form.append($('<input type="hidden" name="mailing_new" value="true"/>'));
+                _form.append($('<input type="hidden" name="mailing" value="true"/>'));
+            var _redirect = '{{ path_for('mailing') }}';
+
+            if (existing) {
+                $('body').modal({
+                    title: '{{ _T("Existing mailing")|e('js') }}',
+                    class: 'tiny',
+                    content: '{{ _T("A mailing already exists. Do you want to create a new one or resume the existing?")|e('js') }}',
+                    actions: [{
+                        text    : '{{ _T("Resume")|e('js') }}',
+                        class   : 'blue',
+                        click   : function() {
+                            location.href = _redirect;
+                        }
+                    }, {
+                        text    : '{{ _T("New")|e('js') }}',
+                        class   : 'green',
+                        click   : function() {
+                            _form.submit();
+                        }
+                    }, {
+                        text    : '{{ _T("Cancel")|e('js') }}',
+                        class   : 'deny'
+                    }]
+                }).modal('show');
+            } else {
+                _form.submit();
+            }
         }
+        var _attendance_sheet_details = function(){
+            $.ajax({
+                url: '{{ path_for('attendance_sheet_details') }}',
+                type: "POST",
+                data: {
+                    ajax: true,
+                    selection: $('#listform input[type=\"checkbox\"]:checked').map(function(){
+                        return $(this).val();
+                    }).get()
+                },
+                dataType: 'html',
+                {% include "elements/js/loader.js.twig" %},
+                success: function(res){
+                    var _res = $(res);
 
-        $('#masschange').off('click').on('click', function(event) {
-            event.preventDefault();
-            var _this = $(this);
+                    $('body').append(_res);
 
-            if (!_checkselection()) {
-                return false;
-            }
+                    $('#attendance_sheet_details').modal({
+                        class: 'tiny',
+                        onApprove : function() {
+                            $('#attendance_sheet_details form').submit();
+                        },
+                        onDeny: function() {
+                            $(this).remove();
+                            $('body').dimmer('hide');
+                        },
+                        actions: [{
+                            text    : '{{ _T("Continue")|e("js") }}',
+                            class   : 'blue approve'
+                        }, {
+                            text    : '{{ _T("Cancel")|e("js") }}',
+                            class   : 'cancel'
+                        }]
+                    }).modal('show');
+                },
+                error: function() {
+                    alert("{{ _T("An error occurred displaying attendance sheet details interface :(")|e('js') }}");
+                }
+            });
+        }
+        var _masscontributions = function(){
             $.ajax({
                 url: '{{ path_for('batch-memberslist') }}',
                 type: "POST",
                 data: {
                     ajax: true,
-                    masschange: true,
+                    masscontributions: true,
                     entries_sel: $('#listform input[type=\"checkbox\"]:checked').map(function(){
                         return $(this).val();
                     }).get()
                 },
-                datatype: 'json',
+                datatype: 'html',
                 {% include "elements/js/loader.js.twig" %},
                 success: function(res){
                     var _res = $(res);
-                    _bindmassres(_res);
+
+                    $('body').append(_res);
 
                     _res.find('form').on('submit', function(e) {
                         e.preventDefault();
                         var _form = $(this);
                         var _data = _form.serialize();
+
                         $.ajax({
                             url: _form.attr('action'),
                             type: "POST",
                             data: _data,
                             datatype: 'json',
                             {% include "elements/js/loader.js.twig" %},
-                            success: function(html) {
-                                var _html = $(html);
-                                _bindmassres(_html);
-
-                                $('#mass_change').remove();
-                                $('body').append(_html);
+                            success: function(data, status, xhr) {
+                                var _res = $(data);
 
-                                //_initTooltips('#mass_change');
-                                //_massCheckboxes('#mass_change');
-
-                                $('#mass_change').modal({
-                                    actions: [{
-                                        text    : '{{ _T("Close")|e('js') }}',
-                                        class   : 'cancel'
-                                    }]
-                                }).modal('show');
+                                $('#mass_contributions').remove();
+                                $('body').append(_res);
 
-                                _html.find('form').on('submit', function(e) {
+                                _res.find('form').on('submit', function(e) {
                                     e.preventDefault();
                                     var _form = $(this);
                                     var _data = _form.serialize();
                                         datatype: 'json',
                                         {% include "elements/js/loader.js.twig" %},
                                         success: function(res) {
-                                            if (res.success) {
-                                                window.location.href = _form.find('input[name=redirect_uri]').val();
-                                            } else {
-                                                $.ajax({
-                                                    url: '{{ path_for('ajaxMessages') }}',
-                                                    method: "GET",
-                                                    success: function (message) {
-                                                        $('#asso_name').after(message);
-                                                    }
-                                                });
-                                            }
+                                            window.location.href = _form.find('input[name=redirect_uri]').val();
+                                        },
+                                        error: function() {
+                                            alert("{{ _T("An error occurred :(")|e('js') }}");
                                         }
                                     });
                                 });
+
+                                $('#mass_contributions').modal({
+                                    onApprove: function() {
+                                        $('#mass_contributions form').submit();
+                                    },
+                                    onDeny: function() {
+                                        $(this).remove();
+                                        $('body').dimmer('hide');
+                                    },
+                                    actions: [{
+                                        text    : '{{ _T("Continue")|e('js') }}',
+                                        class   : 'blue approve'
+                                    }, {
+                                        text    : '{{ _T("Cancel")|e('js') }}',
+                                        class   : 'cancel'
+                                    }]
+                                }).modal('show');
                             },
                             error: function() {
                                 alert("{{ _T("An error occurred :(")|e('js') }}");
                         });
                     });
 
-                    $('body').append(_res);
-
-                    _massCheckboxes('#mass_change');
-
-                    $('#mass_change').modal({
+                    $('#mass_contributions').modal({
+                        class: 'tiny',
+                        onApprove : function() {
+                            $('#mass_contributions form').submit();
+                        },
+                        onDeny: function() {
+                            $(this).remove();
+                            $('body').dimmer('hide');
+                        },
                         actions: [{
-                            text    : '{{ _T("Close")|e('js') }}',
+                            text    : '{{ _T("Continue")|e("js") }}',
+                            class   : 'blue approve'
+                        }, {
+                            text    : '{{ _T("Cancel")|e("js") }}',
                             class   : 'cancel'
                         }]
                     }).modal('show');
+
+                    _massCheckboxes('#mass_contributions');
                 },
                 error: function() {
                     alert("{{ _T("An error occurred :(")|e('js') }}");
                 }
             });
-        });
-
-        var _attendance_sheet_details = function(){
-            var _selecteds = [];
-            $('table.listing').find('input[type=checkbox]:checked').each(function(){
-                _selecteds.push($(this).val());
-            });
+        }
+        var _masschange = function(){
             $.ajax({
-                url: '{{ path_for('attendance_sheet_details') }}',
+                url: '{{ path_for('batch-memberslist') }}',
                 type: "POST",
                 data: {
                     ajax: true,
-                    selection: _selecteds
+                    masschange: true,
+                    entries_sel: $('#listform input[type=\"checkbox\"]:checked').map(function(){
+                        return $(this).val();
+                    }).get()
                 },
-                dataType: 'html',
+                datatype: 'json',
+                {% include "elements/js/loader.js.twig" %},
                 success: function(res){
-                    $('body').modal({
-                        title: '{{ _T("Attendance sheet details")|e("js") }}',
-                        class: 'tiny',
-                        content: res,
-                        actions: [{
-                            text    : '{{ _T("Continue")|e("js") }}',
-                            class   : 'cancel',
-                            click   : function() {
-                                $('#sheet_details_form').submit();
+                    var _res = $(res);
+
+                    $('body').append(_res);
+
+                    _res.find('form').on('submit', function(e) {
+                        e.preventDefault();
+                        var _form = $(this);
+                        var _data = _form.serialize();
+                        $.ajax({
+                            url: _form.attr('action'),
+                            type: "POST",
+                            data: _data,
+                            datatype: 'json',
+                            {% include "elements/js/loader.js.twig" %},
+                            success: function(data, status, xhr) {
+                                var _res = $(data);
+
+                                $('#mass_change').remove();
+                                $('body').append(_res);
+
+                                $('#mass_change').modal({
+                                    onApprove: function() {
+                                        $('#mass_change form').submit();
+                                    },
+                                    onDeny: function() {
+                                        $(this).remove();
+                                        $('body').dimmer('hide');
+                                    },
+                                    actions: [{
+                                        text    : '{{ _T("Continue")|e('js') }}',
+                                        class   : 'blue approve'
+                                    }, {
+                                        text    : '{{ _T("Cancel")|e('js') }}',
+                                        class   : 'cancel'
+                                    }]
+                                }).modal('show');
+
+                                _res.find('form').on('submit', function(e) {
+                                    e.preventDefault();
+                                    var _form = $(this);
+                                    var _data = _form.serialize();
+                                    $.ajax({
+                                        url: _form.attr('action'),
+                                        type: "POST",
+                                        data: _data,
+                                        datatype: 'json',
+                                        {% include "elements/js/loader.js.twig" %},
+                                        success: function(res) {
+                                            window.location.href = _form.find('input[name=redirect_uri]').val();
+                                        },
+                                        error: function() {
+                                            alert("{{ _T("An error occurred :(")|e('js') }}");
+                                        }
+                                    });
+                                });
+                            },
+                            error: function() {
+                                alert("{{ _T("An error occurred :(")|e('js') }}");
                             }
+                        });
+                    });
+
+                    $('#mass_change').modal({
+                        onApprove: function() {
+                            $('#mass_change form').submit();
+                        },
+                        onDeny: function() {
+                            $(this).remove();
+                            $('body').dimmer('hide');
+                        },
+                        actions: [{
+                            text    : '{{ _T("Continue")|e('js') }}',
+                            class   : 'blue approve'
                         }, {
-                            text    : '{{ _T("Cancel")|e("js") }}',
+                            text    : '{{ _T("Cancel")|e('js') }}',
                             class   : 'cancel'
                         }]
                     }).modal('show');
+
+                    _massCheckboxes('#mass_change');
                 },
                 error: function() {
-                    alert("{{ _T("An error occurred displaying attendance sheet details interface :(")|e('js') }}");
+                    alert("{{ _T("An error occurred :(")|e('js') }}");
                 }
             });
         }
index b48e87f330eec940e712d042baaf0976bd0f1659..4d906612ba2aef089467f56f418a8e7e54be8720 100644 (file)
@@ -39,9 +39,20 @@ var _bind_check = function(boxelt){
         return false;
     });
     $('.checkinvert').click(function(){
+        var _haschecked = false;
         $('table.listing :checkbox[name="' + boxelt + '[]"]').each(function(){
-            this.checked = !$(this).is(':checked');
+            if ($(this).is(':checked')) {
+                this.checked = false;
+            } else {
+                this.checked = true;
+                _haschecked = true;
+            }
         });
+        if (!_haschecked) {
+            _is_checked = true;
+        } else {
+            _is_checked = false;
+        }
         return false;
     });
 };
index 7934e0c56ed1bb9ff757244867d14e8f6798e52b..ec5bb0c266114d81c8cbe0db579fce8b7e86109d 100644 (file)
@@ -11,3 +11,7 @@ a.ui.button:hover i.icon {
 .ui.primary.buttons .button {
     color: darken(@textColor, 15);
 }
+
+.ui.upward.dropdown.button:not(.pointing):not(.floating).batch-select-action.active {
+    border-radius: 0;
+}