Knockout Popover

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.css">
<div class="accordion" id="accordion2">
  <div class="accordion-group">
    <div class="accordion-heading">
      <a class="accordion-toggle arrow-up" data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
        Collapsible Group Item #1
      </a>
    </div>
    <div id="collapseOne" class="accordion-body collapse in">
      <div class="accordion-inner">
        <p> first table</p>
        <p>First Content</p>
      </div>
    </div>
  </div>
  
</div>

<ul data-bind="foreach: persons">
    <li> <span data-bind="text: 'name : '+name()+' email : '+ email()">
             </span>
 <a href="#" data-bind="popover: {content :'#popover_content',id: id}" data-title="<strong>Person details</strong>" data-placement="bottom"> Edit
          </a>

    </li>
</ul>
<script id="popover_content" type="text/html">
    <div class="row"> Name: <input type="text" data-bind="value: name, valueUpdate: 'afterkeydown'"/> Email: <input type="text" data-bind="value: email, valueUpdate: 'afterkeydown'"/></div>
<br>
<div class="row">
  <center>
    <div class="span3 offset1">
      <button class="btn btn-small btn-danger" data-bind="click: $root.closePopover">Cancel</button > </div>
  </center > </div>
</script>

CSS

.arrow-down {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAAHwAAAB8ARUP7eQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAACISURBVChTvc+xCoNAEIThDXkQH8FCYhGwsRLEgJ2lEN81VQg2toIW2qVK7z9RREEtHfjg7liWOTslIZzxeJhgYhU+uOmykwQd3rpEaNEg1cMiFzyh4Rc82BU5fqjxf5xS4AstUwMtmJNBm0r4eKCHhtViMzFUTzSsGkd/W9XbrLGXO9zxeG7MBoKmGaM1wCzfAAAAAElFTkSuQmCC) no-repeat right;
}

.arrow-up {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAbrQAAG60BIeRSlQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAANpJREFUOE9jGJzAwsJCyM7OztPMzIwPKkQ8sLe353F2dl7v6ur6BEjPBmI1qBRxAGgAh6OjY4m7u/t/oCF/gQacBtJuUGmiAQvQC7YuLi5fgZr/Ozk5fQCyC6ByxANLS0sxoAsuAzX/dXNz+w9kzwKGDydUmijADPSSA9AVv4CG/Ae5CIhjoXL4gY2NjSjQxlKghtdQb5wGGhYClcYPgBotgQG5BqjxN9TpM4CaNaDS+AEoDQA13ABpBNr+G2hQkpWVFS9UmijABDTAEGj7DqAhIFuZIMLYAAMDAPuUQ9EUeG3QAAAAAElFTkSuQmCC) no-repeat right;
}

JavaScript

var ViewModel = function () {
    var self = this;
    self.persons = ko.observableArray([{
        id: '1',
        name: ko.observable('Mounir'),
        email: ko.observable('[email protected]')
    }, {
        id: '2',
        name: ko.observable('Sam'),
        email: ko.observable('[email protected]')
    }]);
    self.closePopover = function (person) {
        $('#popover' + person.id + "_click").popover("hide");
    };
};

ko.bindingHandlers.popover = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var attribute = ko.utils.unwrapObservable(valueAccessor());
        var cssSelectorForPopoverTemplate = attribute.content;
        var popOverTemplate = "<div id='" + attribute.id + "-popover'>" + $(cssSelectorForPopoverTemplate).html() + "</div>";
        $(element).popover({
            content: popOverTemplate,
            html: true,
            trigger: 'manual'
        });
        $(element).attr('id', "popover" + attribute.id + "_click");
        $(element).click(function () {
            $(this).popover('toggle');
            var thePopover = document.getElementById(attribute.id + "-popover");
            childBindingContext = bindingContext.createChildContext(viewModel);
            ko.applyBindingsToDescendants(childBindingContext, thePopover);
        });
    }
};
ko.applyBindings(new ViewModel());

$('.accordion-group').on('show', function() {
    $(this).find('.accordion-toggle').removeClass('arrow-down').addClass('arrow-up');
});    
$('.accordion-group').on('hide', function() {
    $(this).find('.accordion-toggle').removeClass('arrow-up').addClass('arrow-down');
});