Using the for attribute in JSX - linter unknown property "for" - javascript

I have a label with an input. I want to make the whole label area clickable to trigger the input (a checkbox). So I have used the for attribute as I believe this is exactly what it is intended for:
<label for={id}>
<input
name="checkbox"
type="radio"
data-id={id}
/>
</label>
Functionally this works but the linter does not like it:
error Unknown property 'for' found, use 'htmlFor' instead react/no-unknown-property
htmlFor does not appear to have the same functionality as the for attribute.
How can I change my code to make it work whilst retaining the functionality of for - I'd rather avoid writing a custom function that selects the correlating checkbox when you click on the label when that functionality already exists with for

Nothing special you need to do.Try This,
<input
name="checkbox"
type="radio"
data-id={id}
/>
<label htmlFor={id}></label>

Just replace for with htmlFor.
As in React class becomes className, for becomes htmlFor.
If you do document.getElementById you will have to access for property as label.htmlFor, as under the hood JavaScript uses htmlFor.
You can read about it here : prop_label_htmlfor, React htmlfor
Eslint suggestion for reference :

Related

How can I use setAttribute on an input without an ID or class attribute?

I have a search input tag that is being added by a jQuery plug-in:
<input type="search" />
Note that this does not have an ID, CLASS, or NAME. I need the search input tag to look like this:
<input type="search" name="myname" />
A simple solution is for me to update the jQuery plug-in. However, I do not want to do this as it will cause challenges when I upgrade this plug-in in the future.
This JavaScript works properly and adds the name attribute:
$(document).ready(function() {
document.getElementsByTagName("input")[0].setAttribute("name", "myname");
});
The problem is that the "[0]" in this function relies on the search input being the first input field in the form. I do not think this solution is sustainable.
There are other inputs in the form. This is the only one with the type attribute equal to "search." Is there a way to identify it by this attribute? Or, is there another solution you propose?
Thank you for your time!
You can use the document.querySelector:
document.querySelector("input[type='search']")
Below is an example (you can inspect the output to see name attribute):
document.querySelector("input[type=search]").setAttribute("name", "myname");
<input type="search" value="foo" />
<input type="bar" value="bar" />
You can target a selection by anything. So, the selector input[type="search"]' will work.
If you want to apply this to all input's of type search, this is good enough, and you get all of them in here:
$('input[type="search"]')
This works without jQuery too:
document.querySelectorAll('input[type="search"]')
A more targeted approach would be
document.querySelectorAll('div.filter input[type="search"]')

How to include form field attributes based on state in React?

I am trying to make an accessible form in React and I need to toggle the attribute aria-describedby based on the state of the field (i.e., if it has an error associated with it).
I know how to toggle the value of the attribute, but with regards to WCAG, a present but empty attribute of this type will fail. The entire attribute needs to be fully present or fully absent. Anything I try in-line throws errors and breaks the render.
To give an example, this is what I've been trying:
<label>
<input type="text" name="someName" ref="someRef" {!this.state.isValid ? aria-describedby="helperText" : ''} required />
<p id="helperText">Helper text for this form field.</p>
</label>
Again though, an empty attribute value for aria-describedby is invalid.
Is there any way to acheive this?
Just spread it like this:
<input type="text"
name="someName"
ref="someRef"
{... !this.state.isValid && {'aria-describedby': 'helperText'} }
required />
This is basically spread operator usage.

Most efficient way to select a set of elements?

