What is the best way to connect a chosen observable to a freshly inserted item?

I'm completely new to knockout. I have this sample set up where it will:

  1. Fill the left box with a list of items
  2. When you select an item in the left box, display its details in the right box

Seems like everything is working fine so far. But I want to enhance it further.

  1. On initial load, automatically select the first "foo" and show its details
  2. Clicking on the "+ Add foo" link should add a new "foo", highlight it, then show the editor in the right box. Once you click "save," it should add the new "foo" to the collection.

Is this achievable?

See code snippet below

var data = [
  { id: 1, name: "foo1", is_active: true },
  { id: 2, name: "foo2", is_active: true },
  { id: 3, name: "foo3", is_active: true },
  { id: 4, name: "foo4", is_active: false },
];

var FooBar = function (selected) {
  this.id = ko.observable("");
  this.name = ko.observable("");
  this.is_active = ko.observable(true);
  this.status_text = ko.computed(function () {
    return this.is_active() === true ? "Active" : "Inactive";
  }, this);
  this.is_selected = ko.computed(function () {
    return selected() === this;
  }, this);
};

var vm = (function () {
  var foo_bars = ko.observableArray([]),
    selected_foo = ko.observable(),
    load = function () {
      for (var i = 0; i < data.length; i++) {
        foo_bars.push(new FooBar(selected_foo)
          .name(data[i].name)
          .is_active(data[i].is_active)
          .id(data[i].id));
      }
    },
    select_foo = function (item) {
      selected_foo(item);
    },
    add_foo = function () {
      // Tried this but it's not working at all. Any help would be appreciated.
      // foo_bars.push(new FooBar(selected_foo));
    };

  return {
    foo_bars: foo_bars,
    load: load,
    selected_foo: selected_foo,
    select_foo: select_foo,
    add_foo: add_foo
  };
}());

vm.load();
ko.applyBindings(vm);
.box {
    float: left;
    width: 250px;
    height: 250px;
    border: 1px solid #ccc;
}

