1

When I call genesis_search_form(), it outputs:

<form class="search-form">
  <meta itemprop="target">
  <input type="search">
  <input type="submit">
</form>

But I wanted it to generate with a span inside, like:

<form class="search-form">
  <meta itemprop="target">
  <input type="search">
  <span class="submit-icon"></span>
  <input type="submit">
</form>

Was looking for a safer alternative to:

add_filter( 'genesis_search_form', 'my_search_button' ); 
function my_search_button( $form ) {
    return str_replace( 
        '<input type="submit"', 
        '<span class="submit-icon"></span><input type="submit"', 
        $form 
    );
}

To avoid replacing the start of a tag. Any ideas?

  • 1
    you won't be able to do this as long as the function doesn't offer the ability to do this, you may if it's allowed to fork the function and customize it as you want to fit your needs. – hassan Mar 12 '17 at 16:04

3 Answers3

1

If it is allowed to you to make changes to the function, do it. If not, hack it!

$('form.search-form input[type=search]').after('<span class="submit-icon"></span>');
Reza Saadati
  • 1,224
  • 13
  • 27
  • 2
    Thank you for your answer, `jQuery` is indeed simpler, but was looking for solution in `php` do everything server side. –  Mar 13 '17 at 12:30
0

Use DOMDocument! Here's a working version of your code: https://3v4l.org/ats7D

<?php

// Create a DOM Document
$dom = new DomDocument();

// Load your HTML
$dom->loadHTML('<form class="search-form">  
    <meta itemprop="target">
    <input type="search">
    <input type="submit">
</form>');

// Create a new <span>
$span = $dom->createElement('span', 'hello');

// Grab the <input elements (we dont have an ID)
$inputs  = $dom->getElementsByTagName('input');

// Add the <span> between the inputs 
$inputs->item(0)->parentNode->insertBefore($span, $inputs->item(1));

// By default when you loadHTML(), it generates doctype, html, head, and     body tags. remove them!
$dom->removeChild($dom->doctype);
$dom->replaceChild($dom->firstChild->firstChild->firstChild, $dom->firstChild);

// Finally get the HTML
$html = $dom->saveHTML();

// And output / return / whatever
echo $html;
delboy1978uk
  • 12,118
  • 2
  • 21
  • 39
  • Awesome; it lets you keep it server-side, like he wants. It might also make sense to cache the result somehow, so that he doesn't have to manipulate a DOM chunk with each request. – Cameron Hurd Mar 16 '17 at 13:22
0

If you are okay with DOMDocument, this version works better for HTML5.

add_filter( 'genesis_search_form', 'my_search_button' );
function my_search_button($form) {

    $document = new DOMDocument();
    $document->loadHTML($form);
    $xpath = new DOMXPath($document);
    $input = $xpath->query('//input[@type="submit"]');
    $span = $document->createElement('span');
    $span->setAttribute('class', 'sb-icon');

    if ($input->length > 0) {
        $input->item(0)->parentNode->insertBefore($span, $input->item(0));
    }

    $document->removeChild($document->doctype); 
    $document->replaceChild($document->firstChild->firstChild->firstChild, $document->firstChild);
    $form_html = $document->saveHTML();

    return $form_html;
}
SilverLink
  • 124
  • 2
  • 15