Trouble with binding events to Bootstrap 3 (button.js) button radios - javascript

I'm having trouble getting the correct value from a segmented control I made with the radio button component of button.js in Twitter Bootstrap 3. When I bind a click event to the segmented control that runs $.serialize() on the parent form, it return the unchecked value of the radio button along with all the other correct values from the other inputs.
I suspect it might be related to the fact that I can't bind this event directly to the segmented control's input. When I tried to bind the event directly to the input I didn't get a response back, so I bound it to the label.
Here's an example of the problem in a fiddle: https://jsfiddle.net/stevekas/9w94pL4o/
<form id="form">
<div id="radios">
<div class="radio">
<label class="major-category">
<input facet="exclusive" type="radio" name="hipsum" value="hashtag" />hashtag</label>
</div>
<div class="radio">
<label class="major-category">
<input facet="exclusive" type="radio" name="hipsum" value="farm-to-table" />farm-to-table</label>
</div>
<div class="radio">
<label class="major-category">
<input facet="exclusive" type="radio" name="hipsum" value="gastropub" />gastropub</label>
</div>
</div>
<!--/ #radios -->
<div id="segmented-control" class="btn-group btn-group-justified" data-toggle="buttons">
<label class="btn btn-default active">
<input type="radio" name="segmented-control" id="roof" value="roof" autocomplete="off" checked />roof</label>
<label class="btn btn-default">
<input type="radio" name="segmented-control" id="party" value="party" autocomplete="off" />party</label>
</div>
<!--/ #segmented-control -->
</form>
<script>
$('.radio input').on('click', function () {
var data = $('#form').serialize();
});
$('#segmented-control label').on('click', function () {
var data = $('#form').serialize();
});
</script>

It probably happens because the click for the label is processed before the click for the input (the label is higher in the DOM tree).
You can force debug to be called after all the events have been processed using setTimeout() without any delay, like this:
$('#segmented-control label').on('click', function () {
setTimeout(function() {
debug();
}, 0);
});
This works because setTimeout() enqueues a new event, which will be run after all the current pending ones.

Related

Simulate multiple form clicks with javascript

I have a product page on my website with product options, two with sub options. For those options with sub options they are using type="radio"
I've created javascript buttons which emulate clicking those sub options. I'd like to set up clearing the form and emulating the clicks all on one button. Currently I have a separate clear button, which still doesn't work.
Picture Example: http://i.imgur.com/uAlLBAK.jpg
Code examples below
Sub option code:
<li class="option">
<label for="09f0c74f3d92847ecfcf5837eb6b2f8b">
<input type="radio" class="validation" name="attribute[249]" value="127" id="09f0c74f3d92847ecfcf5837eb6b2f8b"/>
<span class="name">65cc</span>
</label>
</li>
<li class="option">
<label for="06fc48a0a3949a17c28162ea0eb1f406">
<input type="radio" class="validation" name="attribute[249]" value="128" id="06fc48a0a3949a17c28162ea0eb1f406"/>
<span class="name">75cc</span>
</label>
</li>
First button:
<input onclick="document.getElementById('06fc48a0a3949a17c28162ea0eb1f406').click(); document.getElementById('a596a2e871da26ba9b1cf7fffe325848').click();" type="button" value="0911" />
Second button:
<input onclick="document.getElementById('09f0c74f3d92847ecfcf5837eb6b2f8b').click(); document.getElementById('a596a2e871da26ba9b1cf7fffe325848').click();" type="button" value="0916" />
Clear options:
<input onclick="Clear();" type="button" value="Clear" />
<script type="text/javascript">// <![CDATA[
function Clear()
{
clearRadioGroup("09f0c74f3d92847ecfcf5837eb6b2f8b");
clearRadioGroup("a596a2e871da26ba9b1cf7fffe325848");
}
function clearRadioGroup(GroupName)
{
var ele = document.getElementsById(GroupName);
for(var i=0;i<ele.length;i++)
ele[i].checked = false;
}
// ]]></script>
In the above example the second button click would un-select the second element if the buttons were clicked in succession. Thoughts on at the very least being able to clear the form?
There is a typo in function clearRadioGroup. It should be
"var ele = document.getElementById(GroupName);" and not
"var ele = document.getElementsById(GroupName);".
The Clear function will work then.

