How can I update the color of a list item when it is clicked within a foreach loop using knockout js?

Currently, I am encountering an issue with changing the color when a user clicks on a list item using the latest version of knockout js. My goal is to change the color of a list item when it is clicked and maintain that color until another item is clicked, but so far I haven't been successful.

One idea I have is to retrieve the index value of the clicked list item and add a CSS class with inverted colors (color: black, background-color: white).

HTML

<div class="left_pane">
    <div class="location_list" data-bind="foreach: locations">
        <div data-bind="text: title, click: $parent.is_selected, css: {selected: $parent.current_index == $index }"></div>
    </div>
</div>

CSS

.left_pane {
    background-color: black;
    color: white;
    padding-top: 10px;
    height: 850px;
}

.location_list {
    padding-top: 10px;
    padding-bottom: 10px;
    cursor: pointer;
    cursor: hand;
}

.selected {
    background-color: white;
    color: black;
}

JavaScript

var locations = [
    {'title': 'title01'},
    {'title': 'title02'},
    {'title': 'title03'},
    {'title': 'title04'},
    {'title': 'title05'}
];

function InitViewModel() {
    // main viewModel
    var self = this;

    self.current_index = ko.observable('');

    console.log(self.current_index());

    self.is_selected = function(data, event) {
       // save clicked row's index to current_index.
       self.current_index($(event.target).index());
       console.log(self.current_index());
    };
}

ko.applyBindings(new InitViewModel());

Thank you in advance for any support and suggestions provided.

Answer №1

Getting closer! I have found that tracking the selected item in its own observable simplifies things, setting it to the clicked item. You can still use the same method to change the class to selected. If you need to select multiple items, I usually use an object to track the selected status (e.g.,

'title': 'title01', selected: false }
) and then just update the click function to location.selected(true).

The key difference between your code and mine is not tracing back location items but taking them as they are. If it matches, great; if not, you still have what you need.

function InitViewModel() {
  // main viewModel
  var self = this;

  self.Selected = ko.observable("");

  self.locations = [{
      'title': 'title01'
    }, {
      'title': 'title02'
    }, {
      'title': 'title03'
    }, {
      'title': 'title04'
    }, {
      'title': 'title05'
    }
  ];

  self.current_index = ko.observable('');

  console.log(self.current_index());

  self.select = function(location) {
  self.Selected(location);
  };
}

ko.applyBindings(new InitViewModel());
.left_pane {
  background-color: #BBB;
  color: white;
  padding-top: 10px;
  height: 850px;
}

.location_list {
  padding-top: 10px;
  padding-bottom: 10px;
  cursor: pointer;
  cursor: hand;
}

