Concrete5 – Form styling
Concrete5 bietet einen netten Form Block, mit dem man Formulare in wenigen Sekunden erstellen. Dies ohne HTML oder PHP Kenntnisse. Unglücklicherweise lässt sich der HTML Code davon, nur schlecht mit CSS anpassen. In diesem Tutorial zeige ich, wie man ein Formular in diesem Stil erstellen kann:
Custom Templates
Das Stichwort “Custom Templates” sollte bekannt sein, ansonsten bitte zuerst diesen Artikel durchlesen: http://www.codeblog.ch/2009/03/concrete5-templates/. Kurz zusammengefasst: Concrete5 erlaubt es, mittels “Custom Templates” sämtliche Blöcke in ihrem Erscheinungsbild anzupassen, falls mit CSS nicht genügend Möglichkeiten zur Verfügung stehen sollten.
Core Änderungen
Der Controller des Form Blocks hat eine kleine Unschönheit, welche das “stylen” mit CSS etwas erschwert. Da keine Funktionalität daran hängt, hab ich in diesem Fall den Code im “Core” direkt modifiziert. Ev. wird das in einer zukünftigen Version geändert. Es betrifft die Datei “concrete/blocks/form/controller.php” in der Zeile 667:
Die Anweisung ’style=”width:95%”‘ ist zu entfernen.
Das Standard Layout
Wird ein Formular mit Concrete5 erstellt, sieht es standardmässig so aus:
Es funktioniert, sieht aber nicht wirklich hübsch aus.
Das neue Layout
In diesem Tutorial zeige ich, wie man ein Formular erstellen kann, bei dem die Labels nicht neben den Eingabefeldern stehen, sondern gleich im Feld. Dies kann besonders nützlich sein, wenn wenig Platz vorhanden ist, und ein grosses Formular einzufügen ist. Das 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 | <?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> |
Ich werde nicht jede Zeile erklären, da dies etwas umfangreich wäre. Ich geh davon aus, dass PHP Kenntnisse vorhanden sind.
Kurz aufgelistet, was geändert wurde:
- Einige Methoden vom Controller werden neu aus der View aufgerufen
- Das Tabellen Layout durch DIV’s ersetzt
- CSS Klassen eingefügt, welche für die JavaScript Checks verwendet werden
- $_REQUEST angepasst, damit die Labels im “value” Attribute ausgegeben werden
Nun haben wir ein Formular, bei dem die Labels in den Eingabefeldern ausgegeben werden. Wir müssen nun aber auch sicherstellen, dass diese vordefinierten Werte ersettz werden können, ansonsten kann es passieren, dass Formulare mit diesen Werten abgeschickt werden können.
Dazu werden verschiedene Events geprüft:
1 2 3 | $('.miniSurveyView input[type=text], textarea').click(onEnterField); $('.miniSurveyView input[type=text], textarea').focus(onEnterField); $('.miniSurveyView input[type=text], textarea').blur(onLeaveField); |
Sobald ein Benutzer ein Feld aktiviert oder verlässt, werden diese Funktionen aufgerufen. Dort wird geprüft, ob der Wert zu ersetzen ist oder nicht:
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; } |
Zusätzlich kommen ein paar clientseitige Checks dazu, um dem Benutzer sofort einen Hinweis betreffend nicht ausgefüllten Feldern ausgeben zu können.
$(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; }) });
Wir in einem Feld kein Wert eingegeben, wird ganz einfach oberhalb davon eine entsprechende Meldung ausgegeben.
Das Template enthält einige CSS Anweisungen, welche ich hier nicht weiter erkläre. Mit grundlegenden CSS Kenntnissen sind diese problemlos zu verstehen und können auch entsprechend angepasst/erweitert werden. Sämtliche Dateien finden sich in folgendem ZIP:
Den Inhalt der ZIP Datei ins Verzeichnis “blocks/form/templates” entpacken. Die Verzeichnisse “form” und “templates” müssen ev. vorgängig erstellt werden!
Viel Spass!




on Juli 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:’)
on Juli 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..
on Juli 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?
on Juli 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.
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)
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
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?
on März 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!
on März 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/
on Mai 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?
on Juni 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!
on Juni 16th, 2010 at 14:50:40
Sorry i meant Ryan
on Juni 22nd, 2010 at 22:32:18
Thanks for the help guys, used this a few times now, you should submit it to the Marketplace.