Show twitter bootstrap modal dialog automatically with knockout

Show twitter bootstrap modal dialog automatically with knockout

I need to show modal dialog for editing item in single page app when I select an item from list.
Problem: I used visible binding, but that turned out to be cumbersome, and it does not work properly, as it shows only dialog, without overlay, and fade (if any) does not work.
Html:

Model for this is simple object with observableList, obervable selectedItem, and deselectItem function which sets selectedItem to null.

Solutions/Answers:

Solution 1:

As I figured out, the (probably) best way to do this is to create a ko binding handler, I called it showModal:

ko.bindingHandlers.showModal = {
    init: function (element, valueAccessor) {},
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        if (ko.utils.unwrapObservable(value)) {
            $(element).modal('show');
            // this is to focus input field inside dialog
            $("input", element).focus();
        }
        else {
            $(element).modal('hide');
        }
    }
};

Usage is like this:

<div class="modal hide fade" data-bind="showModal:selectedItem, with:selectedItem">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h3 data-bind="text:name"></h3>
  </div>
  <div class="modal-body">
    <form data-bind="submit:deselectItem">
        <!-- editor for item here -->
    </form>
  </div>
  <div class="modal-footer">
    <a href="#" class="btn" data-bind="click:deselectItem">Close</a>
  </div>
</div>

Solution 2:

I like Gorans simple approach. Only problem is, that the html will not work in Bootstrap 3+.
The “hide” class is now enabled by default, and having it as class on modal div, will result in the div not showing. See http://www.bootply.com/bootstrap-3-migration-guide
This works:

Related:  twitter bootstrap navbar fixed top overlapping site
<div class="modal fade" data-bind="showModal:selectedItem, with:selectedItem">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                            <h3 data-bind="text:TextItem"></h3>
            </div>
            <div class="modal-body">
                <form data-bind="submit:$root.accept">
                    <!-- editor for item here -->
                    <div class="form-group">
                        <label>Text</label>
                        <input type="text" class="form-control" data-bind="value: TextItem" placeholder="Text">
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button class="btn" data-dismiss="modal">Luk</button>
                <button class="btn" data-bind="click:$root.accept">Gem</button>
            </div>
        </div>
    </div>
</div>

In this example click:$root.functionName will call a function in your ViewModel.

Solution 3:

It gets a lot easier if you apply the following pattern:

<form class="modal hide fade" data-bind="visible:selectedItem, with:selectedItem, submit:deselectItem">
    ...
</form>

That way, you get the form back in your submit handler and can properly close it there:

deselectItem = function(form){
  ...
  $(form).modal('hide');
}

Solution 4:

I have used this custom binding handler for bootstrap modals. Also in the modal i have added two moment datepicker. but when I use this binding handler the modal is visible on click event but datepicker div also visible

if I don’t use this and use

$('.classname_of_bootstrap_modal').modal('show')

The modal works perfectly fine.

Related:  Disable click outside of bootstrap modal area to close modal

So, i guess there is some issue in using this binding handler and not able to get it.

I commented this

$("input", element).focus();

On doing that the datepicker div’s are not displaying automatically. they are visible on when i click on them but issue on removing this is if i click one of the datepicker, it closes the bootstrap modal. but it shouldnt close it.

References