简体   繁体   中英

how to bind true/false value to checkbox with ASP.NET MVC and Knockout JS

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": "john@jdoe.com",
    "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": "jdoe1@nowhere.com",
    "Role": "Student",
    "DateCreated": "11/12/2012 3:31:38 AM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 8,
    "Username": "nobody@somewhere.com",
    "Role": "Alumni",
    "DateCreated": "11/12/2012 1:24:15 PM",
    "LastFailedLogin": "",
    "IsConfirmed": false
}, {
    "UserId": 9,
    "Username": "test@test.com",
    "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": "test@test.com",
    "Role": "Alumni",
    "DateCreated": "11/11/2012 6:22:23 PM",
    "LastFailedLogin": "11/11/2012 8:23:57 PM",
    "IsConfirmed": false
}, {
    "UserId": 7,
    "Username": "test@test2.com",
    "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.

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM