React & SASS - checkbox component not aligning with label - javascript

I am new to React and converting a previously pure HTML page into a component in React. How do I update the SASS stylesheet to resemble the previous HTML format?
This is what I currently have in React (checkbox is showing on right instead of left, and checkbox and labels are not aligned):
This is what I previously had in HTML, and the ideal format:
checkbox.component.jsx
import React from "react";
import './checkbox.styles.scss'
const Checkbox = ({ label, isSelected, onCheckboxChange }) => (
<div className="form-check">
<li>
<label for={label}> {label} </label>
<input
type="checkbox"
name={label}
id={label}
value={label}
checked={isSelected}
onChange={onCheckboxChange}
/>
</li>
</div>
);
export default Checkbox;
checkbox.styles.scss
.form-check{
li{
list-style: none;
margin-left: 15px;
text-align:left;
}
label{
cursor: pointer;
}
label:hover{
background-color:linen;
text-decoration:underline;
}
}

First - you need to move the div inside the li - the only valid child element of a list is an li element.
If you wrap the input with the label you will get that alignment plust the added benefit of being able to click the lable to change the checkbox. Obvsiously I have replaced the React interpolation with static content.
ul {list-style: none}
ul li {padding: 8px 0}
<ul>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-1"
id="form-check-1"
value="1"
checked=checked
/>
$ - $0 - 50 </label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-2"
id="form-check-2"
value="2"
/>
$$ - $51 - 100</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-3"
id="form-check-3"
value="3"
/>
$$$ - $101 - 150</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-4"
id="form-check-4"
value="4"
/>
$$$$ - $150+</label>
</div>
</li>
</ul>
Also - since these options appear to be mutually exlusive - I would suggest a radio button group to be more appropriate - that way only one option at a time can be selected. Using checkboxes will allow multiple selections - which is probably not intended in this case.
The radio button approach (which I would recommend) - use the same name attribute for all instances of hte radio input.
ul {list-style: none}
ul li {padding: 8px 0}
<ul>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-1"
value="1"
checked=checked
/>
$ - $0 - 50 </label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-2"
value="2"
/>
$$ - $51 - 100</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-3"
value="3"
/>
$$$ - $101 - 150</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-4"
value="4"
/>
$$$$ - $150+</label>
</div>
</li>
</ul>

Related

jQuery manipulate DOM

