Problem mit Validator auf dynamisch erzeugte Input-Felder

Im Entwickler-Forum können Implementierungsdetails sowie Alternativen der Umsetzung diskutiert werden. // Here, developers can discuss implementation details of features of their projects.
Antworten
Benutzeravatar
Paric
Beiträge: 45
Registriert: 25.08.2014, 08:51:04

Problem mit Validator auf dynamisch erzeugte Input-Felder

Beitrag von Paric » 12.12.2014, 10:29:31

Hallo Gemeinde der APF-Jünger ;)

gleiches Problem, neues Problem. in einem Script bearbeite ich die Daten von Kontaktpersonen. da ich im Vorfeld natürlich nicht weiß wie viele Kontakt-Personen die Tabelle beinhaltet, werden die Textfelder natürlich dynamisch angelegt. Da auf diese auch einen Validator angefügt werden sollen, so geschied das natürlich auch im Controller.

mein Template schaut wie folgt aus:

Code: Alles auswählen

<@controller class="TELLA\pres\controller\admin\EditEnsContactController" @>
<div id="rahmen">
    <h2>Administrationsbereich</h2>
    <h3>ENS-Kontakte bearbeiten</h3>
    
    <html:form name="editEnsContacts" method="POST">
        <form:error name="error">
            <div class="error-container">
                <p>
                    Fehler<br />
                    es ist ein Fehler aufgetreten.
                </p>

            </div>
        </form:error>
        <form:success name="success">
        <div class="success-container">
            <p>
                Speichern erfolgreich<br />
                die Daten wurden erfolgreich gespeichert.
            </p>
        </div>
        </form:success>
        <form:marker name="content" />
    <div id="buttons">
        <form:reset name="reset" id="reset" value="abbrechen" />
        <form:button name="submit" id="submit" value="speichern" />
    </div>
    </html:form>
</div>
und der Controller wie folgt:

Code: Alles auswählen

class EditEnsContactController extends BaseDocumentController
{
    /* @var $eM EnsManager */
    private $eM;
    private $form;


    public function __construct()
    {
        /* @var $usr User */
        $usr = $this->getServiceObject('TELLA\biz\User', 'SESSIONSINGLETON', 'ownUser');
        $this->eM = $this->getServiceObject('TELLA\biz\sb20\EnsManager', 'SESSIONSINGLETON');
        
        SecureHandler::hasPermission(SecureHandler::getRights($usr, '20', 'ens_schreiben'));
    }
    
    public function transformContent()
    {
        $this->form = $this->getForm('editEnsContacts');
        $contacts = array();
        
        if ($this->form->isSent() && $this->form->isValid())
        {
            $arrName = RequestHandler::getValue('name');
            $arrHandy = RequestHandler::getValue('handy');
            foreach ($arrName as $id=>$name)
            {
                $objContact = new EnsKontakt();
                $objContact->setId($id);
                $objContact->setName($name);
                if ($arrHandy[$id] != "")
                {
                    $objContact->setHandynumber($arrHandy[$id]);
                }
                $contacts[$id] = $this->eM->saveContact($objContact);
            }
        }
        else
        {
            $contacts = $this->eM->loadAllContacts();
        }
        
        /* @var $contact EnsKontakt */
        foreach ($contacts as $contact)
        {
            $id = $contact->getId();
            $submit = $this->form->getFormElementByName('submit');
            $control = $this->getTextFormElement("content", "name[$id]", $contact->getName());
            $control->addValidator(new TextLengthValidator($control, $submit));
            $this->getTextFormElement("content", "handy[$id]", $contact->getHandynumber());
            $this->getBreakLine("content");
        }
        
        $this->form->transformOnPlace();
        
        
        /* Back-Link erstellen */
        $this->setPlaceHolder('backlink', LinkHandler::getLink(array('subPage'=>NULL)));
        /* Versions-Nummer aus der Registriy laden */
        $this->setPlaceHolder('version', Registry::retrieve('TELLA\biz', 'versionAdmin'));
    }
    
