javascripthtmlknockout.jsoracle-jet

How to uniquely identify the selected value from drop down in Oracle jet which is inside for each bind


1).I have three names Bert,Charles,Denise.

2).Each an every name has drop down and submit button.(Used oj-bind-for-each)

3).I can select value from the drop-down and submit(It will catch the selected value from the drop down)

Action

Suppose I have selected

Problem

Expectation

How Could I achieve this?

Code

dashboard.html

      <div>    
      <oj-bind-for-each data="[[dataProvider]]">
          <template>
              <li>
              <oj-bind-text value="[[$current.data.status]]"></oj-bind-text>
              <oj-bind-text value="[[$current.observableIndex]]"></oj-bind-text> : <oj-bind-text value="[[$current.data.name]]"></oj-bind-text>
              <oj-button class='oj-button-sm' on-oj-action= "[[saveData]]">
                  Submit
              </oj-button>
              <oj-select-one id="[[uniquieId]]"
                             on-value-changed="[[selectedValue]]"  options="[[browsers]]" 
                             value="{{$current.data.status}}" style="max-width:20em">
              </oj-select-one>
              </li>

          </template>  
      </oj-bind-for-each>
  </div>

dashboard.js

define(['accUtils', 'knockout', 'ojs/ojarraydataprovider', 'ojs/ojknockout', 'ojs/ojbutton', 'ojs/ojselectcombobox'],
        function (accUtils, ko, ArrayDataProvider) {

            function DashboardViewModel() {
                var self = this;
                self.uniquieId = ko.observable();

                var users = ko.observableArray([
                    {id: "1", name: "Bert", status: "Internet Explorer"},
                    {id: "2", name: "Charles", status: "Chrome"},
                    {id: "3", name: "Denise", status: "Safari"}
                ]);
                self.dataProvider = new ArrayDataProvider(users, {keyAttributes: 'id'});
                self.selectVal = ko.observable('Chrome');
                self.selected = ko.observable();


                self.browsers = ko.observableArray([
                    {value: 'Internet Explorer', label: 'Internet Explorer'},
                    {value: 'Firefox', label: 'Firefox'},
                    {value: 'Chrome', label: 'Chrome'},
                    {value: 'Opera', label: 'Opera'},
                    {value: 'Safari', label: 'Safari'}
                ]);

                self.selectedValue = function (event, current) {

                    var optionValue = event.detail;
                    self.selected(optionValue.value);
                    console.log(self.selected());
                    console.log(optionValue);
                };

                self.saveData = function (event, current) {
                    self.uniquieId(current.observableIndex());
                    console.log(self.uniquieId());
                    console.log(self.selected());
                };

            }

            return DashboardViewModel;
        }
);

Solution

  • There are 2 fixes to be made:

    1. In the oj-select-one component you are binding the selected value to "{{$current.data.status}}". But for this to work correctly, $current.data.status has to be capable of getting its value updated and then reflecting the latest value. This is not possible when you make 'status' a simple string.

    Instead, they should be observables:

    var users = ko.observableArray([
         {id: "1", name: "Bert", status: ko.observable("Internet Explorer")},
         {id: "2", name: "Charles", status: ko.observable("Chrome")}),
         {id: "3", name: "Denise", status: ko.observable("Safari")}
    ]);
    

    In other words, any value bound between the View and Viewmodel that has to be updated through user interaction should be an observable.

    1. There is no use of the selected observable, because the selectedValue function simply updates selected to whatever was selected last. Instead, you can use your other variable uniquieId to get the correct data because your saveData function updates uniquieId with the index of the row you just clicked Submit on.

    So change your saveData function to this:

                self.saveData = function (event, current) {
                    self.uniquieId(current.observableIndex());
                    console.log(self.uniquieId());
                    console.log(users()[self.uniquieId()].status());
                };