jQuery Serialize working intermittently with Bootstrap radio button group - javascript

I'm trying to serialize a radio-button when the Bootstrap .btn label is clicked.
HTML:
<div class="btn-group" data-toggle="buttons">
<label label-default="" class="btn btn-primary">
<input id="option1" name="options" type="radio" value="1">Option 1</label>
<label label-default="" class="btn btn-primary active">
<input id="option2" name="options" type="radio" value="1">Option 2</label>
<label label-default="" class="btn btn-primary">
<input id="option3" name="options" type="radio" value="1">Option 3</label>
</div>
jQuery:
$(".btn").on('click', function(){
console.log("Name: " + $(this).children('input').attr('name') );
console.log("Value: " + $(this).children('input').val() );
console.log("Serialized: " + $(this).children('input').serialize() );
})
The name and value are always present in my output but the serialization works intermittently (sometimes returning the serialzed value and sometimes returing an empty string) and I can't figure out why.
Demo here: http://www.bootply.com/86422#
Thanks!

You should really read ALL of the documentation on jQuery's .serialize() function if you are having issues.
From the .serialize() API :
Note: Only "successful controls" are serialized to the string. No submit button value is serialized since the form was not submitted using a button. For a form element's value to be included in the serialized string, the element must have a name attribute. Values from checkboxes and radio buttons (inputs of type "radio" or "checkbox") are included only if they are checked. Data from file select elements is not serialized.
Now from W3's documentation on successful controls :
For radio buttons that share the same value of the name attribute, only the "on" radio button may be successful.
All of that explains exactly why it works intermittently. Because sometimes you happen to check the radio button so it is considered "on" and your function serializes that input button.
Here is a workaround :
Instead of using a input of type radio button, just use a plain input and set the display to none.
<div id="mode-group" class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input name="mode" id="option1" value="cash/check" style="display: none">Cash / Cheque / Bank Transfer</label>
<label class="btn btn-primary">
<input name="mode" id="option2" value="jobsBuddy" style="display: none">JobsBuddy Disbursement</label>
</div>
Bootply Demo

jQuery .serialize() and .serializeArray() will only parse buttons which are checked. These are known as "successful controls", as mentioned in the jQuery documentation.
If you'd like to use a Bootstrap button group where all buttons are unchecked (as seen in your question), then you should consider "What if a user never checks any of the buttons?".
Therefore, you should include a hidden button which is checked by default, so that at least one of the buttons in your button group is parsed by .serialize() or .serializeArray().
<form>
<div class="form-group">
<!--
This hidden checked button (with value 'none')
will ensure that `serialize` parses at least one
input in the button group.
-->
<input class="hidden" type="radio" name="color" value="none" checked>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default">
<input type="radio" name="color" value="blue" />
<span>Blue</span>
</label>
<label class="btn btn-default">
<input type="radio" name="color" value="green" />
<span>Green</span>
</label>
</div>
</div>
</form>

Related

How to validate bootstrap radio buttons