I've always used class names to select sets of related elements. e.g.
<input type="checkbox" value="1" class="checkbox_set_1">
<input type="checkbox" value="2" class="checkbox_set_1">
<input type="checkbox" value="3" class="checkbox_set_1">
$('.checkbox_set_1').filter(':checked') ...
I do this because I know jQuery can delegate to document.getElementsByClassName which should be pretty fast. However, adding classes to all the elements I want to select but not style seems kind of dirty. Isn't there some overhead when the browser has to check checkbox_set_1 against its stylesheet to determine if my checkboxes need styling? Plus, there's some risk of accidental styling if I haven't named my classes nicely.
Is there a better way to select elements that doesn't rely on an attribute meant for styling, without giving up the performance benefits? Or more specifically, is there an attribute other than class (used for styling) and id (limited to a single element) that the browser will optimize queries for?
There are many other attributes to pick from, including data-* attributes, but I don't think the browser optimizes lookups on anything other than id and class, does it?
Isn't there some overhead when the browser has to check checkbox_set_1
against its stylesheet to determine if my checkboxes need styling?
Styling isn't determined that way. The browser doesn't take each attributes of an element and look for rules that apply, instead it looks through the rules once and determine which ones applies to the element.
If you are concerned with adding classes to a lot of elements, you can use selectors that make better use of the document structure, for example setting a class on the element containing the checkboxes and use something like $('.CheckboxContainer :checked').
That might not be quite as efficient as setting classes on every element that you want to target, but in most cases the difference is far from noticable. You shouldn't bother too much about efficient selectors until it's an actual problem. After all, you are using jQuery because it's convenient, not to get the best performance.
Yes, it behaves analouge to the "Marker-Interface in java" and you will find the anti-pattern-description of Tom Butler.
If you have a form around, you could use elements (but you must filter other elements) this is faster than calling a method like "getElementsByClassName".
Example
var lst = jQuery(document.foo.elements);
document.write(lst.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="foo">
<input type="checkbox" value="1" />
<input type="checkbox" value="2" />
<input type="checkbox" value="3" />
<input type="checkbox" value="4" form="bar" />
</form>

The for-attribute on labels in jQuery forms

Regarding forms with labeled fields, this (out-dated) jQuery Mobile documentation states:
Be sure to pair them properly with label elements via the for attribute.
The for attribute still exists in the latest version, but the current documentation does not even mention it anymore. What is it used for? Some sort of form validation?
It's standard HTML (not jQm-specific) used to link text with a corresponding input element.
MDN Docs for <label>
Example:
<label for="your_name">Your Name:</label>
<input id="your_name" value="John Smith" />
When I tap on the label, the input text will gain focus. The for attribute should be set to the ID of the input element.

Ractive radio button binding - preserve name

I understand that to bind a ractive variable to a radio-button, the easiest way is to have
<input type="radio" name="{{myVar}}" value="1" checked>
in the template, but the curly brackets on the name persist into the html. Is there a clever way to get it to output
<input type="radio" name="myVar" value="1" checked>
in the html, so I don't have to alter the form-handling? I've tried some logic along the lines of
<input type="radio" name="myVar" value="1" {{#myVar==1}}checked{{/myVar==1}}
but that doesn't bind.
Also, less importantly, is there a way to bind it as a numeric value, as if I have
data:{myVar:1}
Then the button doesn't get checked?
Ractive adds the curly braces to input names to guard against the (highly unlikely) possibility of a conflict between name='{{myVar}}' and name='myVar' - no other reason. The binding is created when the element is rendered; what the name becomes after that is irrelevant.
So although there's no way to prevent the curly braces being added in the first place, you can certainly change them afterwards:
ractive.findAll('input[type="radio"]').forEach( function(input) {
input.name = input.name.replace('{{','').replace('}}','');
});
If you were creating a component with Ractive.extend() this could be part of the init() method, for example.
It shouldn't have a problem with numeric values, at least as of the last released version (0.3.9) and current development version (0.4.0). See this fiddle for an example: http://jsfiddle.net/rich_harris/7qQZ8/
Short answer: I don't think it's possible to do what you want.
Ractive handles radio buttons differently than simple HTML markup. It assumes that you're going to want to retrieve which radio button is set using a simple variable, and it relies on the name attribute to do that. Specifically, it expects you to set the name attribute to the same specific variable (e.g. "{{myVar}}") in all radio buttons in a group. It will then automatically set that variable to the value attribute of whichever individual radio button is selected.
For example, if you have the following code:
<label><input type='radio' name='{{myVar}}' value='1' checked> 1</label>
<label><input type='radio' name='{{myVar}}' value='2' > 2</label>
<label><input type='radio' name='{{myVar}}' value='3' > 3</label>
<p>The selected value is {{myVar}}.</p>
Then Ractive will automatically update the <p> with information on whatever radio button is selected.

Categories