Javascript/Ajax/Jquery Dynamically calculation form on change

I have a small form which is going to be populated from Mysql database and human input. What I want to do is calculate 2 other fields based on the other ones.
Example Form:
Indicator (MySQL) (a dropdown)
Hour Equivalent (MySQL)
SKS Equivalent (MySQL)
Amount (User)
Hour Total (Amount*Hour Equivalent)
SKS Total (Amount*SKS Equivalent)
Submit (Button to save into table)
This is an example for the calculation operation that I try to solve
Indicator = A
Hour Equivalent = 20
SKS Equivalent = 15
Amount = 2
Hour Total (Amount*Hour Equivalent) = 40
SKS Total (Amount*SKS Equivalent) = 30
I have searched around and try some of solutions but I can’t quite find what I am looking for, and my skills are not really good in Javascript/Ajax/Jquery so I haven't able to do anything to work, although I have tried miserably.
How to do it?
This is the HTML Form
<form>
<fieldset>
<legend>PSC Achievement</legend>
<!-- Button Drop Down -->
<div class="form-group">
<label for="buttondropdown">Indicator</label>
<button type="button" data-toggle="dropdown">
Choose
<span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right">
</ul>
</div>
<label for="txtsks">SKS Equivalent</label>
<input id="txtsks" name="txtSks" type="text">
<label for="txtjam">Hour Equivalent </label>
<input id="txtjam" name="txtHour"type="text">
<label for="textjml">Amount</label>
<input id="textjml" name="txtAmount" type="text">
<label for="Totalhour">Hour Total</label>
<input id="Totalhour" name="Totalhour" type="text">
<label for="Totalsks">SKS Total</label>
<input id="Totalsks" name="Totalsks" type="text">
<label for="btn_submit"></label>
<button id="btn_submit" name="btn_submit">Submit</button>
</fieldset>
</form>
Your solution here : https://jsfiddle.net/tv94prmu/ . Calc function is a result of change event. Result will be displayed after one of fields will be filled
$(function(){
$('#txtsks,#txtjam,#textjml').change(function(){
calc();
})
function calc(){
$('#Totalhour').val(parseInt($('#txtjam').val())*parseInt($('#textjml').val()))
$('#Totalsks').val(parseInt($('#txtsks').val())*parseInt($('#textjml').val()))
}
})
Also, you need to include jquery library to page.
If i got your answer correctly.
Your need to provide more info about your code, but, as far as i understood.. u need to add event handlers for your form (as shown below).
Please note that you have set some of the id's of your elements with an uppercase and some with camelCase. which is bad practice, for better practie, decide on a pattern that you are working at.
It will be easier to handle when you are getting back to your code in the future.
txtsks.addEventListener("blur", function( event ) {
/* call SKS Equivalent function */
}, true);
txtjam.addEventListener("blur", function( event ) {
/* call Hour Equivalent function */
}, true);
textjml.addEventListener("blur", function( event ) {
/* call Amount (User) function */
}, true);
Totalhour.addEventListener("blur", function( event ) {
/* call Hour Total (Amount*Hour Equivalent) function */
}, true);
Totalsks.addEventListener("blur", function( event ) {
/* call SKS Total (Amount*SKS Equivalent) function */
}, true);
btn_submit.addEventListener("click", function ( event ) {
/* call Submit(Button to save into table) function */
});
<form>
<fieldset>
<legend>PSC Achievement</legend>
<!-- Button Drop Down -->
<div class="form-group">
<label for="buttondropdown">Indicator</label>
<button type="button" data-toggle="dropdown">
Choose
<span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right">
</ul>
</div>
<label for="txtsks">SKS Equivalent</label>
<input id="txtsks" name="txtSks" type="text">
<label for="txtjam">Hour Equivalent </label>
<input id="txtjam" name="txtHour"type="text">
<label for="textjml">Amount</label>
<input id="textjml" name="txtAmount" type="text">
<label for="Totalhour">Hour Total</label>
<input id="Totalhour" name="Totalhour" type="text">
<label for="Totalsks">SKS Total</label>
<input id="Totalsks" name="Totalsks" type="text">
<label for="btn_submit"></label>
<button id="btn_submit" name="btn_submit">Submit</button>
</fieldset>
</form>