    private function getTextFormElement($marker, $name, $value)
    {
        $frmElementID = $this->form->addFormElementBeforeMarker(
                $marker,
                'form:text',
                array('name' => $name,
                      'value' => $value,
                      'minlength' => 3));

        return $this->form->getFormElementByObjectID($frmElementID);
    }
    
    private function getBreakLine($marker)
    {
        return $this->form->addFormContentBeforeMarker($marker, "<br />");
    }
}
Nun habe ich das Problem das der Validator nicht greift, und statt der Fehlermeldung das Formular abgeschickt wird. Wenn das leere Textfeld in der Datenbank gespeichert ist, und dann neu abgefragt wird, und somit in das INPUT-Feld leer ausgegeben wird, so wird dieses Textfeld als falsch deklariert.
Aber es sollte doch das speichern in der Datenbank unterbinden, tut es aber nicht.

Beste Grüße,
Pit

Benutzeravatar
dr.e.
Administrator
Beiträge: 4538
Registriert: 04.11.2007, 16:13:53

Re: Problem mit Validator auf dynamisch erzeugte Input-Felde

Beitrag von dr.e. » 13.12.2014, 16:51:42

Hallo Pit :),

bei deiner Implementierung liegt ein (zeitliches) Reihenfolgen-Problem vor. Du fragst in der Methode transformContent() auf der dritten Zeile dein Formular nach seinem Validitäts-Status, zu diesem Zeitpunkt im Code gibt es aber weder Formular-Felder noch Validatoren. Wenn du an diese Stelle einen Breakpoint setzt kannst du das im Debugger sehr schön sehen.

Damit ist das Formular natürlich valide und der erste Zweig - logisch natürlich der falsche - wird ausgeführt.

Um das zu lösen, drehst du die Logik einfach um und legst die Felder und Validatoren vor der Abfrage nach isValid() an. Ich bin mir nicht ganz sicher, wie die Logik der Anzeige sein soll, ich nehme mal an, dass beim initialen Laden alle Kontakte ausgegeben werden sollen. Das kannst du wie folgt regeln:

Code: Alles auswählen

class EditEnsContactController extends BaseDocumentController {

   /* @var $eM EnsManager */
   private $eM;
   private $form;


   public function __construct() {
      /* @var $usr User */
      $usr = $this->getServiceObject('TELLA\biz\User', 'SESSIONSINGLETON', 'ownUser');
      $this->eM = $this->getServiceObject('TELLA\biz\sb20\EnsManager', 'SESSIONSINGLETON');

      SecureHandler::hasPermission(SecureHandler::getRights($usr, '20', 'ens_schreiben'));
   }

   public function transformContent() {

      $this->form = $this->getForm('editEnsContacts');

      $contacts = $this->eM->loadAllContacts();

      /* @var $contact EnsKontakt */
      foreach ($contacts as $contact) {
         $id = $contact->getId();
         $submit = $this->form->getFormElementByName('submit');
         $control = $this->getTextFormElement("content", "name[$id]", $contact->getName());
         $control->addValidator(new TextLengthValidator($control, $submit));
         $this->getTextFormElement("content", "handy[$id]", $contact->getHandynumber());
         $this->getBreakLine("content");
      }

      if ($this->form->isSent() && $this->form->isValid()) {
         $arrName = RequestHandler::getValue('name');
         $arrHandy = RequestHandler::getValue('handy');
         foreach ($arrName as $id => $name) {
            $objContact = new EnsKontakt();
            $objContact->setId($id);
            $objContact->setName($name);
            if ($arrHandy[$id] != "") {
               $objContact->setHandynumber($arrHandy[$id]);
            }
            $contacts[$id] = $this->eM->saveContact($objContact);
         }
      }

      $this->form->transformOnPlace();

      /* Back-Link erstellen */
      $this->setPlaceHolder('backlink', LinkHandler::getLink(array('subPage' => null)));
      /* Versions-Nummer aus der Registriy laden */
      $this->setPlaceHolder('version', Registry::retrieve('TELLA\biz', 'versionAdmin'));
   }

