CodeBlog.ch


Concrete5 – Formular Layout anpassen

Posted in Concrete5, PHP by Remo Laubacher on the July 14th, 2009

Concrete5 has a nice form block which allows you to create a contact form within a few seconds. You don’t even need to have any html or php skills to create a simple file upload form. Unfortunately this block isn’t very easy to style. It uses some html markup which makes it a bit tricky to use CSS. However, it doesn’t mean it’s impossible! I’m going to show you how you can easily create a styles form using Concrete5 Custom Templates to produce this:

Styles Form

Custom Templates

If you don’t know anything about “Custom Templates”, you should probably read this article first: http://www.codeblog.ch/2009/03/concrete5-templates/. In short: Concrete5 allows you to style any block using templates in case you need to change the html output and not only the css rules.

Core modification

There’s one small thing I didn’t want to modify in the custom template since it shouldn’t be printed anyways. This might change in a future version, but because it doesn’t break anything I’m going to make the “not recommendable” core change in this case. Open the file “concrete/blocks/form/controller.php” and go to line 667 as shown on this screenshot:

pic1

Remove ’style=”width:95%”‘ as it makes css styling a bit nasty. Please note that this step isn’t necessary, it’s just about the layout!

The default layout

If you create a new form, it usually looks like this:

pic3

It works but doesn’t look very nice.

New form style

In this tutorial I’m showing you how you can create a form in which the labels are in the textfields and not on top or left. This might especially be useful if you have a very small page and a huge form. It also looks nice.

This is how the result is going to look like:
Styles Form

Let me start with the php template view.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php    
defined('C5_EXECUTE') or die(_("Access Denied."));
$survey=$controller; 
$miniSurvey=new MiniSurvey($b);
$miniSurvey->frontEndMode=true;
?>
<div class="ccm-form" id="ccm-form-id-<?php echo intval($bID)?>">
 
<?php  if ($invalidIP) { ?>
<div class="ccm-error">
<?php echo $invalidIP?>
</div>
<?php  } ?>
<form enctype="multipart/form-data" id="miniSurveyView<?php echo intval($bID)?>" class="miniSurveyView" method="post" action="<?php  echo $this->action('submit_form')?>">
	<?php   if( $_GET['surveySuccess'] && $_GET['qsid']==intval($survey->questionSetId) ){ ?>
<div id="msg"><?php  echo $survey->thankyouMsg ?></div>
<?php   }elseif(strlen($formResponse)){ ?>
<div id="msg">
			<?php  echo $formResponse ?>
			<?php  
			if(is_array($errors) && count($errors)) foreach($errors as $error){
				echo '
<div class="error">'.$error.'</div>
';
			} ?></div>
<?php  } ?>
	<input name="qsID" type="hidden" value="<?php echo  intval($survey->questionSetId)?>" />
	<input name="pURI" type="hidden" value="<?php echo  $pURI ?>" />
	<?php   	
	$questionsRS = $miniSurvey->loadQuestions($survey->questionSetId, intval($bID), 0);
	$surveyBlockInfo = $miniSurvey->getMiniSurveyBlockInfoByQuestionId($survey->questionSetId,intval($bID));
 
	$showEdit = false;
	$hideQIDs=array();
 
	while($questionRow=$questionsRS->fetchRow()) {	
		if(in_array($questionRow['qID'], $hideQIDs)) continue;
 
		$msqID=intval($questionRow['msqID']);
 
		$requiredClass=($questionRow['required'])?' required ':'';
		$requiredSymbol=($questionRow['required'])?' *':'';
 
		echo '
<div class="ccm-form-element'.$requiredClass.'">';
		$_REQUEST['Question'.$msqID] = $questionRow['question'] . $requiredSymbol;				
 
		echo $miniSurvey->loadInputType($questionRow,showEdit);
		echo "</div>
";	
	}	
 
	if($surveyBlockInfo['displayCaptcha']) {		
		$captcha = Loader::helper('validation/captcha');				
		echo "
<div class=\"ccm-form-captcha\">";
 
		echo '
<div class="required">';		
		echo '<input type="text" value="Sicherheitscode hier eingeben" name="ccmCaptchaCode" class="ccm-input-captcha"/>';
		// Please note that we need to style our captcha, we therefore create it manually!
		//$captcha->showInput();
		echo "</div>
";
 
		echo "
<div>";
		$captcha->display();
		echo "</div>
";
 
		echo "</div>
";
		echo '
<div style="clear:both"></div>
';
	}
 
	echo '<input class="formBlockSubmitButton button" name="Submit" type="submit" value="senden" />';
 
	?> 
</form></div>

I’m not explaing each line because I assume you understand PHP, otherwise this tutorial isn’t made for you – sorry!
What I changed:

  • Calling some methods found in the controller out of the view
  • Created a div layout instead of a table layout
  • Added some CSS classes to indicate required fields
  • Added a strange line which makes sure that the value attribute of the textfield contain the description

Now, we’ve got a form where we don’t have any labels next to the input fields. But we need to get rid of these values at some point, otherwise the users are able to submit forms using the default values (labels). To achieve this, we’re going to use some JavaScript checks:

1
2
3
   $('.miniSurveyView input[type=text], textarea').click(onEnterField);
   $('.miniSurveyView input[type=text], textarea').focus(onEnterField);
   $('.miniSurveyView input[type=text], textarea').blur(onLeaveField);

These events get raised once a users clicks into a textfield within our form. There we check whether we have to replace the label or not using this code:

