The knockout click event isn't functioning properly for a table generated by ko.computed

My goal is to connect a table to a drop-down menu. Here are the key points of what I'm trying to achieve:

  • The drop-down should list MENUs.

  • Each MENU can have multiple MODULES associated with it, which will be displayed in the table based on the selected menu item.

  • A MODULE doesn't necessarily have to be linked to a specific MENU, and in such cases, it is considered as SHARED among all selected menu items.

Here's an example interface that I currently have:

In this illustration, you can observe that the CommonShellModule is shared, indicating that it will appear for all menus.

This is the progress I've made so far:

http://jsfiddle.net/fag62z1x/

ViewModel:

var ModuleIndexViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, {}, self);

    self.selectedMenu = ko.observable();

    self.selectedMenuModules = ko.computed(function () {

        if (self.selectedMenu()) {

            //display modules for the selected menu or where they are not associated to a menu
            var modules = ko.utils.arrayFilter(self.Modules(), function (module) {
                return self.isModuleAssociatedToCurrentMenuSelection(module) || self.isSharedModule(module);
            });

            //return a sorted list of modules
            return modules.sort(function (left, right) {
                return left.Name() > right.Name() ? 1 : -1;
            }); 
        }
        return null;
    });

    self.isModuleAssociatedToCurrentMenuSelection = function (module) {
        if (self.selectedMenu()) {
            return module.MenuId() == self.selectedMenu().Id()
        }
        return false;
    }

    self.isSharedModule = function (module) {
        return module.MenuId() == null;
    }

    self.handleSharedCheckboxClick = function (module) {

        if (self.isSharedModule(module)) {
            module.MenuId(null);
        }
        else {
            module.MenuId(self.selectedMenu().Id());
        }

        return true; //allow the default click event action
    }
}

Models:

The models being mapped from (these models are serialized and passed into this view model):

public class IndexViewModel
{
    public IEnumerable<MenuViewModel> Menus { get; set; }
    public IEnumerable<ModuleViewModel> Modules { get; set; }
}

public class MenuViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ModuleViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? MenuId { get; set; }
}

View:

...

<div class="form-group top-buffer">
    <label class="control-label" for="menu">Menu</label>
    <select id="menu" class="form-control" data-bind="options: Menus, optionsText: 'Name', value: selectedMenu"></select>
</div>

<div class="row top-buffer">
    <div class="col-lg-12">

        <table class="table table-striped">
            <thead>
                <tr>
                    <th class="col-lg-6">Module Name</th>
                    <th class="col-lg-3">Shared</th>
                    <th class="col-lg-3"></th>
                </tr>
            </thead>
            <tbody data-bind="foreach: selectedMenuModules">
                <tr>
                    <td data-bind="text: Name"></td>
                    <td><input type="checkbox" data-bind="checked: $parent.isSharedModule($data), click: $parent.handleSharedCheckboxClick" /></td>
                    <td><a href="#">Edit</a> | <a href="#">Details</a> | <a href="#">Delete</a></td>
                </tr>
            </tbody>
        </table>

    </div>
</div>

...

The issue I'm facing is that the javascript handleSharedCheckboxClick isn't functioning as expected, and I'm unsure why. It gets triggered every time a shared checkbox is clicked, but when I update the module value within this function, the knockout computed isn't recalculated, leading to the table retaining the previous values.

I would appreciate any advice on how to resolve this matter.

Answer №1

Upon further investigation, I realized that the issue lies in the handling of the shared checkbox click event. Initially, the module value is set to null when it is shared, which prevents any changes from being made. To resolve this, I made a small modification to the code by adding a !, like so:

