How to disable buttons in button-group (Bootstrap)? - javascript

I have a button-group like the one on the picture:
and the code like this:
<span class="btn-group" data-toggle="buttons">
<span class="btn btn-default active">
<input type="radio" value="false"><label >No</label>
</span>
<span class="btn btn-default">
<input type="radio" value="true"><label >Yes</label>
</span>
</span>
How do I disable this control completely? When I added bootstrap class .disabled and/or attribute disabled to any or all of these elements I still could click on the buttons and they were affected even though bootstrap was showing the crossed circle icon.
I found here a workaround that stops events propagation, however it works only to prevent adding active class to the buttons but not focus.
$('.btn-group .btn.disabled').click(function(event) {
event.stopPropagation();
});

$('.btn-group .btn.disabled').click(function(event) {
return false;
});

Related

Additional wrong event being triggered when using bootstrap collpase button

I am using Bootstrap 5.2 and I have two buttons that can hide content, using the Bootstrap collapse plugin.
<div class="col-12 col-sm-auto">
<span class="pe-2">
<button id="show_movements_button" type="btn" class="btn btn-outline-primary" data-bs-toggle="collapse" data-bs-target="#movements_id">
Show Movements
</button>
</span>
<span class="pe-2">
<button id="show_credits_button" type="btn" class="btn btn-outline-secondary" data-bs-toggle="collapse" data-bs-target="#credits_id">
Show All Credits
</button>
</span>
</div>
such as
<tr class="song_id collapse" id="movements_id">
<td class="col-1">
1
</td>
<td class="col">
</td>
<td class="col">
<div>
<label class="h6">
Piano Concerto no. 1 in E minor, op. 11: I. Allegro maestoso
</label>
</div>
<div class="collapse" id="credits_id">
<div class="lh-1">
<div>
<a href="/container.start?cid=0$=Instrument$708&title=Instruments+%2F+piano" class="small text-secondary">
piano
</a>
<label class="small">
by
</label>
<a href="/container.start?cid=0$=Performer_name$5540&title=Performers+%2F+Evgeny+Kissin" class="small text-secondary pe-1">
Evgeny Kissin
</a>
</div>
</div>
</div>
</td>
</tr>
This work correctly, but I want the name of the button to change to indicate if showing or hiding content so I also have this code
<script>
function listenForButtonCollapse(buttonId, collapseId, buttonShowText, buttonHideText)
{
let button = document.getElementById(buttonId);
let section = document.getElementById(collapseId);
if(section!=null)
{
section.addEventListener('show.bs.collapse',
function()
{
button.innerText=buttonHideText;
}
);
section.addEventListener('hide.bs.collapse',
function()
{
button.innerText=buttonShowText;
}
);
}
}
</script>
<script>
listenForButtonCollapse('show_credits_button','credits_id','Show All Credits','Hide Some Credits');
</script>
<script>
listenForButtonCollapse('show_movements_button','movements_id','Show Movements','Hide Movements');
</script>
Now toggling the Show/Hide Movements button works fine, but when I click on the Show/Hide Credits button for some reason it is also triggering the listenForButtonCollapse() call on the movements button as well as the credits button, so the Movement button is updated with the same (Hide/Show) value as the credits button even though it isn't actually been invoked (so it doesn't hide/show the movements div)
The credits div is within the movements div, so Im assuming that why one button works without problem and the other doesn't but I cant see what I am actually doing wrong.
In order to avoid the current behaviour you need to stop further event propagation. You can do this by using stopPropagation(). This method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.
function listenForButtonCollapse(buttonId, collapseId, buttonShowText, buttonHideText)
{
let button = document.getElementById(buttonId);
let section = document.getElementById(collapseId);
if (section != null)
{
section.addEventListener('show.bs.collapse',
function(event)
{
event.stopPropagation();
button.innerText=buttonHideText;
}
);
section.addEventListener('hide.bs.collapse',
function(event)
{
event.stopPropagation();
button.innerText=buttonShowText;
}
);
}
}
I've prepared a Code playground to illustrate that this solves your issue:
https://codesandbox.io/embed/bootstrap-5-playground-forked-b28j0g?fontsize=14&hidenavigation=1&theme=dark
Solution Explanation
The events show.bs.collapse and hide.bs.collapse are being triggered for both buttons when clicked. So when you add more than one event listener for those events, when the event occurs, all event listeners are being executed. This is why for example when you click "Hide Movements" and bootstrap triggers hide.bs.collapse
event then this executes all registered event listeners for it - in this case two - one for the show_credits_button and another for show_movements_button button - leading to changing both button texts. To prevent this you need to stop further event propagation with event.stopPropagation() method - this will stop notifying all other event listeners for this event other than the event target one.

ui not reflecting proper class upon toggle click

I have a toggle button and after wiring it up i noticed that when i click on it - the style doesn't change unless i refresh the page.
Here is my Html:
<div (click)="onValueChange(item)">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-toggle-switch" [ngClass]="{'active': item.isActive}">
<input type="checkbox">
<span class="status-on">on</span>
<span class="status-off">off</span>
</label>
</div>
</div>
What do i have to do to ensure that upon click the active class is added or removed properly without having to refresh?
Here is my on click function:
private onValueChange(item: ItemType) {
item.isActive = !item.isActive;
this.save(item);
}

On mouseover / mousedown inside div should not close And outside div have to close

when user click - 'booking' container, 'open_contents' have to show.
when user mouseout of 'open_contents' container, it have to hide or click outside 'open_contents' or anywhere on 'body' of the page.
with present below code, above point 1 works ok. But, i have increment/decrement button on 'open_contents' container. When user click button, 'open_contents' getting hide on every click. it should not get hide when i click button element on 'open_contents' container.
Please let me know your available comments.
HTML:
<div class="booking">
<div class="head">Ticket Booking</div>
</div>
<div id="open_contents" class="open_contents">
<div class="c_class">
<button type="button" class="btn btn-default minus" id="group-btn-minus" disabled="disabled" data-type="minus" data-field="quant[1]">
<span class="glyphicon glyphicon-minus"></span>
</button>
<input type="text" name="quant[1]" class="form-control group-input minus-plus-input" value="1" min="1" max="10">
<button type="button" class="btn btn-default plus" id="group-btn-plus" data-type="plus" data-field="quant[1]">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div>
</div>
JS:
$(document).mouseup(function (e)
{
var $nonGroupBooking = $('.open_contents');
if (!$nonGroupBooking.is(e.target)
&& $nonGroupBooking.has(e.target).length === 0);
{
$nonGroupBooking.hide();
}
});
If you have bound the onclick event to $(document), all elements inside $(document) on click will also be considered as $(document).clicked
To stop the event bubbling up the event, you could use e.stopPropagation, read more on https://api.jquery.com/event.stoppropagation/
Here please try my example - https://jsfiddle.net/w07gnzgg/1/
I changed the $(".booking").on("click") behavior to show the .open_contents and also disabled $(".open_contents").on("mouseleave") event by default
Bind a click handler to the document to hide the contents, but also add a click handler to the contents that stops propagation (prevents the click event from reaching the document handler).
$(document).on('click', function(e) {
$('.open_contents').hide();
});
$('.open_contents').on('click', function(e) {
e.stopPropagation();
});

Jquery event quits firing after 3 hits

I'm working with a small mvc view and I want to be able to toggle the data source(ajax call to controller) between either 1 of 2 locations or both. It all works great, until I've clicked the toggles 3 different times, then all three toggles become unresponsive. I've tried click and change events, same results.
The only other items are on the page is a left navigation view that still works after the toggles go idle.
If I navigate away from the view with the toggles and then back to it they remain broken. If I hard refresh the page they work for another 3 clicks.
I'm at a loss on this and need some help. Any thoughts?
my toggles
<div class="btn-group"id="divToggle" data-toggle="buttons">
<label class="btn blue">
<input type="radio" value="1" class="toggle DashToggle"> US06
</label>
<label class="btn blue active">
<input type="radio" value="0" class="toggle DashToggle"> BOTH
</label>
<label class="btn blue">
<input type="radio" value="2" class="toggle DashToggle"> US05
</label>
</div>
And my view consist of 5 div blocks like the following
<div class="col-lg-2 col-md-4 col-sm-6 col-xs-12">
<div class="dashboard-stat blue-soft">
<div class="visual">
<i class="fa fa-car"></i>
</div>
<div class="details">
<div class="number stat_ActiveJits">
1349
</div>
<div class="desc">
Active JITS
</div>
</div>
<a class="more" href="javascript:;">
View Details <i class="m-icon-swapright m-icon-white"></i>
</a>
</div>
</div>
I have tried all of the following examples for the Jquery side and they all quit working after 3 clicks...
$(document).ready(function () {
$('#divToggle input[type=radio]').change(function () {
BuildDashBoard(this.value)
});
});
$('#divToggle input[type=radio]').live().change(function () {
BuildDashBoard(this.value)
});
$('.divToggle').on('change', '.DashToggle', (function () {
BuildDashBoard(this.value)
}));
And yes the toggle classes were changed to match these.
$(".US06_DashToggle").change(function () {
BuildDashBoard(1)
})
$(".US05_DashToggle").change(function () {
BuildDashBoard(2)
})
$(".DYNA_DashToggle").change(function () {
BuildDashBoard(0)
})
And finally my ajax call which works fine.
function BuildDashBoard(plantid)
{
var uri = 'http://' + host + '/DashBoard/DashStats';
$.ajax({
type: 'POST',
url: uri,
data: { PlantId: plantid },
success: function (d) {
$('.stat_ActiveJits').text(d.ActiveJits.toString());
$('.stat_PastDueJits').text(d.PastDueJits.toString());
$('.stat_ActiveExpedites').text(d.ActiveExpedites.toString());
$('.stat_PastDueExpedites').text(d.PastDueExpedites.toString());
$('.stat_ActiveProductionOrders').text(d.ActiveProductionOrders.toString());
//$.notific8('Application Options Updated', { theme: 'teal', life: 2000, verticalEdge: 'right', horizontalEdge: 'bottom' });
}
});
}
Well after a couple hours of fighting with this a comment Kevin B made about the radio buttons needing names made me rethink my css. My css was not correctly doing the grouping so once i clicked a button, it was checked and never unchecked. The reason it did not work as buttons, I have no clue and I'm done messing with it.

AngularJS popover: hide popover template on mouse out

I am using AngularJS' ui-bootstrap module. Here's my markup:
<button class="btn btn-default btn-sm" type="button"
popover-template="dynamicPopover.templateUrl"
popover-trigger="click" id="custom_overview"
popover-placement="bottom">Custom</button>
Here's my controller:
$scope.dynamicPopover = {
templateUrl : '../static/templates/popup-templates/datepicker.html'
};
Here's my popover template:
<div class="row" id="datepicker-container">
<div class="col-sm-12 clearfix">
<div class="col-sm-12">
<span class="heading">From:</span>
<input ng-model="timedata.fromDate" type="text" id="fromDate"
class="form-control" datepicker-popup="dd-MM-yyyy"
is-open="fromOpen.isOpen" ng-click="fromOpen.isOpen = true" placeholder="dd-mm-yyyy">
</div>
<div class="col-sm-12" style="margin-top:5px">
<span class="heading">To:</span>
<input ng-model="timedata.toDate" type="text" id="toDate"
class="form-control" datepicker-popup="dd-MM-yyyy"
is-open="toOpen.isOpen" ng-click="toOpen.isOpen = true" placeholder="dd-mm-yyyy">
<div class="error"
ng-show="timedata.toDate <= timedata.fromDate && timedata.fromDate && timedata.toDate">
<span>'To' date cannot be less than 'From' date.</span>
</div>
</div>
</div>
<div class="col-sm-12" id="submit-button">
<button class="btn btn-primary" ng-click="setInterval('custom')"
ng-disabled="timedata.toDate <= timedata.fromDate || !timedata.toDate || !timedata.fromDate">
Submit
</button>
</div>
</div>
As you can see, I am populating a popover with a popover template which contains a form. Here's a screenshot:
This popover opens up when I click on the 'Custom' button. Now, I want this popover to hide when I take the mouse away from the template and the 'Custom' tab. How can I do it?
In short,
replacing popover-trigger="click" by popover-trigger="'mouseleave : click'" should work for you.
For more understanding,
As per uib-popover documentation, both popover open and close triggers will be enabled by default with the popover-trigger attribute(only if you want to close and open on same event).
For example:
popover-trigger="'mouseenter'" This by default should open the popover on mouseover and close the popover on mouseleave
popover-trigger="'click'" - This will show and hide on clicks
In your case(show and close on different events), popover-trigger attribute should contain both events in order to work.
popover-trigger="'mouseleave : click'" This should work. Here first and second values represents hide and show triggers respectively.

Categories