multistep form - toggle between styled radio buttons - html

i have built a multi step form that works , but it is not very "elegant" coded,
so i am asking
for your advice to make it more efficient ,
i have placed here only 2 steps out of 3 because the first step - email name etc', is not relevant for my question:
in each step 2 and 3 there are 2 styled radio button yes and no for the user to select,
in each step i need to toggle between check and uncheck styled images and of course prevnt that both
yes and no check images will show at the same time.
i know that the default/not styled radio buttons behavior prevents two checked buttons at the same time- can i use it here to save some lines of code?
the html(index.php)
<form method="post" id="userForm" action="process_form.php">
<fieldset class="formFieldset">
<div id="second_step" class="vanish">
<div class="form slide_two check_wrap">
<div class="quizyes quizbtn">
<img class="uncheck_pic pic one" src="images/check_not.png">
<img class="check_pic pic agree" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">yes</h1>
</div>
<div class="quizno quizbtn">
<img class="uncheck_pic pic two" src="images/check_not.png">
<img class="check_pic not not_agree pic first_not" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">no</h1>
</div>
<div id="feedback_wrap"><div class="feedback"></div></div>
<div id="submit_wrap" >
<input type="radio" class="yep decideOne" val ="1" name="yep" style="display: none;"/>
<input type="radio" class="nope decideOne" val ="2" name="nope" style="display: none;"/>
</div>
</div></div>
<!-- end of second step -->
<!-- third step -->
<div id="third_step" class="vanish">
<div class="form check_wrap">
<div class="quizyes quizbtn">
<img class="uncheck_pic pic one" src="images/check_not.png">
<img class="check_pic pic agree" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">yes</h1>
</div>
<div class="quizno quizbtn">
<img class="uncheck_pic pic two" src="images/check_not.png">
<img class="check_pic not not_agree pic second_not" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">no</h1>
</div>
<div id="feedback_wrap"><div class="feedback"></div></div>
<div id="submit_wrap">
<input type="radio" class="yep decideTwo" val ="1" name="yep" style="display: none;"/>
<input type="radio" class="nope decideTwo" val ="2" name="nope" style="display: none;"/>
</div>
</div></div>
<!-- end of third step -->
</fieldset>
<div id="submit_wrap">
<input class="submit btn" type="button" name="submit_all" id="submit_all" value="" />
</div>
</form>
the script
$(document).ready(function(){
$(function() {
$('.check_pic').hide();
//original field values
var isDecide= false;
//toggle images and set values
$('.pic').on('click', function(event) {
if ($(this).hasClass('uncheck_pic') && $(this).hasClass('one') ){
$(".yep").val('agree');
$(this).hide();
$(this).siblings('.check_pic').show();
$(".not").hide();
$(".two").show();
}
else if ($(this).hasClass('uncheck_pic') && $(this).hasClass('two') ){
var isDecide = $(".nope").val('notagree');
$(this).hide();
$(this).siblings('.check_pic').show();
$('.agree').hide();
$(".one").show();
}
else if ($(this).hasClass('check_pic') && $(this).hasClass('agree') ){
$(this).hide();
$(this).siblings('.uncheck_pic').show();
}
else if ($(this).hasClass('check_pic') && $(this).hasClass('not_agree') ){
$(this).hide();
$(this).siblings('.uncheck_pic').show();
}
});
// start the submit thing
$('#submit_all').click(function() {
if($('#second_step').is(":visible")) {
$('.decideOne').removeClass('error valid');
// prevent empty boxes and display a message
if($('.one').is(":visible") && $('.two').is(":visible")) {
$('.feedback').text('please select one').show();
return false;
}
// case the user selects yes
if($('.agree').is(":visible")) {
$('.feedback').text('thank you for selecting yes').show();
var isDecide = $(".yep").val();
var name = $("#firstname").val();
var phone = $("#phone").val();
var email = $("#email").val();
var dataString = 'user-details:name=' + name + ' phone=' + phone + ' email=' + email + ' decide=' + isDecide ;
$.ajax({
type : "POST",
url : "/",
data: dataString,
success : function(data) {
console.log('data');
$('#second_step').delay(1000).fadeOut(600, function() {
$('#first_step').fadeIn(400);
$('.feedback').hide();
});
}
});
}
// case the user selects no
if($('.first_not').is(":visible")) {
$(".yep").val();
$(".nope").val();
$('#second_step').fadeOut(600, function() {
$('#third_step').fadeIn(600);
$('.feedback').hide();
});
}
return false;
// end second step
} else if($('#third_step').is(":visible")) {
$('.third_input').removeClass('error').removeClass('valid');
// prevent empty boxes and display a message
if($('.quizyes .one').is(":visible") && $('.quizno .two').is(":visible")) {
$('.feedback').text('please select one').show();
return false;
}
// if decide yes then submit
if($('.agree').is(":visible")) {
$('.feedback').text('thank you for selecting yes').show();
var isDecide = $(".yep").val();
var name = $("#firstname").val();
var phone = $("#phone").val();
var email = $("#email").val();
var dataString = 'user-details:name=' + name + ' phone=' + phone + ' email=' + email + ' decide=' + isDecide ;
$.ajax({
type : "POST",
url : "/",
data: dataString,
success : function(data) {
console.log('data');
$('#second_step').delay(1000).fadeOut(600, function() {
$('#first_step').fadeIn(400);
$('.feedback').hide();
});
}
});//end ajax
return true;
}//end if agree is visible
// if decide no then send message and quit
if($(".second_not").is(":visible")) {
$(".nope").val("no");
$('.feedback').text('too bad bye bye').show();
$('#third_step').fadeOut(3000, function() {
$('#first_step').fadeIn(600);
$('.feedback').hide();
});
}
}
// end third step
});
//end submit_all
}) // general function
}); // document ready