Javascript check bootstrap checkbox by id

I have the following form :
<form class="form-inline" role="form">
<div class="col-xs-3">
<div class="pic-container">
<div class="checkbox">
<label>
<input type="checkbox" name="discounting" onchange='handleChange(this);' id='check11' > Show only price-discounted products
</label>
</div>
</div>
</div>
<div class="col-xs-3">
<div class="pic-container">
<div class="checkbox" id='check21'>
<label>
<input type="checkbox" name="discounting" onchange='' id='check21'> Show only price-discounted products
</label>
</div>
</div>
</div>
</form>
I'd like to be able to check the second checkbox automatically with JavaScript once I check the first one. I tried using the following script :
<script>
function handleChange(cb) {
if(cb.checked == true) {
alert('Message 1');
document.getElementById("check21").checked = true;
} else {
alert('Message 2');
var x = document.getElementById("check21").disabled= false;
}
}
</script>
But it doesn't work since I think with bootstrap is a question of classes.
The problem as Didier pointed out is that you have two elements with the same ID:
<div class="checkbox" id='check21'>
and
<input type="checkbox" name="discounting" onchange='' id='check21'>
The call to document.getElementById('check21') will probably (because the behavior is undefined) return the first one, which in this case is the <div> element, not the checkbox.
You must not use the same ID on two HTML elements, so you need to change the ID on one or the other of them.
http://jsfiddle.net/uywaxds5/2/
I included boostrap as an external reference.
<div class="checkbox" id='check22'>
<label>
<input type="checkbox" name="discounting" onchange='' id='check21'> Show only price-discounted products
</label>
</div>
Fixing the duplicate id seems to work.
If it does not works, the issue might be in another part of your code.
Use a different name for the second radio button
<input type="checkbox" name="discounting21">
There can only be one selected radio button belonging to the same group(ie. name).

Disable radio button in bootstrap 3?

