Posted by 4toddt on February 5, 2013 at 3:39pm
I would like to use the contact form from a template a client bought. I've tried theming a Webform-based contact page, but I was never able to completely theme it. Can I just modify the html from the template and pop it in a Drupal block? The template I'm using is here: http://lawloraincounty.com/alpha/index-4.html .
Edit: To clarify, I need the form to look and work like the one in the link.
Comments
How do I modify a webform to look and work like the template?
If that's not possible, then how do I modify a webform to look and work like the template?
Can I just modify the html
That is technically possible but would remove all the benefit of using Drupal and the forms API. A serious concern here would be security, as Drupal/FAPI is designed to protect you from many of the POST-based attack vectors.
That question is probably too open-ended to get you what you're looking for. What specific parts of the layout/display/behavior are you having trouble with, and what have you tried? Perhaps a link to your work in progress would help someone give more targeted advice.
Specific difficulties with theming Webforms
I don't know how to get labels inside the input fields. There is a module, but it only works for some field types.
I don't know how to get the client-side validation to work. There is a module that does client-side validation, but I had some script conflicts. I'm not interested in customizing the module to the extent needed to make it look and work like the template.
The logical thing would be to use the scripts provided with the template, but I don't know how to make Drupal Webforms output the html used by the template. Here is an example of the code.
<div class="rowElem"><input type="email" name="email" id="email" value="E-mail:" onFocus="if(this.value=='E-mail:'){this.value=''}" onBlur="if(this.value==''){this.value='E-mail:'}" /><br>
<label class="error" for="email" id="email_error">*This field is required.</label>
<label class="error" for="email" id="email_error2">*This is not a valid email address.</label>
</div>
I realize that you can have Drupal output any html you want if you dig deep enough, but I prefer to stay as close to the surface as possible. I have no problem modifying a tpl.php file, but I do very little with overriding functions and such.
Title text in field + insert javascript
// in file: {theme_path}/template.php
/**
* implements hook_form_alter
*
*/
function themename_form_alter(&$form, &$form_state) { # change themename
# to the name of your
# theme
if( $form['#form_id'] == $my_form_id ) { # use dpm($form) to find form_id
# for your form as well as element
# keys
$form[ 'email' ][ '#default_value' ] =
$form[ 'email' ][ '#title' ];
$form[ 'email' ][ '#attributes' ][ 'onFocus' ] =
"if(this.value=='E-mail:'){this.value=''}";
$form[ 'email' ][ '#attributes' ][ 'onBlur' ] =
"if(this.value==\'\'){this.value='E-mail:'}";
}
}
This code hasn't been tested but should get you close.
Thank you and follow-up questions
That is a little deeper than I am used to, but I think I can figure it out from your post. I do have some follow-up questions.
To answer your questions
Should work fine
'email' is the key for the element's array in the FAPI (forms api) array. It's an arbitrary value but by default is used to generate the element's id attribute in the resulting HTML. In this case, the element will probably have id="edit-submitted-email" where "email" comes from the array key. 'email' may not actually be the key in your webform; you'll need to inspect the $form array to find the correct key.
Just use the one function. Repeat the logic from the example, modifying the key and other strings as appropriate.
This is a tough one. The only ways I know of within the drupal api are either relatively complicated, hacky, or both. You'd need to create a custom validation callback, either handling all the validation (tricky and risky), or doing some fancy footwork to merge your logic with the default logic. Probably the cleverest way would be to insert your validator before the default one. That way you wouldn't have to fight with already set errors, but if you failed to handle some validation edge case it would get caught by the webform logic. All too much work in my opinion.
The way I've actually handled this myself in a recent project was by doing my validation and messaging on the client side. Not only does this give you control over the message text, but its placement as well. Plus, it's more responsive as there's no page refresh involved. If you're comfortable with jQuery (e.g.), then that might be the best way to go (and you'd still have the server-side validation backing you up). Also, maybe check out the clientside_validation module as a possibility, tho I don't think it will handle your particular requirements.
Clarification on validation
The template comes with the jquery to do client-side validation. I just need to get the following html into the form (note the labels).
<div class="rowElem"><input type="email" name="email" id="email" value="E-mail:" onFocus="if(this.value=='E-mail:'){this.value=''}" onBlur="if(this.value==''){this.value='E-mail:'}" /><br>
<label class="error" for="email" id="email_error">*This field is required.</label>
<label class="error" for="email" id="email_error2">*This is not a valid email address.</label>
</div>
Here is what Webform is currently generating for an email input:
<div class="form-item webform-component webform-component-email" id="webform-component-e-mail"><label for="edit-submitted-e-mail">E-mail <span class="form-required" title="This field is required.">*</span></label>
<input class="email form-text form-email required" type="email" id="edit-submitted-e-mail" name="submitted[e_mail]" size="60" />
</div>
BTW learning javascript and jquery is on my to-do list. Unfortunately building this site is higher on the to-do list.
I've spent some time trying
I've spent some time trying to come up with a straightforward solution, but unfortunately this gets into some hairy theming stuff, and although it is technically possible to replicate the template's html then you've got to worry about not breaking the webforms integration.
You can get close with the code pasted below, but though it shouldn't break the webforms piece I have no way of knowing if it will work with the client-side validation.
There's a decent chance the template javascript will work with this html. If it doesn't, you should be able to make it work with very modest tweaks to the javascript. Most likely it's going to have some DOM selectors based on the elements' ids, which you could modify. You're going to have to learn this stuff soon anyway:)
Code to approximate the template's html output:
<?php
// this goes in your hook_form_alter along with the code provided earlier
// override the default id for the text field
$form['submitted']['email']['#attributes']['id'] = 'email';
// get rid of the default label
unset( $form['submitted']['email']['#title'] );
// add extra html to approximate the DOM structure expected by the template javascript
$form['submitted']['email']['#prefix'] = '<div class="rowElem">';
$form['submitted']['email']['#suffix'] =
' <label class="error" for="email" id="email_error">*This field is required.</label>
<label class="error" for="email" id="email_error2">*This is not a valid email address.</label>
</div>';
?>
This will result in html that looks like:
<div class="rowElem"><div id="webform-component-email" class="form-item webform-component webform-component-textfield">
<input id="email" class="form-text required" name="submitted[email]" maxLength="128" value="" size="60" type="text">
</div>
<label id="email_error" class="error" for="email">*This field is required.</label>
<label id="email_error2" class="error" for="email">*This is not a valid email address.</label>
</div>
The variances are:
If it doesn't work, look to those bits in terms of modifying the javascript selectors.
Good luck!
You've been immensely helpful.
Thank you for your expertise and your time. This is exactly what I need.
Objective to change layout or HTML elements, both?
Seems like you just want a three-col layout, where the form is on the left there? Then you want to theme the fields a little differently, to include them within the fields with an event to hide/show? Firstly, that's a pretty bad UX for fields. I forget what I'm filling out when I click into those. I'd suggest labels above fields. You might try looking into the following options for your project:
Quevin, LLC - www.Quevin.com - @Quevin
Passionate about planning, designing, and developing exceptional sites.
Just having difficulty with the form itself
I don't have any trouble doing the page layout. The hard part is getting the form to look and work like the template. As for putting the labels above, that's what I ended up doing on the last site I built. But that's not what the client asked for. I really just need to be able to theme the site like the template they purchased.