1
2
3
4
5
6
7
8
9
10
11
12
function onEnterField() {
   if (this.origLabel == null)
      this.origLabel = this.value;
   if (this.origLabel == null || this.origLabel == this.value)
      this.value = '';
 
	$(this).prev(".formError").slideUp();
}
function onLeaveField() {	
   if (this.value == '' && this.origLabel != null)
      this.value = this.origLabel;
}

We also add some client side checks to make sure the users has entered all the required fields. This allows us to safe a request and a few milliseconds of waiting.

$(document).ready(function() {
 
   $('.miniSurveyView input[type=text], textarea').click(onEnterField);
   $('.miniSurveyView input[type=text], textarea').focus(onEnterField);
   $('.miniSurveyView input[type=text], textarea').blur(onLeaveField);
 
	$('.miniSurveyView').submit(function() {
		var formErrors = 0;
 
		$('.formError').remove();
		$('input[type=text], textarea', this).each(function() {
 
			if (($(this).attr('origLabel') == undefined || $(this).val() == $(this).attr('origLabel')) && $(this).parent().hasClass("required")) {
				formErrors++;
				$(this).before('
<div class="formError" id="formError'+formErrors+'" style="height:18px;color:red;font-size:10px;display:none;">Bitte Wert eingeben:</div>
')
				$("#formError" + formErrors).slideDown(200,function() {					
				});
			}
		})
 
		if (formErrors > 0)
			return false;
		else
			return true;
	})
 
});

We check for all fields and make sure the have a value in case they’re underneath a div with the class “required”. We simply display a div above the input fields in case there’s a value missing.

The template also contains some css rules which I’m not going to show in this article. They’re pretty straight forward, but you can also find them here:

Download Form Template

Extract the zip into “blocks/form/templates”. You might have to create the diretories form and templates first!
Enjoy!

13 Responses to 'Concrete5 – Formular Layout anpassen'

Subscribe to comments with RSS or TrackBack to 'Concrete5 – Formular Layout anpassen'.

  1. dekelly said,

    on July 17th, 2009 at 05:41:16

    Thanks Remo – this is so helpful. As always!

    The send button reads “senden” which I changed to English “Send” in view.php, line 66

    Also there was some German in the view.js file, line 29. I changed this to English “Please enter a value” .

    Is that OK?

    $(this).before(‘Bitte Wert eingeben:’)


  2. on July 17th, 2009 at 16:06:17

    Yes of course. I should have made those “translatable” but since block translations aren’t well supported in Concrete5 I tend to use the language I need without using gettext..

  3. dekelly said,

    on July 25th, 2009 at 05:21:08

    Hi Remo,

    The drop down list selector doesnt display properly – the field title disappears and the width is not justified with the other fields. How do I fix this?


  4. on July 25th, 2009 at 07:04:19

    This is most likely a css issue. I think I missed the “select” element. When you look at the css you see a rule which starts like this:
    .ccm-form-element input {

    Modify it to:
    .ccm-form-element input, .ccm-form-element select {

    I haven’t tested it – send me a link if it doesn’t work.

  5. dekelly said,

    on August 1st, 2009 at 11:54:30

    Hi Remo,

    Thanks for your responses.

    I modified the css as you specified above. The url is;

    http://www.espmasia.com/index,php/en/people/careers

    3 issues;

    1. The title for the Attachment field and Expertise drop down menu are not displaying.

    2. Input id= > validator says there is no value specified

    3. ampersand issue highlighted by validator

    INPUT ID ISSUE
    For the div corresponding to the field to browse for and attach a form, the validator highlighted:

    143 E622 The ‘id’ attribute does not have a valid value: It does not contain a valid ID. It must begin with a letter, underscore or colon and may be followed by any number of letters, digits [0-9], hyphens,underscores, colons, and periods:

    143

    Firebug confirms:

    What should this “input id” be and where do I write it?

    AMPERSAND ISSUE (on last line of snippet)

    139 E007 Found ‘&’ within ‘action’. You should use ‘&’ instead:

    I looked in all the associated “view” files but couldnt find where this “&” is coming from.

    I’m not very familiar with php and search and trawl forums for quite a while before I resort to asking you so I appreciate your patience. I’ll post your solutions in the W3C Valid thread on the C5 bug tracker forum (http://www.concrete5.org/index.php?cID=1473)

  6. dekelly said,

    on August 1st, 2009 at 11:56:23

    For some reason the complete code that I copy/pasted is not displaying. (also other posts) You’ll see when you run the validator on the page


  7. on August 1st, 2009 at 12:37:26

    1. see comment above, you need to add some more css rules
    2. not sure, have to check this
    3. this isn’t related to template but has been fixed a while ago as far as I know. Are you using the latest c5 version?


  8. on March 22nd, 2010 at 14:12:57

    Anyone managed to get this to direct the user to a new page when they complete the form?

    Big thanks for this posting, just set it up and it looks great!


  9. on March 22nd, 2010 at 21:27:41

    Thanks Ryan,
    it’s not that difficult to display a different page but you have to modify a couple of lines in the sourcecode, take a look at this discussion http://www.concrete5.org/community/forums/usage/display-thank-you-page-after-user-submits-form/


  10. on May 23rd, 2010 at 17:49:07

    Cant seem to get this to install on the latest version of C5, any ideas of a work around?

  11. Riadh Jouili said,

    on June 16th, 2010 at 14:50:06

    hey Eyan,

    don´t erase ’style=”width:95%”‘ just change it to ’style=”none”‘ and it will work with the latest version!

  12. Riadh Jouili said,

    on June 16th, 2010 at 14:50:40

    Sorry i meant Ryan


  13. on June 22nd, 2010 at 22:32:18

    Thanks for the help guys, used this a few times now, you should submit it to the Marketplace.

Leave a Reply