ReduxForm error when changing value of a radioButton - redux-form

Im using reduxform to generate a survey which includes some radiobutton questions. The problem is that whenever I change the value of the radio button I get this error:
Uncaught Error: Must access array elements with a number, not "undefined".
at deleteInWithPath (deleteIn.js:21)
at deleteInWithPath (deleteIn.js:35)
at deleteIn (deleteIn.js:61)
at createReducer.js:233
at reducer (createReducer.js:548)
at createReducer.js:566
at combination (combineReducers.js:120)
at autoRehydrate.js:30
at computeNextEntry (<anonymous>:2:27469)
at recomputeStates (<anonymous>:2:27769)
I don't know what is causing the error so any helped to spot it would be appreciated.
This is the component that render the radio buttons.
export const QuestionYesNo=({question,valueQuestion,metaData})=>{
let error=null;
if(metaData!==undefined){
if(metaData[question.id]!==undefined){
if((valueQuestion(question.id)===undefined ||valueQuestion(question.id)==='') && metaData[question.id].touched===true){
error=<h4 style={{color:'red'}}>¡Required!</h4>
}
}
}
return(
<div>
<div className="question">
<div><h3>{question.ordinal+"- "+question.name}</h3></div>
<div>
<label>
<Field
name={""+question.id}
component="input"
type="radio"
value="YES"
/>{' '}
Si
</label>
<label>
<Field
name={""+question.id}
component="input"
type="radio"
value="NO"
/>{' '}
No
</label>
</div>
</div>
{error}
</div>
);
};
The above component is inside another component in a loop for each question. The component that contains the above component is the one that has the reduxForm.

This is a bug/limitation of redux-form. Prefix your field names with a letter or with a letter followed by a period if you want your form values to be in an array when passed to onSubmit.
So rather than
name={""+question.id}
do
name={"question"+question.id} // results in {question0: "foo", question1: "bar"}
or (if your ids are monotonically increasing integers starting from zero):
name={"questions."+question.id} // results in array {questions: ["foo", "bar"]}
More info: https://github.com/erikras/redux-form/issues/3753#issuecomment-406435226

Related

How do i match the value which has a radio button checked

I have a list of similar looking DIVs without any Div ID, except one has a check box checked and others doesn't. What i need is to find the value from a child tag only if a radio button is selected.
Below is a simpler version of my code.
<div class = "XYZ">
<input type="radio" checked>
<input type="hidden" value="This is a great thing 1">
</div>
<div class = "XYZ">
<input type="radio">
<input type="hidden" value="This is a great thing 2">
</div>
Result needed is
This is a great thing 1
Unfortunately the source code cannot be changed.
Your xpath should look for a div that contains the checked input and to get the value for the one that has value attribute.
First selector returns the input, the second returns the value.
//div[.//input[#checked]]/input[#value]
//div[.//input[#checked]]/input/#value
As an alternative you can use the following sibling:
//input[#checked]/following-sibling::input
If you want to also use the class of the parent div:
//div[#class='XYZ']/input[#checked]/following-sibling::input

How do we check Twitter Bootstrap radio buttons using Laravel Dusk?

