]> git.agnieray.net Git - galette.git/commitdiff
Merge branch 'hotfix/1.0.2'
authorJohan Cwiklinski <johan@x-tnd.be>
Sat, 3 Feb 2024 08:22:32 +0000 (09:22 +0100)
committerJohan Cwiklinski <johan@x-tnd.be>
Sat, 3 Feb 2024 08:22:32 +0000 (09:22 +0100)
39 files changed:
README.md
bin/release
galette/docs/CHANGES
galette/includes/galette.inc.php
galette/includes/main.inc.php
galette/includes/routes/public_pages.routes.php
galette/lib/Galette/Controllers/AbstractController.php
galette/lib/Galette/Controllers/Crud/GroupsController.php
galette/lib/Galette/Core/Authentication.php
galette/lib/Galette/Core/Login.php
galette/lib/Galette/Middleware/PublicPages.php [new file with mode: 0644]
galette/templates/default/components/forms/account.html.twig
galette/templates/default/components/forms/lang.html.twig
galette/templates/default/components/forms/payment_types.html.twig
galette/templates/default/components/forms/picture.html.twig
galette/templates/default/components/forms/select.html.twig
galette/templates/default/components/forms/status.html.twig
galette/templates/default/components/forms/titles.html.twig
galette/templates/default/elements/edit_entitleds.html.twig
galette/templates/default/elements/edit_pdf_models.html.twig
galette/templates/default/elements/edit_socials.html.twig
galette/templates/default/elements/group.html.twig
galette/templates/default/elements/js/choose_social.js.twig [new file with mode: 0644]
galette/templates/default/elements/js/photo_dnd.js.twig
galette/templates/default/modals/replacements_legend.html.twig
galette/templates/default/pages/advanced_search.html.twig
galette/templates/default/pages/configuration_core_fields.html.twig
galette/templates/default/pages/configuration_dynamic_field_form.html.twig
galette/templates/default/pages/contribution_form.html.twig
galette/templates/default/pages/contributions_list.html.twig
galette/templates/default/pages/history.html.twig
galette/templates/default/pages/mailing_form.html.twig
galette/templates/default/pages/member_form.html.twig
galette/templates/default/pages/members_list.html.twig
galette/templates/default/pages/preferences.html.twig
galette/templates/default/pages/transaction_form.html.twig
ui/js/common.js
ui/semantic/galette/globals/site.overrides
ui/semantic/galette/modules/dropdown.overrides

index 17959b5658fbcaaac2c1639a038afba901c0065e..0d9fc5042ead8a63e1fc5e6b72a51c2464745f3e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 
 ### English
 