Dude my wish to you take a look on good js library - knockout to represants all that kind show, hide functunality and forms inputs, checkbox, radiobutton modifications.

If you're using images to style your radiobuttons I would suggest combining the images into a Sprite and just using css to move the background-position of the image using the input[type=radio]:checked selector. No javascript necessary.
For Example - you combine your two images into a single image that is 100px wide, each individual image being 50px wide. And then style the checkbox...
input[type=radio].myCustomRadioButton {
background: url(myRadioButtonSprite.png) 0 0;
}
input[type=radio].myCustomRadioButton:checked {
background-position: -50px 0;
}
Assuming your images are lined up horizontally in your sprite, this would move the background image of the radiobutton left 50px to display the checked-image, when the radiobutton is checked.
As a side note, doing this is going to require unsetting some of the browser styling that is going to occur automatically. A good reset for form elements is to start with these styles.
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;

Keep in mind if you need to support Internet Explorer versions less than 9, the :checked pseudo-selector isn't available in pure CSS and you may need to resort to some scripting.
Listen for the change event on your custom radio buttons and update a parent element based on that.
Here's an example.
The <input> has position: absolute so the clip property can be applied to hide it and it does not affect the content box of its parent, which has relative position to contain it.
I used background-color but you could swap this in for your image urls or change the background-position of a sprite as suggested in rob-gordon's answer.
You can still add visible label text inside the label as you see in the second set of radio inputs.

Related

Check if text is being entered in input using Javascript/jQuery

I am trying to hide a placeholder while the input is being used and while there's text inside the input. Here's a simplified version of the HTML for the input and placeholder:
<div id="search-placeholder"><span class="fa fa-search"></span> Search</div>
<input id="search-input" type="text" name="search" />
I tried using jQuery but it does not return the desired result:
$(document).ready(function(){
$('#search-input').focus(function(){
$('#search-placeholder').fadeOut(100);
}).focusout(function(){
$('#search-placeholder').fadeIn(100);
});
});
The placeholder will hide when the input is selected, as it should. But it will show again when the user clicks elsewhere, even while the input is not empty! The placeholder is visible on top of the input value, so I tried a different approach:
$('#search-input').change(function(){
if($('#search-input').val() = '') {
$('#search-placeholder').fadeIn(100);
}else{
$('#search-placeholder').fadeOut(100);
}
})
Unfortunately, this only works when the user clicks elsewhere. The placeholder still shows while typing and while the input is selected, again showing itself on top of the input value. How do I hide <div id="search-placeholder"> while <div id="search-input"> is not empty, or when the input is selected by clicking or tapping it (on focus)?
Maybe try to check the value of the input in the focusout event and only show the placeholder if it's empty:
$(document).ready(function(){
$('#search-input').focus(function(){
$('#search-placeholder').fadeOut(100);
}).focusout(function(){
if($('#search-input').val() === '')
{
$('#search-placeholder').fadeIn(100);
}
});
});
I think you could extract the $('#search-input') and $('#search-placeholder') elements to variables, so the code becomes a bit more readable.
You do this using javascript and jquery
jquery :-
$(document).ready(function(){
$('#search-input').focus(function() {
$('#search-placeholder').fadeOut(100);
});
$('#search-input').focusout(function() {
if($('#search-input').val() === '') {
$('#search-placeholder').fadeIn(100);
}
});
});
javascript
var searchInput = document.getElementById("search-input");
var searchPlaceholder = document.getElementById("search-placeholder");
searchInput.onfocus = function() {
searchPlaceholder.style.display = "none";
}
searchInput.onfocusout = function() {
if(this.value == "") {
searchPlaceholder.style.display = "block";
}
}
if you want to add fade-in fade-out transitions in javascript method use css transition property- transition: opacity 1s and instead of changing style.display change style.opacity to 1(show) and 0(hide)

