processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.4k stars 3.28k forks source link

Radio buttons interact with each other #6763

Closed Hansterdam closed 2 weeks ago

Hansterdam commented 7 months ago

Most appropriate sub-area of p5.js?

p5.js version

1.9.0

Web browser and version

Brave 1.61.116 Chromium: 120.0.6099.217

Operating system

Windows 11

Steps to reproduce this

Steps:

  1. Create two radio buttons (with multiple option)
  2. Set a selected value for each
  3. Only the last selected value will be selected
  4. Selecting a value on the first radio will unselect all options from the second radio

Snippet:

function setup() {
  createCanvas(100, 100);

  const radio1 = createRadio();
  radio1.option('car');
  radio1.option('bicycle');
  radio1.option('airplane');
  radio1.selected('bicycle');

  const radio2 = createRadio();
  radio2.option('tiger');
  radio2.option('elephant');
  radio2.option('parrot');
  radio2.selected('tiger');
}
welcome[bot] commented 7 months ago

Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, please make sure to fill out the inputs in the issue forms. Thank you!

lindapaiste commented 7 months ago

You can prevent this by using a name argument for each radio set. That is,

function setup() {
  createCanvas(100, 100);

  const radio1 = createRadio('vehicle');
  radio1.option('car');
  radio1.option('bicycle');
  radio1.option('airplane');
  radio1.selected('bicycle');

  const radio2 = createRadio('animal');
  radio2.option('tiger');
  radio2.option('elephant');
  radio2.option('parrot');
  radio2.selected('tiger');
}

If you don't explicitly set the name then they both get the same name "radioOption".


Questions for the community:

This is the HTML that is created by original code (without the name argument). IMO it can be improved.

<body>
    <main>
      <canvas id="defaultCanvas0" class="p5Canvas" width="100" height="100" style="width: 100px; height: 100px;"></canvas> 
    </main>
    <script src="blob:https://preview.p5js.org/d17e7ba2-41cb-4c1d-86e6-5aeb48737cb1"></script>

<div>
  <label>
    <input type="radio" value="car" name="radioOption">
    <span>car</span>
  </label>
  <label>
    <input type="radio" value="bicycle" name="radioOption" checked="true">
    <span>bicycle</span>
  </label>
  <label>
    <input type="radio" value="airplane" name="radioOption">
    <span>airplane</span>
  </label>
</div>
<div>
  <label>
    <input type="radio" value="tiger" name="radioOption" checked="true">
    <span>tiger</span>
  </label>
  <label>
    <input type="radio" value="elephant" name="radioOption">
    <span>elephant</span>
  </label>
  <label>
    <input type="radio" value="parrot" name="radioOption">
    <span>parrot</span>
  </label>
</div>
</body>

Both "bicycle" and "tiger" do have checked="true". The browser will not render both as checked since it is only valid to have one checked item in a radio select. The browser sees this as one single form field due to the name="radioOption" on all buttons and will only display one as checked.

Hansterdam commented 7 months ago

Thank you, that works! I agree that it working out-of-the-box would present as the most elegant solution, though I'm sure I don't have a full understanding of the context. Currently the documentation also only talks about naming the radio button, but doesn't reflect the consequences of doing or not doing so, so that is already some low hanging fruit that could be addressed.

Prateek-Fst commented 7 months ago

@lindapaiste @Qianqianye @limzykenneth @davepagurek I read the above issue mentioned by @Hansterdam and I would like to add more documentation for createradio() .In this instance would mention the consequences of not adding the name parameter and to better understand the importance of including the 'name' parameter, refer to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio. What are your thoughts on this should I go ahead and create an issue and PR for this .

rupalchandak commented 7 months ago

let myRadio;

function setup() { // Create a radio button element and place it // in the top-left corner. myRadio = createRadio(); myRadio.position(0, 0); myRadio.size(50);

// Add a few color options. // Color values are labeled with // emotions they evoke. myRadio.option('red', 'love'); myRadio.option('yellow', 'joy'); myRadio.option('blue', 'trust');

// Choose a default option. myRadio.selected('yellow');

describe('A yellow square with three options listed, "love", "joy", and "trust". The square changes color when the user selects a new option.'); }

function draw() { // Set the background color using the radio button. let c = myRadio.value(); background(c); }

let c = myRadio.value(); background(c); }

this may help you

limzykenneth commented 6 months ago

For me I think unique name is a bit too magical (but that may be just me).

For radiogroup and fieldset, the are largely functionally equivalent. I would prefer using fieldset instead just to have more semantic HTML where possible.

samrudh3125 commented 6 months ago

Yes I thing we have to use a standard system for naming like [page]-rdbtn-1. The last number is to be incremented for multiple radiobutton in a single page

subhra1jit commented 1 month ago

Hey, I tried to solve the issue and make some changes to the code , the problem is that we are not assigning a unique name attribute to the radio buttons, which causes multiple createRadio buttons to act as a single group. At present, the name attribute value is assigned only if a value is passed while calling the function otherwise it takes the default value 'radioOption'. self._name = name || 'radioOption';

For this I have provided one solution that is instead of radioOption as a default value we can generate a unique nameusing Math.random() function. self._name =name || "radioButtonNumber-" + Math.random().toString(36).slice(2);

If any reviewer confirm that this is the right approach , I would be interested making this changes.