-[![Download most recent Galette release (1.0.1)](https://img.shields.io/badge/1.0.1-Latest_Galette-ffb619.svg?logo=php&logoColor=white&style=for-the-badge)](https://download.tuxfamily.org/galette/galette-1.0.1.tar.bz2)
+[![Download most recent Galette release (1.0.2)](https://img.shields.io/badge/1.0.2-Latest_Galette-ffb619.svg?logo=php&logoColor=white&style=for-the-badge)](https://download.tuxfamily.org/galette/galette-1.0.2.tar.bz2)
 [![Download Galette development (nightly) build](https://img.shields.io/badge/nightly-Galette_development-ffb619.svg?logo=php&logoColor=white&style=for-the-badge)](https://download.tuxfamily.org/galette/galette-dev.tar.bz2)
 
 Galette is a membership management web application towards non profit organizations; released under GPLv3.
@@ -29,7 +29,7 @@ To use Galette, you can either:
 
 ### Français
 
-[![Télécharger la version de Galette la plus récente (1.0.1)](https://img.shields.io/badge/1.0.1-Dernière_Galette-ffb619.svg?logo=php&logoColor=white&style=for-the-badge)](https://download.tuxfamily.org/galette/galette-1.0.1.tar.bz2)
+[![Télécharger la version de Galette la plus récente (1.0.2)](https://img.shields.io/badge/1.0.2-Dernière_Galette-ffb619.svg?logo=php&logoColor=white&style=for-the-badge)](https://download.tuxfamily.org/galette/galette-1.0.2.tar.bz2)
 [![Télécharger la version de développement (nighly) de Galette](https://img.shields.io/badge/nightly-Galette_développement-ffb619.svg?logo=php&logoColor=white&style=for-the-badge)](https://download.tuxfamily.org/galette/galette-dev.tar.bz2)
 
 Galette est un outil de gestion d’adhérents et de cotisations en ligne à destination des associations, sous license GPLV3.
index ac1918ef5b8bc9163f675cb918014e153f8475c4..412bb84236d10ce8844938e9a1e0bbb78f51d605 100755 (executable)
@@ -99,7 +99,7 @@ def get_latest_version():
     last = None
     for tagref in tagrefs:
         tag = tagref.tag
-        if valid_version(tag.tag):
+        if tag != None and valid_version(tag.tag):
             #last minor version is always the last one :)
             if last == None or tag.tag > last:
                 last = tag.tag
index c84baefd05af4e7d3ce5cd12aa2e3be63dabe11f..c95a4ed4031b876e3e9cd7f7194d87cc82bb3acf 100644 (file)
@@ -1,6 +1,15 @@
 Changes
 -------
 
+1.0.1 -> 1.0.2
+
+- Public pages access restriction (CVE-2024-24761)
+- Remove useless class from templates and fix social networks search dropdown
+- Ensure language is changed when login from cron; closes #1769
+- Make replacements icon in PDF Model more visible
+- Fix possible issue on group creation
+- Fix URL redirection
+
 1.0.0 -> 1.0.1
 
 - Title in members list causes an error
index c3d686bd29318de6f0bcb6ab006ca23a0a68f17a..6a83526f542c7afc95de0b96a91d03986ee542aa 100644 (file)
@@ -100,7 +100,7 @@ if (
 }
 
 define('GALETTE_NIGHTLY', false);
-define('GALETTE_VERSION', 'v1.0.1');
+define('GALETTE_VERSION', 'v1.0.2');
 
 //Version to display
 if (!defined('GALETTE_HIDE_VERSION')) {
index 9ee31b98ef18e90331bcb28321f3c91ce90330f9..0609aca80fd32614fa7ac91d01f5d4b8b76dd508 100644 (file)
@@ -134,32 +134,8 @@ if ($needs_update) {
  */
 $authenticate = new Authenticate($container);
 
-/**
- * Show public pages middleware
- *
- * @param $request
- * @param $response
- * @param $next
- * @return mixed
- */
-$showPublicPages = function (Request $request, RequestHandler $handler) use ($container) {
-    $response = $handler->handle($request);
-    $login = $container->get('login');
-    $preferences = $container->get('preferences');
-
-    if (!$preferences->showPublicPages($login)) {
-        $this->get('flash')->addMessage('error', _T("Unauthorized"));
-
-        return $response
-            ->withStatus(403)
-            ->withHeader(
-                'Location',
-                $this->get(RouteParser::class)->urlFor('slash')
-            );
-    }
-
-    return $response;
-};
+//FIXME: remove in 1.1.0; routes/groups should call middleware directly
+$showPublicPages = new \Galette\Middleware\PublicPages($container);
 
 //Maintenance middleware
 if (Galette::MODE_MAINT === GALETTE_MODE && !$container->get('login')->isSuperAdmin()) {
index 13e34f97cc5613026fd348bd719f5552615814f4..71902e007a528ab4839e7a3e3178dd5bb755e716 100644 (file)
@@ -73,4 +73,4 @@ $app->group('/public', function (RouteCollectorProxy $app) use ($routeparser) {
                 ->withHeader('Location', $routeparser->urlFor('publicList', $args));
         }
     );
-})->add($showPublicPages);
+})->add(\Galette\Middleware\PublicPages::class);
index 3a258a820c1feaf2e0722dafccffe27c8eb5a390..75bda451a3a1f95fb6352c07d8af87bacb1364ec 100644 (file)
@@ -199,7 +199,7 @@ abstract class AbstractController
         if ($this->login->isLogged()) {
             $urlRedirect = null;
             if ($this->session->urlRedirect !== null) {
-                $urlRedirect = $this->getGaletteBaseUrl($request) . $this->session->urlRedirect;
+                $urlRedirect = $this->session->urlRedirect;
                 $this->session->urlRedirect = null;
             }
 
@@ -238,31 +238,6 @@ abstract class AbstractController
         }
     }
 
-    /**
-     * Get base URL fixed for proxies
-     *
-     * @param Request $request PSR Request
-     *
-     * @return string
-     */
-    private function getGaletteBaseUrl(Request $request)
-    {
-        $routeContext = RouteContext::fromRequest($request);
-
-        $url = preg_replace(
-            [
-                '|index\.php|',
-                '|https?://' . $_SERVER['HTTP_HOST'] . '(:\d+)?' . '|'
-            ],
-            ['', ''],
-            $routeContext->getBasePath()
-        );
-        if (strlen($url) && substr($url, -1) !== '/') {
-            $url .= '/';
-        }
-        return $url;
-    }
-
     /**
      * Get route arguments
      * php-di bridge pass each variable, not an array of all arguments
index e89e280172625053203dc4ea9ad7120c2ea989ec..020bc53d6511e5c0a30464f516350e836ea5efb3 100644 (file)
@@ -368,14 +368,18 @@ class GroupsController extends CrudController
             if (isset($post['managers'])) {
                 $managers_id = $post['managers'];
                 $managers = $m->getArrayList($managers_id);
-                $group->setManagers($managers);
+                if (is_array($managers)) {
+                    $group->setManagers($managers);
+                }
             }
 
             //handle group members
             if (isset($post['members'])) {
                 $members_id = $post['members'];
                 $members = $m->getArrayList($members_id);
-                $group->setMembers($members);
+                if (is_array($members)) {
+                    $group->setMembers($members);
+                }
             }
 
             $store = $group->store();
index 389450f54f1ed2b07c9910866c71cb33e343f464..bcee491c5608bf0e68d6c3732fdebc78cdb3dcb6 100644 (file)
@@ -129,22 +129,9 @@ abstract class Authentication
      * @param string      $name        Service name
      * @param Preferences $preferences Preferences instance
      *
-     * @return void
+     * @return bool
      */
-    public function logCron($name, Preferences $preferences)
-    {
-        //known cronable files
-        $ok = array('reminder');
-
-        if (in_array($name, $ok)) {
-            $this->logged = true;
-            $this->cron = true;
-            $this->login = 'cron';
-            $this->lang = $preferences->pref_lang;
-        } else {
-            trigger_error('Not authorized!', E_USER_ERROR);
-        }
-    }
+    abstract public function logCron(string $name, Preferences $preferences): bool;
 
     /**
      * Log out user and unset variables
index c9f8750d4ffc4b3037722f9d7ba5c5a38461fdd5..3141ee4be5dcf1ae7bac6f02cbaf69df0fd209d9 100644 (file)
@@ -92,6 +92,32 @@ class Login extends Authentication
         $this->impersonated = false;
     }
 
+    /**
+     * Authenticate from cron
+     *
+     * @param string      $name        Service name
+     * @param Preferences $preferences Preferences instance
+     *
+     * @return bool
+     */
+    public function logCron(string $name, Preferences $preferences): bool
+    {
+        //known cronable files
+        $ok = array('reminder');
+
+        if (in_array($name, $ok)) {
+            $this->logged = true;
+            $this->cron = true;
+            $this->login = 'cron';
+            $this->name = 'cron';
+            $this->lang = $preferences->pref_lang;
+            $this->i18n->changeLanguage($this->lang);
+            return true;
+        } else {
+            trigger_error('Not authorized!', E_USER_ERROR);
+        }
+    }
+
     /**
      * Log out user and unset variables
      *
diff --git a/galette/lib/Galette/Middleware/PublicPages.php b/galette/lib/Galette/Middleware/PublicPages.php
new file mode 100644 (file)
index 0000000..47a63a4
--- /dev/null
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * Copyright © 2003-2024 The Galette Team
+ *
+ * This file is part of Galette (https://galette.eu).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  Core
+ * @package   Galette
+ *
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2024 The Galette Team
+ * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      https://galette.eu
+ */
+
+namespace Galette\Middleware;
+
+use Galette\Core\Login;
+use Galette\Core\Preferences;
+use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
+use Analog\Analog;
+use DI\Container;
+use RKA\Session;
+use Slim\Flash\Messages;
+use Slim\Routing\RouteContext;
+use Slim\Routing\RouteParser;
+
+/**
+ * Galette Slim middleware for public pages access
+ *
+ * @category  Core
+ * @package   Galette
+ *
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2024 The Galette Team
+ * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      https://galette.eu
+ */
+class PublicPages
+{
+    /**
+     * @var Messages
+     */
+    protected Messages $flash;
+
+    /**
+     * @var Login
+     */
+    private Login $login;
+
+    /**
+     * @var RouteParser
+     */
+    private RouteParser $routeparser;
+
+    /**
+     * @var Preferences
+     */
+    private Preferences $preferences;
+
+    /**
+     * Constructor
+     *
+     * @param Container $container Container instance
+     */
+    public function __construct(Container $container)
+    {
+        $this->login = $container->get('login');
+        $this->flash = $container->get('flash');
+        $this->routeparser = $container->get(RouteParser::class);
+        $this->preferences = $container->get('preferences');
+    }
+
+    /**
+     * Middleware invokable class
+     *
+     * @param Request        $request PSR7 request
+     * @param RequestHandler $handler PSR7 request handler
+     *
+     * @return Response
+     */
+    public function __invoke(Request $request, RequestHandler $handler): Response
+    {
+        $response = new \Slim\Psr7\Response();
+
+        if (!$this->preferences->showPublicPages($this->login)) {
+            $this->flash->addMessage('error_detected', _T("Unauthorized"));
+            return $response
+                ->withHeader(
+                    'Location',
+                    $this->routeparser->urlFor('slash')
+                )->withStatus(302);
+        }
+
+        return $handler->handle($request);
+    }
+}
index 6014ada5973e1cd2172210a82f523d24b0cce436..025ef17bbaff54eb13799e1ae62fb69c6927beea 100644 (file)
@@ -1,7 +1,7 @@
 {% extends "components/forms/select.html.twig" %}
 
 {% block element %}
-    <select name="activite_adh" id="activite_adh" class="ui dropdown nochosen"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required is defined and required == 1 %} required="required"{% endif %}>
+    <select name="activite_adh" id="activite_adh" class="ui dropdown"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required is defined and required == 1 %} required="required"{% endif %}>
         <option value="1" {% if member.isActive() == 1 %}selected="selected"{% endif %}>{{ _T("Active") }}</option>
         <option value="0" {% if member.isActive() == 0 %}selected="selected"{% endif %}>{{ _T("Inactive") }}</option>
     </select>
index 14c8ec4fbbf27db0dda1334358c1dd99c00ccbe0..0f86ad98b959abfd6b4cc1594b65ab6c2f2bc6c4 100644 (file)
@@ -1,7 +1,7 @@
 {% extends "components/forms/select.html.twig" %}
 
 {% block element %}
-    <select name="pref_lang" id="pref_lang" class="ui dropdown nochosen lang"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required.pref_lang is defined and required.pref_lang == 1 %} required="required"{% endif %}>
+    <select name="pref_lang" id="pref_lang" class="ui dropdown lang"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required.pref_lang is defined and required.pref_lang == 1 %} required="required"{% endif %}>
         {% for langue in languages %}
             <option value="{{ langue.getID() }}"{% if member.language == langue.getID() %} selected="selected"{% endif %}>{{ langue.getName() }}</option>
         {% endfor %}
index 8a815d97fd57af963e9127b62525c11850dc4673..04013100db9fd22ec3315f92eda3d1bcc28b12c9 100644 (file)
@@ -4,7 +4,7 @@
 <div class="field">
 {% endif %}
     <label for="{{ varname }}">{% if label is defined %}{{ label }}{% else %}{{ _T("Payment type:") }}{% endif %}</label>
-    <select name="{{ varname }}" id="{{ varname }}" class="ui search dropdown nochosen">
+    <select name="{{ varname }}" id="{{ varname }}" class="ui search dropdown">
 {% if empty is defined %}
         <option value="{{ empty.value }}">{{ empty.label }}</option>
 {% endif %}
index 176c3d821899723ca0e44c8705d5f38fedc3a307..50cbbd9cdfdaf8bf5a8d91bfa17be0a68b36c9d8 100644 (file)
@@ -24,7 +24,7 @@
             <div id="crop_focus_field" class="extra ui basic fitted segment displaynone">
                 <div class="inline field">
                     <label for="crop_focus">{{ _T("Cropping focus") }}</label>
-                    <select name="crop_focus" id="crop_focus" class="ui dropdown nochosen">
+                    <select name="crop_focus" id="crop_focus" class="ui dropdown">
                         <option value="center">{{ _T("Center") }}</option>
                         <option value="top">{{ _T("Top") }}</option>
                         <option value="bottom">{{ _T("Bottom") }}</option>
index 054766f1cd2a27a6e420bb86c68cbd6358fa61a8..5f44d0cabb9f1370e703c61eff6c8d3b37144b36 100644 (file)
@@ -8,7 +8,7 @@
         id="{{ id }}"
         {% if required is defined and required == true %} required="required"{% endif %}
         {% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}
-        class="ui search dropdown nochosen"
+        class="ui search dropdown"
     >
     {% for option_value, option_label in values %}
         <option
index 3d7b59e53e17a9d5e64d6d9d53383ac94d3ae059..d7afdebe66754595c51eb4725213c5e236846424 100644 (file)
@@ -1,7 +1,7 @@
 {% extends "components/forms/select.html.twig" %}
 
 {% block element %}
-    <select name="id_statut" id="id_statut" class="ui dropdown nochosen"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required.id_statut is defined and required.id_statut == 1 %} required="required"{% endif %}>
+    <select name="id_statut" id="id_statut" class="ui dropdown"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required.id_statut is defined and required.id_statut == 1 %} required="required"{% endif %}>
         {% for key, value in statuts %}
             <option value="{{ key }}"{% if key == member.status %} selected="selected"{% endif %}>{{ value }}</option>
         {% endfor %}
index 8b8e738a8303a1a87fabc2fa9944d3a8c80724a1..784d27ce87b98e7b1d652dba6397a7b00bc14e33 100644 (file)
@@ -2,7 +2,7 @@
 
 {% block element %}
     {% set values = "" %}
-    <select name="titre_adh" id="titre_adh" class="ui dropdown nochosen"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required is defined and required == true %} required="required"{% endif %}>
+    <select name="titre_adh" id="titre_adh" class="ui dropdown"{% if disabled is defined and disabled == true %} disabled="disabled"{% endif %}{% if required is defined and required == true %} required="required"{% endif %}>
         <option value="{% if required is defined and required == true %}-1{% endif %}">{{ _T("Not supplied") }}</option>
 {% for title in titles_list %}
         <option value="{{ title.id }}"{% if member.title != null and member.title.id == title.id %} selected="selected"{% endif %}>{{ title.long }}</option>
index 7d05d59cabe7d1016b0606689a588e65c8f5050e..ba7b70c254ed2140feb8ee4f48b79f6d705ad454 100644 (file)
@@ -39,7 +39,7 @@
                     </td>
                     <td class="left" data-col-label="{% if class == 'ContributionsTypes' %}{{ _T("Extends membership?") }}{% else %}{{ _T("Priority") }}{% endif %}">
 {% if class == 'ContributionsTypes' %}
-                        <select name="{{ fields.third }}" class="ui dropdown nochosen">
+                        <select name="{{ fields.third }}" class="ui dropdown">
                             <option value="0" selected="selected">{{ _T("No") }}</option>
                             <option value="1">{{ _T("Yes") }}</option>
                         </select>
index 5d3ab22dff8a0cd5b07addc4ac7491eed13fe876..62353329e08c491ee46e6e40fdf23c0ca6ae3bcf 100644 (file)
@@ -46,7 +46,7 @@
 {% if model.id > 4 %}
                     <div class="field">
                         <label for="type_{{ model.id }}">{{ _T("Type") }}</label>
-                        <select name="model_type" id="type_{{ model.id }}" class="ui dropdown nochosen" required>
+                        <select name="model_type" id="type_{{ model.id }}" class="ui dropdown" required>
                             <option value="">{{ _T("Select") }}</option>
                             <option value="{{ constant('Galette\\Entity\\PdfModel::INVOICE_MODEL') }}">{{ _T("Invoice") }}</option>
                             <option value="{{ constant('Galette\\Entity\\PdfModel::RECEIPT_MODEL') }}">{{ _T("Receipt") }}</option>
index 13c1d6d61be0297b0e48ffe33eb484ff767aade0..7b795dffbd07f8e9534c7d536fb7c0411712d41a 100644 (file)
                 <label>{{ _T("Add new social network") }}</label>
                 <div class="combo-social fields">
                     <div class="field">
-                        <select name="social_new_type_1" id="social_new_type_1" class="socials_dropdown ui search dropdown nochosen">
-                            <option value="">{{ _T("Choose or enter your own...") }}</option>
+                        <div id="social_new_type_1" class="jsonly search-dropdown socials-dropdown ui input">
+                            <input id="social_new_type_input_1" type="hidden" name="social_new_type_1" value="">
+                            <i class="jsonly displaynone dropdown icon" aria-hidden="true"></i>
+                            <div class="jsonly displaynone default text">{{ _T("Choose or enter your own...") }}</div>
+                            <div class="jsonly displaynone menu">
                             {% for social_type in osocials.getSystemTypes(false) %}
-                                <option value="{{ social_type }}">{{ osocials.getSystemType(social_type) }}</option>
+                                <div class="item" data-value="{{ social_type }}">{{ osocials.getSystemType(social_type) }}</div>
                             {% endfor %}
-                        </select>
+                            </div>
+                        </div>
                     </div>
                     <div class="field">
-                        <input type="text" name="social_new_value_1" id="social_new_value_1" value="" size="50"/>
+                        <input type="text" name="social_new_value_1" id="social_new_value_1" value="" size="50" class="value"/>
                     </div>
                 </div>
                 <a href="#" class="ui tiny green labeled icon button action addsocial">
                     {{ _T("Add") }}
                 </a>
             </div>
-            <script type="text/javascript">
-                var _dropdown = function(selector) {
-                    if ( !selector ) {
-                        selector = '.socials_dropdown';
-                    }
-
-                    $(selector).dropdown({
-                        allowAdditions: true
-                    });
-                }
-
-                var _rmFilter = function(elt) {
-                    if ( typeof elt == 'undefined') {
-                        elt = $('#social .stored');
-                    }
-                    elt.find('.delsocial').click(function(e){
-                        e.preventDefault();
-                        var _this = $(this);
-                        _this.parents('.field.stored').remove();
-                    });
-                }
-
-                $(function(){
-                    _rmFilter();
-                    _dropdown();
-
-                    $('a.addsocial').click(function(e) {
-                        e.preventDefault();
-
-                        var _newindex = $(this).parents('.addsocial').find('.combo-social:last select').attr('id').replace('social_new_type_', '');
-                        ++_newindex;
-                        $(this).parents('.addsocial').find ('.combo-social:last')
-                            .clone() // copy
-                            .insertAfter('#social .combo-social:last') // where
-                            .find('select').attr('id', 'social_new_type_' + _newindex).attr('name', 'social_new_type_' + _newindex)
-                            .parent().parent().parent().find('input').attr('id', 'social_new_value_' + _newindex).attr('name', 'social_new_value_' + _newindex)
-                        ;
-
-                        _dropdown();
-                    });
-                });
-            </script>
     {% endblock %}
 </div>
 {% else %}
index a44a032b33fc86f66b05e83f21c1ca11d3b520c9..363c7af1adcc5635bd379cbdf1ed96e375e89d1b 100644 (file)
@@ -45,7 +45,7 @@
                         {{ pgroup.getName() }}
                         <input type="hidden" name="parent_group" value="{{ pgroup.getId() }}"/>
                     {% else %}
-                        <div class="ui search compact selection dropdown nochosen">
+                        <div class="ui search compact selection dropdown">
                             <input type="hidden" name="parent_group" id="parent_group" value="{% if pgroup is defined %}{{ pgroup.getId() }}{% endif %}">
                             <i class="dropdown icon" aria-hidden="true"></i>
                             <div class="text">{% if pgroup is defined %}{{ pgroup.getName() }}{% endif %}</div>
diff --git a/galette/templates/default/elements/js/choose_social.js.twig b/galette/templates/default/elements/js/choose_social.js.twig
new file mode 100644 (file)
index 0000000..1f3d69a
--- /dev/null
@@ -0,0 +1,40 @@
+var _dropdownSocials = function() {
+    $('.socials-dropdown').dropdown({
+        allowAdditions: true,
+        onNoResults: function(searchValue) {
+            $(this).dropdown('set value', searchValue);
+        }
+    });
+}
+
+var _rmSocial = function(elt) {
+    if ( typeof elt == 'undefined') {
+        elt = $('#social .stored');
+    }
+    elt.find('.delsocial').click(function(e){
+        e.preventDefault();
+        var _this = $(this);
+        _this.parents('.field.stored').remove();
+    });
+}
+
+$(function(){
+    _rmSocial();
+    _dropdownSocials();
+
+    $('a.addsocial').click(function(e) {
+        e.preventDefault();
+
+        var _newindex = $(this).parents('.addsocial').find('.combo-social:last .socials-dropdown').attr('id').replace('social_new_type_', '');
+        ++_newindex;
+        $(this).parents('.addsocial').find ('.combo-social:last')
+            .clone() // copy
+            .insertAfter('#social .combo-social:last') // where
+            .find('.socials-dropdown').attr('id', 'social_new_type_' + _newindex).dropdown('clear')
+            .find('input:not(.search)').attr('id', 'social_new_type_input_' + _newindex).attr('name', 'social_new_type_' + _newindex)
+            .parent().parent().parent().find('input.value').attr('id', 'social_new_value_' + _newindex).attr('name', 'social_new_value_' + _newindex).val('')
+        ;
+
+        _dropdownSocials();
+    });
+});
index 796d4917ded0c26b4a5ec1a0a837e26229518e82..50544e774ffaaba1fbc2990c5b748f53bf462ea4 100644 (file)
@@ -35,7 +35,7 @@
 
                 var cropping = { ratio: '{{ preferences.pref_member_picture_ratio }}' };
                 var focus_select = '<div class="ui basic horizontally fitted segment form"><div class="field">';
-                    focus_select += '<select name="crop_focus_ajax" id="crop_focus_ajax" class="ui dropdown nochosen">';
+                    focus_select += '<select name="crop_focus_ajax" id="crop_focus_ajax" class="ui dropdown">';
                     focus_select += '<option value="center">{{ _T("Center") }}</option>';
                     focus_select += '<option value="top">{{ _T("Top") }}</option>';
                     focus_select += '<option value="bottom">{{ _T("Bottom") }}</option>';
index 22abc6d3b67443b822f271f8a6ed9bb2a645b147..ed7f61bbfa89b75d6b498a8072d492584452229d 100644 (file)
@@ -28,7 +28,7 @@
 <script type="text/javascript">
 
     var _addLegendButton = function(selector) {
-        $(selector).append('<a class="btnlegend"><i class="circular inverted primary link icon info tooltip" aria-hidden="true"></i> <span class="ui special popup">{{ _T("Show existing variables")|e('js') }}</span></a>');
+        $(selector).append('<i class="btnlegend circular inverted primary link icon info tooltip" aria-hidden="true"></i> <span class="ui special popup">{{ _T("Show existing variables")|e('js') }}</span>');
     };
 
     var _handleLegend = function(selector) {
index 26abe15af5ca03fc840f30e8041308234b8e7640..aeeb4c19f59222823c32a5aa4da1891df333e06a 100644 (file)
@@ -15,7 +15,7 @@
                         </div>
                         <div class="field">
                             <label for="field_filter">{{ _T('in:') }}</label>
-                            <select name="field_filter" class="ui search dropdown nochosen">
+                            <select name="field_filter" class="ui search dropdown">
     {% for key, value in field_filter_options %}
                                 <option value="{{ key }}"{% if key == filters.field_filter %} selected="selected"{% endif %}>{{ value }}</option>
     {% endfor %}
@@ -23,7 +23,7 @@
                         </div>
                         <div class="field">
                             <label for="membership_filter">{{ _T('Membership status') }}</label>
-                            <select id="membership_filter" name="membership_filter" class="ui search dropdown nochosen">
+                            <select id="membership_filter" name="membership_filter" class="ui search dropdown">
     {% for key, value in membership_filter_options %}
                                     <option value="{{ key }}"{% if key == filters.membership_filter %} selected="selected"{% endif %}>{{ value }}</option>
     {% endfor %}
@@ -31,7 +31,7 @@
                         </div>
                         <div class="field">
                             <label for="filter_account">{{ _T('Account activity') }}</label>
-                            <select id="filter_account" name="filter_account" class="ui search dropdown nochosen">
+                            <select id="filter_account" name="filter_account" class="ui search dropdown">
     {% for key, value in filter_accounts_options %}
                                     <option value="{{ key }}"{% if key == filters.filter_account %} selected="selected"{% endif %}>{{ value }}</option>
     {% endfor %}
@@ -39,7 +39,7 @@
                         </div>
                         <div class="field">
                             <label for="group_filter">{{ _T('Member of group') }}</label>
-                            <select name="group_filter" id="group_filter" class="ui search dropdown nochosen">
+                            <select name="group_filter" id="group_filter" class="ui search dropdown">
                                 <option value="0">{{ _T('Select a group') }}</option>
 {% for group in filter_groups_options %}
                                 <option value="{{ group.getId() }}"{% if filters.group_filter == group.getId() %} selected="selected"{% endif %}>{{ group.getIndentName()|raw }}</option>
                         </div>
                         <div class="field">
                             <label for="status">{{ _T('Status') }}</label>
-                            <select name="status[]" id="status" multiple="" class="ui search dropdown nochosen">
+                            <select name="status[]" id="status" multiple="" class="ui dropdown">
                                 <option value="">{{ _T('Status') }}</option>
     {% for key, value in statuts %}
                                     <option value="{{ key }}"{% if key in filters.status %} selected="selected"{% endif %}>{{ value }}</option>
                 </div>
                 <div class="active content">
                     <div class="field">
-                        <select name="groups_logical_operator" class="operator_selector ui search dropdown nochosen">
+                        <select name="groups_logical_operator" class="operator_selector ui search dropdown">
                           <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_AND") }}"{% if filters.groups_search_log_op == constant("Galette\\Filters\\AdvancedMembersList::OP_AND") %} selected="selected"{% endif %}>{{ _T('In all selected groups') }}</option>
                           <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_OR") }}"{% if filters.groups_search_log_op == constant("Galette\\Filters\\AdvancedMembersList::OP_OR") %} selected="selected"{% endif %}>{{ _T('In any of selected groups') }}</option>
                         </select>
                                     <i class="arrows alternate icon" aria-hidden="true"></i>
                                 </div>
                                 <div>
-                                    <select name="groups_search[]" class="group_selector ui search dropdown nochosen">
+                                    <select name="groups_search[]" class="group_selector ui search dropdown">
                                         <option value="">{{ _T('Select a group') }}</option>
                         {% for group in filter_groups_options %}
                                         <option value="{{ group.getId() }}"{% if gs.group == group.getId() %} selected="selected"{% endif %}>{{ group.getName() }}</option>
                     <div class="two fields">
                         <div class="field">
                             <label for="contributions_types">{{ _T('Type') }}</label>
-                            <select name="contributions_types[]" id="contributions_types" multiple="" class="ui dropdown nochosen">
+                            <select name="contributions_types[]" id="contributions_types" multiple="" class="ui dropdown">
                                 <option value="">{{ _T('Type') }}</option>
 
                             {% for key, value in contributions_types %}
                         </div>
                         <div class="field">
                             <label for="payments_types">{{ _T('Payment type') }}</label>
-                            <select name="payments_types[]" id="payments_types" multiple="" class="ui dropdown nochosen">
+                            <select name="payments_types[]" id="payments_types" multiple="" class="ui dropdown">
                                 <option value="">{{ _T('Payment type') }}</option>
                             {% for key, value in payments_types %}
                                 <option value="{{ key }}"{% if key == filters.payments_types %} selected="selected"{% endif %}>{{ value }}</option>
     {% elseif get_class(field) == "Galette\\DynamicFields\\Text" %}
                         <textarea name="cds_{{ field.getId() }}" id="cds_{{ field.getId() }}">{% if attribute(filters.contrib_dynamic, fid) is defined %}{{ attribute(filters.contrib_dynamic, fid) }}{% endif %}</textarea>
     {% elseif get_class(field) == "Galette\\DynamicFields\\Choice" %}
-                        <select name="cdsc_{{ field.getId() }}[]" id="cdsc_{{ field.getId() }}" multiple="multiple" class="ui dropdown nochosen">
+                        <select name="cdsc_{{ field.getId() }}[]" id="cdsc_{{ field.getId() }}" multiple="multiple" class="ui dropdown">
                             <option value="">{{ _T('Select') }}</option>
         {% for k, choice in field.getValues() %}
                             <option value="{{ k }}"{% if attribute(filters.contrib_dynamic, fid) is defined and k in attribute(filters.contrib_dynamic, fid) %} selected="selected"{% endif %}>{{ choice }}</option>
                                         <i class="arrows alternate icon" aria-hidden="true"></i>
                                     </div>
                                     <div class="inline fields">
-                                        <select name="free_logical_operator[]" class="operator_selector ui selection dropdown nochosen">
+                                        <select name="free_logical_operator[]" class="operator_selector ui selection dropdown">
                                             <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_AND") }}"{% if fs.log_op == constant("Galette\\Filters\\AdvancedMembersList::OP_AND") %} selected="selected"{% endif %}>{{ _T('and') }}</option>
                                             <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_OR") }}"{% if fs.log_op == constant("Galette\\Filters\\AdvancedMembersList::OP_OR") %} selected="selected"{% endif %}>{{ _T('or') }}</option>
                                         </select>
-                                        <div class="field_selector ui search selection dropdown origselect nochosen">
+                                        <div class="field_selector ui search selection dropdown origselect">
                                             <input type="hidden" name="free_field[]" value="{{ fs.field }}">
                                             <i class="dropdown icon"></i>
                                             <div class="text">{{ _T('Select a field') }}</div>
                                         <div class="data inline fields">
                                             <input type="hidden" name="free_type[]" value="{% if cur_field is defined %}{{ cur_field.getType() }}{% endif %}"/>
     {% if cur_field is defined and (get_class(cur_field) == "Galette\\DynamicFields\\Choice" or type == constant("Galette\\DynamicFields\\DynamicField::CHOICE")) %}
-                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown nochosen">
+                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown">
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") %} selected="selected"{% endif %}>{{ _T('is') }}</option>
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_NOT_EQUALS") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_NOT_EQUALS") %} selected="selected"{% endif %}>{{ _T('is not') }}</option>
                                             </select>
-                                            <select name="free_text[]" class="free_text ui search dropdown nochosen">
+                                            <select name="free_text[]" class="free_text ui search dropdown">
         {% if cur_field is defined and get_class(cur_field) == "Galette\\DynamicFields\\Choice" %}
             {% for key, value in cur_field.getValues() %}
                                                 <option value="{{ key }}"{% if key == fs.search %} selected="selected"{% endif %}>{{ value }}</option>
         {% endif %}
                                             </select>
     {% elseif cur_field is defined and (get_class(cur_field) == "Galette\\DynamicFields\\Date" or type == constant("Galette\\DynamicFields\\DynamicField::DATE")) %}
-                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown nochosen">
+                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown">
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") %} selected="selected"{% endif %}>{{ _T('is') }}</option>
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_BEFORE") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_BEFORE") %} selected="selected"{% endif %}>{{ _T('before') }}</option>
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_AFTER") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_AFTER") %} selected="selected"{% endif %}>{{ _T('after') }}</option>
                                             <input type="text" name="free_text[]" value="{{ fs.search|date(_T('Y-m-d')) }}" class="modif_date" maxlength="10" size="10"/>
                                             <span class="exemple">{{ _T('(yyyy-mm-dd format)') }}</span>
     {% elseif cur_field is defined and (get_class(cur_field) == "Galette\\DynamicFields\\Boolean" or type == constant("Galette\\DynamicFields\\DynamicField::BOOLEAN")) %}