I am trying to validate this section of the form but whichever button is selected, option1 returns false. How can I get each radio to have different values when they are active/inactive or alternatively get a value from the button-group?
$(function register(){
$('.err').hide();
$("#submit").click(function() {
if ($('#option1').prop("checked", false)){
$("#fcerr").show();
}
if ($('#option1').prop("checked")){
$("#fcerr").hide();
}
});
});
<div class="btn-group btn-group-justified btn-group-sm" data-toggle="buttons">
<label id="lopt1" class="btn btn-primary">
<input type="radio" name="option1" id="option1" autocomplete="off"> Staff
</label>
<label id="lopt2" class="btn btn-primary">
<input type="radio" name="option2" id="option2" autocomplete="off"> Client
</label>
</div>
<div><label class="err" id="fcerr">Error Message</label></div>
<input name="register" type="submit" value="Register" class="btn btn-primary btn-lg btn-block" id="submit">
I have also tried getting the values of the radio boxes but they are always "on" regardless of which radio is active.
var client = $("#option2").val();
alert(client);
With your code:
if ($('#option1').prop("checked", false)){
$("#fcerr").show();
}
You are actually setting the property "checked" to be false, everytime. After that is done the if statement recieves a truthy value so it will execute what's inside the if block.
Try your validation like this instead:
if($('#option1').is(':checked')){
//...
}
Also, if you want your inputs to actually behave as a group (meaning only one can be checked at a given time) you have to share the same name attribute, you can update your html to:
<label id="lopt1" class="btn btn-primary">
<input type="radio" name="myOptions" id="option1" autocomplete="off"> Staff
</label>
<label id="lopt2" class="btn btn-primary">
<input type="radio" name="myOptions" id="option2" autocomplete="off"> Client
</label>
A few things:
You didn't include a javascript framework in your code snippet, though your question is tagged with jQuery.
The 4th line if ($('#option1').prop("checked", false)){ is changing the value that you're trying to evaluate.
The option elements should share the same name attribute if you want to treat them as a group that can be validated

unselect Radio Button and Disable Submit when all inputs are empty

We have an interactive map which connects over PHP to an database.
Since i'm pretty new to javascript i have some question.
We have around 15 text input and one dropdown input.
I only provide the Problematic parts of our code.
HTML
<div class="nav nav-sidebar">
<form action="./action_page.php" method="post">
<ul class="dropdown-item" id="u3">
<div data-toggle="buttons">
<label class ="btn btn-default" style="float:left;">
<input type="radio" class="btn btn-default" name="politic" id="politic" value="2"> Trump
</label>
<label class ="btn btn-default" style="margin-bottom:10px; margin-right: 20%; float:right;">
<input type="radio" class="btn btn-default" name="politic" id="politic" value="1"> Hillary
</label>
</div>
</ul>
<button input type="submit" id="submit-button" class="submit-button" value="Submit">Submit</button>
</form>
<button type="button" onclick="test()" class="clear-button">Reset</button>
</div>
JS
function test(){
$('input[name="politic"]').prop('checked', false);
}
How can I disable the Submit button if atleast 1 input is emtpy?
My test() function resets the value of "poltics" but the Button is still selected. How can I fix this?
I would appreciate to not get the working code, more like a guideline how to start on this Problem, or if you want to provide code, I would appreciate some shorts explanation.
I have added example with 3 input fields that will be empty till all of them are filled.. also for radios I have added class removal that was missing,,
hope that helps, cheers
EDIT: try now..
EDIT2: try now :)
function checkallinputs(){
var ch = false;
$('form input[type="text"]').each(function(el){
if( $(this).val() != '' ) ch = true; return false;
});
if( ch ){ $('button[type="submit"]').removeClass('disabled'); return true; }
if(!ch ){ $('button[type="submit"]').addClass('disabled'); return false; }
}
// run this on document.ready or in (function())() self exe block on page
checkallinputs();
$('form input[type="text"]').on( 'change', function(){ checkallinputs(); });
// disable submit
$( 'form' ).on( 'submit', function(){ return checkallinputs(); });
// reset radio ==>remove class
function test(){
$('input[name="politic"]').prop('checked', false);
$('input[name="politic"]').parent().removeClass('active');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<form action="./action_page.php" method="post">
<div class="form-group">
<label for="input1">Input 1</label>
<input type="text" class="form-control" id="input1">
</div>
<div class="form-group">
<label for="input2">Input 2</label>
<input type="text" class="form-control" id="input2">
</div>
<div class="form-group">
<label for="input3">Input 3</label>
<input type="text" class="form-control" id="input3">
</div>
<div class="checkbox">
<div data-toggle="buttons">
<label class ="btn btn-default" style="float:left1;">
<input type="radio" class="btn btn-default" name="politic" id="politic1" value="2"> Trump
</label>
<label class ="btn btn-default" style="margin-bottom:10px; margin-right: 20%; float:right;">
<input type="radio" class="btn btn-default" name="politic" id="politic2" value="1"> Hillary
</label>
</div>
</div>
<button type="submit" class="btn btn-default disabled">Submit</button>
<br>
<button type="button" onclick="test()" class="btn btn-default">Reset</button>
</form>
How can I disable the Submit button if atleast 1 input is emtpy?
There are a few ways you can get this done.
Number One:
The easiest way is to add in the required attribute to the field, and the user would not be able to submit the form unless all required field are filled up. This is not the recommended way though as it depends on the browser and I believe there are work arounds for this.
<input type="text" name="username" required>
Number Two:
Another way is to add an onkeyup event handler to all your inputs, which calls a function where you check if all the inputs are filled up. Here, by default, you have your submit button disabled, and when all the inputs are filled, you can enable your submit button. This is not the best way since the user might not know why the button is disabled unless you specifically give a feedback, like making the borders red for invalid fields. Also running the validation after every keyup might be demanding for the application.
Number Three:
The one which I would prefer and recommend is this. You can leave the submit button enabled, and bind it to a click event where you check whether your validation is satisfied, that is, for your case you check if any input is empty and if one is empty, then you don't submit the form and display an alert or give the user a feedback to fill in the field. You might want to set focus to an empty field too.
My test() function resets the value of "poltics" but the Button is
still selected. How can I fix this?
What did you mean by "the button is still selected"? The Reset button? You can set focus to another input of your choice if you want
$(.'input-name').focus();
How can I disable the Submit button if atleast 1 input is emtpy?
You just need to keep trace of the change events of the inputs, like the following. If an input is checked, then you have to re-enable the submit button. If the reset button is used, you need to disable the submit button. This button can be disabled by default.
My test() function resets the value of "poltics" but the Button is still selected. How can I fix this?
As you provided your code, the radio buttons for both politicians successfully deselected.
function test(){
$('input[name="politic"]').prop('checked', false);
$('#submit-button').prop('disabled', true);
}
$('input[type="radio"]').on('change', function () {
// Here we set the button to not disabled if the radio was selected
$('#submit-button').prop('disabled', !$(this).prop('checked'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav nav-sidebar">
<form action="./action_page.php" method="post">
<ul class="dropdown-item" id="u3">
<div data-toggle="buttons">
<label class ="btn btn-default" style="float:left;">
<input type="radio" class="btn btn-default" name="politic" id="politic" value="2"> Trump
</label>
<label class ="btn btn-default" style="margin-bottom:10px; margin-right: 20%; float:right;">
<input type="radio" class="btn btn-default" name="politic" id="politic" value="1"> Hillary
</label>
</div>
</ul>
<button type="submit" id="submit-button" class="submit-button" value="Submit" disabled>Submit</button>
</form>
<button type="button" onclick="test()" class="clear-button">Reset</button>
</div>

I can't get jQuery to work with Bootstrap buttons

Put simply: my goal is to have two buttons on a page, so that "1" is displayed when the first is pressed, and "2" is displayed when the second is pressed. This works with radio input, but when I add a button label from Twitter Bootstrap, it no longer works.
First, here is the jquery I am using. I am trying to change the value of the span to the value of the button pressed:
<span id="val">0</span>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(function() {
$('input[type=radio]').click(function() {
$("#val").html($(this).val());
});
});
</script>
It works fine with this:
<input type="radio" Id="Radio1" value="1" name="a">
<input type="radio" Id="Radio2" value="2" name="a">
But when I do this, it no longer works (I can see and press the buttons, but the value of span remains at 0):
<div class="btn-group" data-toggle="buttons">
<label type="button" for="Radio1" class="btn btn-primary active">
<input type="radio" Id="Radio1" value="1" checked>
</label>
<label type="button" for="Radio2" class="btn btn-primary">
<input type="radio" Id="Radio2" value="2">
</label>
</div>
It seems to me like the label tags are causing a problem, but I am unsure why. Removing the labels makes it work, but I need the button labels.
Place the click event on labels, then find the value on its "input" children:
$(function() {
$('div.btn-group label').click(function() {
$("#val").html($(this).children('input').val());
});
});
JsFiddle: https://jsfiddle.net/5vh3yzzq/1/

How to change elements(img's) position via radio buttons?

I got an image positioned in container and 3 radio buttons. I would like to add another images appear over the container main image when some of the radio buttons is chosen. Each of the buttons will have different positions of the images shown when they are active.
So far I got that:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default">
<input type="radio" id="q156" name="quality[25]" value="1" /> 1
</label>
<label class="btn btn-default">
<input type="radio" id="q157" name="quality[25]" value="2" /> 2
</label>
<label class="btn btn-default">
<input type="radio" id="q158" name="quality[25]" value="3" /> 3
</label>
</div>
</div>
</div>
<div class="col-md-8 col-fl">
<div id="img_box">
<img style="width: 100%;" src="img/other/rounded_corners.png" />
</div>
You could add the image sources as data attr. to the radio button.
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default">
<input type="radio" id="q156" name="quality[25]" value="1" data-img="http://placehold.it/350x150/ff0000" /> 1
</label>
<label class="btn btn-default">
<input type="radio" id="q157" name="quality[25]" value="2" data-img="http://placehold.it/350x150/00ff00"/> 2
</label>
<label class="btn btn-default">
<input type="radio" id="q158" name="quality[25]" value="3" data-img="http://placehold.it/350x150/0000ff" /> 3
</label>
</div>
<div class="col-md-8 col-fl">
<div id="img_box"></div>
The img box is empty but size and image are set by css:
#img_box{
width: 350px;
height: 150px;
background: url('http://placehold.it/350x150/ff0000')
}
Then add a event that append a img overlay on click (using source from radio buttons):
$(function(){
$('input[type=radio]').click(function(){
$this = $(this)
$img_box = $('#img_box')
$overlay = $('<img/>').attr('src',$this.data('img'))
$img_box.html('').append($overlay)
});
})
See this example: https://jsfiddle.net/fmytsjv7/1/
You can achieve that using jQuery, and binding event handler to your radio buttons.
Like this one:
$('input:radio[name="quality[25]"]').change(function(){ });
Then add the handler to alter the attributes/css properties of the target image container or the image element directly.
You can use jQuery .css() to alter css properties of your target element
Like:
$("#img_box").css({"height":"100px","width":"100px",background:"red"});
While, you can use jQuery .attr() to alter the attributes of your target element.
Like: (in this case its the img's "src" attribute)
$("#img_box > img").attr("src","path/to/whatever/image");
HERE'S A SAMPLE IN JSFIDDLE
I see that you included jQuery tag in your question, so I assume you are interested in jQuery based solution.

Bootstrap - btn-group, data-toggle="buttons" : how to select a button with JS and deselect all others?

Hi, I'm using Bootstrap's .btn-group class like this:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default active">
<input type="radio" name="radio-popup-position" id="radio-popup-style-1" checked>button-1
</label>
<label class="btn btn-default">
<input type="radio" name="radio-popup-position" id="radio-popup-style-2">button-2
</label>
<label class="btn btn-default">
<input type="radio" name="radio-popup-position" id="radio-popup-style-3">button-3
</label>
<label class="btn btn-default">
<input type="radio" name="radio-popup-position" id="radio-popup-style-4">button-4
</label>
In my app I need to "manually" select a button with JS and currently I'm doing it like this:
$('#radio-popup-style-rect-1').parent().addClass('active');
$('#radio-popup-style-rect-1').get(0).checked = true;
$('#radio-popup-style-rect-2').removeAttr('checked').parent().removeClass('active');
$('#radio-popup-style-rect-3').removeAttr('checked').parent().removeClass('active');
$('#radio-popup-style-rect-4').removeAttr('checked').parent().removeClass('active');
... times four, for each case that I need to select one of the buttons. That's not such a big deal if I have just 4 buttons, but now I need to have 13. Which means a lot of code.
My questions - does Bootstrap have a function that I can call to select a button and automatically deselect other buttons from the same group?
Cheers
You can use the attribute selector
$('[id*="radio-popup-style-"]').click(function(){
$(this).prop('checked', true).parent().addClass('active');
$('[id*="radio-popup-style-"]').not($(this)).removeAttr('checked').prop('checked', false).parent().removeClass('active');
});
JSFIDDLE: http://jsfiddle.net/TRNCFRMCN/6o1k1cvo/1/.
About regex in attribute selector: http://www.thegeekyway.com/css-regex-selector-using-regular-expression-css/.
You can use built-in BS method to toogle button state:
(you need default button.js on your page)
https://github.com/twbs/bootstrap/blob/master/js/button.js#L52-L66
http://getbootstrap.com/javascript/#buttons
$('#the-button-id-you-need').button('toggle');
There is no such function/method. However this is unnecessary.
Use class attribute instead of id. Then the code become much simpler:
HTML:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default active">
<input type="radio" name="radio-popup-position" class="radio-popup-style" checked>button-1
</label>
<label class="btn btn-default">
<input type="radio" name="radio-popup-position" class="radio-popup-style">button-2
</label>
<label class="btn btn-default">
<input type="radio" name="radio-popup-position" class="radio-popup-style">button-3
</label>
<label class="btn btn-default">
<input type="radio" name="radio-popup-position" class="radio-popup-style">button-4
</label>
JS:
var aEls = $('.radio-popup-style-rect');
aEls.prop('checked', false).parent().removeClass('active');
aEls.eq(0).prop('checked', true).parent().addClass('active');
$("body").on("click", "label.btn", function(){$(this).find("input")[0].click();});

Categories