Подсказка Bootstrap с ручным триггером и функцией выбора

У меня есть динамическая таблица, загруженная ajax. Я хочу показать всплывающую подсказку, когда я наводил указатель мыши на строку, но я хочу, чтобы всплывающая подсказка отображалась над определенной ячейкой (с классом .name), а не над всей строкой.

Кроме того, используя функцию заголовка, мне нужно иметь возможность получить идентификатор ближайшего номера и вернуть настраиваемый шаблон.

Вот мой код:

<table class="table" id="myTable">
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Country</th>
            <th>Statistics</th>
        </tr>
    </thead>
    <tbody>
        <tr id="1">
            <td >1</td>
            <td class="name">Name #1</td>
            <td>United States of America</td>
            <td>100%</td>
        </tr>
        <tr id="2">
            <td >2</td>
            <td class="name">Name #2</td>
            <td>United States of America</td>
            <td>50%</td>
        </tr>
    </tbody>
</table>

Инициализация:

$('#myTable').tooltip({
    container: 'body',
    html: true,
    selector: 'td.name',
    trigger: 'manual',
    title: function() {
        // here will be custom template
        var id = $(this).parent().atrr('id');
        return id;
    }
});

Попытка одна: Демо в jsFiddle

$('#myTable')
    .on('mouseenter focusin', 'tbody > tr', function() {
        $(this).find('td.name').tooltip('show');
    })
    .on('mouseleave focusout', 'tbody > tr', function() {
        $(this).find('td.name').tooltip('hide');
    });

Попытка вторая: Демо в jsFiddle

var tip;
$('#myTable')
    .on('mouseenter focusin', 'tbody > tr', function() {
        tip = $(this).find('.offer-name');
        tip.tooltip(hereAllTooltipOptions);
        tip.tooltip('show');
    })
    .on('mouseleave focusout', 'tbody > tr', function() {
        tip.tooltip('hide');
    });

Но я очень удивляюсь выполнению такого решения. Итак, вопрос в том, как это сделать и сделать это лучше?

Ответ 1

Проблема заключается в том, что вы не можете использовать параметр selector, если для параметра trigger установлено значение manual. Селектор используется для делегирования, когда bootstrap обрабатывает события триггеров, но вы прямо сказали, что вы будете одной делегацией обработки, поэтому игнорирует параметр selector.

Это означает, что мы ничего не получаем от предварительной инициализации с таким кодом:

$('.parent').tooltip({
    selector: '.child',
    trigger: 'manual'
})

Он просто говорит, что я хочу установить всплывающие подсказки на элементах .child, но ничего не делаю, потому что я буду обрабатывать их позже.

Хорошо, что мы все-таки хотели сделать, когда использовали manual. Мы будем диктовать, когда всплывающая подсказка будет показана или скрыта.

Посмотрим, как выглядит простой случай:

$('#myTable').on({
    'mouseenter': function() {
        $(this).find('td.name').tooltip('show');
    },
    'mouseleave': function() {
        $(this).find('td.name').tooltip('hide');
    }
},'tbody > tr');

Демо в js Fiddle

Однако это не будет работать в этом случае, потому что мы хотим динамически создавать всплывающие подсказки. Когда мы вызываем .tooltip('show') на конкретный элемент, bootstrap смотрит на этот элемент, чтобы увидеть, была ли она инициализирована или имеет заголовок. Вышеприведенный пример работает, потому что я жестко закодирован в заголовке, но как мы будем использовать его, если мы хотим сначала инициализировать эту подсказку?

Просто инициализируйте "на лету", перед тем, как вы покажете всплывающую подсказку, например:

$('#myTable').on({
    'mouseenter': function() {
        $(this).find('td.name')
            .tooltip({
                container: 'body',
                html: true,
                trigger: 'manual',
                title: function() {
                    return this.parentNode.id;
                }
            }).tooltip('show');
    },
    'mouseleave': function() {
        $(this).find('td.name').tooltip('hide');
    }
},'tbody > tr');

Таким образом, вы не берете на себя стоимость инициализации при каждом наведении, вы можете обернуть инициализацию в инструкции if на проверить, была ли она уже инициализирована следующим образом:

var $cell = $(this).find('td.name');
if (!$cell.data("bs.tooltip")) {
    $cell.tooltip({ /* options */ });
}
$cell.tooltip('show');

Демо в jsFiddle