How can I disable Bootstrap 3 radio buttons? If I start with the BS3 example and add disabled="disabled" to each input element, there are no changes in appearance or behavior:
<div class="container">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked disabled="disabled">Radio 1 (preselected)</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2" autocomplete="off" disabled="disabled">Radio 2</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3" autocomplete="off" disabled="disabled">Radio 3</label>
</div>
Demo: JSFiddle.
I guess this is because the disabled attribute is only applied to the now-invisible button and not the clickable text label, but I don't see anything in the BS3 docs about this.
Add disabled class to the label like this
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 1 (pre-checked)
</label>
<label class="btn btn-primary active disabled">
<input type="checkbox" autocomplete="off"> Checkbox 2
</label>
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 3
</label>
</div>
Here is a demo
As mentioned by #giammin in the comments to the accepted answer, setting 'disabled' on the input elements doesn't work in 3.3.6 of bootstrap. (Current version at time of publication of this answer).
I was having exactly the same issue, and my solution was to use the CSS property "pointer events". This makes sure the element and children are never a target of click events. However this is not a foolproof solution - users can still tab in and use space to click the hidden elements on a desktop browser.
.disabled-group
{
pointer-events: none;
}
If you set this on your '.btn-group' element, you'll completely disable
<div class="btn-group disabled-group" data-toggle="buttons">
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 1 (pre-checked)
</label>
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 2
</label>
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 3
</label>
</div>
The '.disabled' class is then optional - use it for graying out and 'cursor: not-allowed;' property.
The discussion of the fix solution is at this source:
https://github.com/twbs/bootstrap/issues/16703
For radio button groups, add class disabled to the one you wish disabled.
Make sure you have something like this code:
$('.btn-group').on("click", ".disabled", function(event) {
event.preventDefault();
return false;
});
This will get all your .disabled classed buttons inside the button groups also disabled. This works also for radio type button groups.
You can use the above to disable an input[type='radio'] that is inside a label (bootstrap 3 style),
$("input[name='INPUT_RADIO_NAME']").prop("disabled", true);
$("input[name='INPUT_RADIO_NAME']").closest("div").css("pointer-events", "none");
The above to enable again,
$("input[name='INPUT_RADIO_NAME']").prop("disabled", false);
$("input[name='INPUT_RADIO_NAME']").closest("div").css("pointer-events", "auto");
You can also extend JQuery and create a dummy disable method (that you could upgrade with more functionality) like this,
(function ($) {
$.fn.disableMe = function () {
// Validate.
if ($.type(this) === "undefined")
return false;
// Disable only input elements.
if ($(this).is("input") || $(this).is("textarea")) {
// In case it is a radio inside a label.
if ($(this).is("[type='radio']") && $(this).parent().is("label.btn")) {
$("input[name='safeHtml']").closest("label").addClass("disabled");
$(this).closest("div").css("pointer-events", "none");
}
// General input disable.
$(this).prop("disabled", true);
}
};
$.fn.enableMe = function () {
// Validate.
if ($.type(this) === "undefined")
return false;
// Enable only input elements.
if ($(this).is("input") || $(this).is("textarea")) {
// In case it is a radio inside a label.
if ($(this).is("[type='radio']") && $(this).parent().is("label.btn")) {
$("input[name='safeHtml']").closest("label").removeClass("disabled");
$(this).closest("div").css("pointer-events", "auto");
}
// General input enable.
$(this).prop("disabled", false);
}
};
$.fn.toggleDisable = function () {
if ($.type(this) === "undefined")
return false;
// Toggle only input elements.
if ($(this).is("input") || $(this).is("textarea")) {
var isDisabled = $(this).is(":disabled");
// In case it is a radio inside a label.
if ($(this).is("[type='radio']") && $(this).parent().is("label.btn")) {
$("input[name='safeHtml']").closest("label").toggleClass("disabled");
$(this).closest("div").css("pointer-events", isDisabled ? "auto" : "none");
}
// General input enale.
$(this).prop("disabled", !isDisabled);
}
};
}(jQuery));
Usage example,
$("input[name='INPUT_RADIO_NAME']").disableMe();
$("input[name='INPUT_RADIO_NAME']").enableMe();
$("input[name='INPUT_RADIO_NAME']").toggleDisable();
In bootstrap if you want to disabled any input type or button, You just have to add bootstrap's .disabled class then your button become disabled.
Like this
<input type="radio" class="btn btn-primary disabled">Primary Button</button>

Getting active buttons in button-group (bootstrap)

I have a button group and am willing to update some other field on change according to the active buttons.
See the jsfiddle here
This is the HTML, copied from the documentation:
<div class="btn-group arrActiviteit arrUpdate" data-toggle="buttons">
<label class="btn btn-primary active" data-wat='foo'>
<input type="checkbox"> Item 1
</label>
<label class="btn btn-primary" data-wat='bar'>
<input type="checkbox"> Item 2
</label>
<label class="btn btn-primary" data-wat='something'>
<input type="checkbox"> item 3
</label>
<label class="btn btn-primary" data-wat='orElse'>
<input type="checkbox"> item 4
</label>
</div>
The Button row acts like it should do.
Then I watch for a click event on the .arrUpdate div for change. I've got multiple button groups which all have the .arrUpdate class. That's the reason for the second class: .arrActiviteit
$('.arrUpdate').click(function(e){
val = ''; // for holding the temporary values
$('.arrActiviteit label').each(function(key, value){
if(value.className.indexOf('active') >=0){
val += value.dataset.wat
}
})
// just for debug reasons.
$('#hierHier').html(val);
})
But it appears that the 'active' class gets added after the click event is fired. So the value in #hierHier is always behind one click, so to say.
How can I resolve this?
Or is there a better way to retrieve all the active buttons in this checkbox-array?
SOLVED
update: better solution Twitter Bootstrap onclick event on buttons-radio
http://jsfiddle.net/hA423/7/
I solved it using a timeout to make your function run after bootstrap events...
There must be some other ways to do it...
$('.btn').on('click',function(e){
setTimeout(count);
})

Categories