SilverStripe CreditCardField bad html and submission error - php

I have a form which works fine without it but when I add
CreditCardField::create('CreditCard','Credit Card')->setAttribute('placeholder', '0000')
it displays the credit card field with the same name, id and other attributes. When I go to submit it of course the validation throws an error as it's expecting an array but only gets a string of the last 4 digits.
Am I creating this field correctly? I'm assuming that once I fix the display issues it will fix the validation issues.

I'm not hugely familiar with this field type, but you can see from it's template that it doesn't expect to be able to set a placeholder:
<span id="{$Name}_Holder" class="creditCardField">
<input $AttributesHTML('id', 'name', 'value', 'tabindex') name="{$Name}[0]" value="{$ValueOne}" $TabIndexHTML(0)/>
-
<input $AttributesHTML('id', 'name', 'value', 'tabindex') name="{$Name}[1]" value="{$ValueTwo}" $TabIndexHTML(1)/>
-
<input $AttributesHTML('id', 'name', 'value', 'tabindex') name="{$Name}[2]" value="{$ValueThree}" $TabIndexHTML(2)/>
-
<input $AttributesHTML('id', 'name', 'value', 'tabindex') name="{$Name}[3]" value="{$ValueFour}" $TabIndexHTML(3)/>
</span>
The attributes you can set are ID, name, value and tabindex. Placeholder may be omitted deliberately for some sort of security reason, or it may just be a missing feature.
Your best bet might be to use some javascript instead:
$('#MyCreditCard_Holder').find('input').attr('placeholder', '0000');

So there is a bug in the template that I've logged a ticket for. The work around for it at the moment is you have to have your own CreditCardForm.ss template that uses $getAttributesHTML rather than $AttributesHTML

Related

YII form input with html5 required="required"

