chrisblakley / Nebula

Nebula is a WordPress theme framework that focuses on enhancing development. The core features of Nebula make it a powerful tool for designing, developing, and analyzing WordPress websites consistently, yet its deliberately uncomplicated code syntax also serves as a learning resource for programmers themselves.
https://nebula.gearside.com
GNU General Public License v2.0
143 stars 36 forks source link

Verify contact form input autocomplete is available #1780

Closed chrisblakley closed 5 years ago

chrisblakley commented 5 years ago

This may just be a documentation and/or demo update for CF7, but make sure appropriate autocomplete attributes can be used.

Examples: https://businesshelp.snapchat.com/en-US/a/auto-fill

chrisblakley commented 5 years ago

It does not appear that we can add autocomplete="whatever" to CF7 inputs without modifying them on the server-side by hooking into the output by field name.

https://contactform7.com/text-fields/

add_filter('wpcf7_form_elements', function($content){
    return substr_replace($content, ' autocomplete="name" ', strpos($content, 'name="your-name"'), 0);
});

For multiple input fields at the same time:

add_filter('wpcf7_form_elements', function($content){
    $content = substr_replace($content, ' autocomplete="name" ', strpos($content, 'name="your-name"'), 0);
    $content = substr_replace($content, ' autocomplete="email" ', strpos($content, 'name="your-email"'), 0);
    return $content;
});
chrisblakley commented 5 years ago

Here's a fill example of something that could actually be implemented into Nebula:

//Add autocomplete attributes to CF7 forms
add_filter('wpcf7_form_elements', function($content){
    $content = substr_replace($content, ' autocomplete="name" ', strpos($content, 'name="name"'), 0);
    $content = substr_replace($content, ' autocomplete="name" ', strpos($content, 'name="full-name"'), 0);
    $content = substr_replace($content, ' autocomplete="name" ', strpos($content, 'name="your-name"'), 0);
    $content = substr_replace($content, ' autocomplete="given-name" ', strpos($content, 'name="first-name"'), 0);
    $content = substr_replace($content, ' autocomplete="family-name" ', strpos($content, 'name="last-name"'), 0);
    $content = substr_replace($content, ' autocomplete="email" ', strpos($content, 'name="your-email"'), 0);
    $content = substr_replace($content, ' autocomplete="email" ', strpos($content, 'name="email"'), 0);
    $content = substr_replace($content, ' autocomplete="tel" ', strpos($content, 'name="phone"'), 0);
    $content = substr_replace($content, ' autocomplete="organization" ', strpos($content, 'name="company"'), 0);
    $content = substr_replace($content, ' autocomplete="address-line1" ', strpos($content, 'name="address"'), 0);
    $content = substr_replace($content, ' autocomplete="address-line1" ', strpos($content, 'name="street"'), 0);
    $content = substr_replace($content, ' autocomplete="address-level2" ', strpos($content, 'name="city"'), 0);
    $content = substr_replace($content, ' autocomplete="address-level1" ', strpos($content, 'name="state"'), 0);
    $content = substr_replace($content, ' autocomplete="postal-code" ', strpos($content, 'name="zip"'), 0);
    $content = substr_replace($content, ' autocomplete="postal-code" ', strpos($content, 'name="zipcode"'), 0);
    $content = substr_replace($content, ' autocomplete="postal-code" ', strpos($content, 'name="postalcode"'), 0);
    return $content;
});
chrisblakley commented 5 years ago

I've added this to Nebula and will monitor it. I'm just not in love with the giant find/replace that this requires... I'd love to find a way to optimize this.

chrisblakley commented 5 years ago

Ok, Nebula has been updated. Here's how I ended up doing it:

//Add autocomplete attributes to CF7 forms
public function cf7_autocomplete_attribute($content){
    $content = $this->autocomplete_find_replace($content, array('name', 'full-name', 'your-name'), 'name');
    $content = $this->autocomplete_find_replace($content, 'first-name', 'given-name');
    $content = $this->autocomplete_find_replace($content, 'last-name', 'family-name');
    $content = $this->autocomplete_find_replace($content, array('email', 'your-email'), 'email');
    $content = $this->autocomplete_find_replace($content, 'phone', 'tel');
    $content = $this->autocomplete_find_replace($content, 'company', 'organization');
    $content = $this->autocomplete_find_replace($content, array('address', 'street'), 'address-line1');
    $content = $this->autocomplete_find_replace($content, 'city', 'address-level2');
    $content = $this->autocomplete_find_replace($content, 'state', 'address-level1');
    $content = $this->autocomplete_find_replace($content, array('zip', 'zipcode', 'postalcode'), 'postal-code');

    return $content;
}

//Find field names and add the autocomplete attribute when found
public function autocomplete_find_replace($content, $finds=array(), $autocomplete_value){
    if ( !empty($content) && !empty($finds) && !empty($autocomplete_value) ){
        if ( is_string($finds) ){
            $finds = array($finds); //Convert the string to an array
        }

        foreach ( $finds as $find ){
            $field_name = strpos($content, 'name="' . $find . '"');
            if ( !empty($field_name) ){
                $content = substr_replace($content, ' autocomplete="' . $autocomplete_value . '" ', $field_name, 0);
            }
        }
    }

    return $content;
}
chrisblakley commented 5 years ago

Child themes can add to this with the following:

add_filter('wpcf7_form_elements', function($content){
    $content = nebula()->autocomplete_find_replace($content, array('bday', 'birthday'), 'bday');
    return $content;
});
chrisblakley commented 5 years ago

Just made a minor update to make the search case-insensitive.