Posting Data to an ASP.NET Page Method with Knockout

PostingDataToPageMethodWithKnockoutSample

Last time in my Knockout series of posts, I explored how to retrieve and bind data from an ASP.NET page method. That’s only half the battle, though. How can you take data captured and do interesting things with it? I’ve got an idea! How about passing it to an ASP.NET page method!

I’m going to use my example from last time with a few modifications. I added some entry controls to capture the user’s status, and I modified the GetStatus page method to return the user’s last status. The last status values will be displayed as read-only and will only be visible when a value exists. Here’s the ASPX and code-behind. Note that ASPX contains a button bound to a method in the view model that’s not yet implemented, and the code-behind has a UpdateStatus method.

default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="adamprescott.net.Knockout.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-2.0.2.min.js"></script>
    <script src="Scripts/knockout-2.2.1.js"></script>
    <script type="text/javascript">
        $(function () {
            var viewModel = {
                wasHappy: ko.observable(),
                lastStatusText: ko.observable(),
                isCurrentlyHappy: ko.observable(),
                currentStatusText: ko.observable(),
                updateStatus: updateStatus,
            };
            ko.applyBindings(viewModel);
            getLastStatus();

            function updateStatus() {
                // todo: post data to page method
            }

            function getLastStatus() {
                $.ajax({
                    type: "POST",
                    url: "Default.aspx/GetStatus",
                    data: "{}",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (result) {
                        var data = result.d;
                        if (data == null) {
                            $("#lastTime").hide();
                            return;
                        }
                        $("#lastTime").show();
                        viewModel.wasHappy(data.HappyFlag);
                        viewModel.lastStatusText(data.Text);
                    }
                });
            }
        });
    </script>
</head>
<body>
    <div>
        <strong>How are you feeling?</strong><br/>
        Are you happy? <input data-bind="checked: isCurrentlyHappy" type="checkbox"/><br/>
        Tell me about it: <input data-bind="value: currentStatusText"/><br/>
        <button data-bind="click: updateStatus">Update Status</button>
    </div>
    <div id="lastTime">
        <strong>How you felt last time:</strong><br/>
        Were you happy? <input data-bind="checked: wasHappy" type="checkbox" disabled="true"/><br/>
        What you told me about it: <span data-bind="text: lastStatusText"></span>
    </div>
</body>
</html>

default.aspx.cs:

using System;
using System.Web.Services;

namespace adamprescott.net.Knockout
{
    public class Status
    {
        public bool HappyFlag { get; set; }
        public string Text { get; set; }
    }

    public partial class Default : System.Web.UI.Page
    {
        private static Status lastStatus = null;

        [WebMethod]
        public static Status GetStatus()
        {
            return lastStatus;
        }

        [WebMethod]
        public static void UpdateStatus(Status status)
        {
            lastStatus = status;
        }
    }
}

When the button is pressed, we need to collect values and put them into an object to be passed to our page method. That’s easy–just grab values from the view model:

var data = {};
data.HappyFlag = viewModel.isCurrentlyHappy();
data.Text = viewModel.currentStatusText();

Now that we’ve got our values, we just need to pass them to our page method. Once again, it’s jQuery to the rescue!

$.ajax({
    type: "POST",
    url: "Default.aspx/UpdateStatus",
    data: JSON.stringify({ 'status': data }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function () {
        // todo: anything?
    }
});

Bam! We just passed data to the page method in the code-behind. Tutorial accomplished. However, I need to go a little further. Now that I just updated the status, I want my UI to update its view to show the latest status. So, when my call to UpdateStatus finishes successfully, I just need to make another call to GetStatus. Super easy!

Here’s the final ASPX.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="adamprescott.net.Knockout.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-2.0.2.min.js"></script>
    <script src="Scripts/knockout-2.2.1.js"></script>
    <script type="text/javascript">
        $(function () {
            var viewModel = {
                wasHappy: ko.observable(),
                lastStatusText: ko.observable(),
                isCurrentlyHappy: ko.observable(),
                currentStatusText: ko.observable(),
                updateStatus: updateStatus, 
            };
            ko.applyBindings(viewModel);
            getLastStatus();

            function updateStatus() {
                // todo: post data to page method
                return;
                var data = {};
                data.HappyFlag = viewModel.isCurrentlyHappy();
                data.Text = viewModel.currentStatusText();
                $.ajax({
                    type: "POST",
                    url: "Default.aspx/UpdateStatus",
                    data: JSON.stringify({ 'status': data }),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function () {
                        getLastStatus();
                    }
                });
            }

            function getLastStatus() {
                $.ajax({
                    type: "POST",
                    url: "Default.aspx/GetStatus",
                    data: "{}",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (result) {
                        var data = result.d;
                        if (data == null) {
                            $("#lastTime").hide();
                            return;
                        }
                        $("#lastTime").show();
                        viewModel.wasHappy(data.HappyFlag);
                        viewModel.lastStatusText(data.Text);
                    }
                });
            }
        });
    </script>
</head>
<body>
    <div>
        <strong>How are you feeling?</strong><br/>
        Are you happy? <input data-bind="checked: isCurrentlyHappy" type="checkbox"/><br/>
        Tell me about it: <input data-bind="value: currentStatusText"/><br/>
        <button data-bind="click: updateStatus">Update Status</button>
    </div>
    <div id="lastTime">
        <strong>How you felt last time:</strong><br/>
        Were you happy? <input data-bind="checked: wasHappy" type="checkbox" disabled="true"/><br/>
        What you told me about it: <span data-bind="text: lastStatusText"></span>
    </div>
</body>
</html>
Advertisements

One thought on “Posting Data to an ASP.NET Page Method with Knockout”

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s