Skip to content

Commit 3b72432

Browse files
committed
Merge pull request silverstripe#1868 from wilr/pen-6245
FIX: Disable autocomplete on ConfirmedPasswordField instances.
2 parents d47b202 + 94d6b1c commit 3b72432

File tree

2 files changed

+106
-38
lines changed

2 files changed

+106
-38
lines changed

forms/ConfirmedPasswordField.php

+105-37
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?php
2+
23
/**
34
* Two masked input fields, checks for matching passwords.
4-
* Optionally hides the fields by default and shows
5-
* a link to toggle their visibility.
5+
*
6+
* Optionally hides the fields by default and shows a link to toggle their
7+
* visibility.
68
*
79
* @package forms
810
* @subpackage fields-formattedinput
@@ -39,11 +41,12 @@ class ConfirmedPasswordField extends FormField {
3941
public $canBeEmpty = false;
4042

4143
/**
42-
* If set to TRUE, the "password" and "confirm password"
43-
* formfields will be hidden via CSS and JavaScript by default,
44-
* and triggered by a link. An additional hidden field
45-
* determines if showing the fields has been triggered,
46-
* and just validates/saves the input in this case.
44+
* If set to TRUE, the "password" and "confirm password" form fields will
45+
* be hidden via CSS and JavaScript by default, and triggered by a link.
46+
*
47+
* An additional hidden field determines if showing the fields has been
48+
* triggered and just validates/saves the input in this case.
49+
*
4750
* This behaviour works unobtrusively, without JavaScript enabled
4851
* the fields show, validate and save by default.
4952
*
@@ -52,8 +55,7 @@ class ConfirmedPasswordField extends FormField {
5255
protected $showOnClick = false;
5356

5457
/**
55-
* Title for the link that triggers
56-
* the visibility of password fields.
58+
* Title for the link that triggers the visibility of password fields.
5759
*
5860
* @var string
5961
*/
@@ -93,6 +95,12 @@ public function __construct($name, $title = null, $value = "", $form = null, $sh
9395
if($showOnClick) {
9496
$this->children->push(new HiddenField("{$name}[_PasswordFieldVisible]"));
9597
}
98+
99+
// disable auto complete
100+
foreach($this->children as $child) {
101+
$child->setAttribute('autocomplete', 'off');
102+
}
103+
96104
$this->showOnClick = $showOnClick;
97105

98106
// we have labels for the subfields
@@ -102,6 +110,11 @@ public function __construct($name, $title = null, $value = "", $form = null, $sh
102110
$this->setValue($value);
103111
}
104112

113+
/**
114+
* @param array $properties
115+
*
116+
* @return string
117+
*/
105118
public function Field($properties = array()) {
106119
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js');
107120
Requirements::javascript(FRAMEWORK_DIR . '/javascript/ConfirmedPasswordField.js');
@@ -129,11 +142,13 @@ public function Field($properties = array()) {
129142
foreach($this->children as $field) {
130143
$field->setDisabled($this->isDisabled());
131144
$field->setReadonly($this->isReadonly());
145+
132146
if(count($this->attributes)) {
133147
foreach($this->attributes as $name => $value) {
134148
$field->setAttribute($name, $value);
135149
}
136150
}
151+
137152
$content .= $field->FieldHolder();
138153
}
139154

@@ -146,65 +161,91 @@ public function Field($properties = array()) {
146161
}
147162

148163
/**
149-
* Can be empty is a flag that turns on/off empty field checking.
164+
* Can be empty is a flag that turns on / off empty field checking.
165+
*
150166
* For example, set this to false (the default) when creating a user account,
151-
* and true
167+
* and true when displaying on an edit form.
168+
*
169+
* @param boolean $value
170+
*
171+
* @return ConfirmedPasswordField
152172
*/
153173
public function setCanBeEmpty($value) {
154174
$this->canBeEmpty = (bool)$value;
175+
155176
return $this;
156177
}
157178

158179
/**
159-
* The title on the link which triggers display of the
160-
* "password" and "confirm password" formfields.
161-
* Only used if {@link setShowOnClick()} is set to TRUE.
180+
* The title on the link which triggers display of the "password" and
181+
* "confirm password" formfields. Only used if {@link setShowOnClick()}
182+
* is set to TRUE.
162183
*
163-
* @param $title
184+
* @param string $title
185+
*
186+
* @return ConfirmedPasswordField
164187
*/
165188
public function setShowOnClickTitle($title) {
166189
$this->showOnClickTitle = $title;
190+
167191
return $this;
168192
}
169193

170194
/**
171-
* @return string
195+
* @return string $title
172196
*/
173197
public function getShowOnClickTitle() {
174198
return $this->showOnClickTitle;
175199
}
176200

201+
/**
202+
* @param string $title
203+
*
204+
* @return ConfirmedPasswordField
205+
*/
177206
public function setRightTitle($title) {
178207
foreach($this->children as $field) {
179208
$field->setRightTitle($title);
180209
}
210+
181211
return $this;
182212
}
183213

184214
/**
185-
* @param array: 2 entrie array with the customised title for each of the 2 children.
215+
* @param array $titles 2 entry array with the customized title for each
216+
* of the 2 children.
217+
*
218+
* @return ConfirmedPasswordField
186219
*/
187220
public function setChildrenTitles($titles) {
188-
if(is_array($titles)&&count($titles)==2){
221+
if(is_array($titles) && count($titles) == 2) {
189222
foreach($this->children as $field) {
190-
if(isset($titles[0])){
223+
if(isset($titles[0])) {
191224
$field->setTitle($titles[0]);
225+
192226
array_shift($titles);
193227
}
194228
}
195229
}
230+
196231
return $this;
197232
}
198233

199234
/**
200-
* Value is sometimes an array, and sometimes a single value, so we need to handle both cases
235+
* Value is sometimes an array, and sometimes a single value, so we need
236+
* to handle both cases.
237+
*
238+
* @param mixed $value
239+
*
240+
* @return ConfirmedPasswordField
201241
*/
202242
public function setValue($value) {
203243
if(is_array($value)) {
204244
if($value['_Password'] || (!$value['_Password'] && !$this->canBeEmpty)) {
205245
$this->value = $value['_Password'];
206246
}
207-
if($this->showOnClick && isset($value['_PasswordFieldVisible'])){
247+
248+
if($this->showOnClick && isset($value['_PasswordFieldVisible'])) {
208249
$this->children->fieldByName($this->getName() . '[_PasswordFieldVisible]')
209250
->setValue($value['_PasswordFieldVisible']);
210251
}
@@ -213,29 +254,40 @@ public function setValue($value) {
213254
$this->value = $value;
214255
}
215256
}
216-
$this->children->fieldByName($this->getName() . '[_Password]')->setValue($this->value);
217-
$this->children->fieldByName($this->getName() . '[_ConfirmPassword]')->setValue($this->value);
257+
258+
$this->children->fieldByName($this->getName() . '[_Password]')
259+
->setValue($this->value);
260+
261+
$this->children->fieldByName($this->getName() . '[_ConfirmPassword]')
262+
->setValue($this->value);
218263

219264
return $this;
220265
}
221266

222267
/**
223-
* Determines if the field was actually
224-
* shown on the clientside - if not,
268+
* Determines if the field was actually shown on the client side - if not,
225269
* we don't validate or save it.
226270
*
227-
* @return bool
271+
* @return boolean
228272
*/
229273
public function isSaveable() {
230274
$isVisible = $this->children->fieldByName($this->getName() . '[_PasswordFieldVisible]');
275+
231276
return (!$this->showOnClick || ($this->showOnClick && $isVisible && $isVisible->Value()));
232277
}
233278

279+
/**
280+
* @param Validator $validator
281+
*
282+
* @return boolean
283+
*/
234284
public function validate($validator) {
235285
$name = $this->name;
236286

237287
// if field isn't visible, don't validate
238-
if(!$this->isSaveable()) return true;
288+
if(!$this->isSaveable()) {
289+
return true;
290+
}
239291

240292
$passwordField = $this->children->fieldByName($name.'[_Password]');
241293
$passwordConfirmField = $this->children->fieldByName($name.'[_ConfirmPassword]');
@@ -246,16 +298,26 @@ public function validate($validator) {
246298

247299
// both password-fields should be the same
248300
if($value != $passwordConfirmField->Value()) {
249-
$validator->validationError($name, _t('Form.VALIDATIONPASSWORDSDONTMATCH',"Passwords don't match"),
250-
"validation", false);
301+
$validator->validationError(
302+
$name,
303+
_t('Form.VALIDATIONPASSWORDSDONTMATCH',"Passwords don't match"),
304+
"validation",
305+
false
306+
);
307+
251308
return false;
252309
}
253310

254311
if(!$this->canBeEmpty) {
255312
// both password-fields shouldn't be empty
256313
if(!$value || !$passwordConfirmField->Value()) {
257-
$validator->validationError($name, _t('Form.VALIDATIONPASSWORDSNOTEMPTY', "Passwords can't be empty"),
258-
"validation", false);
314+
$validator->validationError(
315+
$name,
316+
_t('Form.VALIDATIONPASSWORDSNOTEMPTY', "Passwords can't be empty"),
317+
"validation",
318+
false
319+
);
320+
259321
return false;
260322
}
261323
}
@@ -302,29 +364,35 @@ public function validate($validator) {
302364
"validation",
303365
false
304366
);
367+
305368
return false;
306369
}
307370
}
371+
308372
return true;
309373
}
310374

311375
/**
312-
* Only save if field was shown on the client,
313-
* and is not empty.
376+
* Only save if field was shown on the client, and is not empty.
377+
*
378+
* @param DataObjectInterface $record
314379
*
315-
* @param DataObject $record
316-
* @return bool
380+
* @return boolean
317381
*/
318382
public function saveInto(DataObjectInterface $record) {
319-
if(!$this->isSaveable()) return false;
383+
if(!$this->isSaveable()) {
384+
return false;
385+
}
320386

321387
if(!($this->canBeEmpty && !$this->value)) {
322388
parent::saveInto($record);
323389
}
324390
}
325391

326392
/**
327-
* Makes a pretty readonly field with some stars in it
393+
* Makes a read only field with some stars in it to replace the password
394+
*
395+
* @return ReadonlyField
328396
*/
329397
public function performReadonlyTransformation() {
330398
$field = $this->castedCopy('ReadonlyField')

javascript/ConfirmedPasswordField.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(function ($) {
2-
$('.confirmedpassword .showOnClick a').live('click', function () {
2+
$(document).on('click', '.confirmedpassword .showOnClick a', function () {
33
var $container = $('.showOnClickContainer', $(this).parent());
44

55
$container.toggle('fast', function() {

0 commit comments

Comments
 (0)