self.handleSharedCheckboxClick = function (module) {

    if (!self.isSharedModule(module)) {
        module.MenuId(null);
    }

This change now ensures that the shared status updates properly when toggling between menu item values - clicking the checkbox sets the item as unshared and bound to the current menu item, while clicking again reverts it back to shared.

Check out the jsfindle for more details: http://jsfiddle.net/yj1s9qod/

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

How to adjust the size of the text on a button in jQuery mobile using custom

I am facing an issue with my jQuery mobile buttons that are placed inside a fieldset. Specifically, I need to adjust the font-size of one of the buttons. Despite attempting to add an inline style, it did not have the desired effect. Furthermore, I tried u ...

Dimming the background of my page as the Loader makes its grand entrance

Currently, I am in the process of developing a filtering system for my content. The setup involves displaying a loader in the center of the screen whenever a filter option is clicked, followed by sorting and displaying the results using JQuery. I have a v ...

Demonstrate the proper implementation of a Stepper component using Material UI in a React.js

I am trying to display a responsive screen using "progressive forms" with React.js and Material Ui. I have implemented the Stepper component for this purpose, but when I click the "Next Button", the button is hidden but the next step content with the text ...

Is there a way for me to prevent the setTimeout function from executing?

I have a function that checks the status of a JSON file every 8 seconds using setTimeout. Once the status changes to 'success', I want to stop calling the function. Can someone please help me figure out how to do this? I think it involves clearTi ...

Search through an array, identify duplicates, and transfer them into a separate array

I am working with an array of objects containing dates and I am looking to extract objects with the same date values into a new array. Below is the code snippet. var posts = [ { "userid": 1, "rating": 4, "mood": "happy", "date": "2 ...

Using Tween animations with Three.js

I have some queries regarding tween js within three.js. Below is the code snippet where the particles are generated as shown in the image: Image 1 // Code snippet for initializing var scene; var renderer; var container; var stats; var sphere; // Omitted ...

Load JavaScript files in order within the <body> tag and trigger a callback function when all files have

Currently, my website (which is actually a Cordova/Phonegap app) has the following scripts in the <head>: <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="appPolyfills.js"></script> ...

retrieve the position of a descendant element in relation to its ancestor element

I'm encountering a challenge while attempting to solve this issue. I have elements representing a child, parent, and grandparent. My goal is to determine the offset position of the child (positioned absolutely) in relation to the grandparent. However, ...

What could be causing the erratic jumping behavior of the "newsletter sign-up" form within my modal dialog window?

On the homepage, there is a modal window that appears upon every pageload (it will be changed later), however, there seems to be an issue with the 'email sign up' form inside the window. The form seems to momentarily display at the top of the si ...

What is the best way to download the entire page source, rather than just a portion of it

I am currently facing an issue while scraping dynamic data from a website. The PageSource I obtain using the get() method seems to be incomplete, unlike when viewing directly from Chrome or Firefox browsers. I am seeking a solution that will allow me to fu ...

Load information into array for jqGrid display

I am attempting to populate my JQgrid with data every time I click the "1" button, but I am encountering difficulties. As a newbie in jQuery, I am able to display the data in a p tag without any issues. Currently, I am considering whether to use push or a ...

Substitute all items identified by a particular tag with a component

Is it possible to replace elements with React? I am interested in replacing all elements with a specific tag with an input field when an event like clicking an 'edit' button occurs. I have experience doing this with jQuery, but I would prefer us ...

Displaying a collapsible table directly centered within the table header

I am having trouble centering my table header in the web browser page. When I click the "+" button, the data is displayed beneath the table header, but I want the collapsible table to be centered directly below the header. I have tried making changes in CS ...

Modify the location of the input using jQuery

Hey there, I've got this snippet of HTML code: <div class='moves'> <div class='element'><input type='text' value='55' /></div> <input class='top' type='text&apo ...

Can we display the chosen form values before submitting?

Want to implement a confirmation message for users before submitting their form using onClick="return confirm('are you sure ?')". The basic form structure is as follows: <form> <Select name='val[]' class='select'> ...

Is it feasible to transmit telemetry through a Web API when utilizing ApplicationInsights-JS from a client with no internet connectivity?

My Angular application is running on clients without internet access. As a result, no telemetry is being sent to Azure. :( I am wondering if there is a way to configure ApplicationInsights-JS to call my .Net Core WebApi, which can then forward the inform ...

Avoiding the use of apostrophes in jQuery or JavaScript

I need to show the text below for the <span> element. What's the best way to handle single quotes in this case? $("#spn_err").text($('#txt1').attr('value')+" is not valid"); The desired message format is 'ZZZ' is ...

When it comes to mapping routes in the express framework of Node.js

Currently, I am facing an issue while setting up the route in my app.js file. The route for the listing of flights is passed in the routes/flights.js file. When I define the route at the bottom of all routes, it results in a 404 error. However, if I place ...

How can I retrieve information from PHP using json_encode and access it in JavaScript?

Currently in the process of developing a web app using Phonegap and XUI. Fetching data from an external domain through an http request with XUI. The retrieval process is successful, as I am able to receive JSON data in the following format: ({"first":"J ...

What is the purpose of re-checking the user in the passport.deserializeUser function?

After reading multiple articles on how to utilize passport.js, I'm left wondering why user verification is repeated within the passport.deserializeUser function. The code snippet looks like this: passport.deserializeUser((id, done) => { console. ...