.selected {
  background-color: white;
  color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="left_pane">
  <div class="location_list" data-bind="foreach: locations">
    <div data-bind="text: title, click: $parent.select, css: {selected: $data === $parent.Selected() }"></div>
  </div>
</div>

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

Having trouble getting the jQuery autocomplete feature to function properly?

On my page, there is a button labeled "Add a Skill." Clicking on this button should trigger the display of an input box where you can enter your skill, another input box for your skill level, and a horizontal slider to select the skill level. In my databa ...

Utilize the client-side JavaScript file with ejs framework

Recently, I have been working on creating a website using Express and EJS. I discovered that using just one JavaScript file for all my EJS (view) files was causing issues. If I target a DOM element in one view page and it doesn't exist in another, I w ...

Troubles arise with IE8 when using Position: fixed styling

Here is the CSS code I am using: background-color: White; border: 2px solid black; padding: 10px; position: fixed; right: 5px; top: 0; width: 250px; While this code works well in Chrome, Firefox, and Safari, I am facing issues with IE8. The position of t ...

The Angular scope remains stagnant even after applying changes

Having trouble updating a variable in the ng-repeat loop <div ng-controller="MapViewCtrl"> <a class="item item-avatar" ng-href="#/event/tabs/mapView" > <img src="img/location.jpg"/> <span cl ...

Utilizing JQuery, Ajax, and a Struts2 framework to manage and display

I am in need of assistance in implementing a JQuery/Ajax call to retrieve a List from a Struts action and populate a DIV with the list elements using s:iterator. Below is the JQuery code snippet I have: function lookupCustomerJs() { alert("lets s ...

Setting up a CentOs Linux environment to host and run a node.js server

Just installed node.js on my new VPS server. I have written a basic script called "server.js" and it is currently running on port 8080. The location of the script is in the "var/www/html/" directory. However, whenever I try to access my domain, it only dis ...

Is it possible for ng-change to invoke another controller?

Can someone help me with the following HTML code? <div ng-controller="select"> <select ng-options="n for n in names" ng-model="selected.item" ng-change="change()"> </select> </div> <div ng-co ...

Add content to a jQuery element containing table cells at a specific position

Can the following task be achieved? If we take a string of table cells as an example: let str = "<td></td><td></td><td></td>"; Is it possible to convert this string into a jQuery object like this and insert text into ...

Is it necessary to incorporate Babel into a project that involves developing a backend service using Node.js and a front-end component using the EJS view engine?

I find myself a little confused. Some say that if you are working on pure Node.js projects, there is no need to stress about this issue. However, for web development, it's important to be familiar with these tools. On the other hand, some recommend us ...

What is the best way to arrange an array in either javascript or typescript based on a specific key, and in the case of identical keys,

Below is an array with objects that need to be sorted: [ { "Books": [], "_id": "5dea9a11a8e1bf301c462ce4", "FileName": "AAAAA", "Order": 99999 }, { "_id": "5dea9864a8e1bf301c462cdb", "Books": [], "FileName": "some1", ...

Is it possible to retrieve the parent object?

My code snippet is as follows, and I'm struggling to access the data object from within the innerFn function. Is there a way to accomplish this? export default { data: { a: "a", b: "b" }, fn: { innerFn: () => co ...

Show the value in the input text field if the variable is present, or else show the placeholder text

Is there a ternary operator in Angular 1.2.19 for templates that allows displaying a variable as an input value if it exists, otherwise display the placeholder? Something like this: <input type="text "{{ if phoneNumber ? "value='{{phoneNumber}}&a ...

Retrieve the key value from the specified input ID using jQuery

I have a list containing multiple input fields <input type="hidden" id="elevens_id_ea" value="<?php echo $_GET['elev_id']; ?>" /> <input type="hidden" id="arskursen_ea" value="<?php echo $arskursen; ?>" /> <?php if ($ ...

Sequential selection in Node-firebird is non-functional

I've been testing some simple code sequentially using the Firebird library called "node-firebird." Despite having multiple rows, it only returns 1 row every time. exports.sequentially = (select, db_con_options) => { Firebird.attach(db_con_options, ...

Avoid re-rendering the page in Nuxt when adjusting dynamic parameters

My page has two dynamic parameters that trigger the fetch method to run again when the URL params are changed. I want to avoid this behavior. Fetch Method: async fetch() { await this.getFlightResult(); } Get Result Method: async getResult() { th ...

Effectively detect the 'scrollend' event on mobile devices

When implementing the -webkit-overflow-scrolling: touch; style on a mobile element, dealing with scroll events can be quite challenging as they are triggered by various actions such as 'flicking', 'panning' and when the scroll comes to ...

Obtain every Scope within an AngularJS application

Is there a method to access all the Scopes within an AngularJS application? This would allow me to manage them at the same level and arrange them in a directive manner or order. Alternatively, is it possible to retrieve all the Scopes of the instances of ...

Execute Validation Function on Every TextField and Radio Button

I'm new to Javascript and struggling to make my function work for both radio buttons and text fields. Here is the HTML code for the form: <form action="sendmail.php" method="post" name="cascader" onsubmit="prepareEventHandlers()" id="cascader"&g ...

Delving into the World of ES6 Symbols

Throughout my experience with various programming languages, from C# to Lisp to Scala to Haskell, symbols have consistently behaved as singleton objects. This means that any two symbols with the same name are guaranteed to be identical. In Racket: (equal? ...

Having trouble with the alignment of the product grid on Woocommerce with the Wootique theme?

Hey there, I've been facing an issue with the woocommerce product display grid layout. The items keep getting misaligned, with one on a line and the others right next to each other. I attempted to fix it by adding some custom CSS code: .woocommerce ...