private function setMessages(array $data) : void
    {
        /**
         * @var string $name
         * @var array  $errors
         */
        foreach ($data as $name => $errors) {
            // Not sure if this can be optimized and create the DOMXPath only once.
            // At this point the dom is constantly changing.
            $xpath = new DOMXPath($this->document);
            // Get all elements with the name
            $nodeList = $xpath->query(sprintf('//*[@name="%1$s"] | //*[@data-input-name="%1$s"]', $name));

            if ($nodeList->length === 0) {
                // No element found for this element ???
                continue;
            }

            // Get first element only
            $node = $nodeList->item(0);

            /** @var DOMElement $parent */
            $parent = $node->parentNode;
            if (strpos($parent->getAttribute('class'), $this->cssHasErrorClass) === false) {
                // Set error class to parent
                $class = trim($parent->getAttribute('class') . ' ' . $this->cssHasErrorClass);
                $parent->setAttribute('class', $class);
            }

            // Inject error messages
            foreach ($errors as $code => $message) {
                $div = $this->document->createElement('div');
                $div->setAttribute('class', $this->cssErrorClass);
                $div->nodeValue = $message;
                $node->parentNode->insertBefore($div, $node->nextSibling);
            }

            /** @var DOMElement $node */
            foreach ($nodeList as $node) {
                // Set aria-invalid attribute on all elements
                $node->setAttribute('aria-invalid', 'true');
            }
        }
    }
private function setMessages(array $data) : void
    {
        /**
         * @var string $name
         * @var array  $errors
         */
        foreach ($data as $name => $errors) {
            // Not sure if this can be optimized and create the DOMXPath only once.
            // At this point the dom is constantly changing.
            $xpath = new DOMXPath($this->document);
            // Get all elements with the name
            $nodeList = $xpath->query(sprintf('//*[@name="%1$s"] | //*[@data-input-name="%1$s"]', $name));

            if ($nodeList->length === 0) {
                // No element found for this element ???
                continue;
            }

            // Get first element only
            $node = $nodeList->item(0);

            /** @var DOMElement $parent */
            $parent = $node->parentNode;
            if (strpos($parent->getAttribute('class'), $this->cssHasErrorClass) === false) {
                // Set error class to parent
                $class = trim($parent->getAttribute('class') . ' ' . $this->cssHasErrorClass);
                $parent->setAttribute('class', $class);
            }

            // Inject error messages
            foreach ($errors as $code => $message) {
                $div = $this->document->createElement('div');
                $div->setAttribute('class', $this->cssErrorClass);
                $div->nodeValue = $message;
                $node->parentNode->insertBefore($div, $node->nextSibling);
            }

            /** @var DOMElement $node */
            foreach ($nodeList as $node) {
                // Set aria-invalid attribute on all elements
                $node->setAttribute('aria-invalid', 'true');
            }
        }
    }
private function setMessages ( array $ data ) : void { /**
         * @var string $name
         * @var array  $errors
         */ foreach ( $ data as $ name => $ errors ) { // Not sure if this can be optimized and create the DOMXPath only once. // At this point the dom is constantly changing. $ xpath = new DOMXPath ( $ this -> document ) ; // Get all elements with the name $ nodeList = $ xpath -> query ( sprintf ( '//*[@name="%1$s"] | //*[@data-input-name="%1$s"]' , $ name ) ) ; if ( $ nodeList -> length === 0 ) { // No element found for this element ??? continue ; } // Get first element only $ node = $ nodeList -> item ( 0 ) ; /** @var DOMElement $parent */ $ parent = $ node -> parentNode ; if ( strpos ( $ parent -> getAttribute ( 'class' ) , $ this -> cssHasErrorClass ) === false ) { // Set error class to parent $ class = trim ( $ parent -> getAttribute ( 'class' ) . ' ' . $ this -> cssHasErrorClass ) ; $ parent -> setAttribute ( 'class' , $ class ) ; } // Inject error messages foreach ( $ errors as $ code => $ message ) { $ div = $ this -> document -> createElement ( 'div' ) ; $ div -> setAttribute ( 'class' , $ this -> cssErrorClass ) ; $ div -> nodeValue = $ message ; $ node -> parentNode -> insertBefore ( $ div , $ node -> nextSibling ) ; } /** @var DOMElement $node */ foreach ( $ nodeList as $ node ) { // Set aria-invalid attribute on all elements $ node -> setAttribute ( 'aria-invalid' , 'true' ) ; } } }
Set validation messages, bootstrap style
Set validation messages bootstrap style