how to append a custom component to a div on button click

47 views
Skip to first unread message

Clint Meyer

unread,
Apr 5, 2017, 3:00:22 PM4/5/17
to KnockoutJS
Hi all,
I appreciate your help in advance.

I'm just messing around with an example using components. I'm trying to build up to a bigger project.

Below is the code. I'm able to inject the component directly into the markup, but I'm having trouble appending the component dynamically on a button click. Please offer any suggestions you may have to get this going.

<!DOCTYPE html>
<html>
<head>
    <title></title>
<meta charset="utf-8" />
    <script src="../scripts/knockout-3.4.0.js"></script>
    <script src="../scripts/jquery-1.9.1.js"></script>
</head>
<body>
    <greetings-component></greetings-component>
    <br /><br />
    <hr />
    <br /><br />
    <greetings-component params="fName: 'George', lName: 'Jones'"></greetings-component>
    <br /><br />
    <hr />
    <br /><br />
    <button id="add">Add Greeting</button>
    <div id="greet_container"></div>

    <script>
        $('#add').click(function () {
            $('#greet_container').append('<greetings-component></greetings-component>'); // ****** problem is right here: jquery isn't noticing the custom tag ******
        })

        ko.components.register('greetings-component', {
            viewModel: function (params) {
                this.fName = ko.observable(params && params.fName);
                this.lName = ko.observable(params && params.lName);
                this.fullName = ko.computed(function () {
                    var name = this.fName() + " " + this.lName();
                    if (this.fName() == null || this.lName() == null)
                        name = "Sir or Ma'am";
                    return name;
                }, this);
            },
            template: "<input type='text' data-bind='value: fName' />" +
                "<br> <input type='text' data-bind='value: lName' />" +
                "<br> Dear:  <span data-bind='text: fullName'></span>"
        });
        ko.applyBindings();
    </script>
</body>
</html>

noirabys

unread,
Apr 6, 2017, 3:28:26 AM4/6/17
to KnockoutJS
Hi,

i would recommend:

  1.) use object orientation
  2.) you don't need jquery at all
  3.) don't use events if not really necessary, let knockout handle it
  4.) see example:
  

<body>
    <button data-bind="click: addGreeting">Add Greeting</button>
    <div data-bind="foreach: greetings">
        <!-- perhaps put in greeting object instead of single params"-->
        <greetings-component params="{ fName:$data.fName ,lName:$data.lName }"></greetings-component>
    </div>

    <script>

        ko.components.register('greetings-component', {
            viewModel: function (params) {
                this.fName = params.fName;
                this.lName = params.lName;
                this.fullName = ko.computed(function () {
                    var name = this.fName() + " " + this.lName();
                    if (this.fName() == null || this.lName() == null)
                        name = "Sir or Ma'am";
                    return name;
                }, this);
            },
            template: "<input type='text' data-bind='value: fName' />" +
                "<br> <input type='text' data-bind='value: lName' />" +
                "<br> Dear:  <span data-bind='text: fullName'></span>"
        });
        function Greeting(data){
          var self = this;
          self.fName = ko.observable(data.fName);
          self.lName = ko.observable(data.lName);
        }
        
        function Model(){
          var self = this;
          self.greetings = ko.observableArray();

          self.addGreeting =function(){
             self.greetings.push(new Greeting({}));
          } 
        }
        
        ko.applyBindings(new Model());
    </script>
</body>

best regards,
 noirabys
Reply all
Reply to author
Forward
0 new messages