According to twitter bootstrap, this is how we do a radio:
<div class="radio">
<label>
<input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
Option one is this and that—be sure to include why it's great
</label>
</div>
And this is my code:
$browser->click('#menu-reports')
->waitForText('Users')
->click('#menu-reports-users')
->radio('sitesActive', '2')
->radio('includeDisabled', '2')
->radio('includeNonCertifiable', '2')
->press('Apply')
->waitForText('Showing 0 to 0 of 0 entries')
;
With the input inside the label tag. But the problem is that Dusk (actually Facebook Webdriver) is not able to find it this way. It keeps raising:
Facebook\WebDriver\Exception\ElementNotVisibleException: element not visible
To make it work I have put the input outside the label, but then, of course, the boostrap radio does not show as it should anymore.
<div class="radio">
<input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
<label>
Option one is this and that—be sure to include why it's great
</label>
</div>
Does not work using IDs either:
Not even setting an ID to the input:
<input
type="radio"
name="sitesActive"
id="sitesActive3"
value="2"
>
And trying to select it this way:
->radio('#sitesActive3', '2')
The problem is that Dusk (Webdriver) cannot even see the element in the page, as this simple like fails the exact same way:
$browser->waitFor('#sitesActive3');
Resulting in:
Facebook\WebDriver\Exception\TimeOutException: Waited 5 seconds for selector [#sitesActive3].
And that happens every time I have a form with an input with a label surrounding it, if I take the input out of the label, it works. But that's not as simple with radios, as it was with some other inputs, radios.
This is a properly coded radio:
This is a radio with the input outside the label tag:
So, how are you doing this?
My form has a radio button. This how I checked it.
userCreate.blade.php
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Gender</label>
<div>
<label class="radio-inline">
<input type="radio" id="gender" name="gender" value="m">Male
</label>
<label class="radio-inline">
<input type="radio" id="gender" name="gender" value="f">Female
</label>
</div>
</div>
</div>
</div>
CreateUserTest.php
class CreateUserTest extends DuskTestCase
{
public function testCreateForm()
{
$this->browse(function (Browser $browser) {
$browser->visit('/user/create')
->radio('#gender', 'm')
->click('button[type="submit"]')
->assertSee('Successfully created user.');
});
}
}
This works for me. I think this will help you.
simplest way is to click on the parent
$el = $this->resolver->resolveForRadioSelection($field, $value);
$el = $el->findElement(WebDriverBy::xpath(".."));
$el->click();
Since the radio is not visible dusk cannot click on it
You may create a trait like the following if you are using bootstrap in your project
trait BootstrapInteraction
{
/**
* Undocumented variable
* #var \Laravel\Dusk\ElementResolver $resolver
*/
public $resolver;
public function radioB($field, $value)
{
/**
* #var RemoteWebElement $el
*/
$radio = $this->resolver->resolveForRadioSelection($field, $value);
// click on parent
$el = $radio->findElement(WebDriverBy::xpath(".."));
$el->click();
// if not selected click on label
if (!$radio->isSelected()) {
$el = $el->findElement(WebDriverBy::cssSelector("label"));
$el->click();
}
PHPUnit::assertTrue(
$radio->isSelected(),
"Not able to select Radio [{$field}] within value [{$value}]."
);
return $this;
}
You may not be happy to edit your views for the sake of your test script but if you are open to that, what about adding a class to the
<input type="radio" ... >
and then using
->click('.yourClass')
in your Dusk test?
The Dusk docs say:
To "select" a radio button option, you may use the radio method. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a radio with matching name and value attributes: $browser->radio('version', 'php7');
In my case, Dusk was working fine for most of my radio buttons, but it would not work for:
->radio('Field728', 'Know it\'s what anyone committed to this dream would do if she found a great program that features a proven process and supportive community')
I also tried using double-quotes, but that didn't work either. (Maybe the value is too long? I don't know.)
So instead I did this:
->radio('#Field728_0', true)//this is the specific ID of the first radio button of this group

How to select a Radio button in Watir with label text?

The cheatsheets and docs on Watir show something like this to set a radio button
b.radio(:id => "radio").set
How can I select a Radio button based on the text next to it?
Sometimes this text is inside the label tag , sometimes its just inside some div/form tag. How do we handle this in Watir??
(Label texts in CAPS in below examples)
Example 1:
<form action="">
<input type="radio" value="male" name="sex"/>
MALE
<br/>
<input type="radio" value="female" name="sex"/>
FEMALE
</form>
Example 2 :
<div class="isoversixteen_false_container">
<input id="isoversixteen_false" class="radio" type="radio" value="0" name="isoversixteen" autocomplete="off"/>
<label class="isoversixteen_false_label" for="isoversixteen_false">
<span class="label_main">UNDER 16</span>
</label>
</div>
<div class="isoversixteen_true_container">
<input id="isoversixteen_true" class="radio" type="radio" value="1" name="isoversixteen" autocomplete="off" checked="checked"/>
<label class="isoversixteen_true_label" for="isoversixteen_true">
<span class="label_main">16 OR OVER</span>
</label>
</div>
Orde's comment about using attributes of the input element is a good idea as it is the easiest to program. However, to answer the question:
Example 1 - Adjacent text node
In this example, the desired text is in an adjacent text node. Given that the radio buttons share the same parent, I think the easiest solution would be to use XPath:
browser.radio(xpath: '//input[following-sibling::text()[1][normalize-space(.) = "MALE"]]').set
browser.radio(xpath: '//input[following-sibling::text()[1][normalize-space(.) = "FEMALE"]]').set
The XPath says to:
Find an input element where
The following text node - ie the [1]
Has the text "MALE" or "FEMALE", ignoring the leading/following spaces - ie the [normalize-space(.) = "FEMALE"]
Example 2 - Label text
In this example, the checkboxes have a properly associated label element - ie the id of the checkbox matches the for attribute of the label. Watir supports locating elements by their label text through the :label locator:
browser.radio(label: 'UNDER 16').set
browser.radio(label: '16 OR OVER').set
Example - First following non-blank text node
If you want a single solution that works with both examples, the following seems to work:
browser.radio(xpath: '//input[following::text()[normalize-space(.) != ""][1][normalize-space(.) = "UNDER 16"]]').set
browser.radio(xpath: '//input[following::text()[normalize-space(.) != ""][1][normalize-space(.) = "16 OR OVER"]]').set
browser.radio(xpath: '//input[following::text()[normalize-space(.) != ""][1][normalize-space(.) = "MALE"]]').set
browser.radio(xpath: '//input[following::text()[normalize-space(.) != ""][1][normalize-space(.) = "FEMALE"]]').set
The intent here is to find the first text node after the checkbox that has text (the [normalize-space(.) != ""][1] portion) and that text matches the expected text (the [normalize-space(.) = "UNDER 16" portion).
This is HTML structure I have in my example:
<div class="radio-inline">
<label for="job_type">Second Type</label>
<input id="job_service" name="job" type="radio" value="remote">
</div>
Normally I'd select it with:
#browser.input(:value => 'remote').click
However, per your question, I tried to see if I could select by text. I found this works, but may be dependent on the labels being nested in a div.
#browser.label(:text => /Second Type/).click
The / around "Second Type" were due to some weird line breaks in the HTML, may work with just quotes.

javascript 'tagName' is null or not an object in IE8 - Not validating radiobuttons in Ie8

I am using validatious-custom-0.9.1.js framework in my project and I am trying to validate required fields for radio buttons. But it is not validating the radio buttons in IE8. I am getting the following error in console
Message: 'tagName' is null or not an object
Line: 7
Char: 9921
Code: 0
URI: http://validatious.org/design/js/validatious.0.9.1.min.js?1256063644
HTML code used.
<div>
<label for="_button_880">Radio List
<div>
<p>some text</p>
</div>
</label>
<div>
<ul>
<li>
<div>
<div>
<input type="radio" name="radio1" id="radio1" value="Radio1" class="required" title="Required."/>
<label for="radio1">Radio1</label>
</div>
</div>
</div>
</div>
JS where it is failing - First 2 are the examples that are given in the framework file. So you will get to know how it is implemented
/* A radio button field is assumed to be either a list - ordered or unordered -
with some element in front that acts as a label. This may be any element.
If it is not in a list (ie the element does not have "li" parent elements),
the label is assumed to be the element before the first input element.
Example1 (list approach):
<h2>Favourite food:</h2>
<ul>
<li>
<input type="radio" name="food" value="hamburger" id="food_hamburger" />
<label for="food_hamburger">Haburger</label>
</li>
<li>
<input type="radio" name="food" value="pizza" id="food_pizza" />
<label for="food_pizza">Pizza</label>
</li>
</ul>
getLabel() will in this case return the h2 element.
Example2 (no list).
<label class="groupLabel">Favourite food:</label>
<input type="radio" name="food" value="hamburger" id="food_hamburger" />
<label for="food_hamburger">Hamburger</label>
<input type="radio" name="food" value="pizza" id="food_pizza" />
<label for="food_pizza">Pizza</label>
getLabel() will in this case return the first label element
*/
Actual code
getLabel: function() {
var parent = this.__elements[0].parentNode;
//alert(parent1.nodeName); --- Gives 'nodeName' is null or not an object IN Ie8
if (parent1.tagName.toLowerCase() === 'li') { ---Gives 'tagName' is null or not an object
return v2.$(parent1.parentNode).previous();
}
var element = v2.$(this.__elements[0]).previous();
return element || this.base();
}
Required field validation in the js file
v.reg('required', function(field, value, params) {
return !v2.empty(value) && !(typeof value.length !== 'undefined' && value.length == 0);
}, null, null, 'not-empty', false);
It works fine in firefox, IE7 and IE9. But in Ie8, I get message tagName is null or not an object.
Can somebody please help me in this. If this is solved, then this framework will be very useful to avoid all the hardships in validating.
Thanks in advance..

Kendo Grid custom pop up editor & validation

I have this simple kendo-template script:
<!-- popup editor template -->
<script id="userEditor" type="text/x-kendo-template">
<div id="popServerErrorSummaryPlaceholder" style="display:none"></div>
<div class="control-row">
<label class="span2" for="FirstName">Vorname</label>
<input Id="FirstName" class="span4" data-bind="value:FirstName" maxlength="50" name="FirstName" required="true" type="text" />
<span class="k-invalid-msg" data-for="FirstName"></span>
</div>
<div class="control-row">
<label class="span2" for="LastName">Nachname</label>
<input Id="LastName" class="span4" data-bind="value:LastName" maxlength="50" name="LastName" required="true" type="text" />
<span class="k-invalid-msg" data-for="LastName"></span>
</div>
</script>
Which is used while editing a single row within the Kend-UI grid.
I have got right now two issues:
a) The documentation states that I can control the position for validation messages via a "span" element that has a class "k-invalid-msg".
The behaviour right now is that this span Element gets replaced with a div element and it is positioned below the label element. I would like to get the message next to the input.
b) The validation is triggered immediately when the pop up is displayed.The validation should be trigger either when leaving the input or clicking the "update" button.
Someone out there who can help me here?
Things I am not quite sure how to handle:
c) Some validations are performed at the server. I get them back to the browser via the DataSource error event (custom JSON which is basically a list of field name and associated error messages). I would like to display the error messages within the validation span. I can create custom validation rules as documented here.
How do I get the validator that is associated with the pop up editor window? Or is there foreach input a validator created?
Anyone did this before?
Thanks for any help!
Updates:
regarding to point a)
OnaBai pointed me to the right direction. Thanks for that.

Resources