.selected {
    background-color: #ffa !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="box">
    <a href="#" data-bind="click: add_foo">+ Add foo</a>
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: foo_bars">
            <tr data-bind="click: $root.select_foo, css: { selected: is_selected }">
                <td><a href="#" data-bind="text: $data.name"></a></td>
                <td data-bind="text: $data.status_text"></td>
            </tr>
        </tbody>
    </table>
</div>
<div class="box" data-bind="with: selected_foo">
    Id: <span data-bind="text: id"></span><br />
    Name: <input type="text" data-bind="value: name" /><br />
    Status: <input type="checkbox" data-bind="checked: is_active"> <span data-bind="text: status_text"></span><br />
    <button>Save</button>
</div>

Answer №1

example: http://example.com/jsfiddle/sample/

initialize = function () {
    for(var j = 0; j < values.length; j++){
        bar_foos.push(new BarFoo(selected_bar)
              .name(values[j].name)
              .is_enabled(values[j].is_enabled)
              .identifier(values[j].identifier)
        );
    }
    selected_bar(bar_foos()[0]); // set first bar as default
},


add_bar = function() {
    var counter = bar_foos().length + 1;
    var newItem = new BarFoo(selected_bar).name('')
                .is_enabled(true)
                .identifier(counter)
    bar_foos.push(newItem);
    selected_bar(newItem);
};

Answer №2

It seems like the new object you are trying to add is missing the assigned name and id, which may be why it's not appearing. Additionally, remember that you have to select the new object in order for it to show up as selected in the left panel. Here is my code snippet for the add method:

add_item = function() {
    var new_item = new ItemElement(selected_item)
        .name("item_" + (items().length + 1));
    select_item(new_item);
    items.push(new_item);
};

You can check out the fully functional demo here http://jsfiddle.net/euq48em4/1/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to display items within a table using React?

I'm just starting to learn React. Can someone show me how to use the "map" function to list elements from two different arrays in two columns? state = { dates: ["2000", "2001", "2002"], cases: ["1", "2", "3"] } render() { return ( <thea ...

Having trouble connecting HTML and JS in jsFiddle? Unable to call a basic function using a button?

Help! I can't figure out why my code isn't working as expected. I've been trying to set up a jsFiddle, but for some reason, none of the JavaScript functions are being attached to the elements. For example, when I click on a button, nothing ...

Utilizing React JS to dynamically populate a table with data from an external JSON file

As a newcomer to the realm of React, I am facing challenges in displaying my JSON data in a table. class GetUnassignedUsers extends React.Component { constructor () { super(); this.state = { data:[] }; } com ...

Utilizing browser local storage in web development

Currently, I am in the midst of working on an e-commerce platform, a project that holds significant importance for me as it marks my debut into major projects. For the first time, I am delving into the realm of local storage to manage basket data such as q ...

Searching recursively for keys with empty values in an array using Javascript

I've written a function that recursively locates empty values in a nested array. The function initially produces the correct value, but it seems to reset it to the input value before returning the result. What could I be overlooking? Below is my co ...

The slow loading time of the website can be attributed to the excessive loading time of over 30 seconds due

My website, , is experiencing slow loading times due to a file named "json.gdn/gpl" which is causing it to take over 30 seconds to load completely. Unfortunately, I am not familiar with how to resolve this issue. I discovered this problem while using . If ...

Implementing Window.Open function within a jQuery Modal

I've set up my Modal Div like this: <div id="dialog-modal" title="Open File"> <img alt="progress" src="images/ajax-loader.gif"/> </div> When I click the button, the modal appears and I can see the progress icon. <sc ...

Switch the text display by clicking on a different button in the list

I am currently dealing with an issue involving a list of boxes containing text/images and buttons for expanding/collapsing the text. Whenever I click on another item's button, the text box that was previously opened gets closed, but the button text re ...

Mapping objects in an array with Javascript

This code snippet is intended for a React Native Chat app. The structure of my data should look something like this: const chatData = [ { id: 1, name: 'John Doe', messages: [ {text: 'Hello', sentAt: 'time here' ...

The styling of JSX input elements is not performing as anticipated

I am facing an issue with a component that is responsible for mapping input elements. These input elements have a flag indicating whether they should be displayed inline or not. Despite my efforts, I am struggling to make the flex property work as intended ...

Is it possible to execute a specified quantity of Promises simultaneously in Nodejs?

Currently, I am working on developing a web scraping application that utilizes a REST API to gather information from multiple entities on the server. The core functionality of this application can be summarized as follows: let buffer = [] for(entity in ent ...

Access cookie data using JavaScript or jQuery

One of my tasks is to include an asp page inside an iframe. You can view the page here: If a customer selects a font and then chooses a clip art image or uploads their own image for the clip art, I need to store all those values in cookies. Now, my goal ...

Dealing with Large JSON Strings in ASP.NET MVC Views

Large JSON Objects (approximately 1.5 MB) are received in Controller C1. They are then converted to strings and stored in a hidden label in View V1. The JSON data in V1 is utilized by parsing it in JavaScript J1. An occurrence of Out of Memory Excepti ...

"How can I extract father's details by clicking on a button

After clicking, I need to access the parent element. Here is the HTML code I have: <button mat-icon-button (click)="download($event)"> The generated HTML code is as follows: <button _ngcontent-wsc-c153="" mat-icon-button=&q ...

Change a space-separated string containing coordinates into an array of JavaScript objects

Here is a string separated by spaces: const coordinates = "42.44492,75.637764 42.445503,75.64534 42.433681,75.6604" Now, we want to convert it into an array of objects: const coordinatesArray = [ { lat: 42.44492, lng: 75.637764 }, { lat: 42.4455 ...

Disable browser autocomplete for Material-UI TextField

I am currently using Material UI version 0.20.0 and I am facing an issue where I need to prevent the password from being saved for a user in a TextField. I tried adding props to the TextField with autocomplete='nope' since not all browsers suppor ...

Unable to display date array in chart.js labels or x-axis within Django framework

In my Django project, I have a model called EmployeeDayOutput with two columns: output_date (which can be either a datetime or date field) and output_hours (a float). On an HTML page, I am using chart.js to display the data from EmployeeDayOutput, where ou ...

Set the background-color of each <td> element to be equal to a value in the array, with each group of three elements having the same

I am trying to color every <td> element in a row of three columns with the same color using the following code: for (var i = 0; itr < $("td").length; i++) { $("td").eq(i).css("background-color", Colors[i]); } However, this code colors each i ...

Retrieving Form Validation Error Value in AngularJS

Incorporating AngularJS 1.2 RC2 and utilizing Bootstrap for CSS, I have constructed a straightforward form as shown below: <form class="form-horizontal" name="form" novalidate> <label class="col-lg-2 control-label" for="name">Name</labe ...

The CSRF token is required for this action to be completed

Just recently, I discovered how to set up a web server on a Raspberry Pi using Django. I'm in the process of enhancing it by integrating JS to generate a form every time data is sent. However, I've encountered an error that I haven't been ab ...