   private function getTextFormElement($marker, $name, $value) {
      $frmElementID = $this->form->addFormElementBeforeMarker(
            $marker,
            'form:text',
            array('name'      => $name,
                  'value'     => $value,
                  'minlength' => 3));

      return $this->form->getFormElementByObjectID($frmElementID);
   }

   private function getBreakLine($marker) {
      return $this->form->addFormContentBeforeMarker($marker, "<br />");
   }

} 
Die Idee ist, zunächst das Formular vollständig aufzubauen - die Kontakte kennst du ja - und dann die Validierung und Verarbeitung auszuführen.

Hoffe das hilft dir weiter.
Viele Grüße,
Christian

Benutzeravatar
Paric
Beiträge: 45
Registriert: 25.08.2014, 08:51:04

Re: Problem mit Validator auf dynamisch erzeugte Input-Felde

Beitrag von Paric » 17.12.2014, 09:42:14

Hallo Christian,

danke für den Gedankenanstoß. Dank Deiner Hilfe habe ich es jetzt lauffähig bekommen, auch wenn Deine "Version" leider auch nicht funktioniert, denn mit der Zeile

Code: Alles auswählen

$contacts = $this->eM->loadAllContacts();
lädtst du die alten Daten aus der Datenbank in die Felder, somit werden diese überprüft. Meine funktionierende Version schaut wie folgt aus:

Code: Alles auswählen

class EditEnsContactController extends BaseDocumentController
{
    /* @var $eM EnsManager */
    private $eM;
    private $form;


    public function __construct()
    {
        /* @var $usr User */
        $usr = $this->getServiceObject('TELLA\biz\User', 'SESSIONSINGLETON', 'ownUser');
        $this->eM = $this->getServiceObject('TELLA\biz\sb20\EnsManager', 'SESSIONSINGLETON');
        
        SecureHandler::hasPermission(SecureHandler::getRights($usr, '20', 'ens_schreiben'));
    }
    
    public function transformContent()
    {
        $this->form = $this->getForm('editEnsContacts');
        $this->setPlaceHolder("intro", $lM->getLanguageText("20--ens--editContact--intro"));
        
        $contacts = array();
        if ($this->form->isSent())
        {
            $arrName = RequestHandler::getValue('name');
            $arrHandy = RequestHandler::getValue('handy');
            foreach ($arrName as $id=>$name)
            {
                $objContact = new EnsKontakt();
                $objContact->setId($id);
                $objContact->setName($name);
                if ($arrHandy[$id] != "")
                {
                    $objContact->setHandynumber($arrHandy[$id]);
                }
                $contacts[$id] = $objContact;
            }
        }
        else
        {
            $contacts = $this->eM->loadAllContacts();
        }
        
        /* @var $contact EnsKontakt */
        foreach ($contacts as $contact)
        {
            $id = $contact->getId();
            $submit = $this->form->getFormElementByName('submit');
            $control = $this->getTextFormElement("content", "name[$id]", $contact->getName());
            $control->addValidator(new TextLengthValidator($control, $submit));
            $this->getTextFormElement("content", "handy[$id]", $contact->getHandynumber());
            $this->getBreakLine("content");
        }
        
        if ($this->form->isSent() && $this->form->isValid())
        {
            foreach ($contacts as $contact)
            {
                $this->eM->saveContact($contact);
            }
        }
        
        $this->form->transformOnPlace();
        
        
        /* Back-Link erstellen */
        $this->setPlaceHolder('backlink', LinkHandler::getLink(array('subPage'=>NULL)));
        /* Versions-Nummer aus der Registriy laden */
        $this->setPlaceHolder('version', Registry::retrieve('TELLA\biz', 'versionAdmin'));
    }
Beste Grüße,
Pit

Benutzeravatar
dr.e.
Administrator
Beiträge: 4538
Registriert: 04.11.2007, 16:13:53

Re: Problem mit Validator auf dynamisch erzeugte Input-Felde

Beitrag von dr.e. » 17.12.2014, 22:04:19

Super, dass du es mit meinem Anstoß lösen konntest! :)
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast