0

I have a html form for adding multiple addresses:

http://i48.tinypic.com/jg2ruo.png

This way If I change the Address Type selection the entire form has to bind to the correct json address object:

var jsonAddresses = { Addresses:
            [
                { AddressType: 1, Address1: "", Address2: "",Province:"",City:"",State:"",PostalCode:"",Municipal:"" },
                { AddressType: 2, Address1: "", Address2: "",Province:"",City:"",State:"",PostalCode:"",Municipal:"" },
                { AddressType: 3, Address1: "", Address2: "",Province:"",City:"",State:"",PostalCode:"",Municipal:"" },
                { AddressType: 4, Address1: "", Address2: "",Province:"",City:"",State:"",PostalCode:"",Municipal:"" }
            ] 
         };

I have done this with Jquery with a lot of code actually but I want to know how can I do this with Knockout. The idea is instead of having a fixed json object with the 4 types of addresses i want to have only 1 json object and if I select an address type that is not in the array then the object is added and binded, if the address type already exists in the array then just bind it. then i can have a "remove" link that when clicked the selected address type object is removed from the array.

Thanks in advance.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
VAAA
  • 14,531
  • 28
  • 130
  • 253

1 Answers1

0

I'm guessing a little bit on this, because its not entirely clear. You want a single form for editing addresses, with a dropdown that lets you select which address you are editing. I've put a working fiddle together, but here are the important parts.

You have a concept of an Address object, which is observable since you will be updating the values. Then you need a viewmodel to keep track of all the address, have some concepted of the selected address, and the ability to add new addresses. This is the part that wasn't clear, so I just went with a New Address button. Let me know if you have something else in mind. Other than the list of states, and the initial address data (both which should come from the server) this is all the code, and as you can see knockout makes it pretty simple.

HTML:

<select data-bind="options: addresses, optionsText: 'typeName', value: selectedAddress"></select>
<div data-bind="with: selectedAddress">
    Name: <input data-bind="value: typeName" /></br>
    Line1: <input data-bind="value: address1" /></br>
    Line2: <input data-bind="value: address2" /></br>
    City: <input data-bind="value: city" /></br>
    State: <select data-bind="options: $parent.states, value: state"></select></br>
    Postal Code: <input data-bind="value: postalCode" />
</div>
<button data-bind="click: addAddress">New Address</button>
<button data-bind="click: deleteAddress">Remove Address</button>

ViewModels:

var Address = function(address) {
    this.id = ko.observable(address.AddressType || 0);
    this.typeName = ko.observable(address.TypeName || '');
    this.address1 = ko.observable(address.Address1 || '');
    this.address2 = ko.observable(address.Address2 || '');
    this.city = ko.observable(address.City || '');
    this.state = ko.observable(address.State || '');
    this.postalCode = ko.observable(address.PostalCode || '');
};

var App = function(addressList) {
    var self = this;
    self.states = states;
    self.addresses = ko.observableArray(ko.utils.arrayMap(addressList,
          function(i) { return new Address(i); }
    ));
    self.selectedAddress = ko.observable(self.addresses[0]);

    self.addAddress = function() {
        var newId = self.addresses()[self.addresses().length -1].id + 1;
        var newAddress = new Address({AddressType: newId});
        self.addresses.push(newAddress);
        self.selectedAddress(newAddress);
    };

    self.deleteAddress = function() {
        self.addresses.remove(self.selectedAddress());
        self.selectedAddress(self.addresses[0]);
    };
};

EDIT1: added remove button. This is for the demo, obviously you will want some safety logic when the array is empty.

Kyeotic
  • 19,697
  • 10
  • 71
  • 128
  • Wooow!!!! Amazing Tyrsius thank you very much for your support, i will try to hook up everything with my project and will post any news. thanks – VAAA Jul 05 '12 at 21:31
  • Sorry, now is marked as accepted... by the way where does the address type select change event is triggered in knockout? Thanks – VAAA Jul 05 '12 at 22:37
  • I am not sure I understand your question. Are you asking how the address type changes? Its the value binding on the first select element. – Kyeotic Jul 05 '12 at 22:38
  • Yes, exactly is the binding value: selectedAddress in the first select but when you setup the viewModel App i can only see: self.selectedAddress = ko.observable(self.addresses[0]); sorry.... i think i just get it :) – VAAA Jul 05 '12 at 22:48
  • @VAAA yea so what that does is make the `selectedAddress` an observable, since we are binding on it, and starts its initial value as the first address in our array. Later, when the `select` changes, its value binding will update the `selectedAddress`. – Kyeotic Jul 05 '12 at 22:58
  • Tyrsius, I did a change in http://jsfiddle.net/VAs5r/6/ in order to activate or deactivate an address (new address button or remove address button), this way I want to know if I need to save the object in server or not. Its working but it don't update the fields until I change the select option. Any clue? – VAAA Jul 06 '12 at 15:42
  • @VAAA, please ask this in another question with as much detail on how you want it to work. I'll be sure to check. – Kyeotic Jul 06 '12 at 15:47
  • Thanks.. ready http://stackoverflow.com/questions/11365664/knockout-force-select-update-binding – VAAA Jul 06 '12 at 16:04
  • hi, I just publish this, hope you can help me. Thanks a lot http://stackoverflow.com/questions/11618337/knockout-binding-select-first-filled-object – VAAA Jul 23 '12 at 18:32
  • @VAAA I will definitely look at that later, but I stalk the knockout tag pretty regularly, so if you post something there I will probably see it. – Kyeotic Jul 23 '12 at 18:38