AleshaOleg
AleshaOleg

Reputation: 2211

Add data to model from input

I want to know how to add data to mode, from my input. Here is my code:

Main file

var Bintime = new Marionette.Application();

Bintime.on("before:start", function(){
    var RegionContainer = Marionette.LayoutView.extend({
        el: "#app",
        regions: {
            contacts: "#contacts",
            name: "#name",
            messages: "#messages",
            input: "#input"
        }
    });

    Bintime.regions = new RegionContainer();
});

Bintime.on("start", function(){
    Bintime.Contacts.List.Controller.listContacts();
});

Model

Bintime.module("Contacts", function(Contacts, Bintime, Backbone, Marionette, $, _){
    Contacts.Contacts = Backbone.Model.extend({});

    Contacts.ContactsCollection = Backbone.Collection.extend({
        model: Contacts.Contacts,
        comparator: "firstName"
    });

    var contacts;

    var initializeContacts = function(){
        contacts = new Contacts.ContactsCollection([
            {
                id: 1,
                firstName: "Alice",
                lastName: "Arten",
                messages: [
                    {
                        from: "1",
                        message: "Hello"
                    },
                    {
                        from: "1",
                        message: "How r u?"
                    },
                    {
                        to: "1",
                        message: "Hey!"
                    },
                    {
                        to: "1",
                        message: "Great!"
                    }
                ]
            },
            {
                id: 2,
                firstName: "Bob",
                lastName: "Brigham"
            },
            {
                id: 3,
                firstName: "Charlie",
                lastName: "Campbell"
            }
        ]);
    };

    var API = {
        getContactContact: function(){
            if(contacts === undefined){
                initializeContacts();
            }
            return contacts;
        }
    };

    Bintime.reqres.setHandler("contacts:contacts", function(){
        return API.getContactContact();
    });
});

Main Controller

Bintime.module("Contacts.List", function(List, Bintime, Backbone, Marionette, $, _) {
    List.Controller = {
        listContacts: function() {
            var contacts = Bintime.request("contacts:contacts");

            var contactsView = new List.Contacts({
                collection: contacts
            });

            contactsView.on("childview:contact:contacts", function(childView, model) {
                Bintime.Contact.Name.Controller.nameContact(model);
            });

            contactsView.on("childview:chat:contacts", function(childView, model) {
                Bintime.Contacts.Messages.Controller.chatMessages(model);
            });

            contactsView.on("childview:message:contacts", function(childView, model) {
                Bintime.Message.Input.Controller.messageField(model);
            });

            Bintime.regions.contacts.show(contactsView);
        }
    }
});

Controller for module, which add message from input

Bintime.module("Message.Input", function(Input, Bintime, Backbone, Marionette, $, _) {
    Input.Controller = {
        messageField: function(model){
            var contacts = new Input.Contacts({
                model: model
            });

            Bintime.regions.input.show(contacts);
        }
    }
});

View for module, which add message from input

Bintime.module("Message.Input", function(Input, Bintime, Backbone, Marionette, $, _) {
    Input.Contacts = Marionette.ItemView.extend ({
        template: "#new",
        events: {
            "change input#message-input": "sendInput"
        },
        sendInput: function(e){
            e.preventDefault();
            var message = this.$("input#message-input").val();
            console.log(message);
        }
    });

    $('#new').append(v.el);
});

index.html

<div id="app" class="full-width full-height">
      <div class="full-width full-height">
        <div class="large-3 column contacts nopadding full-height">
          <div id="contacts">
          </div>
        </div>
        <div class="large-9 column full-height nopadding">
          <div id="name" class="user full-width">
            <div>

            </div>
          </div>
          <div id="messages">
          </div>
          <div id="input">
          </div>
        </div>
      </div>
    </div>
    <script type="text/template" id="contacts-list">
      <div class="contact">
        <div class="center text-center">
          <a href="#"><span class="text-center"><%= firstName%> <%= lastName%></span></a>
        </div>
      </div>
    </script>
    <script type="text/template" id="user">
        <h5 class="text-center"><%= firstName%> <%= lastName%></h5>
    </script>
    <script type="text/template" id="message">
      <% _.each(messages, function (item) { %>
        <div class="message">
          <div>
            <% if (item.from) { %>
              <div class="in">
                <%= item.message %>
              </div>
            <% } else if (item.to) { %>
              <div class="out">
                <%= item.message %>
              </div>
            <% } %>
          </div>
        </div>
      <% }); %>
    </script>
    <script type="text/template" id="new">
      <div class="enter full-width">
        <input id="message-input" type="text" placeholder="Enter your message..">
      </div>
      <a href="#" id="send" class="button">
        <span>Send</span>
      </a>
    </script>

As you can see, I already get my data from input field, here:

sendInput: function(e){
   e.preventDefault();
   var message = this.$("input#message-input").val();
   console.log(message);
}

But I can't add my data to model. I tried do it with .set(), but it override all my messages array. Something like that, but not exactly same:

sendInput: function(e){
    e.preventDefault();
    var field = $(e.currentTarget);
    var message = this.$("input#message-input").val();
    var data = {};
    data[field.attr("messages")] = message;
    this.model.set(data);
}

The result of adding "111" string to model, with previous example:

enter image description here

So, basically I need add new message to my model. Like this:

    id: 1,
    firstName: "Alice",
    lastName: "Arten",
    messages: [
        {
            from: "1",
            message: "Hello"
        },
        {
            from: "1",
            message: "How r u?"
        },
        {
            to: "1",
            message: "Hey!"
        },
        {
            to: "1",
            message: "Great!"
        },
        {
            to: "1",
            message: "HERE SHOULD BE NEW MESSAGE"
        }
   ]

Upvotes: 0

Views: 501

Answers (1)

T J
T J

Reputation: 43166

Assuming you have access to the model via this.model whose attribute hash looks like this:

{
   id: 1,
   firstName: "Alice",
   lastName: "Arten",
   messages: [{
        from: "1",
        message: "Hello"
      },
      {
        from: "1",
         message: "How r u?"
      },
      {
         to: "1",
         message: "Hey!"
      },
      {
         to: "1",
         message: "Great!"
      }]
}

as shown in question, you can add a new message to it like this:

this.model.get("messages").push({
    to: "1", // fill this as per your logic
    message: message 
});

This works because objects are passed by reference in JavaScript, and arrays are special objects.

Upvotes: 1

Related Questions