Toggle Text between multiple buttons

I would like to have two buttons which are basically categories. Let's name them category A and category B. The are displayed left and right. Below i would like to display some text which is dependent of the chosen category (i.e the clicked button) so that category A shows text A and category B shows text B.
This if for html. I'm working on a wordpress homepage.
I was able to install one button which toggles text (basically button 1 = Category A). But i couldn't manage to insert a second button (basically button 2 = Category B). Any ideas? Highly appreciated!
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Click the button to swap the text of the DIV element:</p>
<p><button onclick="myFunction()">Click Me</button></p>
<div id="myDIV">Hello</div>
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.innerHTML === "Hello") {
x.innerHTML = "Swapped text!";
} else {
x.innerHTML = "Hello";
}
}
</script>
</body>
</html>
I expect to have 2 buttons which display 2 categories, the text should toggle according to which button has been clicked.
Could put the description in an attribute, then get the attributes value on click and change the html of the description. Here is a jsFiddle
<div>
<button class="js-button default-button" data-description="Category A's Description" onclick="myFunction(this)">
Category A
</button>
<button class="js-button default-button" data-description="Category B's Description" onclick="myFunction(this)">
Category B
</button>
</div>
<div id="js-description" class="description">
</div>
<script>
function myFunction(elem) {
var x = document.getElementById("js-description");
var description = elem.getAttribute('data-description');
x.innerHTML = description;
var button = document.getElementsByClassName('js-button');
for (var i = 0; i < button.length; i++) {
button[i].classList.remove('active-button');
}
elem.classList.add('active-button');
}
</script>
<style>
.default-button{
font-size:16px;
border-radius: 4px;
padding:7px 12px;
}
.active-button{
background:blue;
color:#fff;
}
.description{
margin-top:20px;
}
</style>
I don't really like all these solutions because everything is written from JS but contents probably come from database. So here is my solution :
// Native JS version
// Working Fiddle : https://jsfiddle.net/d34cbtw7/
var togglers = document.querySelectorAll('[data-toggle="tab"]');
for (var i = 0; i < togglers.length; i++) {
togglers[i].addEventListener('click', function() {
var tabs = document.querySelectorAll('.tab');
for(var j = 0; j < tabs.length; j++) {
tabs[j].classList.remove('active');
}
var $target = document.querySelector(this.getAttribute('data-target'));
$target.classList.add('active');
});
}
// jQuery version
$('body').on('click', '[data-toggle="tab"]', function(e) {
e.preventDefault();
// Select our target
var $target = $($(this).data('target'));
// Hide all tabs
$('.tab-contents .tab').removeClass('active');
// Show only $target tab
$target.addClass('active');
});
.tab-contents .tab {
display: none;
}
.tab-contents .tab.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-toggle="tab" data-target="#cat-A-content">
Cat A
</button>
<button data-toggle="tab" data-target="#cat-B-content">
Cat B
</button>
<div class="tab-contents">
<div class="tab active" id="cat-A-content">
My category A contents
</div>
<div class="tab" id="cat-B-content">
My category B contents
</div>
</div>
I also don't really like "onclick" attribute in HTML...
I've made a quick codepen as example.
You can achieve this by passing a parameter to the onClick function. In this example I keep track of the last button clicked, and the text it should render. If the last button clicked was the same button, the switched back to default. I hope this helps.
https://codepen.io/maffekill/pen/rbpjzw
HTML
<p>Click the button to swap the text of the DIV element:</p>
<p><button onclick="myFunction(1, 'TEXT A')">TEXT A</button></p>
<p><button onclick="myFunction(2, 'TEXT B')">TEXT B</button></p>
<div id="myDIV">Default Text</div>
JS
// Keep track of the button currently clicked
var activeBtn = null;
function myFunction(btnId, text) {
var x = document.getElementById("myDIV");
// If the last button is the same as the new one, show default text
if (activeBtn === btnId) {
x.innerHTML = "Default Text";
activeBtn = null
} else {
// Else show the text given to the text param
x.innerHTML = text;
activeBtn = btnId;
}
}
There are multiple ways to achieve this, but the easiest way I could come up with to explain this to you would be as following:
function myFunction(myEle) {
var x = document.getElementById("myDIV");
x.innerHTML = "This is category " + myEle.value;
}
<p>Click the button to swap the text of the DIV element:</p>
<p>
<button onclick="myFunction(this)" value="a">
Category A
</button>
<button onclick="myFunction(this)" value="b">
Category B
</button>
</p>
<div id="myDIV">Hello</div>
JSFiddle
No need to overcomplicate things.
Firstly you would like to send the clicked element from the caller (which in this case would be the clicked element as well, the <button> element). You could use JavaScript's thisfor this purpose.
Within your function you can name a parameter between parenthesis, so in my example above: function myFunction() contains a parameter called myEle so it will look like: function myFunction(myEle). Once the function will be triggered, the parameter called myEle will be set to the clicked element (or
JavaScript's this). You can simply access any of its attributes like value by using a dot: myEle.value.
Knowing the above, you could apply it to whatever you require your function to do (refer to my example code above).

Display user input to a different Div on button click

Currently on button click, I'm able to display the user input from inside the textbox, but it's displayed inside the same Div every time.
Textbox and the button (HTML file)-
<input type="text" name="inputText"><br>
<tr>
<input type="button" value="ADD" ng-click="$ctrl.addtext()">
</tr>
<div id="outputDiv"></div>
JS function-
ctrl.addtext = function () {
var div = document.getElementById('outputDiv');
div.innerHTML += newtext+"\n";
}
How can I get the user input in a different Div and a newline every time?
EDIT: A similar question has been asked for JQuery and it's JS is-
$('#submit').click(function() {
var text = $('#input').val();
$('#newDivs').append('<div>' + text + '</div>');
});
How can I do that append in Angular?
Got it to work using this in the JS function-
div.innerHTML += "<div>"+newtext+"</div>\n";
Instead of-
div.innerHTML += newtext+"\n";
Reference (solved for Jquery)-
Create/Display a new Div each time text is submitted by a user

Script working in major browsers but not IE8

I hace some code that adds dynamic input boxes on a click. In all of the major browsers, it works fine. But in IE8 it does nothing. There are no errors being reported and developer tools shows no errors either. should this code work with IE8. Thanks
jQuery 1.7.1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
Script an doctype in the head section.
<script type="text/javascript">
$(function() {
var MaxInputs = 7; //maximum input boxes allowed
var InputsWrapper = $("#INTKInputsWrapper"); //Input boxes wrapper ID
var AddButton = $("#INTKAddMoreFileBox"); //Add button ID
var x = InputsWrapper.length; //initlal text box count
var FieldCount=1; //to keep track of text box added
$(AddButton).click(function (e) //on add input button click
{
if(x <= MaxInputs) //max input box allowed
{
FieldCount++; //text box added increment
//add input box
$(InputsWrapper).append('<div><input type="text" name="box_add[]'+FieldCount+'" required="required" " /><img src="/domain/users/css/images/redclose.png" style="margin-left: 10px; margin-right:10px;" /><span style="margin-left:2px;font-size:10px;color: grey;">Remove</span></div>');
x++; //text box increment
}
return false;
});
$("body").on("click",".removeclass", function(e){ //user click on remove text
if( x > 1 ) {
$(this).parent('div').remove(); //remove text box
x--; //decrement textbox
}
return false;
})
});
</script>
HTML relevant code
<fieldset>
<legend>Input box reference(s)</legend>
Add More Boxes<span style="margin-left:10px;font-size:10px;color: grey;">( Maximum 8 )</span>
<div id="INTKInputsWrapper">
<input name="box_add[]" type="text" required="required />
<a style="margin-left: 14px;" href="javascript:void(0)" class="boxhelp">Help</a>
</div>
</fieldset>

Implementing toggles on more than one div

I have a div which I want to toggle show on button click.
Here's the HTML structure :
<div>
<button onclick="toggle()"> Show </show>
<div id="toggle"> </div>
</div>
The script for this would be :
var div = document.getElementById("toggle");
if(div.style.display=="none" ||div.style.display == ""){
div.style.display="block" }
else{
div.style.display="none";
}
This works fine but what I I have multiple button-div combo ? Obviously I will have to use different id for each div but how will I get this id inside the function ? Or is there any other way ?
Also is this the right way to do it ? Using multiple id's for each div ? Is there any other way to implement such a system?
function toggle(id) {
var div = document.getElementById(id);
if(div.style.display=="none" ||div.style.display == ""){
div.style.display="block" }
else{
div.style.display="none";
}
}
And in your HTML
<div>
<button onclick="toggle('toggle')"> Show </show>
<div id="toggle"> </div>
</div>