1

I'm trying to bind the IsConfirmed field from the ASP.NET webpages_Membership table to a checkbox, using Knockout JS and can't seem to get it working.

I have it binding to the checkbox, but unless I set it to !$data.IsConfirmed, the checkboxes are not check. I have also hooked up a click event to fire an updateUser function in my view-model, it does update it, but doesn't toggle the value sent. It always sends true, when it should send true if the checkbox is checked, otherwise false and then uncheck the checkbox.

Here is my markup

<table id="usersTable" class="table table-striped table-bordered table-hover">
    <thead>
        <tr>
            <th>User ID</th>
            <th>Username</th>
            <th>Role</th>
            <th>Date Created</th>            
            <th>Last Failed Login</th>            
            <th>Active</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: users">
        <tr>            
            <td>
                <span data-bind="text: $data.UserId"></span>
            </td>
            <td>
                <span data-bind="text: $data.Username"></span>
            </td>
            <td>
                <span data-bind="text: $data.Role"></span>
            </td>            
            <td>
                <span data-bind="text: $data.DateCreated"></span>
            </td>
            <td>
                <span data-bind="text: $data.LastFailedLogin"></span>
            </td>
            <td>
                <input type="checkbox" data-bind="click: updateUser, checked: $data.IsConfirmed" />
            </td>           
        </tr>
    </tbody>
</table>

And the Javascript

<script type="text/javascript">
    var baseUri = '@ViewBag.ApiUrl';
    var self = this;
    self.users = ko.observableArray();
    // define user view-model
    function UsersViewModel() {               
        // get users to populate the view model        
        $.getJSON(baseUri, self.users);        

        // update the users IsConfirmed status
        self.updateUser = function (user) {            
            $.ajax({ type: "PUT", url: baseUri + '/' + user.UserId, data: user });
        }
        // re-load the users after any modifications
        $.getJSON(baseUri, self.users);        
    };   
    $(document).ready(function () {
        ko.applyBindings(new UsersViewModel());        
    });
</script>

JSON From Server

[{
    "UserId": 6,
    "Username": "[email protected]",
    "Role": "Guest",
    "DateCreated": "11/12/2012 1:18:41 PM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 3,
    "Username": "simpleuser",
    "Role": "Administrator",
    "DateCreated": "11/11/2012 6:17:32 PM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 2,
    "Username": "testUser",
    "Role": "Administrator",
    "DateCreated": "11/11/2012 6:17:32 PM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 5,
    "Username": "[email protected]",
    "Role": "Student",
    "DateCreated": "11/12/2012 3:31:38 AM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 8,
    "Username": "[email protected]",
    "Role": "Alumni",
    "DateCreated": "11/12/2012 1:24:15 PM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 9,
    "Username": "[email protected]",
    "Role": "Applicant",
    "DateCreated": "11/12/2012 1:25:18 PM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 1,
    "Username": "user1",
    "Role": "Administrator",
    "DateCreated": "11/11/2012 6:17:31 PM",
    "LastFailedLogin": "11/12/2012 4:54:51 PM",
    "IsConfirmed": false
}, {
    "UserId": 4,
    "Username": "[email protected]",
    "Role": "Alumni",
    "DateCreated": "11/11/2012 6:22:23 PM",
    "LastFailedLogin": "11/11/2012 8:23:57 PM",
    "IsConfirmed": false
}, {
    "UserId": 7,
    "Username": "[email protected]",
    "Role": "Student",
    "DateCreated": "11/12/2012 1:23:56 PM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}]

C# Web API Controller

// GET api/Membership
        public IEnumerable<SiteMemberDTO> GetMemberships()
        {
            var users = db.webpages_Membership.AsEnumerable();
            var profiles = db.UserProfiles.AsEnumerable();            

            // now build our DTO object
            var membersList = new List<SiteMemberDTO>();
            foreach (var profile in profiles)
            {
                var member = new SiteMemberDTO() {
                    UserId = profile.UserId, 
                    Username = profile.UserName,
                    Role = profile.webpages_Roles.SingleOrDefault(r => r.RoleName != "").RoleName,
                    DateCreated = db.webpages_Membership.Find(profile.UserId).CreateDate.ToString(),
                    LastFailedLogin = db.webpages_Membership.Find(profile.UserId).LastPasswordFailureDate.ToString()
                };

                membersList.Add(member);
            }
            return membersList;
        }

DTO (Data-Transfer-Object)

 public class SiteMemberDTO
    {
        public int UserId { get; set; }
        public string Username { get; set; }
        public string Role { get; set; }

        public string DateCreated { get; set; }
        public string  LastFailedLogin { get; set; }

        public bool IsConfirmed { get; set; }
    }

This is the complete code for what I'm doing. For some reason I see in the JSON it's returning false for IsConfirmed, when in the database it's true for every record.

5
  • Can you show more of your markup? You must be iterating over the users at some point I presume? Commented Nov 13, 2012 at 5:12
  • Updated it with the complete markup. Commented Nov 13, 2012 at 5:19
  • Is the IsConfirmed property on the javascript object actually a boolean as opposed to a string value? Commented Nov 13, 2012 at 5:22
  • It si a bit column in the webpages_Membership table that gets created with ASP.NET's SimpleMembership provider. In my DTO (data-transfer-object) I have it in a boolean field, which is getting returned in the json as true or false. Commented Nov 13, 2012 at 5:27
  • Can you maybe post a sample json what you get from the server? Because your code looks fine... Commented Nov 13, 2012 at 6:20

1 Answer 1

2

I see you are not assigning the IsConfirmed when you create the DTO object. That's why it's always false!

var member = new SiteMemberDTO() {
                UserId = profile.UserId, 
                Username = profile.UserName,
                Role = profile.webpages_Roles.SingleOrDefault(r => r.RoleName != "").RoleName,
                DateCreated = db.webpages_Membership.Find(profile.UserId).CreateDate.ToString(),
                LastFailedLogin = db.webpages_Membership.Find(profile.UserId).LastPasswordFailureDate.ToString(),
                IsConfirmed = profile.IsConfirmed
            };

EDIT:

it seems there is a problem with checkboxes and click event: Checkboxes are being checked before click handler is even called

so instead of click, use change event:

data-bind="checked: IsConfirmed, event: { change: $parent.updateUser}"

checkout this fiddle: http://jsfiddle.net/Soroush/89anx/10/

Sign up to request clarification or add additional context in comments.

1 Comment

Nice catch! Thanks :) That fixed the value being returned to false, but now I need to know why when you click a checkbox, it doesn't un-check/re-check and it always sends the value true to the server in the updateUser javascript function. It needs to change it's value, based on the check state and then call the updateUser function, with the value. Trying to update the status field to activate and de-activate users. Thanks for all the help. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.