I have one application in Yii and its creating one field for email input,
the code in view is
<?php echo $form->textField($model, 'email', $model->getHtmlOptions('email')); ?>
I want to add required="required" in the same field.
Even I don't know from where this $model->getHtmlOptions('email')) is coming from.
I don't know how to do it. I've searched all day in google but could not find a solution.
You might be use some third part extension or behavior with getHtmlOptions() method. Concerning $form->textField signature third parameter should be an array. So to keep getHtmlOptions working and add required attribute we need to merge two arrays:
<?php echo $form->textField(
$model,
'email',
CMap::mergeArray(
$model->getHtmlOptions('email'),
array('required' => true)
);
?>
Hope it will work.

HTML input tag passing placeholder as value to PHP

I'm trying to implement the 'placeholder' attribute on a new mobile web site. Running into an issue where if a user leaves the field blank (showing the placeholder) then that placeholder is submitted as the field value for PHP to receive and place in the database. Instead it should (I assume) be sending an empty value. This causes problems with server side validation - the receiving PHP script thinks a legitimate value has been submitted instead of an empty value which would throw an error back to the user.
I am hoping there is a quick fix to this issue.
Sample code below:
<form action="somepage.php" method="post">
<input type="text" name="yourName" placeholder="Enter your name here">
<input type="submit">
</form>
PHP sees:
$_POST['yourName'] = 'Enter your name here';
instead of:
$_POST['yourName'] = '';
The latter is what I want it to see.
Any help would be greatly appreciated!!!
* EDIT **
Here is an example form with the problem:
https://www.badgleymischka.com/mobileTest.php
Leave all fields as is (note in the source these are filled in by the placeholders, not the values). Click the "CONTINUE" button and you will see the _POST variables with the placeholder values.
Something is removing the placeholder attr text on page load on several inputs...
Based on your source, you're calling two different jQuery scripts. Delete this found near your closing <body /> tag. This may be conflicting with Foundation's included Placeholder plugin.
<script src="js/vendor/jquery.js"></script>
But this is probably the culprit: Not sure what you're trying to write here. But this looks to be the issue. See line 17 in jquery.main.js. Remove this all. I don't think it's needed and is conflicting.
// clear inputs on focus
function initInputs() {
PlaceholderInput.replaceByOptions({
// filter options
clearInputs: true,
clearTextareas: true,
clearPasswords: true,
skipClass: 'default',
// input options
wrapWithElement: false,
showUntilTyping: false,
getParentByClass: false,
placeholderAttr: 'value' // <-- ding, ding! Prob the conflictor, if not this entire function
});
}
I cannot reproduce your error. I tested it using Firefox 25 and 26, Chrome 31, IE 11, Opera 12.16 and Safari 5.1.7. And looking at the specification I don't believe that the placeholder is intended to be submitted - so you are indeed experiencing some kind of bug.
The only reason for this behavior I can think of is that you are including a (java)script in your HTML, aimed at browsers that don't support HTML5 (and the placeholder attribute). Such a script could be filling empty inputs with their placeholders, but failing to remove them before the form is submitted.
If this is indeed the case, and your problems are caused by such a script, you can solve them by either fixing the script or removing it completely. If you choose to fix the script, you'll need to make sure that inputs whose value equals their placeholder are reset to their default value.
Just stumbled across this in my own search, so if anyone else is looking for an answer to this try this:
<input type="text" name="yourName" placeholder="Enter your name here" required>
By adding "required" to the input tag the user must fill out this field before submitting.
This should work like charm but i assume since its on mobile something is different.
One solution(i am sure there is a better one) is to check it with an if.
So if the value is the same as the place holder then make it blank and then continue your validations.
Also try to put val="".

cakephp form helper bug

I think I've found a bug in Cake's FormHelper class, but maybe I'm just not using the correct function, so hopefully somebody on here knows. Here's the relevant code:
<?php
echo $this->Form->input('first_name', array('value' =>'First Name', 'label' => false));
?>
As you can see, I'm just outputting an input text field that has a default value of First Name. The issue I'm experiencing is that if the user does not provide a valid name, then the form does not preserve the value that the user tried to submit with, instead it just shows the default value again (First Name). So basically, if I were to enter into the field "hey123" and then click submit, the form will show the appropriate validation error message next to the text field, but the text field itself won't contain my previous entry of hey123, it will show the First Name text again.
Is it possible to have the input field show the default value initially while also allowing whatever the user entered into the form to be preserved when validation errors occur? So in the previous example, instead of showing the First Name text on the error validation page, it'd show my original entry that caused the issue, hey123.
Use:
<?php
echo $this->Form->input('first_name', array('default' =>'First Name', 'label' => false));
?>
Note, use default instead of value. Default will set a 'default' value, while value will explicitly set the value of that field.

Why doesn't set_value() work with foo[bar][x][lorem] array inputs?

So let's say i have a form where the user can add as many dogs as they want by pressing a + button.
The form is like:
Dog #1 <br/>
<input name="house[dogs][][name]" value="<?=set_value('house[dogs][0][name'])?>"/>
<input name="house[dogs][][age]" value="<?=set_value('house[dogs][0][age]')?>" />
Dog #2 <br/>
<input name="house[dogs][][name]" value="<?=set_value('house[dogs][1][name'])?>"/>
<input name="house[dogs][][age]" value="<?=set_value('house[dogs][1][age]')?>" />
On CodeIgniter, I run a form validation in order for set_value() to work as well:
$house = $this->input->post('house');
$dogs = $house['dogs'];
$i = 0;
foreach($dogs AS $dog){
$this->form_validation->set_rules("house[dogs][$i][name]", 'Dog Name', 'required');
$this->form_validation->set_rules("house[dogs][$i][age]" , 'Dog Age' , 'required');
$i++;
}
This whole thing doesn't work, How to make set_value() support array inputs like that?
Thanks in advance.
You might have to make the input name the exact same as the first parameter of set_value().
One might not be able to be [], while the other can use [0].
Very related: http://codeigniter.com/forums/viewthread/179581/ Ironically, a post I made months ago that was bumped this morning.
Also related: CodeIgniter: Validate form with multidimensional POST data
<ignore>
To make a long story short, Codeigniter does not handle indexed field names very well by default.
To simply repopulate the input and work around set_value()'s shortcomings, you can try something like this:
<?php
$value = isset($_POST['house']['dogs'][1]['age']) ? // was the value posted?
form_prep($_POST['house']['dogs'][1]['age']) : // if so, clean it
''; // if not, leave empty
?>
<input name="house[dogs][1][age]" value="<?php echo $value; ?>" />
Since you're probably using a loop to output these, I don't think it will be too much of a bother. You could populate a separate array of values and read those instead if you wish, you get the idea. set_value() automatically runs form_prep(), so that's why I added it.
I'm not too sure about the validation. You may have to do the validation yourself, which while bothersome, shouldn't be too difficult. Remember you can always run the validation methods manually. Example:
if ($this->form_validation->valid_email($this->input->post('email')) {}
You may want to just take the easy way out and change your field names to use a single index, like dog_age[], which I believe will make the validation easier for CI to handle. Best of luck, hoping for a fix one of these days in CI core.
</ignore>
EDIT: I have no idea how this escaped me, but apparently validation and set_value should in fact work as expected - not sure if this was a recent change or if the issue never really existed. I definitely remember having issues with it before, and the linked posts suggests others are too. Check out this answer though:
CodeIgniter: Validate form with multidimensional POST data
I tested it (running 2.0.2) and it does in fact work. I don't see anything in the change log, but I did test it and it did work. Make sure your on the latest version and try again perhaps, or let us know if I'm missing something here.
Like your other answer says, you probably just have to explicitly index the field names like name="house[dogs][1][name]" instead of name="house[dogs][][name]".

Validating one or the other

I've created a javascript function that allows me to validate if one field or the other is filled (called, shockingly enough, oneortheother). Essentially, it checks if neither is filled, or both, and throws an error.
One of the fields being validated is a input type="file" field. I'm displaying below the field the existing file, so that the users can see if it's the file they want.
Is there any way to still validate via oneortheother without having a value in the input type="file"? Any kind of javascript trickery?
I'm at wits end at this point, and have a demo later today that needs this functionality, so any help would be greatly appreciated.
EDIT:
As requested, here's some examples:
<label for="pdf">Upload PDF:
<span class="fieldnote">Files of type .pdf</span>
</label>
<input type="file" name="pdf" id="pdf" class="external_form_field oneortheother_url" value="/downloads/white_papers/HigherOrderPerl.pdf" />
<label>Existing file:</label><span class="preview">HigherOrderPerl.pdf</span>
<label for="url">Link to asset:</label>
<input type="text" name="url" id="url" class="external_form_field oneortheother_pdf" value="" size="25" />
Notice that the class oneortheother_url and oneortheother_pdf are applied. This allows the validation routine to know which field to compare to. The comparison is:
if (fObj.value && fObj2.value) { }
and
if (!fObj.value && !fObj2.value) { }
I unfortunately I couldn't understand the actual question, but here's a sidebar tip:
The XOR operator can come in handy (though obscure) in cases like this:
if (fObj.value ^ fObj2.value) {
// Only one value is set, we're good
} else {
// Both of them are set or neither of them are set
}
I am not sure how your validation function works, but it seems like you could add a hidden input that holds the url of the uploaded preview file OR the value in the file input. Then you could just compare the url input with the hidden input.
But it seems likely you'll just need to write a custom validation function.
I'm not sure I understand your question completely as it's not clear to me.
You want to check this:
if (fObj.value && fObj2.value) {}
and
if (!fObj.value && !fObj2.value) {}
So why not add this in as well...
if (fObj.value && !fObj2.value) {}
or
if (!fObj.value && fObj2.value) {}
What about adding a radio button next to each option, and allowing the selected radio button to determine which option is used?
I'm not sure exactly what you're trying to do here, but you could add a hidden form field, then attach a function to both the file input and the URL inputs' onchange events, that would set the hidden field to this value.
Fundamentally I'm not even sure that the approach you're currently taking is appropriate - Firefox 3, for example, doesn't let you edit the contents of a file field directly and as far as I can tell gives you no way to "unset" a value. So once a file has been chosen, the "pdf" input will always be non-null, which with the constraints you have set (as I understand them) means that the "url" input is effectively permanently disabled. This is even worse since you give the file input an initial value so that it will never ever be null/empty string.
You may need to take a step back and think about exactly what you're trying to acheive and whether an alternative technique might be better. For example, a radio button to select between the file upload box or a URL resource, which disables and enables fields as appropriate.
Additionally, the fact that most people here didn't understand quite what you're asking even after an edit is an indication that there's something about it that's not too intuitive, and it implies that people who will need to maintain this code in future might go through a similar thing. Again, refactoring the design is probably in order, or perhaps jsut a bunch of descriptive comments.

Categories