-                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown nochosen">
+                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown">
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") %} selected="selected"{% endif %}>{{ _T('is') }}</option>
                                             </select>
                                             <input type="radio" name="free_text[]" id="free_text_yes" value="1"{% if fs.search == 1 %} checked="checked"{% endif %}/><label for="free_text_yes">{{ _T('Yes') }}</label>
                                             <input type="radio" name="free_text[]" id="free_text_no" value="0"{% if fs.search == 0 %} checked="checked"{% endif %}/><label for="free_text_no">{{ _T('No') }}</label>
     {% else %}
-                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown nochosen">
+                                            <select name="free_query_operator[]" class="free_operator ui selection dropdown">
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_EQUALS") %} selected="selected"{% endif %}>{{ _T('is') }}</option>
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_CONTAINS") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_CONTAINS") %} selected="selected"{% endif %}>{{ _T('contains') }}</option>
                                                 <option value="{{ constant("Galette\\Filters\\AdvancedMembersList::OP_NOT_EQUALS") }}"{% if fs.qry_op == constant("Galette\\Filters\\AdvancedMembersList::OP_NOT_EQUALS") %} selected="selected"{% endif %}>{{ _T('is not') }}</option>
                                         _options += '<option value="' + key + '">' + _field.values[key] + '</option>';
                                     }
                                 }
