Ankündigung

Einklappen
Keine Ankündigung bisher.

Tabellen sortieren

Einklappen

Unconfigured Ad Widget

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Tabellen sortieren

    Hallo,

    ich arbeitet gerade an einem Tabellen Frontend mit Symfony2.

    Nun möchte ich die Tabelle sortieren, dass heisst, wenn ich bsw, auf die Spalte Nachnamen klicke, so sollte die Tabelle alle Nachnamen aufsteigend darstellen.
    Sollte ich dannach nochmal auf die Spalte klicken, so sollten die Nachnamen absteigend präsentiert werden.

    Soviel zum "Feature".

    Nun zur Umsetzung....
    Das umschalten sollte per $_GET realisiert werden, deswegen wollte ich folgendes Routing verwenden:
    Code:
    _customers:
        pattern:    /contacts/{column}/{orderBy}
        defaults:   { _controller: TableAppBundle:Contact:index, column: 'lastName', orderBy: 'asc' }
    Der Controller wertet die Parameter dann aus und fetched die Tabelle je nach angefordertet Sortierung in ein array, welches dann in einem Template ausgegeben werden kann:

    PHP-Code:
        public function indexAction($column$orderBy) {
            
    $em $this->getDoctrine()->getEntityManager();
            switch (
    $column) {
                case 
    'lastName':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByLastNameAsc();
                    break;
                case 
    'firstName':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByFirstNameAsc();
                    break;
                case 
    'birth':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByBirthAsc();
                    break;
                case 
    'street':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByStreetAsc();
                    break;
                case 
    'nr':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByNrAsc();
                    break;
                case 
    'zipCode':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByZipCodeAsc();
                    break;
                case 
    'email':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByEmailAsc();
                    break;
                case 
    'phone':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByPhoneAsc();
                    break;
                case 
    'mobile':
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAllOrderedByMobileAsc();
                    break;
                default:
                    
    $customers $em->getRepository('TableAppBundle:Contact')
                        ->
    findAll();
                    break;
            }

            return 
    $this->render('TableAppBundle:Contact:index.html.twig', array(
                
    'contactss'                 => $contacts,
            )); 
    Hier ist die Repository:
    PHP-Code:
    class CustomerRepository extends EntityRepository
    {
        public function 
    findAllOrderedByLastNameAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.last_name ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByLastNameDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.last_name DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByFirstNameAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.firstName ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByFirstNameDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.firstName DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByBirthAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.birth ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByBirthDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.birth DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByStreetAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.street ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByStreetDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.street DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByNrAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.nr ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByNrDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.nr DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByZipCodeAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.zipCode ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByZipCodeDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.zipCode DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByEmailAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.email ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByEmailDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.email DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByPhoneAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.phone ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByPhoneDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.phone DESC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByMobileAsc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.mobile ASC')
                ->
    getResult();
        }

        public function 
    findAllOrderedByMobileDesc() {
            return 
    $this->getEntityManager()
                ->
    createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.mobile DESC')
                ->
    getResult();
        }




    Wie jeder sehen kann verursacht eine "einfache" Funktion so einen großen Aufwund... einen eigentlich zu großen.
    Meine Frage ist nun, ob sowas auch schöner gehen kann?

    Gruß


  • #2
    Funktionsparameter und die Abfrage entsprechend zusammenbauen.

    Edit: Ich frag mich erneut, ob du überhaupt die Symfony2/Doctrine Dokumentation gelesen hast. Das wird alles beschrieben: http://symfony.com/doc/current/book/doctrine.html

    Kommentar


    • #3
      So, in etwa?

      PHP-Code:
      public function indexAction($column$orderBy) {
              
      $em $this->getDoctrine()->getEntityManager();
              
               
      $customers $em->getRepository('TableAppBundle:Contact')
                          ->
      findAllOrderedBy($column$orderBy);
                      

              return 
      $this->render('TableAppBundle:Contact:index.html.twig', array(
                  
      'contactss'                 => $contacts,
              
      ));

      class 
      CustomerRepository extends EntityRepository
      {
          public function 
      findAllOrderedBy($column$orderBy) {
              return 
      $this->getEntityManager()
                  ->
      createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.'.$column.' '.$orderBy)
                  ->
      getResult();
          }

      Kommentar


      • #4
        Das war mein erster Gedanke, allerdings wird kein SQL escaped und man könnte ohne Probleme eine Code injection starten.

        Deswegen müsste man vermutlich $column und $orderBy aufjedenfall immer erst durch kontrollieren so:
        PHP-Code:
        public function indexAction($column$orderBy) { 
                
        $em $this->getDoctrine()->getEntityManager(); 
                if (
        $orderBy !== 'DESC') {
                     
        $orderBy 'ASC';
                }
                case (
        $column) { //.... alle Möglichen Spalten }
                 
                 
        $customers $em->getRepository('TableAppBundle:Contact'
                            ->
        findAllOrderedBy($column$orderBy); 
                         

                return 
        $this->render('TableAppBundle:Contact:index.html.twig', array( 
                    
        'contacts'                 => $contacts
                 
        )); 

        class 
        CustomerRepository extends EntityRepository 

            public function 
        findAllOrderedBy($column$orderBy) { 
                return 
        $this->getEntityManager() 
                    ->
        createQuery('SELECT p FROM TableAppBundle:Contact ORDER BY p.'.$column.' '.$orderBy
                    ->
        getResult(); 
            } 

        Und das führt dann mehr oder weniger zu dem was ich zuerst habe bis auf, dass das Repository sauberer ist..

        Kommentar


        • #5
          Der QueryBuilder hilft dir weiter.

          Kommentar


          • #6
            PHP-Code:
                public function indexAction($column$orderBy) {
                    
            $em $this->getDoctrine()->getEntityManager();

                    if (
            $orderBy !== 'DESC') {
                        
            $orderBy 'ASC';
                    }

                    
            $columns = array('lastName''firstName''birth''street''nr''zipCode','email''phone''mobile');
                    if (!
            in_array($column$columns)) {
                        
            $column 'lastName';
                    }

                    
            $customers $em->getRepository('TableAppBundle:Contact')
                        ->
            findAllOrderedBy($column$orderBy);

                    return 
            $this->render('TableAppBundle:Contact:index.html.twig', array(
                        
            'contacts'                 => $contacts,
                    ));

                } 
            Ist zwar auch nicht "schön" was die "Validierung" angeht, aber naja....

            Kommentar


            • #7
              Zitat von archer42 Beitrag anzeigen
              Das war mein erster Gedanke, allerdings wird kein SQL escaped und man könnte ohne Probleme eine Code injection starten.
              Haben wir schon den 1. April?

              Kommentar


              • #8
                Was willst du mir damit sagen?...

                Kommentar


                • #9
                  vermutlich dass es dir frei steht die Werte selbst zu quoten
                  "Mein Name ist Lohse, ich kaufe hier ein."

                  Kommentar


                  • #10
                    Ich überlege gerade hin-und-her wie es möglich wäre die Tabellenverwaltung zu kapseln.

                    Das heisst Erzeugung der Tabelle ähnlich des Formbuilders bei Symfony.
                    Das an sich ist noch nicht das schwierige, was mir nun Kopfzerbrechen bereitet ist der Sortierungsvorgang.

                    Eine Möglichkeit wäre den Sortiervorgang in den "TableBuilder" zu verlagern, aber das ist denk ich mal auch nicht die Lösung.

                    Gibt es noch eine andere Möglichkeit, wie man die Tabellensortierung ohne das $_GET-Gepfusche hinkriegt.
                    Vielleicht Clientseitig über Javascript?

                    EDIT:
                    jquery mit plugins

                    Kommentar


                    • #11
                      Ich denke das willst du nicht, du kannst das zwar mit dataTable (jQuery Plugin) machen, aber bei einigen hundert Einträgen wird das dann schon sehr träge.
                      "Mein Name ist Lohse, ich kaufe hier ein."

                      Kommentar


                      • #12
                        Wieso sollte das träge werden?

                        Wenn sich das "clientär" abspielt sollten doch genügend Ressourcen da sein, zumindest würde mir das mein Laien Wissen so sagen

                        Für das Sortieren benutze ich Tablesorter, dies sah mir etwas "leichter" aus.

                        Das Selektieren werde ich mit jQuery-UI umsetzen, allerdings mache ich mich damit morgen dran.

                        Wenn man tausende Einträge handeln muss, bei welchen man zwischen Seiten umschalten muss, dann fliegt javascript aus Prinzip raus,
                        aber bisher würde mir nur "Pfusch" einfallen, was die Tabellenfunktionen angeht.

                        Kommentar


                        • #13
                          Was verstehst du bitte unter Pfusch?

                          Kommentar


                          • #14
                            Was verstehst du bitte unter Pfusch?
                            Naja, wenn ich
                            • Sortierfunktion
                            • Auswahlfunktion
                            • Detailansicht

                            Implementiere, dann habe ich als Ergebnis eine vollgestopfte Action (beachte Umschalten von ASC auf DESC!) mit vollgestopftem Routing.
                            Abhilfe würde ein eigener "TableManager" schaffen, den ich allerdings nicht sehr positiv gewillt bin umzusetzen...

                            Kommentar


                            • #15
                              Zitat von archer42 Beitrag anzeigen
                              Wieso sollte das träge werden?

                              Wenn sich das "clientär" abspielt sollten doch genügend Ressourcen da sein, zumindest würde mir das mein Laien Wissen so sagen
                              JavaScript ist immer noch JavaScript. Es geht nicht nur darum, dass du alle Clientmaschinen unnötig belastest, sondern auch noch bei allen ein erhöhtes Datenaufkommen verursachst. Aber das wäre eher nebensächlich. Du merkst es einfach nach ein paar tausend Einträgen.
                              "Mein Name ist Lohse, ich kaufe hier ein."

                              Kommentar

                              Lädt...
                              X