this is my default HTML-Markup from the Wordpress-Plugin:
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<label for="choice_2_21_1" id="label_2_21_1">Option One</label>
</li>
<li class="gchoice_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<label for="choice_2_21_2" id="label_2_21_2">Option Two</label>
</li>
</ul>
After the document is ready I want to change the HTML-Markup to this:
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1 checkbox checkbox-styled">
<label for="choice_2_21_1" id="label_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<span>Option One</span>
</label>
</li>
<li class="gchoice_2_21_2 checkbox checkbox-styled">
<label for="choice_2_21_2" id="label_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<span>Option Two</span>
</label>
</li>
</ul>
Thats what I actually did:
$('.gfield_checkbox > li').addClass('checkbox checkbox-styled');
But how do I change the other parts of the code?
To change the html, there is a few ways to do it. One way is to wrap the text inside with the span, and than select the sibling and add it inside of the label.
$("li")
.addClass("checkbox checkbox-styled")
.find("label")
.wrapInner("<span/>")
.each(function(){
label = $(this)
label.prepend(label.prev())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<label for="choice_2_21_1" id="label_2_21_1">Option One</label>
</li>
<li class="gchoice_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<label for="choice_2_21_2" id="label_2_21_2">Option Two</label>
</li>
</ul>
Details are commented in demo.
Demo
/*
On each <li>...
- ...add class .checkbox and .checkbox-styled
- Find each <label> and <input> nested in each <li>
- Remove the text from the <label>...
- ...append the <input> to <label>...
- ...append a <span> to <label>...
- ...insert the value of <input> as the text of the <span>
*/
$('li').each(function(i) {
$(this).addClass('checkbox checkbox-styled');
var label = $(this).find('label');
var input = $(this).find('input');
label.text('').append(input).append(`<span>${input.val()}</span>`);
});
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<label for="choice_2_21_1" id="label_2_21_1">Option One</label>
</li>
<li class="gchoice_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<label for="choice_2_21_2" id="label_2_21_2">Option Two</label>
</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Select child element from parent data attributes value

I have this kind of html blocks:
<div data-target="TargeID" data-action="toggle" data-trigger="Yes">
...
<ul>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_0" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl01$rbAnswer">
Yes
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_1" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl02$rbAnswer">
No
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_2" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl03$rbAnswer">
maybe
</label>
</li>
</ul>
</div>
I need to select every input inside elements with data-action="toggle"
and Im using this jQuery selector: $('[data-action="toggleQuestions"] :input');
but I need to select those input which text value is equal to the parent data-trigger value.
Is it possible directly with a selector?
The logic is too complex to put in to a single selector. Instead you can use filter() to find the :input elements, then match the text() of their parent label to the data-trigger value on the container. Try this:
var $container = $('[data-action="toggle"]');
var $input = $container.find(':input').filter(function() {
return $(this).closest('label').text().trim() == $container.data('trigger');
})
$input.prop('checked', true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-target="TargeID" data-action="toggle" data-trigger="Yes">
<ul>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_0" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl01$rbAnswer">
Yes
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_1" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl02$rbAnswer">
No
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_2" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl03$rbAnswer">
maybe
</label>
</li>
</ul>
</div>
Use the below code
$('[data-action="toggle"]').each(function() {
var triggerValue = $(this).attr("data-trigger");
$(this).find('input[type=radio]').each(function() {
if ($(this).parent().text().trim() === triggerValue) {
$(this).prop("checked", true);
}
});
});

Create a new <td> if it exceeds a certain width?

In my MVC site, I have a these lines of code:
<h2>#Model.Question</h2>
#using (Html.BeginForm("Index", "Result", FormMethod.Post))
{
<table cellspacing="10">
<tr>
#foreach (string answer in Model.Answers)
{
<td><input type="radio" name="answer" value="#answer" /><span>#answer</span></td>
}
</tr>
</table>
<div id="footer">
<input class="btn btn-success" direction="false" type="submit" name="Back" value="Back" />
<input class="btn btn-success" type="submit" />
</div>
}
(Ignore the currently poorly implement first button in the footer)
The <input type="radio... returns the same amount of radio buttons as answers from a database. My problem is that for one question, there are a lot of answers and it starts making the page scroll sideways, as shown in the image below
What I want to happen is for the radio buttons to start on a new line, possibly in another <td>, when it starts to go too far sideways. Possibly done when it hits the border of a surrounding div I could create? Or when it exceeds a certain pixel width? I am not quite sure how to approach this at all. Thanks in advance!
Instead of using tables for your job, it is better to use DIV with fixed width (or percentage width) and floating them left so they stick together in one line. When there will be too much elements for one line, they will automatically jump to a new line. This will also work if you will change width of your browser.
CSS part:
.elements {
border: 1px solid red;
}
.elements:before,
.elements:after{
display: table;
content: " ";
}
.elements:after {
clear: both;
}
.element {
float: left;
min-height: 1px;
border: 1px solid blue;
margin: 2px;
}
HTML Part:
<div class="elements">
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
<div class="element">
<input type="radio" name="radio" value="" /> Radio
</div>
</div>
https://jsfiddle.net/4xvdcw9b/2/
If using table is not necessary you can try this approach:
<ul>
#foreach (string answer in Model.Answers)
{
<li><input type="radio" name="answer" value="#answer" /><span>#answer</span></li>
}
</ul>
with this styles:
ul
{
max-width:300px;
list-style-type: none;
}
li
{
display: inline;
}

How to get last selected radio button id

I have two UL lists with some radio buttons. Now I want to get last selected radio button ID attribute form their UL.
For example:
If I selected radio button from first UL then return selected radio ID.
If I selected radio button from second UL then return seledted radio ID.
I have tried bellow code but not working properly. If you try with selecting first radio button from first UL you will get alert with selected ID, but when you selected radio button from second UL you will get alert from first UL and that I dont want. :(
I want to get last checked radio button ID from that UL.
Any idea how to do this?
Can you please check with this way:
First select 20 from first UL you will get 20.
Second select 80 from second UL you will get 80.
Now again change radio button from first UL and that changed radio ID I want.
Here is my JSFiddle.
Thanks.
$("#update_cart").click(function() {
var radioID = $("input[type='radio']:checked").attr("id");
if (radioID) {
alert(radioID);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<ul class="one">
<li>
<label for="1" class="label_check">
<input type="radio" id="1" name="one" value="10">10
</label>
</li>
<li>
<label for="2" class="label_check">
<input type="radio" id="2" name="one" value="20">20
</label>
</li>
<li>
<label for="3" class="label_check">
<input type="radio" id="3" name="one" value="30">30
</label>
</li>
<li>
<label for="4" class="label_check">
<input type="radio" id="4" name="one" value="40">40
</label>
</li>
<li>
<label for="5" class="label_check">
<input type="radio" id="5" name="one" value="50">50
</label>
</li>
</ul>
<ul class="two">
<li>
<label for="6" class="label_check">
<input type="radio" id="6" name="two" value="40">60
</label>
</li>
<li>
<label for="7" class="label_check">
<input type="radio" id="7" name="two" value="70">70
</label>
</li>
<li>
<label for="8" class="label_check">
<input type="radio" id="8" name="two" value="100">80
</label>
</li>
<li>
<label for="9" class="label_check">
<input type="radio" id="9" name="two" value="120">90
</label>
</li>
<li>
<label for="10" class="label_check">
<input type="radio" id="10" name="two" value="120">100
</label>
</li>
</ul>
<input type="button" id="update_cart" class="update_cart" value="Update Cart">
Use
$("#update_cart").click(function () {
var radioID = $("input[type='radio'].active").attr("id");
if (radioID) {
alert(radioID);
}
});
$("input[type='radio']").click(function(){
$('.active').removeClass('active');
$(this).addClass('active');
});
Working Demo

jQuery show hide divs on radio buttons

I have got a group of radio buttons that when clicked need to display a corresponding unordered list. I have got as far as showing the correct list according to which radio button is clicked but cannot figure out how to hide the other lists that need to be hidden. So if i click the second benefits radion then the second 'spend' ul will display and the other 'spend' uls will hide.
This is my jQuery:
// hide all except first ul
$('div.chevron ul').not(':first').hide();
//
$('div.chevron > ul > li > input[name=benefits]').live('click',function() {
// work out which radio has been clicked
var $radioClick = $(this).index('div.chevron > ul > li > input[name=benefits]');
var $radioClick = $radioClick + 1;
$('div.chevron > ul').eq($radioClick).show();
});
// trigger click event to show spend list
var $defaultRadio = $('div.chevron > ul > li > input:first[name=benefits]')
$defaultRadio.trigger('click');
And this is my HTML:
<div class="divider chevron">
<ul>
<li><strong>What benefit are you most interested in?</strong></li>
<li>
<input type="radio" class="inlineSpace" name="benefits" id="firstBenefit" value="Dental" checked="checked" />
<label for="firstBenefit">Dental</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="benefits" id="secondBenefit" value="Optical" />
<label for="secondBenefit">Optical</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="benefits" id="thirdBenefit" value="Physiotherapy" />
<label for="thirdBenefit">Physiotherapy, osteopathy, chiropractic, acupuncture</label>
</li>
</ul>
<ul>
<li><strong>How much do you spend a year on Dental?</strong></li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate1a" value="£50" />
<label for="rate1a">£50</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate2a" value="£100" />
<label for="rate2a">£100</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate3a" value="£150" />
<label for="rate3a">£150</label>
</li>
</ul>
<ul>
<li><strong>How much do you spend a year on Optical?</strong></li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate1b" value="£50" />
<label for="rate1a">£50</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate2b" value="£100" />
<label for="rate2a">£100</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate3b" value="£150" />
<label for="rate3a">£150</label>
</li>
</ul>
<ul>
<li><strong>How much do you spend a year on Physiotherapy, osteopathy, chiropractic, acupuncture?</strong></li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate1c" value="£50" />
<label for="rate1a">£50</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate2c" value="£100" />
<label for="rate2a">£100</label>
</li>
<li>
<input type="radio" class="inlineSpace" name="spend" id="rate3c" value="£150" />
<label for="rate3a">£150</label>
</li>
</ul>
<label class="button"><input type="submit" value="View your quote" class="submit" /></label>
</div>
I tried using:
$('div.chevron > ul').not($radioClick).hide();
But that yielded a bad result where all the lists where hidden.
Thanks in advance.
This will hide the currently visible one.. ( you should run it before showing the newly clicked ul )
$('div.chevron > ul:visible').hide();
thanks. I solved it with:
$('div.chevron > ul:visible').hide();
$('div.chevron > ul:first').show();
$('div.chevron > ul').eq($radioClick).show();
I don't know what it is but i always seem to over complicate stuff like this in my code when the answer is very easy.

Categories

Resources