0
votes

I'm trying to bind values from observabeArray to select element. This observable array is the part of view model that binding to table with foreach. Unfortunately it's not working - I got just two empty elements.

JavaScript/jQuery:

<script>
        // heres what we are going to use for binding parameters
        var Roles = function (name, id) {
            this.Role = name;
            this.id = id;
        };
        var Sexes = function (name, id) {
            this.Sex = name;
            this.id = id;
        }
        function UsersViewModel() {
            //This is array values that I want to bind to select
            rolex: ko.observableArray([
                new Roles("Admin", 3),
                new Roles("User", 1),
                new Roles("Operator", 2)
            ]);
            sexx: ko.observableArray([
                new Sexes("Муж", 1),
                new Sexes("Жен", 0)
            ]);
            var self = this;
            //self.Id = ko.observable();
            //self.Login = ko.observable("");
            //self.Password = ko.observable("");         
            //self.Role = ko.observable();
            //self.Sex = ko.observable();           
            //var user = {
            //    Id: self.Id,
            //    Login: self.Login,
            //    Password: self.Password,
            //    Role: self.Role,
            //    Sex: self.Sex
            //};
            self.user = ko.observable();
            self.users = ko.observableArray();         
            var baseUri = '/api/users';
            $("#adduser").click(function () {
                var json = '{"Login":"' + $("#login").val() + '", "Password":"' + $("#password").val() + '", Sex":' + $("#_sex option:selected").val() + ', "Role":' + $("#_role option:selected").val() + '}';
                $.ajax({
                    url: baseUri,
                    cache: false,
                    type: 'POST',
                    contentType: 'application/json; charset=utf-8',
                    data: json,
                    success: function (data) {
                        $("#notification").text("Пользователь успешно добавлен!");
                        $('#notification').removeClass("hidden");
                        self.users.push(data);
                        setTimeout(function () {
                            $('#notification').addClass("hidden");
                        }, 3000);
                    }
                });
            });
            self.remove = function (user) {
                $.ajax({ type: "DELETE", url: baseUri + '/' + user.Id })
                    .done(function () {
                        $("#notification").text("Пользователь успешно удален!");
                        $('#notification').removeClass("hidden");
                        self.users.remove(user);
                        setTimeout(function () {
                            $('#notification').addClass("hidden");
                        }, 3000);
                    });
            }
            self.update = function (user) {
                $.ajax({ type: "PUT", url: baseUri + '/' + user.Id, data: user })
                .done(function () {
                    $("#notification").text("Изменения сохранены!");
                    $('#notification').removeClass("hidden");
                    setTimeout(function () {
                        $('#notification').addClass("hidden");
                    }, 3000);
                });
            }
            $.getJSON(baseUri, self.users);
        }
        $(document).ready(function () {
            ko.applyBindings(new UsersViewModel());
        })
    </script>


And here is table that show all data including mentioned selects.

HTML:

<table class="pure-table">
                <thead>
                    <tr>
                        <td></td>
                        <td>#</td>
                        <td>Логин</td>
                        <td>Пароль</td>
                        <td>Роль</td>
                        <td>Пол</td>
                    </tr>
                </thead>
                <tbody data-bind="foreach: users">
                    <tr>
                        <td>
                            <input type="button" value="Сохранить" data-bind="click: $root.update" class="pure-button" />
                            <input type="button" value="Удалить" data-bind="click: $root.remove" class="pure-button" />
                        </td>
                        <td data-bind="text: $data.ID"></td>
                        <td>
                            <input type="text" data-bind="value: $data.Login" />
                        </td>
                        <td>
                            <input type="text" data-bind="value: $data.Password" />
                        </td>
                        <td>
                            <select data-bind="options: rolex, optionsText: 'Role'">
                            </select>
                        </td>
                        <td>
                            <select id="sex" data-bind="options: sexx, optionsText: 'Sex'">
                            </select>
                        </td>
                    </tr>
                </tbody>
            </table>
1
Don't have time to answer, so I'm just going to quickly comment and say you need to do: data-bind="options: $root.rolex, optionsText: 'Role'" because the binding context is within a user (because of the foreach) - David Sherret
@DavidSherret, thanks for advise. It fixed error "rolex is not defined" but still not solved problem with options binding. - andrey.shedko
what error does it throw now? - Rahul Patil

1 Answers

2
votes

There are several changes that need to be made. First, your html needs to use the $root:

<td>
    <select data-bind="options: $root.rolex, optionsText: 'Role'"></select>
</td>
<td>
    <select id="sex" data-bind="options: $root.sexx, optionsText: 'Sex'"></select>
</td>

The code below works (see comments with what was changed):

var Roles = function (name, id) {
    this.Role = name;
    this.id = id;
}; 
var Sexes = function (name, id) {
    this.Sex = name;
    this.id = id;
};

function UsersViewModel() {
    //You should assign self on the first line and use it to assign all properties
    var self = this;

    self.rolex = ko.observableArray([
        new Roles("Admin", 3),
        new Roles("User", 1),
        new Roles("Operator", 2)]);
    self.sexx = ko.observableArray([
        new Sexes("Муж", 1),
        new Sexes("Жен", 0)]);

    self.user = ko.observable();
    self.users = ko.observableArray();

    //You should not add call to $("#adduser").click(...) here, it seems it belongs outside of model

    self.remove = function (user) {
        //Did not test, but it probably works
    };
    self.update = function (user) {
        //Did not test, but it probably works
    };
    return self;
}

// You can use such code to bind the values:
$(function(){
    //Create the model
    var model = new UsersViewModel();

    //Apply bindings
    ko.applyBindings(model);

    //Push the value to the array
    model.users.push({
        Id: 1,
        Login: "Login",
        Password: "Psw",
        Role: 3,
        Sex: 1
    });
});