In my example below, I've managed to disable the next button until the form field (Case Title) has content in it. I don't quite understand how to disable the next tab until that form field is complete.
How can I disable the other tabs until the form field in the first tab is completed?
$(".btnNext").click(function () {
$(".nav-tabs > .active").next("li").find("a").trigger("click");
});
$(".btnPrevious").click(function () {
$(".nav-tabs > .active").prev("li").find("a").trigger("click");
});
let caseTitle = document.getElementById("caseTitle");
let caseTitleNext = document.querySelector("#tab1 .btnNext");
caseTitle.addEventListener("keyup", () => {
caseTitleNext.removeAttribute("disabled");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="ibox-content">
<ul class="nav nav-tabs">
<li class="active">
Case Creation <i class="fa-solid fa-folder"></i>
</li>
<li>
Attributes <i class="fa-duotone fa-circle-nodes"></i>
</li>
<li>
Individual Involvement <i class="fa-solid fa-person"></i>
</li>
<li>
Agency Involvement <i class="fa-solid fa-building"></i>
</li>
<li>
Review Information <i class="fa-solid fa-memo"></i>
</li>
</ul>
<form id="createCase" name="createCase">
<div class="panel blank-panel">
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="caseTitle" class="is-required">Case Title</label>
<input type="text" class="form-control" id="caseTitle">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Case Number</label>
<input type="text" placeholder="Enter case number" class="form-control">
</div>
</div>
</div>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-default btnPrevious">Cancel</button>
<button type="button" class="btn btn-primary btnNext" disabled="disabled">Next</button>
</div>
</div>
<div class="tab-pane" id="tab2">
<h2>Tab 2 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="button" class="btn btn-warning btnNext">Skip</button>
<button type="button" class="btn btn-primary btnNext">Next</button>
</div>
</div>
<div class="tab-pane" id="tab3">
<h2>Tab 3 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="button" class="btn btn-primary btnNext">Next</button>
</div>
</div>
<div class="tab-pane" id="tab4">
<h2>Tab 4 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="button" class="btn btn-primary btnNext">Next</button>
</div>
</div>
<div class="tab-pane" id="tab5">
<h2>Tab 5 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
Base on the Bootstrap docs, you can disable tabs by setting <li class="disabled"> and removing the tab from data-toggle. I wrote a setTabDisabled(tabElement) method for quick toggling
Here is a working example
$(".btnNext").click(function () {
$(".nav-tabs > .active").next("li").find("a").trigger("click");
});
$(".btnPrevious").click(function () {
$(".nav-tabs > .active").prev("li").find("a").trigger("click");
});
let caseTitle = document.getElementById("caseTitle");
let caseTitleNext = document.querySelector("#tab1 .btnNext");
const setTabDisabled = (tabEl, isDisabled = true) => {
tabEl.setAttribute("class", isDisabled ? "disabled" : "");
const tabLink = tabEl.querySelector('a');
tabLink.setAttribute("data-toggle", isDisabled ? "" : "tab");
};
const setNonActiveTabsDisabled = (isDisabled = true) => {
document.querySelectorAll('.nav.nav-tabs li:not(.active)').forEach(element => {
setTabDisabled(element, isDisabled);
});
};
caseTitle.addEventListener("keyup", () => {
if(caseTitle.value.trim().length){
caseTitleNext.removeAttribute("disabled");
setNonActiveTabsDisabled(false);
}
else{
caseTitleNext.setAttribute("disabled","");
setNonActiveTabsDisabled(true);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="ibox-content">
<ul class="nav nav-tabs">
<li class="active">
Case Creation <i class="fa-solid fa-folder"></i>
</li>
<li class="disabled">
Attributes <i class="fa-duotone fa-circle-nodes"></i>
</li>
<li class="disabled">
Individual Involvement <i class="fa-solid fa-person"></i>
</li>
<li class="disabled">
Agency Involvement <i class="fa-solid fa-building"></i>
</li>
<li class="disabled">
Review Information <i class="fa-solid fa-memo"></i>
</li>
</ul>
<form id="createCase" name="createCase">
<div class="panel blank-panel">
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="caseTitle" class="is-required">Case Title</label>
<input type="text" class="form-control" id="caseTitle">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Case Number</label>
<input type="text" placeholder="Enter case number" class="form-control">
</div>
</div>
</div>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-default btnPrevious">Cancel</button>
<button type="button" class="btn btn-primary btnNext" disabled="disabled">Next</button>
</div>
</div>
<div class="tab-pane" id="tab2">
<h2>Tab 2 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="button" class="btn btn-warning btnNext">Skip</button>
<button type="button" class="btn btn-primary btnNext">Next</button>
</div>
</div>
<div class="tab-pane" id="tab3">
<h2>Tab 3 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="button" class="btn btn-primary btnNext">Next</button>
</div>
</div>
<div class="tab-pane" id="tab4">
<h2>Tab 4 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="button" class="btn btn-primary btnNext">Next</button>
</div>
</div>
<div class="tab-pane" id="tab5">
<h2>Tab 5 Content</h2>
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-primary btnPrevious">Previous</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
I have run into an issue I hope you can help solve.
I have a button group which when the browser expanded 100% wraps around the label. What is the best method to stop this happening. As I do not want the button group wrapping the label.
see html below.
<div class="form-group">
<label for="selectme" class="form-control-label">add and remove me</label>
<div class="btn-group btn-group-sm" role="group">
<input name="selectme" id="selectme" placeholder="add and remove me" class="form-control" type="text">
<button onclick="addItem()" type="button" class="btn btn-success btn-sm">
<i class="fa fa-plus-circle"></i> Add
</button>
<button onclick="removeItem()" type="button" class="btn btn-secondary btn-sm">
<i class="fa fa-minus-circle"></i> Remove
</button>
</div>
<ul class="list-group" id="my-list">
</ul>
</div>
Does simply adding <br> after your input solve your issue? like this:
<div class="form-group">
<label for="selectme" class="form-control-label">add and remove me</label>
<div class="btn-group btn-group-sm" role="group">
<input name="selectme" id="selectme" placeholder="add and remove me" class="form-control" type="text"><br>
<button onclick="addItem()" type="button" class="btn btn-success btn-sm">
<i class="fa fa-plus-circle"></i> Add
</button>
<button onclick="removeItem()" type="button" class="btn btn-secondary btn-sm">
<i class="fa fa-minus-circle"></i> Remove
</button>
</div>
<ul class="list-group" id="my-list">
</ul>
</div>
The problem is described in title.
I have a Bootstrap 4 modal and one popover with input field with buttons.
In IE 11 everything is ok, but in Firefox input loses focus.
Popover:
$('[data-toggle="popover"]').popover({
container: "body",
sanitize: false,
content: function () {
return $("#choose-user-popover-content").html();
}
}).on('shown.bs.popover', function () {
$('#ExecutorSNPSearchStr').focus();
});
Popover html:
<div id="choose-user-popover-content" style="display: none;">
<div class="row">
<div class="col">
<div class="input-group">
<input type="text" class="form-control" id="ExecutorSNPSearchStr" aria-describedby="ExecutorSNPSearchStrAddon"/>
<div class="input-group-append" id="ExecutorSNPSearchStrAddon">
<button class="btn btn-sm btn-outline-info w-3" type="button">
<i class="fas fa-search"></i>
</button>
<button class="btn btn-sm btn-outline-danger w-3" type="button">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
</div>
</div>
https://i.stack.imgur.com/rTe2q.png
Can anyone tell what is the reason for this, and how to solve this problem?
UPD: I recreated the situation in a separate html-file.
$(function () {
$('[data-toggle="popover"]').popover({
sanitize: false,
content: function () {
return $("#PopoverContent").html();
}
});
}).on('shown.bs.popover', function () {
$('#ExecutorSNPSearchStr').focus();
});
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<section>
<div id="PopoverContent" style="display: none;">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons" aria-describedby="button-addon1">
<div class="input-group-append" id="button-addon1">
<button class="btn btn-outline-primary" type="button" data-toggle="popover" data-placement="bottom"
data-html="true" data-title="Search">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</div>
</section>
<section>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Test modal</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons"
aria-describedby="button-addon4">
<div class="input-group-append" id="button-addon4">
<button class="btn btn-outline-primary" type="button" data-toggle="popover"
data-trigger="click" data-placement="bottom" data-html="true"
data-title="Search">
<i class="fas fa-user-plus"></i>
</button>
<button class="btn btn-outline-danger" type="button">
<i class="fas fa-user-minus"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</section>
<div class="container">
<div class="row">
<div class="col mt-5">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.8.1/js/all.js"></script>
There is a simple mistake, you have tabindex="-1" in your modal so your input focus is removing by it.
For Bootstrap 4
MODAL + INPUT POPOVER
$(function () {
$('[data-toggle="popover"]').popover({
container: 'body',
title: 'Search',
html: true,
placement: 'bottom',
sanitize: false,
content: function () {
return $("#PopoverContent").html();
}
});
})
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<section>
<div id="PopoverContent" class="d-none">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons" aria-describedby="button-addon1">
<div class="input-group-append" id="button-addon1">
<button class="btn btn-outline-primary" type="button" data-toggle="popover" data-placement="bottom"
data-html="true" data-title="Search">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</div>
</section>
<section>
<div class="modal fade" id="exampleModal" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Test modal</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons"
aria-describedby="button-addon4">
<div class="input-group-append" id="button-addon4">
<button class="btn btn-outline-primary" type="button" data-toggle="popover">
<i class="fas fa-user-plus"></i>
</button>
<button class="btn btn-outline-danger" type="button">
<i class="fas fa-user-minus"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</section>
<div class="container">
<div class="row">
<div class="col mt-5">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.8.1/js/all.js"></script>
INPUT POPOVER + INSIDE CONTENT
$(function () {
$('[data-toggle="popover"]').popover({
container: 'body',
html: true,
placement: 'bottom',
sanitize: false,
content:
`<div id="PopoverContent">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons" aria-describedby="button-addon1">
<div class="input-group-append" id="button-addon1">
<button class="btn btn-outline-primary" type="button" data-toggle="popover" data-placement="bottom"
data-html="true" data-title="Search">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</div>`
})
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title">Click to toggle popover</button>
<script src="https://code.jquery.com/jquery-3.4.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
INPUT POPOVER + OUTSIDE CONTENT
$(function () {
$('[data-toggle="popover"]').popover({
container: 'body',
html: true,
placement: 'bottom',
sanitize: false,
content: function() {
return $('#PopoverContent').html()
}
})
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<div id="PopoverContent" class="d-none">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons" aria-describedby="button-addon1">
<div class="input-group-append" id="button-addon1">
<button class="btn btn-outline-primary" type="button" data-toggle="popover" data-placement="bottom"
data-html="true" data-title="Search">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</div>
<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title">Click to toggle popover</button>
<script src="https://code.jquery.com/jquery-3.4.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
For Bootstrap 5
MODAL + INPUT POPOVER
const popover = new bootstrap.Popover(document.querySelector('.callPopover'), {
container: 'body',
title: 'Search',
html: true,
placement: 'bottom',
sanitize: false,
content() {
return document.querySelector('#PopoverContent').innerHTML;
}
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<section>
<div id="PopoverContent" class="d-none">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username with two button addons" aria-describedby="button-addon1">
<button class="btn btn-outline-primary" type="button" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-html="true" data-bs-title="Search">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</section>
<section>
<div class="modal fade" id="exampleModal" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Test modal</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username with two button addons" aria-describedby="button-addon4">
<button class="btn btn-outline-primary callPopover" type="button" data-bs-toggle="popover">
<i class="fas fa-user-plus"></i>
</button>
<button class="btn btn-outline-danger" type="button">
<i class="fas fa-user-minus"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</section>
<div class="container">
<div class="row">
<div class="col mt-5">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Launch demo modal
</button>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
<script defer src="https://use.fontawesome.com/releases/v5.8.1/js/all.js"></script>
INPUT POPOVER + INSIDE CONTENT
const popover = new bootstrap.Popover(document.querySelector('[data-toggle="popover"]'), {
container: 'body',
title: 'Search',
html: true,
placement: 'bottom',
sanitize: false,
content: `<div id="PopoverContent">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons" aria-describedby="button-addon1">
<button class="btn btn-outline-primary" type="button" data-toggle="popover" data-placement="bottom"
data-html="true" data-title="Search">
<i class="fas fa-search"></i>
</button>
</div>
</div>`
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title">Click to toggle popover</button>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
<script defer src="https://use.fontawesome.com/releases/v5.8.1/js/all.js"></script>
INPUT POPOVER + OUTSIDE CONTENT
const popover = new bootstrap.Popover(document.querySelector('.callPopover'), {
container: 'body',
title: 'Search',
html: true,
placement: 'bottom',
sanitize: false,
content() {
return document.querySelector('#PopoverContent').innerHTML;
}
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<div id="PopoverContent" class="d-none">
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username"
aria-label="Recipient's username with two button addons" aria-describedby="button-addon1">
<button class="btn btn-outline-primary" type="button" data-toggle="popover" data-placement="bottom"
data-html="true" data-title="Search">
<i class="fas fa-search"></i>
</button>
</div>
</div>
<button type="button" class="btn btn-lg btn-danger callPopover" data-toggle="popover" title="Popover title">Click to toggle popover</button>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
<script defer src="https://use.fontawesome.com/releases/v5.8.1/js/all.js"></script>
Coming in late on this, but see https://github.com/twbs/bootstrap/issues/36692#issuecomment-1178261690
In short, newer Bootstrap versions more strictly enforce keeping focus inside the modal. By default, if there's a popover inside the modal, it will generate its own popover container outside of the modal itself - so because of the focus enforcement, it won't be reachable. The solution is to explicitly set the container for the popover not to be "body", but the modal (or an explicit container inside the modal).
I'm late to this thread but I am having the same problem using Bootstrap 5.
I copied the Bootstrap 5 code answer into my own files and it worked fine.
I then changed the html to include a cutdown version of my modal (minus the tabindex=1) and my popover and it still worked.
I then replaced the link to the beta version of Bootstrap 5 with a link to the latest full release and the original problem returned, it's not possible to type anything into the popover input field.
I'm including my code below in case anyone can spot an error but this fieels like a Bootstrap 5 bug.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
</head>
<body>
<section>
<div id="status-form" class="card col-md-6 offset-md-1 d-none mb-2">
<div class="card-header"><h5 id="statusHeader"> Add new status</h5></div>
<div class="card-body">
<input id='popoverStatusID' type='hidden' disabled>
<input id='popoverMode' type='hidden' value='add' disabled>
<div class="mb-2 ms-2">
<input id='popoverStatusEdit' type='text' maxlength='20' class='form-control' value=''>
</div>
<span id='status-message' class='text-danger' value=''></span>
</div>
<div class="card-footer text-muted">
<div class="mt-1 ms-2 mb-2">
<button id="close-status-form" class='btn btn-default btn-sm' type='button'>
Close
</button>
<button id="submit-status-form" class='btn btn-primary btn-sm float-end' type='button'>
Submit
</button>
</div>
</div>
</div>
</section>
<section>
<div id="location-maintenance" class="modal fade" role="dialog" data-bs-backdrop="static">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<form id="location-form"
" method="POST" action="#">
<div class="modal-header d-inline">
<h4 id="location-title" class="ms-2">Edit Location</h4>
<p id="edit-location-name" class="ms-2"></p>
</div>
<div class="col-md-6">
<div class="form-floating">
<select id="location-status-text" class="form-select mb-2" aria-label="Role" placeholder="xxx" name="RoomStatusText">
<option value="17" data-active="1">Active
</option>
<option value="18" data-active="0">Blocked
</option>
<option value="19" data-active="0">ISO
</option>
<option value="268" data-active="0" selected>Onboarding
</option>
</select>
<label class="text-muted">Status</label>
</div>
</div>
<div class="row mb-2">
<div class="col-md-2">
<button class="btn btn-primary status-maintenance" type="button" data-mode="add">Add</button>
</div>
</div>
<div class="modal-footer">
<a class="btn btn-danger btn-delete d-none" role="button" data-bs-toggle="modal" data-bs-target="#modal-delete" title="Delete location" href="#" data-type="location">Delete...<i class="fas fa-times-circle"></i>
</a>
<div>
<button id="cancel-location-edit" type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Cancel
</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
<span id="add-message" class="text-success fw-bold"></span>
</form>
</div>
</div>
</div>
</section>
<div class="container">
<div class="row">
<div class="col mt-5">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#location-maintenance">
Launch demo modal
</button>
</div>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.8.1/js/all.js"></script>
<script>
const popover = new bootstrap.Popover(document.querySelector('.status-maintenance'), {
container: 'body',
title: 'Search',
html: true,
placement: 'bottom',
sanitize: false,
content() {
return document.querySelector('#status-form').innerHTML;
}
})
</script>
I am trying to pick two different start points for the slide content. The setSlideContent indicator is set to 17 for the main gallery. But for the modal that will popup if there is alternate variations of that image will start at 0. Is there a way to start the slide content at 17 for main gallery carousel, but if it is a modal carousel, have it start at 0? I'm guessing I need an if/else here.
Would (using the original script) changing the setSlideContent to check if $carouselSelector contains .modal return setSlideSelector(0) else if $carouselSelector does not contain .modal return setSlideSelector(17) or whatever number I need work? Still extremely new to this.
NOTE in the example below the setSlideContent is set to 0 but but it is never set to 0 in practice (unless the carousel is in a modal) to take into account new slides being added. The number will always be the last slide added in my case it is 17.
$(function() {
$('.carousel-container').each(function() {
var $carouselContainer = $(this);
var $carousel = $carouselContainer.find('.carousel');
var $carouselText = $carouselContainer.find('.carousel-text');
var $carouselSelector = $carouselContainer.find('.carousel-selector');
$carousel.carousel({
interval: false
});
function setSlideContent(id) {
var targetContent = $carouselContainer.find('.slide-content[data-slide="' +
id +
'"]').html();
$carouselText.html(targetContent);
}
setSlideContent(0);
$carouselSelector.on('click', function() {
var targetSlide = $(this).data('slide');
$carousel.carousel(targetSlide);
});
$carousel.on('slid.bs.carousel', function() {
var targetSlide = $carousel.find('.active').index();
setSlideContent(targetSlide);
});
});
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>
<div class="container carousel-container">
<div class="row">
<div class="col">
<div class="carousel slide" id="carousel-0">
<!-- change this id and match with that in the JS -->
<!-- Carousel items -->
<div class="carousel-inner">
<div class="active carousel-item" data-slide-number="0">
<img src="http://placehold.it/770x300&text=one">
</div>
<div class="carousel-item" data-slide-number="1">
<img src="http://placehold.it/770x300&text=two">
</div>
<!-- Carousel nav -->
<a class="carousel-control-prev" href="#carousel-0" role="button" data-slide="prev">
<!-- change this id and match with that in the JS -->
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
</a>
<a class="carousel-control-next" href="#carousel-0" role="button" data-slide="next">
<!-- change this id and match with that in the JS -->
<span class="carousel-control-next-icon" aria-hidden="true"></span>
</a>
</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col carousel-text"></div>
<div style="display: none;">
<!-- only needs the inline CSS -->
<div class="slide-content" data-slide="0">
<h5>Slide 1</h5>
<button class="btn btn-outline-dark btn-sm" data-toggle="modal" data-target="#modal1" type="button" style="margin-left: -1px;">press me</button>
<div class="dropdown">
<button class="btn btn-outline-dark btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Download</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="./Downloads/avarice/avarice1/avarice-nodof1280.jpg" download>1280x1024</a>
</div>
</div>
</div>
<div class="slide-content" data-slide="1">
<!-- change this id and match with that in the JS -->
<h5>Slide 2</h5>
<div class="dropdown">
<button class="btn btn-outline-dark btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Downloads</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="./Downloads/avarice/avarice0/avarice01280.jpg" download>1280x1024</a>
</div>
</div>
</div>
</div>
</div>
<hr>
<!--/Slider-->
<div class="row">
<div class="col">
<a class="carousel-selector" data-slide="0"><img src="http://placehold.it/170x100&text=one" class="img-thumbnail"></a>
<!-- change this id and match with that in the JS -->
</div>
<div class="col">
<a class="carousel-selector" data-slide="1"><img src="http://placehold.it/170x100&text=two" class="img-thumbnail"></a>
<!-- change this id and match with that in the JS -->
</div>
</div>
</div>
<div class="container carousel-container">
<div class="row">
<div class="col">
<div class="carousel slide" id="carousel-1">
<!-- change this id and match with that in the JS -->
<!-- Carousel items -->
<div class="carousel-inner">
<div class="active carousel-item" data-slide-number="0">
<img src="http://placehold.it/770x300&text=one">
</div>
<div class="carousel-item" data-slide-number="1">
<img src="http://placehold.it/770x300&text=two">
</div>
<!-- Carousel nav -->
<a class="carousel-control-prev" href="#carousel-1" role="button" data-slide="prev">
<!-- change this id and match with that in the JS -->
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
</a>
<a class="carousel-control-next" href="#carousel-1" role="button" data-slide="next">
<!-- change this id and match with that in the JS -->
<span class="carousel-control-next-icon" aria-hidden="true"></span>
</a>
</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col carousel-text"></div>
<!-- change this id and match with that in JS -->
<div style="display: none;">
<!-- only needs the inline CSS -->
<div class="slide-content" data-slide="0">
<!-- change this id and match with that in the JS -->
<h5>Dreams of Avarice1</h5>
<div class="dropdown">
<button class="btn btn-outline-dark btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Download</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="./Downloads/avarice/avarice1/avarice-nodof1280.jpg" download>1280x1024</a>
</div>
</div>
</div>
<div class="slide-content" data-slide="1">
<!-- change this id and match with that in the JS -->
<h5>Avarice Zero1</h5>
<div class="dropdown">
<button class="btn btn-outline-dark btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Downloads</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="./Downloads/avarice/avarice0/avarice01280.jpg" download>1280x1024</a>
</div>
</div>
</div>
</div>
</div>
<hr>
<!--/Slider-->
<div class="row">
<div class="col">
<a class="carousel-selector" data-slide="0"><img src="http://placehold.it/170x100&text=one" class="img-thumbnail"></a>
<!-- change this id and match with that in the JS -->
</div>
<div class="col">
<a class="carousel-selector" data-slide="1"><img src="http://placehold.it/170x100&text=two" class="img-thumbnail"></a>
<!-- change this id and match with that in the JS -->
</div>
</div>
</div>
<!-- modal -->
<div class="modal fade" id="modal1" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h3>...</h3>
</div>
<div class="modal-body">
<div class="container-fluid carousel-container">
<div class="container">
<div class="row mx-auto">
<div class="col">
<div class="carousel slide carousel-fade" id="carousel-...">
<div class="carousel-inner">
<div class="active carousel-item" data-slide-number="0">
<img data-src="./Downloads/hoohum" src="./loader-carousel.gif" class="lazy img-thumbnail" width="450" height="250"></div>
<div class="carousel-item" data-slide-number="1">
<img data-src="./Downloads/hoohum" src="./loader-carousel.gif" class="lazy img-thumbnail" width="450" height="250"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="row mx-auto">
<div class="col carousel-text"></div>
<div style="display: none;">
<div class="slide-content" data-slide="0">
<h5>0ne</h5>
<div class="btn-group">
<div class="btn-group">
<button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle" data-toggle="dropdown">Desktop</button>
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="./Downloads/something/something" download>1280x1024</a>
</div>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle" data-toggle="dropdown">Dual</button>
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="./Downloads/something/something" download>2560x1024 (Dual)</a>
</div>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle" data-toggle="dropdown">Triple</button>
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="./Downloads/something/something" download>3840x1024 (Triple)</a>
</div>
</div>
</div>
</div>
<div class="slide-content" data-slide="1">
<h5>two</h5>
<div class="btn-group">
<div class="btn-group">
<button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle" data-toggle="dropdown">Desktop</button>
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="./Downloads/other/other" download>1280x1024</a>
</div>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle" data-toggle="dropdown">Dual</button>
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="./Downloads/other/other" download>2560x1024 (Dual)</a>
</div>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle" data-toggle="dropdown">Triple</button>
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="./Downloads/other/other" download>3840x1024 (Triple)</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<!--/Slider-->
<div class="row mx-auto">
<div class="col">
<a class="carousel-selector" data-slide="0"><img data-src="./Downloads/hoohum" src="./loader-thumb.gif" class="lazy img-thumbnail" width="75" height="42"></a>
</div>
<div class="col">
<a class="carousel-selector" data-slide="1"><img data-src="./Downloads/hoohum" src="./loader-thumb.gif" class="lazy img-thumbnail" width="75" height="42"></a>
</div>
<div class="col"></div>
<div class="col"></div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark btn-sm" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
If I understand correctly, you want :
to initialize the modal carousel at its first slide, with corresponding caption.
to initialize all other carousels at their last slide, with corresponding caption.
At least, that would makes sense.
If I'm right, then the javascript will be something like this :
$(function() {
$('.carousel-container').each(function() {
var $carouselContainer = $(this);
var $carousel = $carouselContainer.find('.carousel').on('slid.bs.carousel', function() {
var targetSlide = $carousel.find('.active').index();
var targetContent = $carouselContainer.find('.slide-content[data-slide="' + targetSlide + '"]').html();
$carouselContainer.find('.carousel-text').html(targetContent);
}).carousel({
interval: false
});
$carouselContainer.find('.carousel-selector').on('click', function() {
var targetSlide = $(this).data('slide');
$carousel.carousel(targetSlide);
});
// The carousel is already at first slide (slide 0).
var n = $carouselContainer.find(".slide-content").length; // number of slides in this carousel
if (n < 2 || $carouselContainer.closest(".modal").length > 0) { // if there are less than 2 slides, or the carousel is in a .modal container
// Trigger the 'slid.bs.carousel' event so its handler can look after the .carousel-text ...
$carousel.trigger('slid.bs.carousel');
} else { // ... else, there are 2 or more slides and this is a non-modal carousel:
// send to last slide
$carousel.carousel(n - 1);
$carousel.trigger('slid.bs.carousel'); // shouldn't be necessary but has been found to be a workaround for `slid.bs.carousel` not being triggered automatically under some (undiagnosed) circumstances.
}
});
});
Demo
I am using bootstrap panel to display data and there is a description field which i am displaying in panel body
I want to implement read more and read less link for description field in panel body
Here is what i have done until now
function readmore(data){
if (data.length > 100) {
// truncate string
datacut = data.substring( 0, 50);
// make sure it ends in a word so assassinate doesn't become ass...
data2 = datacut + '<span id="restOfArticle" style="display:none">'+ data.substring( datacut.length, data.length);+'</span>' ;
return data2 + '<a onclick=showMoreOrLess(this,"restOfArticle") >..Read more</a>';
}
return data;
}
function showMoreOrLess(thisObj,bonusContent){
var caption = thisObj.innerHTML;
//alert(caption);
if ( caption == "..Read more" ) {
document.getElementById(bonusContent).style.display = "inline";
thisObj.innerHTML = "..Read less";
} else {
document.getElementById(bonusContent).style.display = "none";
thisObj.innerHTML = "..Read more";
}
}
Read more and read less is working fine but its not right after the hidden content is finished but its in new div and when i click on the read more it collapses the panel body
Here is how i display the html data using jquery and webservice
<div class="panel-group" id="accordion">
<div data-toggle="collapse" href="#collapse0" class="panel panel-default panel-style row event-row" id="panel0">
<div id="event-title" class="panel-heading event-heading"><h4 class="panel-title">test</h4>
<div class="pull-right">
<button type="button" id="5" onclick="checkinEvent(this)" class="checkin-btn btn btn-xs btn-danger"><i
id="i5" class="glyphicon glyphicon-plus"></i> Check in
</button>
<span class="label label-default badge-round pull-right label-checkin">1 </span></div>
</div>
<div id="collapse0" class="panel-collapse collapse">
<div class="panel-body">
<div><p>test<strong> description</strong></p>
</div>
<div>
<button id="5" data-toggle="modal" data-target="#myModal" type="button"
class="btn btn-danger btn-sm location-btn center-block"><span
class="glyphicon glyphicon-map-marker"></span>00 Piter Street, New South Wales,
Australia
</button>
</div>
</div>
</div>
</div>
<div data-toggle="collapse" href="#collapse1" class="panel panel-default panel-style row event-row collapsed"
id="panel1" aria-expanded="false">
<div id="event-title" class="panel-heading event-heading"><h4 class="panel-title">show jumping test 1</h4>
<div class="pull-right">
<button type="button" id="10" onclick="checkinEvent(this)" class="checkin-btn btn btn-xs btn-danger"><i
id="i10" class="glyphicon glyphicon-plus"></i> Check in
</button>
<span class="label label-default badge-round pull-right label-checkin">1 </span></div>
</div>
<div id="collapse1" class="panel-collapse collapse" aria-expanded="false" style="height: 0px;">
<div class="panel-body">
<div><p><strong>This is a very long description written<span id="restOfArticle" style="display:none"> just to test the word wrap and make it more compatible with the mobile screen. ThisIsAVeryVeryLongWordWrittenToTestWordWrapCSSIHopeItWorks</span></strong>
</p>
<a onclick="showMoreOrLess(this,"restOfArticle")">..Read more</a></div>
<div>
<button id="10" data-toggle="modal" data-target="#myModal" type="button"
class="btn btn-danger btn-sm location-btn center-block"><span
class="glyphicon glyphicon-map-marker"></span>500 Piter Street, New South Wales,
Australia
</button>
</div>
</div>
</div>
</div>
What should i do to keep that body open and display the data
Thank you
I'll provide a simple solution that you can adapt. Check this code one: http://jsfiddle.net/c7pcu5gy/