-                                _html += '<select name="free_text[]" class="ui search selection dropdown nochosen">' + _options + '</select>';
+                                _html += '<select name="free_text[]" class="ui search selection dropdown">' + _options + '</select>';
                                 break;
                             case '{{ constant('Galette\\DynamicFields\\DynamicField::DATE') }}':
                                 _html  = _getOperatorSelector(['op_equals', 'op_before', 'op_after']);
                     var _operator = _operators[list[i]];
                     _options += '<option value="' + _operator.id + '">' + _operator.name + '</option>';
                 }
-                return '<select name="free_query_operator[]" class="free_operator ui selection dropdown nochosen">' + _options + '</select>';
+                return '<select name="free_query_operator[]" class="free_operator ui selection dropdown">' + _options + '</select>';
             }
 
             var _initSortable = function(){
index f149b376e5e9ca5d7a076fbd68edcc993ac643ed..4934c74b642f570a18d4a5f39f0806ebe4f57151 100644 (file)
@@ -60,7 +60,7 @@
                                 </div>
                                 <div class="column">
                                     <span data-prop-label="{{ _T("Permissions") }}" class="access" title="{{ _T("Change '%field' permissions")|replace({'%field': field.label}) }}">
-                                        <select name="{{ fid }}_visible" id="{{ fid }}_visible" class="ui dropdown nochosen">
+                                        <select name="{{ fid }}_visible" id="{{ fid }}_visible" class="ui dropdown">
                                             <option value="{{ constant('Galette\\Entity\\FieldsConfig::NOBODY') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::NOBODY') %} selected="selected"{% endif %}>{{ _T("Inaccessible") }}</option>
                                             <option value="{{ constant('Galette\\Entity\\FieldsConfig::ADMIN') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::ADMIN') %} selected="selected"{% endif %}>{{ _T("Administrator") }}</option>
                                             <option value="{{ constant('Galette\\Entity\\FieldsConfig::STAFF') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::STAFF') %} selected="selected"{% endif %}>{{ _T("Staff member") }}</option>
index 68d079488b4cd01fd6d20a69bc6560b84302be89..fc0eeec77f1105b0751226619744ab4d9e48b2fb 100644 (file)
@@ -16,7 +16,7 @@
                 </div>
                 <div class="inline field">
                     <label for="field_perm">{{ _T("Permissions:") }}</label>
-                    <select name="field_perm" id="field_perm" class="ui dropdown nochosen">
+                    <select name="field_perm" id="field_perm" class="ui dropdown">
                         {% for key, value in perm_names %}
                             <option value="{{ key }}"{% if key == df.getPerm() %} selected="selected"{% endif %}>{{ value }}</option>
                         {% endfor %}
@@ -25,7 +25,7 @@
     {% if df.hasData() %}
                 <div class="inline field">
                     <label for="field_required">{{ _T("Required:") }}</label>
-                    <select name="field_required" id="field_required" class="ui dropdown nochosen">
+                    <select name="field_required" id="field_required" class="ui dropdown">
                         <option value="0" {% if not df.isRequired() %}selected="selected"{% endif %}>{{ _T("No") }}</option>
                         <option value="1" {% if df.isRequired() %}selected="selected"{% endif %}>{{ _T("Yes") }}</option>
                     </select>
                 </div>
                 <div class="inline field">
                     <label for="field_perm">{{ _T("Visibility") }}</label>
-                    <select name="field_perm" id="field_perm" class="ui dropdown nochosen">
+                    <select name="field_perm" id="field_perm" class="ui dropdown">
                         {% set perm = 0 %}
                         {% if df is defined %}
                             {% set perm = df.getPerm() %}
                 </div>
                 <div class="inline field">
                     <label for="field_type">{{ _T("Type") }}</label>
-                    <select name="field_type" id="field_type" class="ui dropdown nochosen">
+                    <select name="field_type" id="field_type" class="ui dropdown">
                         {% set type = 0 %}
                         {% if df is defined %}
                             {% set type = df.getType() %}
                 </div>
                 <div class="inline field">
                     <label for="field_required">{{ _T("Required") }}</label>
-                    <select name="field_required" id="field_required" class="ui dropdown nochosen">
+                    <select name="field_required" id="field_required" class="ui dropdown">
                         <option value="0"{% if df is not defined or not df.isRequired() %} selected="selected"{% endif %}>{{ _T("No") }}</option>
                         <option value="1"{% if df is defined and df.isRequired() %} selected="selected"{% endif %}>{{ _T("Yes") }}</option>
                     </select>
index 1fb1b796d8218b9e8a4e09f4f81a910c1fdc7615..8aaed30d2add618a362dea26cd69cdf7f3b37c0e 100644 (file)
@@ -25,7 +25,7 @@
     {% if not require_mass %}
                             <div class="inline field">
                                 <label for="id_adh">{{ _T("Contributor:") }}</label>
-                                <div id="id_adh" class="jsonly search-dropdown ui input nochosen paginated">
+                                <div id="id_adh" class="jsonly search-dropdown ui input paginated">
                                     <input id="id_adh_input" type="hidden" name="id_adh" value="{{ contribution.member is not null ? contribution.member }}" placeholder="{{ _T("Member ID") }}">
                                     <i class="jsonly displaynone dropdown icon" aria-hidden="true"></i>
                                     <span class="ui mini compact icon disabled button prev-results"><i class="jsonly displaynone chevron circle left icon disabled button tooltip" title="{{ _T("Load previous members...") }}" aria-hidden="true"></i></span>
@@ -41,7 +41,7 @@
     {% endif %}
                             <div class="inline field{% if required.id_type_cotis is defined and required.id_type_cotis == 1 %} required{% endif %}">
                                 <label for="id_type_cotis">{{ _T("Contribution type:") }}</label>
-                                <div id="id_type_cotis" class="ui dropdown selection nochosen">
+                                <div id="id_type_cotis" class="ui dropdown selection">
                                     {% if contribution.type %}
                                         {% set selectedid = contribution.type.id %}
                                     {% else %}
index 312528bef670e438f74c80165139131e9b4722ec..3cb9a32bc371fa4291284f20098a000de537efde 100644 (file)
@@ -44,7 +44,7 @@
         <div class="four fields">
             <div class="field">
                 <label for="date_field">{{ _T("Show contributions by") }}</label>
-                <select name="date_field" id="date_field" class="ui search dropdown nochosen">
+                <select name="date_field" id="date_field" class="ui search dropdown">
                     <option value="{{ constant("Galette\\Filters\\ContributionsList::DATE_BEGIN") }}"{% if filters.date_field == constant('Galette\\Filters\\ContributionsList::DATE_BEGIN') %} selected="selected"{% endif %}>{{ _T("Begin") }}</option>
                     <option value="{{ constant("Galette\\Filters\\ContributionsList::DATE_END") }}"{% if filters.date_field == constant('Galette\\Filters\\ContributionsList::DATE_END') %} selected="selected"{% endif %}>{{ _T("End") }}</option>
                     <option value="{{ constant("Galette\\Filters\\ContributionsList::DATE_RECORD") }}"{% if filters.date_field == constant('Galette\\Filters\\ContributionsList::DATE_RECORD') %} selected="selected"{% endif %}>{{ _T("Record") }}</option>
index 6a486f5a71542c4d764f6b02a51286752e322b7d..663732ade283c082a4ff5ca46e7a1f6c2dec444d 100644 (file)
@@ -71,7 +71,7 @@
                 {% set users = history.getUsersList() %}
                 {% if users|length > 0 %}
                     <label for="user_filter">{{ _T("Member") }}</label>
-                    <select name="user_filter" id="user_filter" class="ui search dropdown nochosen">
+                    <select name="user_filter" id="user_filter" class="ui search dropdown">
                         <option value="0"{% if history.filters.user_filter == 0 %} selected="selected"{% endif %}>{{ _T("Select an user") }}</option>
                         {% for user in users %}
                             <option value="{{ user }}"{% if history.filters.user_filter == user %} selected="selected"{% endif %}>{{ user }}</option>
@@ -83,7 +83,7 @@
                 {% set actions = history.getActionsList() %}
                 {% if actions|length > 0 %}
                     <label for="action_filter">{{ _T("Action") }}</label>
-                    <select name="action_filter" id="action_filter" class="ui search dropdown nochosen">
+                    <select name="action_filter" id="action_filter" class="ui search dropdown">
                         <option value="0">{{ _T("Select an action") }}</option>
                         {% for action in actions %}
                             <option value="{{ action|escape }}"{% if history.filters.action_filter == action %} selected="selected"{% endif %}>{{ action|escape }}</option>
index 1d6c4d8d0d1673a1847ab9dc357906a8b0346130..68d73b57ff848878b994f26d3a89d63fda12c897 100644 (file)
@@ -20,7 +20,7 @@
                         <div class="three fields">
                             <div class="field">
                                 <label for="sender">{{ _T("Sender") }}</label>
-                                <select name="sender" id="sender" class="ui dropdown nochosen">
+                                <select name="sender" id="sender" class="ui dropdown">
                                     <option value="{{ constant('Galette\\Core\\GaletteMail::SENDER_PREFS') }}">{{ _T("from preferences") }}</option>
                                 {% if not login.isSuperAdmin() %}
                                     <option value="{{ constant('Galette\\Core\\GaletteMail::SENDER_CURRENT') }}">{{ _T("current logged in user") }}</option>
index 6e1a0024a653d851e5c041b7dd3af3e88abf47e1..e3cd2b3ac7c1adb82bd4510073e7ca5307da9945 100644 (file)
@@ -67,7 +67,7 @@
                             </div>
                         </div>
                         <span id="parent_id_elt" class="">
-                            <div id="parent_id" class="jsonly search-dropdown ui input nochosen paginated">
+                            <div id="parent_id" class="jsonly search-dropdown ui input paginated">
                                 <input id="parent_id_input" type="text" name="parent_id" value="{{ member.isDuplicate() and member.parent is defined and member.parent is not null ? member.parent.id }}" placeholder="{{ _T("Member ID") }}">
                                 <i class="jsonly displaynone dropdown icon" aria-hidden="true"></i>
                                 <span class="ui mini compact icon disabled button prev-results"><i class="jsonly displaynone chevron circle left icon disabled button tooltip" title="{{ _T("Load previous members...") }}" aria-hidden="true"></i></span>
             <div class="ui center aligned yellow segment">
                 <div class="inline field">
                     <label for="redirect_on_create">{{ _T("After member creation:") }}</label>
-                    <select name="redirect_on_create" id="redirect_on_create"i class="ui search dropdown nochosen">
+                    <select name="redirect_on_create" id="redirect_on_create"i class="ui search dropdown">
                         <option value="{{ constant('Galette\\Entity\\Adherent::AFTER_ADD_DEFAULT') }}"{% if preferences.pref_redirect_on_create == constant('Galette\\Entity\\Adherent::AFTER_ADD_DEFAULT') %} selected="selected"{% endif %}>{{ _T("create a new contribution (default action)") }}</option>
                         <option value="{{ constant('Galette\\Entity\\Adherent::AFTER_ADD_TRANS') }}"{% if preferences.pref_redirect_on_create == constant('Galette\\Entity\\Adherent::AFTER_ADD_TRANS') %} selected="selected"{% endif %}>{{ _T("create a new transaction") }}</option>
                         <option value="{{ constant('Galette\\Entity\\Adherent::AFTER_ADD_NEW') }}"{% if preferences.pref_redirect_on_create == constant('Galette\\Entity\\Adherent::AFTER_ADD_NEW') %} selected="selected"{% endif %}>{{ _T("create another new member") }}</option>
 {% block javascripts %}
         <script type="text/javascript">
             {% include "elements/js/choose_adh.js.twig" with {"js_chosen_id": "#parent_id"} %}
+            {% include "elements/js/choose_social.js.twig" %}
 
             $(function() {
                 $('#company_field.nocompany').addClass('displaynone');
index 5e4af977bd29a5094e28da2a51e50f4bbede1e47..605d336c7d88c2193213f932b9b6e26df40fbe8a 100644 (file)
@@ -86,7 +86,7 @@
                 </div>
                 <div class="field">
                     <label for="field_filter">{{ _T('in:') }}</label>
-                    <select name="field_filter" id="field_filter" class="ui search dropdown nochosen">
+                    <select name="field_filter" id="field_filter" class="ui search dropdown">
     {% for key, value in field_filter_options %}
                         <option value="{{ key }}"{% if key == filters.field_filter %} selected="selected"{% endif %}>{{ value }}</option>
     {% endfor %}
@@ -94,7 +94,7 @@
                 </div>
                 <div class="field">
                     <label for="filter_str">{{ _T('among:') }}</label>
-                    <select name="membership_filter" class="ui search dropdown nochosen">
+                    <select name="membership_filter" class="ui search dropdown">
                         {% for key, value in membership_filter_options %}
                             <option value="{{ key }}"{% if key == filters.membership_filter %} selected="selected"{% endif %}>{{ value }}</option>
                         {% endfor %}
                 </div>
                 <div class="flexend field">
                     <label for="filter_account" class="visually-hidden">{{ _T('among:') }}</label>
-                    <select name="filter_account" class="ui search dropdown nochosen">
+                    <select name="filter_account" class="ui search dropdown">
                         {% for key, value in filter_accounts_options %}
                             <option value="{{ key }}"{% if key == filters.filter_account %} selected="selected"{% endif %}>{{ value }}</option>
                         {% endfor %}
                 </div>
                 <div class="flexend field">
                     <label for="group_filter" class="visually-hidden">{{ _T('among:') }}</label>
-                    <select name="group_filter" class="ui search dropdown nochosen">
+                    <select name="group_filter" class="ui search dropdown">
                         <option value="0">{{ _T('Select a group') }}</option>
     {% for group in filter_groups_options %}
                         <option value="{{ group.getId() }}"{% if filters.group_filter == group.getId() %} selected="selected"{% endif %}>{{ group.getIndentName()|raw }}</option>
index 53522cb05f2eaeec117b1cfd803c7b25910359c2..5a8eef96bc56a06d5edcaab4067460a487290dd1 100644 (file)
                             </div>
                         </div>
                         <label for="pref_postal_staff_member">{{ _T("Staff member") }}</label>
-                        <select name="pref_postal_staff_member" id="pref_postal_staff_member" class="ui search dropdown nochosen">
+                        <select name="pref_postal_staff_member" id="pref_postal_staff_member" class="ui search dropdown">
                             <option value="-1">{{ _T("-- Choose a staff member --") }}</option>
                         {% for staff in staff_members %}
                             <option value="{{ staff.id }}"{% if staff.id == pref.pref_postal_staff_member %} selected="selected"{% endif %}>{{ staff.name }} ({{ staff.sstatus }})</option>
                 <div class="column">
                     <div class="{% if required.pref_lang is defined and required.pref_lang == 1 %}required {% endif %}field">
                         <label for="pref_lang" >{{ _T("Default language:") }}</label>
-                        <select name="pref_lang" id="pref_lang" class="lang ui search dropdown nochosen"{% if required.pref_lang is defined and required.pref_lang == 1 %} required="required"{% endif %}>
+                        <select name="pref_lang" id="pref_lang" class="lang ui search dropdown"{% if required.pref_lang is defined and required.pref_lang == 1 %} required="required"{% endif %}>
         {% for langue in languages %}
                             <option value="{{ langue.getID() }}" {% if pref.pref_lang == langue.getID() %}selected="selected"{% endif %}>{{ langue.getName()|capitalize }}</option>
         {% endfor %}
                     </div>
                     {#<div class="field">
                         <label for="pref_theme">{{ _T("Default theme:") }}</label>
-                        <select name="pref_theme" id="pref_theme" class="ui search dropdown nochosen">
+                        <select name="pref_theme" id="pref_theme" class="ui search dropdown">
         {% for theme in themes %}
                             <option value="{{ theme }}" {% if pref.pref_theme == theme %}selected="selected"{% endif %}>{{ theme|capitalize }}</option>
         {% endfor %}
                     </div>#}
                     <div class="{% if required.pref_numrows is defined and required.pref_numrows == 1 %}required {% endif %}field">
                         <label for="pref_numrows">{{ _T("Lines / Page:") }}</label>
-                        <select name="pref_numrows" id="pref_numrows" class="ui search dropdown nochosen"{% if required.pref_numrows is defined and required.pref_numrows == 1 %} required="required"{% endif %}>
+                        <select name="pref_numrows" id="pref_numrows" class="ui search dropdown"{% if required.pref_numrows is defined and required.pref_numrows == 1 %} required="required"{% endif %}>
                             {% for key, value in pref_numrows_options %}
                                 <option value="{{ key }}"{% if key == pref.pref_numrows %} selected="selected"{% endif %}>{{ value }}</option>
                             {% endfor %}
                     </div>
                     <div class="field">
                         <label for="pref_redirect_on_create">{{ _T("After member creation:") }}</label>
-                        <select name="pref_redirect_on_create" id="pref_redirect_on_create" class="ui search dropdown nochosen">
+                        <select name="pref_redirect_on_create" id="pref_redirect_on_create" class="ui search dropdown">
                             <option value="{{ constant('Galette\\Entity\\Adherent::AFTER_ADD_DEFAULT') }}"{% if pref.pref_redirect_on_create == constant('Galette\\Entity\\Adherent::AFTER_ADD_DEFAULT') %} selected="selected"{% endif %}>{{ _T("create a new contribution (default action)") }}</option>
                             <option value="{{ constant('Galette\\Entity\\Adherent::AFTER_ADD_TRANS') }}"{% if pref.pref_redirect_on_create == constant('Galette\\Entity\\Adherent::AFTER_ADD_TRANS') %} selected="selected"{% endif %}>{{ _T("create a new transaction") }}</option>
                             <option value="{{ constant('Galette\\Entity\\Adherent::AFTER_ADD_NEW') }}"{% if pref.pref_redirect_on_create == constant('Galette\\Entity\\Adherent::AFTER_ADD_NEW') %} selected="selected"{% endif %}>{{ _T("create another new member") }}</option>
                     </div>
                     <div class="{% if required.pref_log is defined and required.pref_log == 1 %}required {% endif %}field">
                         <label for="pref_log">{{ _T("Logging level:") }}</label>
-                        <select name="pref_log" id="pref_log" class="ui search dropdown nochosen"{% if required.pref_log is defined and required.pref_log == 1 %} required="required"{% endif %}>
+                        <select name="pref_log" id="pref_log" class="ui search dropdown"{% if required.pref_log is defined and required.pref_log == 1 %} required="required"{% endif %}>
                             <option value="{{ constant('Galette\\Core\\Preferences::LOG_DISABLED') }}" {% if pref.pref_log == constant('Galette\\Core\\Preferences::LOG_DISABLED') %}selected="selected"{% endif %}>{{ _T("Disabled") }}</option>
                             <option value="{{ constant('Galette\\Core\\Preferences::LOG_ENABLED') }}" {% if pref.pref_log == constant('Galette\\Core\\Preferences::LOG_ENABLED') %}selected="selected"{% endif %}>{{ _T("Enabled") }}</option>
                         </select>
                     </div>
                     <div class="field">
                         <label for="pref_filter_account">{{ _T("Default account filter:") }}</label>
-                        <select name="pref_filter_account" id="pref_filter_account" class="ui search dropdown nochosen">
+                        <select name="pref_filter_account" id="pref_filter_account" class="ui search dropdown">
                             {% for key, value in accounts_options %}
                                 <option value="{{ key }}"{% if key == pref.pref_filter_account %} selected="selected"{% endif %}>{{ value }}</option>
                             {% endfor %}
                     </div>
                     <div class="field">
                         <label for="pref_default_paymenttype">{{ _T("Default payment type:") }}</label>
-                        <select name="pref_default_paymenttype" id="pref_default_paymenttype" class="ui search dropdown nochosen">
+                        <select name="pref_default_paymenttype" id="pref_default_paymenttype" class="ui search dropdown">
                             {% for key, value in paymenttypes %}
                                 <option value="{{ key }}"{% if key == pref.pref_default_paymenttype %} selected="selected"{% endif %}>{{ value }}</option>
                             {% endfor %}
                     </div>
                     <div id="publicpages_visibility" class="field{% if not pref.pref_bool_publicpages %} displaynone{% endif %}">
                         <label for="pref_publicpages_visibility">{{ _T("Show public pages for") }}</label>
-                        <select name="pref_publicpages_visibility" id="pref_publicpages_visibility" class="ui search dropdown nochosen">
+                        <select name="pref_publicpages_visibility" id="pref_publicpages_visibility" class="ui search dropdown">
                             <option value="{{ constant('Galette\\Core\\Preferences::PUBLIC_PAGES_VISIBILITY_PUBLIC') }}"{% if pref.pref_publicpages_visibility == constant('Galette\\Core\\Preferences::PUBLIC_PAGES_VISIBILITY_PUBLIC') %} selected="selected"{% endif %}>{{ _T("Everyone") }}</option>
                             <option value="{{ constant('Galette\\Core\\Preferences::PUBLIC_PAGES_VISIBILITY_RESTRICTED') }}"{% if pref.pref_publicpages_visibility == constant('Galette\\Core\\Preferences::PUBLIC_PAGES_VISIBILITY_RESTRICTED') %} selected="selected"{% endif %}>{{ _T("Up to date members") }}</option>
                             <option value="{{ constant('Galette\\Core\\Preferences::PUBLIC_PAGES_VISIBILITY_PRIVATE') }}"{% if pref.pref_publicpages_visibility == constant('Galette\\Core\\Preferences::PUBLIC_PAGES_VISIBILITY_PRIVATE') %} selected="selected"{% endif %}>{{ _T("Admin and staff only") }}</option>
                     </div>
                     <div id="pref_member_picture_ratio_field" class="inline field{% if pref.pref_force_picture_ratio != 1 %} displaynone{% endif %}">
                         <label for="pref_member_picture_ratio">{{ _T("Select a ratio") }}</label>
-                        <select name="pref_member_picture_ratio" id="pref_member_picture_ratio" class="ui dropdown nochosen">
+                        <select name="pref_member_picture_ratio" id="pref_member_picture_ratio" class="ui dropdown">
                             <option value="square_ratio"{% if pref.pref_member_picture_ratio == 'square_ratio' %} selected="selected"{% endif %}>{{ _T("Square (1:1)") }}</option>
                             <option value="portrait_ratio"{% if pref.pref_member_picture_ratio == 'portrait_ratio' %} selected="selected"{% endif %}>{{ _T("Portrait (3:4)") }}</option>
                             <option value="landscape_ratio"{% if pref.pref_member_picture_ratio == 'landscape_ratio' %} selected="selected"{% endif %}>{{ _T("Landscape (4:3)") }}</option>
                 <div class="column">
                     <div class="field{% if required.pref_statut is defined and required.pref_statut == 1 %} required{% endif %}">
                         <label for="pref_statut">{{ _T("Default membership status:") }}</label>
-                        <select name="pref_statut" id="pref_statut" class="ui search dropdown nochosen"{% if required.pref_statut is defined and required.pref_statut == 1 %} required="required"{% endif %}>
+                        <select name="pref_statut" id="pref_statut" class="ui search dropdown"{% if required.pref_statut is defined and required.pref_statut == 1 %} required="required"{% endif %}>
                             {% for key, value in statuts %}
                                 <option value="{{ key }}"{% if key == pref.pref_statut %} selected="selected"{% endif %}>{{ value }}</option>
                             {% endfor %}
                     </div>
                     <div class="field">
                         <label for="pref_card_address">{{ _T("Address type:") }}</label>
-                        <select name="pref_card_address" id="pref_card_address" class="ui search dropdown nochosen">
+                        <select name="pref_card_address" id="pref_card_address" class="ui search dropdown">
                             <option value="0" {% if pref.pref_card_address == 0 %}selected="selected"{% endif %}>{{ _T("Email") }}</option>
                             <option value="5" {% if pref.pref_card_address == 5 %}selected="selected"{% endif %}>{{ _T("Zip - Town") }}</option>
                             <option value="6" {% if pref.pref_card_address == 6 %}selected="selected"{% endif %}>{{ _T("Nickname") }}</option>
                 </div>
                 <div class="inline field">
                     <label for="pref_password_strength" title="{{ _T("Enforce password strength") }}">{{ _T("Password strength:") }}</label>
-                    <select name="pref_password_strength" id="pref_password_strength" class="ui dropdown nochosen">
+                    <select name="pref_password_strength" id="pref_password_strength" class="ui dropdown">
                         <option value="{{ constant('Galette\\Core\\Preferences::PWD_NONE') }}"{% if pref.pref_password_strength == constant('Galette\\Core\\Preferences::PWD_NONE') %} selected="selected"{% endif %}>{{ _T("None (default)") }}</option>
                         <option value="{{ constant('Galette\\Core\\Preferences::PWD_WEAK') }}"{% if pref.pref_password_strength == constant('Galette\\Core\\Preferences::PWD_WEAK') %} selected="selected"{% endif %}>{{ _T("Weak") }}</option>
                         <option value="{{ constant('Galette\\Core\\Preferences::PWD_MEDIUM') }}"{% if pref.pref_password_strength == constant('Galette\\Core\\Preferences::PWD_MEDIUM') %} selected="selected"{% endif %}>{{ _T("Medium") }}</option>
 
 {% block javascripts %}
         <script type="text/javascript">
+            {% include "elements/js/choose_social.js.twig" %}
+
             $(function(){
     {% if pref.pref_mail_method != constant('Galette\\Core\\GaletteMail::METHOD_SMTP') %}
                 $('#smtp_parameters').addClass('displaynone');
index 684093a4867433aa6a4fb9b512c9886807e4bda3..fb22acdcbb87be82357bd86a9401dae7278d9b2c 100644 (file)
@@ -16,7 +16,7 @@
                         </div>
                         <div class="field inline{% if required.id_adh is defined and required.id_adh == 1 %} required{% endif %}">
                             <label for="id_adh" >{{ _T("Originator:") }}</label>
-                            <div id="id_adh" class="jsonly search-dropdown ui input nochosen paginated"{% if required.id_adh is defined and required.id_adh == 1 %} required="required"{% endif %}>
+                            <div id="id_adh" class="jsonly search-dropdown ui input paginated"{% if required.id_adh is defined and required.id_adh == 1 %} required="required"{% endif %}>
                                 <input id="id_adh_input" type="text" name="id_adh" value="{{ transaction.member is not null ? transaction.member }}" placeholder="{{ _T("Member ID") }}">
                                 <i class="jsonly displaynone dropdown icon" aria-hidden="true"></i>
                                 <span class="ui mini compact icon disabled button prev-results"><i class="jsonly displaynone chevron circle left icon disabled button tooltip" title="{{ _T("Load previous members...") }}" aria-hidden="true"></i></span>
index ca7042027549afa9efeca2b2c500d87c90c39615..78d4d487b67234e6e899a0851c325ca003568c59 100644 (file)
@@ -30,7 +30,7 @@
 var _bindFomanticComponents = function() {
     var
         $sidebar         = $('.ui.sidebar'),
-        $dropdown        = $('.ui.dropdown:not(.navigation, .autosubmit, .nochosen), select:not(.nochosen)'),
+        $dropdown        = $('.ui.dropdown:not(.navigation, .autosubmit), select'),
         $dropdownNav     = $('.ui.dropdown.navigation'),
         $accordion       = $('.ui.accordion'),
         $checkbox        = $('.ui.checkbox, .ui.radio.checkbox'),
index b04af28fc9e3a2c949bf0222135b0f835dedd11f..14c9a9403f790983318741c826a5b0179c9c73c0 100644 (file)
   display: none !important;
 }
 
+.ui.corner.label .icon.btnlegend {
+    cursor: pointer;
+}
+
 /* Content using visually-hidden is read by screen readers */
 .visually-hidden {
   position: absolute !important;
index 6a4c7d4b8f572edada50c5b7abea08b7530b2f6c..62edaaead994e298b0627f2efba813f99868d61f 100644 (file)
 /*------------------------
      Search dropdown
 -------------------------*/
+.ui.form .fields .field .ui.input.search input,
+.ui.search.selection.dropdown > input.search {
+  width: 100%;
+}
 .ui.search.selection.paginated.dropdown {
     > .ui.mini.button {
         display: none;
     }
-    > input.search {
-        width: 100%;
-    }
     &.visible > .ui.mini.button {
         display: block;
         margin-right: 0;