0

I have an ASP.Net MVC4 website. Here's the problem view:

@model TVS.ESB.BamPortal.Website.Models.MyTasksViewModel
@using System.Web.Script.Serialization
@{
    ViewBag.Title = "My Tasks";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@ViewBag.Title</h2>
@{  string data = new JavaScriptSerializer().Serialize(Model); }

<div id="Knockout">
    @*  When select added thenKoGrid does not display! <select class="form-control" data-bind="options:users, optionsText: 'AdLoginId', value:selectedUser" />*@
    <div id="Buttons">
        <span>Reassign to User: <input class="form-control" data-bind="text:username"/></span>
        <button class="btn-default" data-bind="click:promoteState">Promote State</button>
        <button class="btn-default" data-bind="click:reassignTasks">Reassign Task(s)</button>
    </div>
    <div id="KoGrid" data-bind="koGrid: gridOptions" />


</div>


@section Scripts {
    <script src="~/KnockoutVM/Mytasks.js"></script>
    <link rel="stylesheet" type="text/css" href="~/Content/KoGrid.css">
    <script type="text/javascript">
        var vm = new ViewModel(@Html.Raw(data));
        ko.applyBindings(vm, document.getElementById("Knockout"));
    </script>
}

I have commented out the select that gives the problem. If I leave this in, then it displays fine, including the items from the observeable array I'd expect. However, for some reason the KoGrid is then not displayed. If I remove the Select then the KoGrid displays just fine. I've tried refreshing with the Google dev tool console window open but no errors are reported. Any ideas why?

Here are relevant parts of the knockout view model:

function ViewModel(vm) {
    var self = this;
    this.myData = ko.observableArray(vm.Recs);
    this.selected = ko.observableArray();
    this.users = ko.observableArray(vm.Users);
    this.selectedUser = ko.observable("");
    this.username = ko.observable("");

    this.rows = ko.observableArray(vm.Recs);

    this.gridOptions = {
        data: self.myData,
        enablePaging: true,
        pagingOptions: self.pagingOptions,
        filterOptions: self.filterOptions,
        selectWithCheckboxOnly: true,
        selectedItems: self.selected,
        canSelectRows: true,
        displaySelectionCheckbox: true,
        columnDefs: [{ field: 'Timestamp', displayName: 'Timestamp', width: 130 },
                    { field: 'State', displayName: 'State', width: 70 },
                    { field: 'FaultApplication', displayName: 'Application', width: 110 },
                    { field: 'FaultExceptionMessage', displayName: 'Exception Message', width: 400 },
                    { field: 'FaultServiceName', displayName: 'ServiceName', width: 140 },
                    { field: 'LinkToFaultsPage', displayName: 'Link to Fault', width: 80, cellTemplate: '<a data-bind="attr: { href: $parent.entity.LinkToFaultsPage}" >Fault</a>' }
        ]
    };
};
Rob Bowman
  • 7,632
  • 22
  • 93
  • 200

2 Answers2

1

Your KOGrid is not displayed because your HTML is invalid:

The select tag cannot be self-closing see also on MDN.

So you need to always write out the closing tag </select>:

<select class="form-control" 
        data-bind="options:users, 
        optionsText: 'AdLoginId', value:selectedUser">
</select> 

Otherwise the HTML is invalid and Knockout cannot interpret it properly.

nemesv
  • 138,284
  • 16
  • 416
  • 359
0

I was able to work-around by moving the select list to a separate div and using the ko.applyBindings twice:

<div id="ControlPanel">
    <select class="form-control" data-bind="options:users, optionsText: 'AdLoginId', value:selectedUser" />
    <div id="Buttons">
        <span>Reassign to User: <input class="form-control" data-bind="text:username" /></span>
        <button class="btn-default" data-bind="click:promoteState">Promote State</button>
        <button class="btn-default" data-bind="click:reassignTasks">Reassign Task(s)</button>
    </div>
    <div id="KoGrid" data-bind="koGrid: gridOptions" />
</div>

@section Scripts {
    <script src="~/KnockoutVM/Mytasks.js"></script>
    <link rel="stylesheet" type="text/css" href="~/Content/KoGrid.css">
    <script type="text/javascript">
        var vm = new ViewModel(@Html.Raw(data));
        ko.applyBindings(vm, document.getElementById("ControlPanel"));
        ko.applyBindings(vm, document.getElementById("KoGrid"));
    </script>
}
Rob Bowman
  • 7,632
  • 22
  • 93
  • 200
  • 1
    **The `select` tag cannot be self-closing** https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select. So you need to always write out the closing tag: `` otherwise your HTML is invalid and KO cannot parse it properly. – nemesv Mar 22 '16 at 09:54
  • Thanks again nemesv. Life would be so much easier if I knew basic html! If you could add as answer i will mark as correct – Rob Bowman Mar 22 '16 at 10:00