Contao-Camp 2024
Ergebnis 1 bis 15 von 15

Thema: DCA - Filter erstellen von Child-Table

  1. #1
    Alter Contao-Hase
    Registriert seit
    18.07.2012.
    Ort
    Löbau
    Beiträge
    1.124

    Standard DCA - Filter erstellen von Child-Table

    Hallo,

    möchte gern einen eigenen Filter erstellen, den ich per Select auswählen kann. Da wir viele Reisen verwalten wäre es schön wenn man sich auch Reisen nur aus einen Land anzeigen lassen könnte.

    Im Screenshot sieht man wie es aussieht, was ja aber keinen was bringt. Ich bräucht quasie nur eine Liste mit allen Ländern. Leider bringen mich die bisherigen Funde im Forum und Goggle nicht weiter.

    Kann man sowas überhaupt umsetzten?

    AUszug auf der DCA
    PHP-Code:
            'travelCountries' => array
            (
                
    'label'            => &$GLOBALS['TL_LANG']['tl_wt_travel']['travelCountries'],
                
    'exclude'         => true,
                
    'filter'        => true,
                
    'inputType'     => 'multiColumnWizard',
                
    'eval'             => array
                (
                    
    'columnFields' => array
                    (
                        
    'land_id' => array
                        (
                            
    'label'                 => &$GLOBALS['TL_LANG']['tl_wt_travel']['land_id'],
                            
    'exclude'               => true,
                            
    'filter'        => true,
                            
    'inputType'             => 'select',
                            
    'options_callback'      => array('tl_wt_travel','create_countires_options'),
                            
    'eval'                     => array('style' => 'width:250px''includeBlankOption'=>false'chosen'=>true)
                        ),
                    )
                ),
                
    'sql'            => "varchar(255) NOT NULL default ''"
            
    ), 
    LG Ralf

    EDIT: ups falsches Board kann das bitte jemand verschieben in ENtwickler-Fragen :/ sorry
    Angehängte Grafiken Angehängte Grafiken
    Geändert von WebRoxx (18.02.2014 um 14:17 Uhr)

  2. #2
    Contao-Urgestein Avatar von Tim G
    Registriert seit
    13.02.2010.
    Ort
    Lübeck
    Beiträge
    2.210
    User beschenken
    Wunschliste

    Standard

    Ja, das geht. Z.B. über den loadDataContainer HOOK und darin in einer Funktion dem aktuellen DCA einen eigenen Filterwert unterjubeln.
    Damit hast Du Einfluss auf das query, was die Listeneinträge erstellt.

    Beispiel nur id 1 zeigen im aktuellen DCA

    PHP-Code:
    public function showId1(\DataContainer $objDC)
    {
    $GLOBALS['TL_DCA'][$objDC->table]['list']['sorting']['filter'][] = array('id=?',1);

    Wie man zu dem Filter kommt, ist jedem natürlich freigestellt.
    http://www.tim-gatzky.de ˙ auch schon wieder 2 Jahre alt - wie die Zeit vergeht... muss mal umbauen.

  3. #3
    Alter Contao-Hase
    Registriert seit
    18.07.2012.
    Ort
    Löbau
    Beiträge
    1.124

    Standard

    Zitat Zitat von Tim G Beitrag anzeigen
    Ja, das geht. Z.B. über den loadDataContainer HOOK und darin in einer Funktion dem aktuellen DCA einen eigenen Filterwert unterjubeln.
    Damit hast Du Einfluss auf das query, was die Listeneinträge erstellt.

    Beispiel nur id 1 zeigen im aktuellen DCA

    PHP-Code:
    public function showId1(\DataContainer $objDC)
    {
    $GLOBALS['TL_DCA'][$objDC->table]['list']['sorting']['filter'][] = array('id=?',1);

    Wie man zu dem Filter kommt, ist jedem natürlich freigestellt.
    Ja, aber so zeigt es mir doch aber nun den Datensatz mit id 1 ein, ic hbracuhe aber oben ein Filterfeld

  4. #4
    Contao-Urgestein Avatar von Tim G
    Registriert seit
    13.02.2010.
    Ort
    Lübeck
    Beiträge
    2.210
    User beschenken
    Wunschliste

    Standard

    Bau dir dazu ein eigenes Feld im DCA, was nur den Filter stellt.
    http://www.tim-gatzky.de ˙ auch schon wieder 2 Jahre alt - wie die Zeit vergeht... muss mal umbauen.

  5. #5
    Alter Contao-Hase
    Registriert seit
    18.07.2012.
    Ort
    Löbau
    Beiträge
    1.124

    Standard

    Zitat Zitat von Tim G Beitrag anzeigen
    Bau dir dazu ein eigenes Feld im DCA, was nur den Filter stellt.
    Mh ich glaub du verstehst das miss.

    Der Filter soll oben als select erscheinen...wenn man da was wählt soll halt nur das angezeigt werden. Wie hslt im standart.

    Nur ist das feld was ich habe halt ein mukticolum feld

    Oder was meinst du jetzt mit feld?

  6. #6
    Contao-Nutzer
    Registriert seit
    15.02.2014.
    Beiträge
    5

    Standard

    Ich habe ein ähnliches Problem gelöst indem ich den panel_callback benutzt habe um einen eigenen Filter generieren zu lassen.
    Soweit ich das richtig sehr ist dieser callback noch nicht dokumentiert und ich habe ihn per Zufall im Code des Isotope Shops gefunden. Dort wird er wenn ich mich richtig erinnere in der tl_product dca benutzt.
    Vllt hilft es ja weiter

    MfG Marco


    Gesendet von meinem iPhone mit Tapatalk

  7. #7
    Alter Contao-Hase
    Registriert seit
    18.07.2012.
    Ort
    Löbau
    Beiträge
    1.124

    Standard

    Ok, damit geht´s,

    PHP-Code:
    'panelLayout'             => 'myfilter,filter;sort,search,limit',
    'panel_callback'             => array('myfilter' => array('tl_wt_travel''generateFilterButtons')), 
    PHP-Code:
        public function generateFilterButtons(DataContainer $dc)
        {
        
            if (\
    Input::get('id') > 0) {
                return 
    '';
            }

            
    $filter '<div class="tl_filter tl_subpanel"><select name="travelCountries" id="travelCountries" class="tl_select">';
            
    $objPages $this->Database->prepare("SELECT c.id,cc.continent,c.country FROM tl_wt_countries c INNER JOIN tl_wt_continent cc ON cc.id = c.pid")->execute();
            while(
    $objPages->next()){
                 
    $filter .= '<option value="'.$objPages->id.'">'.$objPages->country.'</option>';
            }
            
    $filter .= '</select></div>';
            return 
    $filter;
        } 
    Jetzt bräuchte ich nur noch genau dafür ne extra query in der ich dann Suchen kann und die ergebniss liefern kann. Denn nur so klappt es noch nicht da das Feld travelCountries ja eine multicoulum feld ist was die daten so enthält
    Code:
    a:1:{i:0;a:1:{s:7:"land_id";s:2:"80";}}
    Gab es da n et auch ein Hook wo man die SQL bearbeiten konnte vom Filter?

    LG Ralf

  8. #8
    Contao-Urgestein Avatar von Tim G
    Registriert seit
    13.02.2010.
    Ort
    Lübeck
    Beiträge
    2.210
    User beschenken
    Wunschliste

    Standard DCA - Filter erstellen von Child-Table

    Cool panel callback kannte ich jetzt auch nicht.
    Aber den sql query der liste kannst du wie oben erwähnt im onload_callback einbauen.
    Dein filter sollte ja entweder via post oder get optionen feuern, auf die du reagieren kannst.
    loadDataContainer Hook sollte event auch schon passen.


    Sent from my iPhone using Tapatalk
    Geändert von Tim G (24.02.2014 um 15:02 Uhr)
    http://www.tim-gatzky.de ˙ auch schon wieder 2 Jahre alt - wie die Zeit vergeht... muss mal umbauen.

  9. #9
    Alter Contao-Hase
    Registriert seit
    18.07.2012.
    Ort
    Löbau
    Beiträge
    1.124

    Standard

    So nach ewigen probiere habsch einfach mal das aus dem Isotobe genommen.

    PHP-Code:
            'onload_callback' => array
            (
                array(
    'tl_wt_travel''applyAdvancedFilters'),
        ) 
    PHP-Code:
                'panelLayout'             => 'iso_filter,filter;sort,search,limit',
                
    'panel_callback'        => array
                (
                    
    'iso_filter'  => array('tl_wt_travel''generateAdvancedFilters'),
                ) 


    PHP-Code:
         */
        public function 
    generateAdvancedFilters()
        {
            if (\
    Input::get('id') > 0) {
                return 
    '';
            }
            
            
    $arrOptions  = array();
            
    $objPages $this->Database->prepare("SELECT c.id,c.pid,c.country,k.continent FROM tl_wt_countries c
                                                    LEFT JOIN tl_wt_continent k ON c.pid = k.id
                                                    ORDER BY c.country ASC"
    )->execute();
            while(
    $objPages->next()){
                
    $arrOptions[$objPages->continent][$objPages->id] = "$objPages->country";
            }
            
            
    $session = \Session::getInstance()->getData();

            
    // Filters
            
    $arrFilters = array
            (
                
    'travelCountries'   => array
                (
                    
    'name'    => 'travelCountries',
                    
    'label'   => $GLOBALS['TL_LANG']['tl_wt_travel']['filter_travelCountries'],
                    
    'options' => $arrOptions,
                ),
            );

            
    $strBuffer '<div class="tl_filter iso_filter tl_subpanel">
            <strong>' 
    $GLOBALS['TL_LANG']['tl_wt_travel']['filter'] . '</strong>' "\n";

            
    // Generate filters
            
    foreach ($arrFilters as $arrFilter) {
                
    $strOptions '
      <option value="' 
    $arrFilter['name'] . '">' $arrFilter['label'] . '</option>
      <option value="' 
    $arrFilter['name'] . '">---</option>' "\n";

                
    // Generate options
                
    foreach ($arrFilter['options'] as $k => $v) {
                    if(
    is_array($v)) {
                        
    $strOptions .= '<optgroup label="'.$k.'">';    
                        foreach (
    $v as $id => $name) {
                            
    $strOptions .= '  <option value="' $id '"' . (($session['filter']['tl_wt_travel'][$arrFilter['name']] === (string) $id) ? ' selected' '') . '>' $name '</option>' "\n";
                        }        
                        
    $strOptions .= '</optgroup>';    
                    } else {
                        
    $strOptions .= '  <option value="' $k '"' . (($session['filter']['tl_wt_travel'][$arrFilter['name']] === (string) $k) ? ' selected' '') . '>' $v '</option>' "\n";
                    }
                }

                
    $strBuffer .= '<select name="' $arrFilter['name'] . '" id="' $arrFilter['name'] . '" class="tl_select' . (isset($session['filter']['tl_wt_travel'][$arrFilter['name']]) ? ' active' '') . '">
    $strOptions '
    </select>' 
    "\n";
            }

            return 
    $strBuffer '</div>';
        }
        
        
        
       public function 
    applyAdvancedFilters()
       {
            
    $session $this->Session->getData();

            
    // Store filter values in the session
            
    foreach ($_POST as $k => $v) {
                
    // Reset the filter
                
    if ($k == \Input::post($k)) {
                    unset(
    $session['filter']['tl_wt_travel'][$k]);
                } 
    // Apply the filter
                
    else {
                    
    $session['filter']['tl_wt_travel'][$k] = \Input::post($k);
                }
            }

            
    $this->Session->setData($session);

            if (\
    Input::get('id') > || !isset($session['filter']['tl_wt_travel'])) {
                return;
            }

            
    $arrProducts null;

            
    // Filter the products
            
    foreach ($session['filter']['tl_wt_travel'] as $k => $v) {

                switch (
    $k) {
                    
    // Show products with or without images
                    
    case 'travelCountries':
                        
    $objProducts = \Database::getInstance()->prepare("SELECT id FROM tl_wt_travel WHERE travelCountries LIKE ?")->execute('%'.serialize($v).'%');
                        
    $arrProducts is_array($arrProducts) ? array_intersect($arrProducts$objProducts->fetchEach('id')) : $objProducts->fetchEach('id');
                        break;

                    default:
                        
    // !HOOK: add custom advanced filters
                        
    if (isset($GLOBALS['ISO_HOOKS']['applyAdvancedFilters']) && is_array($GLOBALS['ISO_HOOKS']['applyAdvancedFilters'])) {
                            foreach (
    $GLOBALS['ISO_HOOKS']['applyAdvancedFilters'] as $callback) {
                                
    $objCallback = \System::importStatic($callback[0]);
                                
    $arrReturn   $objCallback->$callback[1]($k);

                                if (
    is_array($arrReturn)) {
                                    
    $arrProducts is_array($arrProducts) ? array_intersect($arrProducts$arrReturn) : $arrReturn;
                                    break;
                                }
                            }
                        }
                        \
    System::log('Advanced product filter "' $k '" not found.'__METHOD__TL_ERROR);
                        break;
                }
            }

            if (
    is_array($arrProducts) && empty($arrProducts)) {
                
    $arrProducts = array(0);
            }
            
    $GLOBALS['TL_DCA']['tl_wt_travel']['list']['sorting']['root'] = $arrProducts;
        } 

    Also funktiniert jetzt echt super und wir können nun die Reisen 1a nach Länder anzeigen lassen

    Meine Frage ist nun, gehts eventuell auch einfacher?

    EDIT: kleines Problem,

    wenn man einen Datensatz bearbeitet, werden automotsch die anderen Felder die man Filtern kann in der Listenansicht übernommen und es werden die Einträge gefiltet.

    Beispiel:

    Custom Filter: LAnd 1 Contao Filter Tage ---

    jetzt bearbeite ich einen Datensatz -> Speichern und Schließen

    Custom Filter: LAnd 1 Contao Filter Tage 7
    Geändert von WebRoxx (03.03.2014 um 14:49 Uhr)

  10. #10
    Alter Contao-Hase
    Registriert seit
    18.07.2012.
    Ort
    Löbau
    Beiträge
    1.124

    Standard

    So habs hammer mäßig hinbekommen, jetzt klappen eigene Filter super....herrlich

    Danke für die Hilfe !!!!!

  11. #11
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    Hallo Ralf2011,

    freut mich sehr, dass Du eine gute Lösung gefunden hast. Ich habe ein ähnliches Problem mit einem benutzerdefinierten Filter.
    Ich glaube, auch andere Beobachter dieses Threads würden sich freuen, wenn Du uns mit ein paar Details amüsieren könntest

    Herzliche Grüße
    der Theo

  12. #12
    Gesperrt
    Registriert seit
    02.11.2012.
    Beiträge
    52

    Standard

    Zitat Zitat von theobald Beitrag anzeigen
    Hallo Ralf2011,

    freut mich sehr, dass Du eine gute Lösung gefunden hast. Ich habe ein ähnliches Problem mit einem benutzerdefinierten Filter.
    Ich glaube, auch andere Beobachter dieses Threads würden sich freuen, wenn Du uns mit ein paar Details amüsieren könntest

    Herzliche Grüße
    der Theo
    Wäre ich auch stark dafür

  13. #13
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    Hallo qf_rigo,

    ich muss sagen, ich habe damals mit dem Code von Ralf2011 etwas herumgespielt und da habe ich es hinbekommen. Ein kritischer Punkt ist der Inhalt der Session, die den Filtermechanismus stören kann, wenn dort noch Fehler drin sind. Daher ist es empfehlenswert, sich die Session währen der Entwicklung und Fehlersuche immer anzeigen zu lassen. So habe ich dann meine Filter hinbekommen. Ich kann auch den Code posten. Das Projekt habe ich aber bisher leider nicht weiter führen können, daher ist das eher Spaghetti-Code - unansehnlich!

    Grüße vom
    Theo

  14. #14
    Contao-Nutzer
    Registriert seit
    15.03.2010.
    Ort
    AT
    Beiträge
    204

    Standard Contao 5 Beispiel

    Soeben in Contao 5 getest! Supergeil das Ganze:

    Parent -> Events
    Child -> Anmeldungen/Personen

    In der Eventübersicht (parent) wird ein Suchfeld (Name/Email) für Anmeldungen/Personen (child) eingefügt.
    So kann man die Parent-Liste-View nach Child-Eigenschaften filtern.
    Angezeigt werden dann alle Events, an denen die gefilterte Person teilgenommen hat.

    PHP-Code:
     ...
     
    'onload_callback' => array
     (
         [
    'tl_enr''applyChildNameSearch']
     )
     ...
     
    'sorting' => array
     (
         ....
         
    'panelLayout'             => 'sort,filter;nameSearch,search,limit',
         
    'panel_callback'             => array('nameSearch' => array('tl_enr''generateChildNameSearch')), 
     ),
     ... 
    PHP-Code:
    public function generateChildNameSearch(DataContainer $dc)
    {
        
        
    $objSessionBag System::getContainer()->get('request_stack')->getSession()->getBag('contao_backend');
        
    $data $objSessionBag->all();
       
        
    $personSearchValue "";
        
    $personSearchValueActive "";
        if (
    $data['custom_personsearch'] ?? false ) {
            
    $personSearchValue $data['custom_personsearch'];
            
    $personSearchValueActive "active";
        }

        
    $filter '
        <div class="tl_customsearch tl_subpanel">
        <strong>Teilnehmer-Suche: Vorname,Nachname/E-Mail:</strong>
        <input name="custom_personsearch" class="tl_text '
    .$personSearchValueActive.'" value="'.$personSearchValue.'" type="text">
        </div>
        '
    ;
       
        return 
    $filter;

    PHP-Code:
    public function applyChildNameSearch(DataContainer $dc)
    {
        
    $objSessionBag System::getContainer()->get('request_stack')->getSession()->getBag('contao_backend');
        
    $data $objSessionBag->all();
       
        if (
    null != Input::post('FORM_SUBMIT')) {

                if (
    null != Input::post('custom_personsearch')) {
                    
    $data['custom_personsearch'] = Input::post('custom_personsearch');
                    
    $objSessionBag->replace($data);
                } else {
                    unset(
    $data['custom_personsearch']);
                    
    $objSessionBag->replace($data);
                }

                if (
    null != Input::post('filter_reset')) {
                    unset(
    $data['custom_personsearch']);
                    
    $objSessionBag->replace($data);
                }
            }

        if (
    $data['custom_personsearch'] ?? false ) {
            
    $root = [];
            
    $allPersons EnrRegistrationModel::findAll();

            foreach (
    $allPersons as $person) {
                if (
    false !== stripos($person->firstname$data['custom_personsearch'])) {
                    
    $root[$person->pid] = $person->pid;
                }
                if (
    false !== stripos($person->lastname$data['custom_personsearch'])) {
                    
    $root[$person->pid] = $person->pid;
                }
                if (
    false !== stripos($person->email$data['custom_personsearch'])) {
                    
    $root[$person->pid] = $person->pid;
                }
            }

            if (!empty(
    $root)) {
                    
    $GLOBALS['TL_DCA']['tl_enr']['list']['sorting']['root'] = $root;
                } else {
                    
    $GLOBALS['TL_DCA']['tl_enr']['list']['sorting']['root'] = [0];
                }
        }


    Geändert von heyho (04.01.2023 um 07:58 Uhr)

  15. #15
    Contao-Urgestein Avatar von zonky
    Registriert seit
    19.03.2010.
    Ort
    Berlin, Rdf
    Beiträge
    9.674
    User beschenken
    Wunschliste

    Standard

    Zitat Zitat von heyho Beitrag anzeigen
    Soeben in Contao 5 getest! Supergeil das Ganze:

    Parent -> Events
    Child -> Anmeldungen/Personen

    In der Eventübersicht (parent) wird ein Suchfeld (Name/Email) für Anmeldungen/Personen (child) eingefügt.
    So kann man die Parent-Liste-View nach Child-Eigenschaften filtern.
    Angezeigt werden dann alle Events, an denen die gefilterte Person teilgenommen hat.
    sowas wäre sicher als Snippet im Manual gut aufgehoben

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •