4

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">&times;</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>
Nisharg Shah
  • 16,638
  • 10
  • 62
  • 73
vladver
  • 97
  • 1
  • 1
  • 8

3 Answers3

18

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">&times;</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>
Nisharg Shah
  • 16,638
  • 10
  • 62
  • 73
  • 1
    Excellent! Thank you so much! I spent a few days trying to understand the problem. It's strange that in the Bootstrap 4 documentation there is nothing about such things. Thank you again so much! – vladver Apr 23 '19 at 15:59
  • very good catch @NishargShah the issue is strange we should report this issue to Bootstrap Repo so they can at least add it to their docs – Ismail Farooq Apr 23 '19 at 17:48
  • yes, i think about it to create issue in github repo but after solving that i think this is silly solution – Nisharg Shah Apr 23 '19 at 20:02
1

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).

0

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>
phaworth
  • 399
  • 2
  • 8