If statements in jquery not behaving as expected - javascript

I am relatively new to jQuery. I am trying to create a survey; in the survey each question in in its own div and is revealed by clicking the "Next" button. I just have all divs hidden except for the current div. I'm trying to write the answers to an object as I go to simplify the code. There are questions answered with radio buttons, some text areas, some check boxes, and some selects. Here is my code:
$('.next-button').click(function() {
if ($(this).parent().has('.survey-question-option')) {
replies[$(this).parent().attr('id')] = $(this).parent().contents('.survey-question-option:checked').val();
} else if ($(this).parent().has("textarea")) {
replies[$(this).parent().attr('id')] = $(this).parent().contents("textarea").val();
}
console.log(replies);
$(this).parent().attr('hidden', '');
$(this).parent().next().removeAttr('hidden');
});
I'm logging the Object (replies) to make sure things are working. As the code is currently formulated I get the answers to the first two questions (both of which are radio buttons) added to replies, but the next two objects (textareas) populate as undefined. ({reason: "bill", wish: "newstart", dislike: undefined, like: undefined}). I tried formulating the if statement as two separate statements:
if ($(this).parent().has('.survey-question-option')) {
replies[$(this).parent().attr('id')] = $(this).parent().contents('.survey-question-option:checked').val();
};
if ($(this).parent().has("textarea")) {
replies[$(this).parent().attr('id')] = $(this).parent().contents("textarea").val();
};
That returns undefined for the radio buttons, but the contents of the two textareas shows up in the object. ({reason: undefined, wish: undefined, dislike: "dislike text", like: "like text"}). In doing some testing on my own I've determined that if the if statement is formulates as if...else if the formula always applies the if statement only, but if it is created with two if statements it skips thew first and goes straight for the second.
My logic is that each Next button is in a div with the responses, so I should be able to look at the parent of the Next button, find the appropriate class, and get the value. And it seems to only work 50% of the time no matter how I formulate it.
EDIT: I am attaching the relevant html sections.
$('.next-button').click(function() {
if ($(this).parent().has('.survey-question-option')) {
replies[$(this).parent().attr('id')] = $(this).parent().contents('.survey-question-option:checked').val();
} else if ($(this).parent().has("textarea")) {
replies[$(this).parent().attr('id')] = $(this).parent().contents("textarea").val();
}
console.log(replies);
$(this).parent().attr('hidden', '');
$(this).parent().next().removeAttr('hidden');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="survey">
<div id="reason" class='radio'>
<p class="survey-question">What is the primary reason you visit the site? </p>
<input type="radio" id="bill" name="reason" class="survey-question-option" value="bill">
<label for="bill" class="survey-question-option-label">To view or pay my bill online</label><br>
<input type="radio" id="outage" name="reason" class="survey-question-option" value="outage">
<label for="outage" class="survey-question-option-label">To view or report an outage</label><br>
<input type="radio" id="start" name="reason" class="survey-question-option" value="start">
<label for="start" class="survey-question-option-label">To get information about starting or stopping services</label><br>
<input type="radio" id="hours" name="reason" class="survey-question-option" value="hours">
<label for="hours" class="survey-question-option-label">To find Frederick Waster's business hours</label><br>
<input type="radio" id="board" name="reason" class="survey-question-option" value="board">
<label for="board" class="survey-question-option-label">To get information about Frederick Water's governance or board meetings</label><br>
<input type="radio" id="devel" name="reason" class="survey-question-option" value="devel">
<label for="devel" class="survey-question-option-label">To get information about new water or wastewater lines for new development</label><br>
<input type="radio" id="other" name="reason" class="survey-question-option" value="other">
<label for="other" class="survey-question-option-label">Other</label><br>
<div id="other-fill-reason" class="other-fill" hidden>
<label for="othertext-reason" class="survey-question-option-label">Please specify: </label>
<input type="text" class="survey-question-other" id="othertext-reason">
</div>
<input type="button" class="next-button" id="reason-next" value="Next">
</div>
<div id="wish" class='radio' hidden>
<p class="survey-question">What do you wish the site did better?</p>
<input type="radio" id="newstart" name="wish" class="survey-question-option" value="newstart">
<label for="newstart" class="survey-question-option-label">Allow me to pay deposit while starting new service</label><br>
<input type="radio" id="outinfo" name="wish" class="survey-question-option" value="outinfo">
<label for="outinfo" class="survey-question-option-label">Provide easier-to-find information about outages</label><br>
<input type="radio" id="startstop" name="wish" class="survey-question-option" value="startstop">
<label for="startstop" class="survey-question-option-label">Make it easier to start and stop services</label><br>
<input type="radio" id="request" name="wish" class="survey-question-option" value="request">
<label for="request" class="survey-question-option-label">Make it easier to request maintenance for existing service</label><br>
<input type="radio" id="chat" name="wish" class="survey-question-option" value="chat">
<label for="chat" class="survey-question-option-label">Let me talk to customer service online</label><br>
<input type="radio" id="other2" name="wish" class="survey-question-option" value="other">
<label for="other2" class="survey-question-option-label">Other</label><br>
<div id="other-fill-wish" class="other-fill" hidden>
<label for="othertext-wish" class="survey-question-option-label">Please specify: </label>
<input type="text" class="survey-question-other" id="othertext-wish">
</div>
<input type="button" class="next-button" id="wish-next" value="Next">
</div>
<div id="dislike" class="textbox" hidden>
<p class="survey-question">What do you dislike about the site?</p>
<textarea id="dislike-text" class="like-dislike" cols="100" rows="5" maxlength="500" wrap="soft"></textarea><br>
<input type="button" class="next-button" id="dislike-next" value="Next">
</div>
<div id="like" class="textbox" hidden>
<p class="survey-question">What do you like about the site?</p>
<textarea id="like-text" class="like-dislike" cols="100" rows="5" maxlength="500" wrap="soft"></textarea><br>
<input type="button" class="next-button" id="like-next" value="Next">
</div>

has() doesn't return a boolean, it returns a jQuery object. Objects are always truthy.
If you want to test whether a selector finds anything, test the length of the result.
$('.next-button').click(function() {
if ($(this).parent().find('.survey-question-option').length > 0) {
replies[$(this).parent().attr('id')] = $(this).parent().find('.survey-question-option:checked').val();
} else if ($(this).parent().find("textarea").length > 0) {
replies[$(this).parent().attr('id')] = $(this).parent().find("textarea").val();
}
console.log(replies);
$(this).parent().attr('hidden', '');
$(this).parent().next().removeAttr('hidden');
});

Related

JS Turning Radio Button into algorithm param

I made a simple program that generates a random build for an NBA 2k21 MyPlayer for one of my classes. Every button the user clicks generates a random value for each trait.
I am now trying to alter the program to remember the user input for the height radio buttons and then generate a random position based on that user's selection.
I want the program to randomize between:
PG/SG if the height is between 6'2" and 6'5" or
SG/SF if the height is between 6'5" and 6'8" or
SF/PF if the height is between 6'8" and 6'10" or
PF/C if the height is between 6'10 and 6'11"
Originally the program was just 3 buttons that generates random values from an array, but now it consists of 3 buttons and a user selection of radio buttons. Here is what I had before I got stuck:
<h1>
2k Archetype Generator
</h1>
<p>
Choose Height
</p>
<form>
<input name="height" type="radio" id="h1"> 6'2"
<br>
<input name="height" type="radio" id="h2"> 6'3"
<br>
<input name="height" type="radio" id="h3"> 6'4"
<br>
<input name="height" type="radio" id="h4"> 6'5"
<br>
<input name="height" type="radio" id="h5"> 6'6"
<br>
<input name="height" type="radio" id="h6"> 6'7"
<br>
<input name="height" type="radio" id="h7"> 6'8"
<br>
<input name="height" type="radio" id="h8"> 6'9"
<br>
<input name="height" type="radio" id="h9"> 6'10"
<br>
<input name="height" type="radio" id="h10"> 6'11"
<br>
</form>
<br>
<button id="positionchoice" onclick="randpos()">
Position
</button>
<p id="pos">
</p>
<button id="primary" onclick="randprim()">
Primary
</button>
<p id="no1">
</p>
<button id="secondary" onclick="randsecond()">
Secondary
</button>
<p id="no2">
</p>
var p = document.getElementById("pos");
var skill1 = document.getElementById("no1");
var skill2 = document.getElementById("no2");
var height = ["6'2","6'3","6'4","6'5","6'6","6'7"
,"6'8","6'9","6'10","6'11"];
var primary = ["Shot Creating", "Playmaking", "Defensive"
,"Sharpshooting","3-Point","Rebounding"];
var secondary = ["Slasher", "Finisher", "Shooter",
"Ball Handler","Lockdown", "Two-Way"];
var arr = ["PG", "SG", "SF", "PF", "C"];
function randpos() {
}
function randprim() {
skill1.innerHTML = primary[Math.floor(Math.random()*primary.length)];
}
function randsecond() {
skill2.innerHTML = secondary[Math.floor(Math.random() * secondary.length)];
}
Hopefully this will help get you unstuck so that you can write the next part of your function. Here is how you can get the currently selected option:
function randpos() {
let height = document.querySelector("input[name='height']:checked").value;
height = parseInt(height);
}
<h1>
2k Archetype Generator
</h1>
<p>
Choose Height
</p>
<form>
<input name="height" type="radio" id="h1" value="74"> 6'2"
<br>
<input name="height" type="radio" id="h2" value="75"> 6'3"
<br>
<input name="height" type="radio" id="h3" value="76"> 6'4"
<br>
<input name="height" type="radio" id="h4" value="77"> 6'5"
<br>
<input name="height" type="radio" id="h5" value="78"> 6'6"
<br>
<input name="height" type="radio" id="h6" value="79"> 6'7"
<br>
<input name="height" type="radio" id="h7" value="80"> 6'8"
<br>
<input name="height" type="radio" id="h8" value="81"> 6'9"
<br>
<input name="height" type="radio" id="h9" value="82"> 6'10"
<br>
<input name="height" type="radio" id="h10" value="83"> 6'11"
<br>
</form>
<br>
<button id="positionchoice" onclick="randpos()">
Position
</button>
I have edited your <input/> elements to include a value attribute so that you can then select that directly from the JS. Additionally you may notice that these values are in inches only. You can make these values in feet and inches, like are still displayed to the user, but it is likely going to make your life easier implementing the next part of your function if you have a single number you can make comparisons with.
In the JavaScript since your button is not attached to a form you want to set up a query selector looking for any <input/> element with a name set to height. To get only the currently selected element we then look for the :checked pseudo-class selector. Finally we get the value of the element that is returned and assign it to a height variable. (Alternatively you can attach your button to the form if you give the form a name which then would allow you to process it in a more typical fashion)
Since you are likely going to want to make comparisons with this value you can then take the height variable, a string, and convert it to a number using the parseInt() function.

populate 'today + x days' as form input value [duplicate]

I am trying to use the innerHTML method on an input tag and all i get back is a blank string. Here is the code i am useing.
javascript
function setName(ID){
document.getElementById('searchtitle').innerHTML = "Enter " + ID.innerHTML;
}
HTML
<input type="radio" name="searchtype" id="test" value="name" onclick="setName(this)">Last Name</input><br/>
<input type="radio" name="searchtype" value="phonenumber" onclick="setName(this)">Phone Number</input><br/>
<label for="inputfield" id="searchtitle" style="font-size:2em;">Enter Last Name</label><br/>
<input type="text" name="inputfield" id="inputfield" style="font-size:2em;"></input>
What is supposed to happen is depending on which radio button I pick the label for the input box should change. I can make the label.innerHTML=radio.value but the values are named for my php code and not formated nicely(ie. phonenumber vs. Phone Number) this is why I am trying to use the innerHTML of the radio button.
Any help I could get would be greatly appriciated.
you should embed input inside of label tag. input tag should closed by />. It's semantic HTML. When you do this clicking on label activate the input. InnerHTML only works for label then. It will return you label value.
<label for="inputfield" id="searchtitle" style="font-size:2em;">Enter Last Name
<input type="text" name="inputfield" id="inputfield" style="font-size:2em;" />
</label>
JavaScript:
console.log(document.getElementById('searchtitle').innerHTML); // returns 'Enter Last Name'
If you want the value of an input tag, you want to use .value.
First, add labels around your inputs. Second, use getName(this.parentNode). Finally, call innerText instead of innerHtml.
<html>
<head>
<script>
function setName(el){
document.getElementById('searchtitle').innerHTML = "Enter " + el.innerText;
}
</script>
</head>
<body>
<label><input type="radio" name="searchtype" value="name" onclick="setName(this.parentNode)"/>Last
Name</label><br/>
<label><input type="radio" name="searchtype" value="phonenumber" onclick="setName(this.parentNode)"/>Phone
Number</label><br/>
<label for="inputfield" id="searchtitle" style="font-size:2em;">Enter Last Name</label><br/>
<input type="text" name="inputfield" id="inputfield" style="font-size:2em;"></input>
</body>
</html>
Complete edit.
Ok, I figured out what you were looking for. First off, you've got to fix your HTML (don't put text inside of an input... and don't next an input inside of a label).
<label for="test">Last Name</label>
<input type="radio" name="searchtype" id="test" value="name" onclick="setName(this)" />
<br/>
<label for="test2">Phone Number</label>
<input type="radio" id="test2" name="searchtype" value="phonenumber" onclick="setName(this)" />
<br/>
<label for="inputfield" id="searchtitle" style="font-size:2em;">Enter Last Name</label>
<br/>
<input type="text" name="inputfield" id="inputfield" style="font-size:2em;" />
JavaScript (in Jquery, for brevity):
function setName(elem)
{
$('#searchtitle').html('Enter ' + $('label[for="'+elem.id+'"]').html());
}
You have closed the Input tag improperly with </input>
this should be
<input type="radio" name="searchtype" id="test" value="name" onclick="setName(this)"/>Last Name<br/>
<input type="radio" name="searchtype" value="phonenumber" onclick="setName(this)"/>Phone Number<br/>

jQuery - Checking value of various input types

I have no idea what I'm doing wrong here. I have a form with radio buttons and simple text fields. I'm checking to see if there is a value within the form fields or if either of the radio buttons have been checked. If there is no value add a red color to the label. If they have a value I'm adding back the default black. But for some reason no matter if I put a value in the text field it stays red. Also kind of strange but if I check the first checkbox the black text appears. Any help is greatly appreciated.
JS Fiddle: http://jsfiddle.net/5Sacj/
<form name="headerForm">
<label id="gender" for="gender">Gender</label>
<input type="radio" name="customer" value="male" />Male
<input type="radio" name="customer" value="female" />Female
<br/>
<label for="fname">*First Name</label>
<input type="text" class="text" id="fname" name="fname" />
<br/>
<label for="fname">*Last Name</label>
<input type="text" class="text" id="lname" name="lname" />
<input id="submit" type="submit" name="submit" value="submit"
</form>
JQUERY
$(document).ready(function() {
$("#submit").on('click', function() {
$(":text, :radio").each(function() {
if($(this).val() === '' || !$(this).is(':checked')){
$(this).prev('label').css('color','red');
} else {
$(this).prev('label').css('color','black');
}
});
});
});
That is because you are using or operator ||.
It will execute even if one is true. Try using && or have separate if condition for both.

How to check if all the radio buttons are selected or not?

Well I am trying to build a web page that has set of radio buttons. I am using jquery to check if all the radio buttons are checked or not. Here is the code:
<body>
<p class="Cal">Welcome,</p>
<hr />
<p class="Radio1">Answer the questions below. You will find the results after clicking 'Check my score'.</p>
<hr />
<form method="post">
<p class="Question">1. Do you sleep early at night? (Anywhere around 9-10pm)</p>
<p>
<label>
<span class="Radio">
<input type="radio" name="RadioGroup1" value="Yes" id="RadioGroup1_0" />
</span></label>
<span class="Radio"> Yes
<br />
<label>
<input type="radio" name="RadioGroup1" value="No" id="RadioGroup1_1" />
No
</label>
<br />
<label>
<input type="radio" name="RadioGroup1" value="Sometimes" id="RadioGroup1_2" />
Sometimes </label>
</span><br />
</p>
<p class="Question">2. Do you wake up early in morning?(Anywhere around 5-7am)</p>
<p>
<label>
<span class="Radio">
<input type="radio" name="RadioGroup2" value="Yes" id="RadioGroup2_0" />
Yes </span></label>
<span class="Radio"><br />
<label>
<input type="radio" name="RadioGroup2" value="No" id="RadioGroup2_1" />
No
</label>
<br />
<label>
<input type="radio" name="RadioGroup2" value="Sometimes" id="RadioGroup2_2" />
Sometimes
</label>
</span><br />
</p><input type="submit" value="Check my score" /></form></body>
Well there are 30 such questions. And my jquery code is as follows:
$(document).on('submit', 'form', function () {
var validate = true;
var unanswered = new Array();
// Loop through available sets
$('.Radio').each(function () {
// Question text
var Question = $(this).prev().text();
// Validate
if (!$(this).find('input').is(':checked')) {
// Didn't validate ... dispaly alert or do something
unanswered.push(Question);
validate = false;
}
});
if (unanswered.length > 0) {
msg = "Please answer the following questions:\n" + unanswered.join('\n');
alert(msg);
}
else{
msg = "Done!";
alert(msg);
}
return validate;
});
Now I tried all ways possible to make this work. But even after I check radio button for each answer I keep on getting the popup saying "Please answer the following questions:" and then a blank list. I never get the message "Done!" even though answer for all the questions are checked.
Where is the fault?
You can use the HTML5 required attribute, which is better option.
You can also use JavaScript loop and retrieve the value from each radio group, using
$("input:radio[name=radiogroupX]:checked")

jQuery generated text on click upon if statement, remains after if is false

I've got a form with some radio buttons in it. When a link is clicked, the value of the selected radio button is passed to a text field. If the value is '0', the text 'Not required' is given to a div, overwriting where the output would have been if it wasn't '0'.
When you click the '0' radio button then click the link, it works as it should. The problem is that if you change to a different radio button then click the link again, the text remains. What I want to happen is for that message to only appear when the '0' is selected and for it to be removed if a non-'0' is chosen.
I've set it up on http://jsfiddle.net/thewebdes/gnW2c/ so you can see what I mean. In the actual project, the 'Not required' text will overwrite anything else that would have appeared so clearing the html using jquery at the beginning of the click function is a no-go.
HTML
<form action="#" method="post">
<label for="item1_qty1">0</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="0">
<br>
<label for="item1_qty1">100</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="100">
<br>
<label for="item1_qty1">250</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="250">
<br>
<label for="item1_qty1">500</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="500">
Get Value
<div class="output">
<label for="item1_qty_output">Item 1 Output</label>
<input type="text" id="item1_qty_output">
</div>
</form>
JS
$('.gen_output').click(function() {
$('#item1_qty_output').val($('input:radio:checked').val());
if ($('input:radio:checked').val() == '0') {
$('.output').html('Not required')
}
});
I think this is what you want - http://jsfiddle.net/ntTcr/
You were replacing the entire content of the output div when the value was 0 so you could not get it back when you selected a different value.
You were replacing all the content with .html, so your inputs werent there when you tried to update them.
http://jsfiddle.net/loktar/gnW2c/6/
JS
$('.gen_output').click(function() {
$('#item1_qty_output').val($('input:radio:checked').val());
if ($('input:radio:checked').val() == '0') {
$('#msg').html('Not required').show();
$('#fields').hide();
}else{
$('#fields').show();
$('#msg').hide();
}
});
Markup
<form action="#" method="post">
<label for="item1_qty1">0</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="0">
<br>
<label for="item1_qty1">100</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="100">
<br>
<label for="item1_qty1">250</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="250">
<br>
<label for="item1_qty1">500</label>
<input type="radio" id="item1_qty1" name="item1_qty" value="500">
Get Value
<div class="output">
<div id="msg"></div>
<div id="fields">
<label for="item1_qty_output">Item 1 Output</label>
<input type="text" id="item1_qty_output">
</div>
</div>
</form>
Just added each one in the output container div, then do a hide/show.
You need to set it back if it's not 0, like this:
$('.gen_output').click(function() {
$('#item1_qty_output').val($('input:radio:checked').val());
if ($('input:radio:checked').val() == '0') {
$('.output').html('Not required');
}
else {
$('.output').html("<label for='item1_qty_output'>Item 1 Output</label><input type='text' id='item1_qty_output'");
}
});
I'd suggested adding a second div for "not required" and change the click function to show/hide the two divs.
<div class="output">
<label for="item1_qty_output">Item 1 Output</label>
<input type="text" id="item1_qty_output">
</div>
<div id="notRequired" style="display:none">
Not required
</div>
$('.gen_output').click(function() {
$('#item1_qty_output').val($('input:radio:checked').val());
if ($('input:radio:checked').val() == '0') {
$("#notRequired").show();
$(".output").hide();
}
else {
$("#notRequired").hide();
$(".output").show();
}
});

Categories