Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Knockout JS inside JQuery dialog

I am using knockout js on a view to display a list of fields (ie, first name, last name, etc). The fields are listed inside a knockout template using the an observable array. The template contains the following fields: name (input), translation (select), and an add/remove function. (See below)

var viewModel = {
    Fields: ko.observableArray([new Field(2, "First Name", 1), new Field(3, "Last Name", 2)]),
    AvailableTranslations: ko.observableArray([new Translation(1, "Prefixes"), new Translation(2, "Suffixes")]),
    remove: function(item) {
        ko.utils.arrayRemoveItem(this.Fields, item)
    },
    add: function() {
        this.Fields.push(new Field(0, "", ""));
    }
};

var Translation = function(id, name) {
    this.ID = id;
    this.Name = name;
};

var Field = function(id, name, translationID){
    this.ID = ko.observable(id);
    this.Name = ko.observable(name);
    this.TranslationID = ko.observable(translationID);
};

Next to the translation select list in the template, I would like an option to add a new translation that does not exist. When the button is clicked I want to open a jquery UI dialog box containing a partial view that utilizes knockout. The partial view will contain a translation name as well as an old value and a new value (both text fields). The old and new values are an observable array.

var viewModelPartialDialog = {
    TranslationName: ko.observable(),
    Values: ko.observableArray([]),
};

var Value = function(id, oldVal, newVal) {
    this.ID = id;
    this.OldVal = oldVal;
    this.NewVal = newVal;
};

When the user submits the partial view's form, I would like it to make a save call as well as update the AvailableTranslations observable array.

Can anyone help me out or point me in the right direction to accomplish this?


Thanks for the example. It is helpful but not exactly what I'm trying to do. In your example, I wasn't able to add an observableArray to the Product and then have a nested template inside the dialog's edit template.

Going back to my original example, I would like to add new fields in viewModelA, similar to how you have the product list. However, instead of edit the field in the dialog, I'd like to open a dialog to add a new Translation. The new translation that opens in the dialog would be a separate view model (viewModelB). Once the translation name and values are added, the dialog would post asynchronously and then update original view model's (viewModelA) AvailableTranslations observable array.

Can you provide an example of this functionality?

like image 940
user947496 Avatar asked Sep 15 '11 19:09

user947496


1 Answers

Here is a sample that might be similar to what you are doing: http://jsfiddle.net/rniemeyer/WpnTU/

It sets up the dialog when the page loads, but doesn't open it. Then, there is a custom binding handler that will get called whenever a "selectedItem" observable is populated (which could be with an existing item or a new item).

The simple custom binding handler looks like:

//custom binding handler that opens the jQuery dialog, if the selectedProduct is populated
ko.bindingHandlers.openDialog = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (value) {
            $(element).dialog("open");
        }
    }
}
like image 176
RP Niemeyer Avatar answered Sep 24 '22 05:09

RP Niemeyer