I have a page with a table, bound with Knockout inside an UpdatePanel. My goal is to get the binding successfully applied after a postback. Everything works as expected on initial page load, so the model is working.
I'm using pageLoad() to call a function that gets the model's JSON data from a HiddenField that was set server side. In the view I have each RadioButton's click data-bind set to a JS function outside the ViewModel that sets a hidden input field's value to the ID specified by the button, and then causes a server postback by clicking a hidden button client-side.
Inside pageLoad() I'm using Sys.WebForms.PageRequestManager.getInstance().add_endRequest to specify that the binding helper function should be called after the server-side of the postback is complete.
My problems:
After being set server-side, the HiddenField with the JSON data still has the same string as it did client-side when it returns to the client, even though when the server-side scriptlet is executed, I can see that the value updated correctly. Not sure what is going on here.
Even if the values don't update, BindingHelper() is called, although for some reason clicking on the RadioButtons no longer causes the event after one postback has already occurred.
Any insight into this would be greatly appreciated!
Code:
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(BindingHelper)
function pageLoad() {
if (!isPostBack()){
BindingHelper();
}
}
function BindingHelper() {
var data = <%= hfData.Value%>;
var model = new DataViewModel();
model.load(data);
ko.applyBindings(model);
}
function Select(id) {
document.getElementById('<%=hfSelectedID.ClientID%>').value = id;
document.getElementById('<%=rbSelect.ClientID%>').click();
}
function isPostBack() {
return document.getElementById('hfPostback').value == 'True';
}
</script>
HTML:
<table id="tblData">
<thead>
<tr>
<th></th>
<!-- ko foreach: subViewModel -->
<th><input type="radio" name="rbGroup" data-bind="value: id, checked: $root.selectedID, click: function() {Select(id);}" /><span data-bind="text: name"></span></th>
<!-- /ko -->
</tr>
</thead>
</table>
<asp:HiddenField ID="hfData" runat="server" />
<asp:HiddenField ID="hfSelectedID" runat="server" />
<input id="hfPostback" type="hidden" value="<%=Page.IsPostBack.ToString()%>" />
<div style="display:none">
<asp:RadioButton ID="rbSelect" runat ="server" AutoPostBack="true" />
</div>
Edit: I've since determined that this works if the binding is not inside an UpdatePanel, just by registering BindingHelper() as a startup script in Page_Load.
Oddly enough, even if I register the startup script by specifying the UpdatePanel, the results are the same. There are other controls in the UpdatePanel so I know the UpdatePanel is in fact, updating, and it isn't set to conditionally update.