I have some checkboxes and their name maps to a column in my activerecord model. Problem is, when the checboxes are selected, they appear in the params array in Sinatra, which works fine. But when they are deselected, the params never contains :checkbox => false. It only contains :checkbox => true. So the user can go from deselected to selected, but never vice versa as the params hash for :checkbox => false is never passed.
I feel like I am missing something fundamental here. Please help.
Thanks
A control in a HTML form only gets submitted to the server if it is “successful’. For checkboxes this means that it is checked. An unchecked checkbox doesn’t get submitted. This means that in Sinatra the value of params[:the_checkbox] is either the value of the checkbox specified in the HTML (if you don’t specify a value this will be the default which is the string 'on') if it is checked, or will be nil since nothing will have been submitted.
The obvious solution is to explicitly check for nil, and then assume that the checkbox is unchecked in that case:
checkbox_value = params[:the_checkbox].nil? ? false : true
Another option is to make use of the fact that the name/value pairs of the form data are sent to the server in the order that they appear in the document, and that when Sinatra sees a repeated name when parsing the data it will override the earlier value with the later one. This means that you can do something like this in the HTML:
<input type='hidden' name='the_checkbox' value='false' />
<input type='checkbox' name='the_checkbox' value='true' />
Now if the checkbox isn’t checked it won’t get submitted, but the hidden input will, and if it is checked it will get submitted, but will appear after the hidden input with the same name. The result is that params[:the_checkbox] will be the string 'true' if it has been checked, and the string 'false' if it hasn’t. (Note that you may still have to convert the strings to booleans, depending on what you’re doing with the submitted data).
You could do something like this :
post '/your-route' do
params[:checkbox] ||= false
# now do whatever you want with params[:checkbox]
end
What this does is assign false to params[:checkbox] unless it is already defined and set to true.
Related
Unfortunately, the Apps Script documentation page about DataValidation builder is missing information about the requireCheckbox method.
When you type it in via a script file, though, autocompletion offers 3 overloads:
no args:
requireCheckbox()
1 arg:
requireCheckbox(Object checkedValue)
2 args:
requireCheckbox(Object checkedValue, Object uncheckedValue)
What parameters of an object can I use in these arguments and what purposes they may serve?
CHECKBOX cell by default, has two values:
TRUE, when checked and
FALSE when unchecked.
Depending on the number of arguments provided to requireCheckbox, different values are used:
No argument:
The default values are used.
One argument:
The provided argument, when checked
Blank, when unchecked
Two arguments:
The provided arguments are used for checked and unchecked states respectively.
Sample code:
function yesNoDV() {
//Changes checked state to 'Yes' and Unchecked state to 'No'
SpreadsheetApp.getActive()
.getRange('Sheet1!A1')
.setDataValidation(
SpreadsheetApp.newDataValidation()
.requireCheckbox('Yes', 'No')
.build()
);
}
Object is the default type Google's documentation uses when more specific types do not apply. You can safely interpret it as an analog for any (and in fact, the #types TypeScript package for Google Apps Script has those parameters annotated with any).
Also, as of 2021, the documentation has information on all method overloads. To quote from it, the overloads function is as follows.
No arguments
Sets the data validation rule to require that the input is a boolean value; this value is rendered as a checkbox.
One argument
Sets the data validation rule to require that the input is the specified value or blank. When the input matches the specified value the cell is rendered as a checked checkbox. When the input is blank the cell is rendered as an unchecked checkbox.
Two arguments
Sets the data validation rule to require that the input is one of the specified values. When the input is checkedValue the cell is rendered as a checked checkbox. When the input is uncheckedValue the cell is rendered as an unchecked checkbox.
The meaning of each overload hasn't changed from that outlined in TheMaster's answer.
This may be somewhat basic but cannot find a definitive answer anywhere. I have set up a contact form within my app and have put in a hidden field that when completed disables the submit button with some Jquery. My attempt at stopping automated spam..
Can I also add some validations in my model?
validates :ghost, :presence => false
Looking at the docs this is invalid? I want the form to fail if this field is filled in. Not sure how to go about this one
EDIT
So I have now read that I could possibly use
validates_exclusion_of :ghost, :on => :create
Though this is still failing as i dont think i am passing the correct arguments.
:presence => false means that you disable presence validator.
You need to write own absence validation (though in Rails 4.0 such validation exists, absence: true).
validate :ghost_is_absent
def ghost_is_absent
errors.add :ghost if ghost.present?
end
I am sorry to say , but why are you trying to do things so differently, doing it this way will make things more confusing for any future developer working on this piece of validation.
First thing:
1) You can do the reverse of it , mark it as spam when the field is empty and vice versa and then simply check with the validation validates_presence_of :ghost
2)or if you want to protect spam use capcha (recapcha gem for that)
3) or if you want it do it your way only , then just add a custom validation
Try creating a custom validation.
validate :check_for_spam
def check_for_spam
errors.add_to_base "ghost is present this is a spam" if ghost.present?
end
If you want to check if :ghost is blank:
validates :ghost, inclusion: {in: ['']}
If you want to check if :ghost is nil, you have to rely to a custom validator.
Gah.. I have spent way to long on this, but I believe I have found the problem.
Essentially I have a hidden field which is populated when a user clicks on an image.
It is required that the user has clicked the image but I do not want the generic form error message for a 'required' check with the CI form validation class.
As such I quickly made a image_required function in my extended form validation class, and set a rule such that this rule was applied to the hidden field.
function image_required($str)
{
$CI =& get_instance();
$CI->form_validation->set_message('image_required','Please click the image above.');
if($str != '')
{
return TRUE;
}
else
{
return FALSE;
}
}
If the hidden field was blank no error was being called.
I am led to believe now that this is because CI says this field is empty yet it is not 'required', therefore we will ignore all the other validation rules for the field. Is this correct?
If so how can i go about requiring this field be set but having a custom error message?
bangs head
Thanks
If you look at the source code (v2.1.3) for the '_execute' routine (system/libraries/Form_validation.php) you will see on line 486
// If the field is blank, but NOT required, no further tests are necessary
So you are correct, it needs to be required and then it will process your rule.
In order to fix it so you can have a non-required blank field that still processes rules, you should override the '_execute' method by creating a file called 'MY_Form_validation.php' in the application/libraries folder (I think, you might need to check exactly how you extend an existing library) and then copy the '_execute' method and alter the code to continue on a non-required but blank entry.
I do love CI, but I have to say this does not allow the flexibility required. It is perfectly reasonable to have a field that cannot be empty, but is NOT required. As in, you wouldn't enforce "user MUST enter a value", but they cannot submit a blank. I think someone got confused between EMPTY and REQUIRED.
1) REQUIRED: User MUST put a value in the field and it cannot be empty (i.e. '')
2) EMPTY: User does not HAVE to enter a value, BUT, if they do, it's cannot be empty. This not the same as REQUIRED... Looks like I'll be using a callback again.
REQUIRED incorporates two logical steps (1->Must enter a value, and 2->Cannot be empty) these two steps should be separated logically to allow either / or.
In constraint terms it would be either, REQUIRED, NOT NULL. Or NOT REQUIRED, NOT NULL.
I have a problem with a sfWidgetFormInputCheckbox. It do not save false in the database when the checkbox is unchecked.
In my schame my field is a boolean, and i don't have bug in the value displayed.
Set the default value like this : $this->setDefault('status', false); don't work either.
My widget :
$this->widgetSchema['SUSPENSION_TEMP'] = new sfWidgetFormInputCheckbox();
$this->validatorSchema['SUSPENSION_TEMP'] = new sfValidatorBoolean(array('required' => false));
The default :
$this->setDefault('SUSPENSION_TEMP', false);
Any ideas ?
Edit:
It save 1 when the checkbox is checked. And do not change the database value when you unchecked and save. So once you checked once, value is always 1 in database (true for my code).
Edit2:
I have two clues to add. If the field is an integer in the schema.xml, both values work, bu we got a poblem on value displayed (checkbox checked qih the 0 value). Here, he field is a boolean.
The setter receive two kinds of value, 'on' when checkbox is checked and true when it's not. I tried to set default value to false in form, and to overide he setter. Both don't work.
I mean the setter work, but for an unknown reason the basic seer is called right after with a wrong value.
Edit3:
Ok, i understand part of the problem. The setter is not called, when the checkbox is unchecked. I thought it was because, m code displayed a var_dump(). It was because later i copy the old version of this object in archive purpose.
But symfony should detect that the field has been rendered and it doesn't. I don't know why. I know why in html, but obviously symfony should be able to tell himself "hey, i add a checkbox here".
Is there an elegant way o do this, or should i checked it by hand ?
The problem came from my form handling. My legacy code, did no render all fields (ex : some stamp field, updated by a behavior). It was using fromArray, then save. This update only the fiels rendered.
The traditionnal symfony form, give null to all non-rendered fiels in order to chcuk for required validation.
So you need to check by yourself and set to 0, when you are using a fromArray then save. Still, i find the form->save really dumb, because you need to send useless(in this case) or confidentials data to your client in order to use it.
I'm using following spec with MiniTest::Spec and Capybara:
find_field('Email').must_have_css('[autofocus]')
to check if the field called 'Email' has the autofocus attribute. The doc says following:
has_css?(path, options = {})
Checks if a given CSS selector is on the page or current node.
As far as I understand, field 'Email' is a node, so calling must_have_css should definitely work! What I'm doing wrong?
Got an answer by Jonas Nicklas:
No, it shouldn't work. has_css? will check if any of the descendants
of the element match the given CSS. It will not check the element
itself. Since the autofocus property is likely on the email field
itself, has_css? will always return false in this case.
You might try:
find_field('Email')[:autofocus].should be_present
this can also be done with XPath, but I can't recall the syntax off
the top of my head.
My solution:
find_field('Email')[:autofocus].must_equal('autofocus')
Off top of my head. Can you use has_selector?(). Using Rspec wit Capy:
page.should have_selector('email', autofocus: true)
Also check Capybara matchers http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers
I've not used MiniTest before but your syntax for checking for the attribute looks correct.
My concern would be with your use of find_field. The docs say:
Find a form field on the page. The field can be found by its name, id or label text.
It looks like you are trying to find the field based on the label. If so I would check that you have the for attribute on it and and that it has the correct id of the form field you are looking for. To rule out this being the issue you could temporarily slap an id your form field and look for that explicitly.