установить выбор опции для привязанного ко входу в шаблоне, ИСПОЛЬЗУЯ java-скрипт (SIMPLIFIED EX ADDED) - PullRequest
0 голосов
/ 18 мая 2018

ОБНОВЛЕНО УПРОЩЕННЫМ ПРИМЕРОМ, СМОТРИТЕ ВТОРОЙ НАБОР КОДА И УПРОЩЕННУЮ СКРЕПКУ

У меня есть страница с шаблоном ко.Страницы '$ (document) .ready (function ()' выполняют кучу обработок на основе данных, которые она извлекает из базы данных, используя параметры url страниц. Эта обработка создает строку имени dbcolumn. Из этой функции doc ready js, которую я пытаюсь выполнитьустановить выбор опции для привязанного ко входу в шаблоне ко.

Я смоделировал это, используя поле ввода в следующем примере скрипки.

Когда страница скрипта запускает первый список, загружается и автоматически выбирает первый параметр, затем настраивает параметры второго списка на основе этого выбора. Это работает, как задумано. Но затем, когда я ввожу 'fname' в поле ввода и нажимаю, введите выбранный первый списокопция становится пустой (хотелось, чтобы она выбрала «имя»), и список опций List Two не изменился.

Я попытался использовать значение связывания [optionsValue: 'dbcolumn'] в List One (виднов закомментированном коде скрипки), но это только усугубило ситуацию. Я также попытался установить значение выбора для объекта '{"dbcolumn": "fname",«display»: «first name», «fieldtype»: «Text»} ', чтобы соответствовать элементу привязки, но это тоже не сработало.

Fiddle Пример: https://jsfiddle.net/bkhummingbird/r0kdL3sb/

Я ценю любую помощь или советы, которые вы можете мне дать для решения этой проблемы.:)

html-код ...

<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~MODEL~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<div class="container">
  <div data-bind="with: group">
    <div data-bind="template: templateName"></div>
  </div>
</div>
<div>
  1-db column name to pick from List One:
  <input id='strgToSelect' onchange='updateListOnePick();'/>
  <br/>
  <!-- 2-db column name to pick from List One:
  <input id='strgToSelect' onchange='updateListOnePick2();'/> -->
</div>

<!-- ~~~~~~~~~~~~~~~group-template~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<script type="text/html" id="group-template">
<br>
<u>This part works, you see it happen witht he inital page load</u>
<br/>
The intent of this page is that when <b>List One</b> selection changes <b>List Two</b> options reload with just the options from the get_jsonAttrList() call that have the same "fieldtype" as <b>List One</b>'s selection.
<br><br>
<u>This part FAILS, you see it fail by entering a column name like '<b>fname</b>' in the input box.'</u>
<br/>
The <b>'db column name to pick from List One:'</b> input should set the <b>List One</b> combo box selection on change which should inturn reload the <b>List Two</b> options.  
<br><br><b>**In my actual application the db column name will come from a parsed string from the database.
</b>
<br>
<br>
  <div class="alert alert-warning alert-group" style="border-width: 5px;border-color:blue;">
    List One: 
    <select data-bind="options: attributesAvailable,     
                     optionsText: 'display', 'fieldtype', 
                     value: compareAttrObject
                    " id='attrOne'>
    </select>
    <!-- this attempt made things worse:
                <select data-bind="options: attributesAvailable,     
                    optionsValue: 'dbcolumn', 
                     optionsText: 'display', 'fieldtype', 
                     value: compareAttrObject
                    " id='attrOne'>
    </select> -->
    <br>
    List Two:  
    <select data-bind="options: attributesAvailable2(), 
                     optionsText: 'display', 'fieldtype', 
                     value: compareToAttrObject
                    ">        
    </select>
  </div>
</script>


<script>
  window.addEventListener('load', function() {
    ko.applyBindings(new QueryBuilder.ViewModel());
  }, true);

</script>

js код ...

function updateListOnePick(){
    document.getElementById('attrOne').value = document.getElementById('strgToSelect').value
}
/* function updateListOnePick2(){
  document.getElementById('attrOne').value = '{"dbcolumn": "Apply_d", "display": "Application date", "fieldtype": "Date" }';
} */

function get_jsonAttrList() {
  return [{
      "dbcolumn" : "fid",
      "display" : "id #",
      "fieldtype" : "Number"
    }, {
      "dbcolumn": "fname",
      "display": "first name",
      "fieldtype": "Text"
    }, {
      "dbcolumn": "Apply_d",
      "display": "Application date",
      "fieldtype": "Date"
    }, {
      "dbcolumn": "location",
      "display": "location",
      "fieldtype": "Text"
    }, {
      "dbcolumn": "press_in",
      "display": "press in",
      "fieldtype": "Text"
    }, {
      "dbcolumn": "node1",
      "display": "node count",
      "fieldtype": "Number"
    }, {
      "dbcolumn": "comments",
      "display": "comments",
      "fieldtype": "Text"
    }, {
      "dbcolumn": "reg1_posname",
      "display": "Position Name",
      "fieldtype": "Text"
    }, {
      "dbcolumn": "reg1_inst_",
      "display": "inst count",
      "fieldtype": "Number"
    }, {
      "dbcolumn": "create_d8",
      "display": "create #",
      "fieldtype": "Number"
    }, {
      "dbcolumn": "mapped_d8",
      "display": "mapped #",
      "fieldtype": "Number"
    }, {
      "dbcolumn": "term_d",
      "display": "terminated date",
      "fieldtype": "Date"
    }, {
      "dbcolumn": "start",
      "display": "emp start date",
      "fieldtype": "Date"
    }]
}


//~~~~~~~~~~~~~~~~~~~~~~group~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
window.QueryBuilder = (function(exports, ko) {
  var Condition = exports.Condition;
  /**
   * creates an instants of the group template.
   */
  function Group() {
    var self = this;
    self.templateName = 'group-template';


    self.compareAttrObject = ko.observable();
    self.attributesAvailable = ko.observableArray(get_jsonAttrList());
    self.compareToAttrObject = ko.observable("");
    self.attributesAvailable2 = ko.observableArray(new Array());

    self.compareAttrObject.subscribe(function() {
      var tempAttrList = get_jsonAttrList();
      if (tempAttrList != null && tempAttrList.length > 0) {
        if (self.compareAttrObject() != undefined && self.compareAttrObject() != null) {
          alert("Length of list two BEFORE list one changed to ["+
                    self.compareAttrObject().fieldtype+
                    "]..." + self.attributesAvailable2().length);

                self.attributesAvailable2.removeAll();

          for (var i = 0; i < tempAttrList.length; i++) {
            if (tempAttrList[i].fieldtype == self.compareAttrObject().fieldtype) {
              self.attributesAvailable2.push(tempAttrList[i]);
            }
          }
          alert("Length of list two AFTER list one changed to ["+
                    self.compareAttrObject().fieldtype+
                    "]..." + self.attributesAvailable2().length);
        }
      }
    });

  }
  exports.Group = Group;
  return exports;
})(window.QueryBuilder || {}, window.ko);

//~~~~~~~~~~view model~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
window.QueryBuilder = (function(exports, ko) {

  var Group = exports.Group;

  function ViewModel() {
    var self = this;
    self.group = ko.observable(new Group());
  }

  exports.ViewModel = ViewModel;
  return exports;

})(window.QueryBuilder || {}, window.ko);

* ОБНОВЛЕНОС упрощенным примером *


Упрощенная скрипта Пример той же задачи

Упрощенный HTML:

<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~MODEL~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<div class="container">
  <div data-bind="with: group">
    <div data-bind="template: templateName"></div>
  </div>
</div>

<!-- ~~~~~~~~~~~~~~~group-template~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<script type="text/html" id="group-template">
 <center> (Simplified Try)</center><br>
  <u>This part FAILS</u>
  <br/> Press the <b>[Try]</b> button, which should change the selection in <b>List One</b> to be the option tied to '"dbcolumn": "comments1"' via the hard coded entry in the updateListOneSelection function. In turn the column name.type text next to the combo box should change to comments1.text.
  <br><br>
  <div>
    <button data-bind='click:updateListOneSelection'>Try</button>
  </div>
  <div class="alert alert-warning alert-group" style="border-width: 5px;border-color:blue;">
    <b>List One: </b>
    <select data-bind="options: attributesAvailable,   
                     optionsText: 'display', 'fieldtype', 
                     value: compareAttrObject
                    " id='attrOne'>
    </select>
    <b>Column Name.type: </b>
    <span data-bind="text:compareAttrObject().dbcolumn + '.' + compareAttrObject().fieldtype"></span>
  </div>
</script>

<script>
  window.addEventListener('load', function() {
    ko.applyBindings(new QueryBuilder.ViewModel());
  }, true);
</script>

Упрощенный JS:

function get_jsonAttrList() {
  return [{
    "dbcolumn": "fid",
    "display": "id #",
    "fieldtype": "Number"
  }, {
    "dbcolumn": "fname",
    "display": "first name",
    "fieldtype": "Text"
  }, {
    "dbcolumn": "location",
    "display": "location",
    "fieldtype": "Text"
  }, {
    "dbcolumn": "comments1",
    "display": "comments",
    "fieldtype": "Text"
  }, {
    "dbcolumn": "start",
    "display": "emp start date",
    "fieldtype": "Date"
  }]
}

//~~~~~~~~~~~~~~~~~~group~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~creates an instants of the group template.
window.QueryBuilder = (function(exports, ko) {
  var Condition = exports.Condition;

  function Group() {
    var self = this;
    self.templateName = 'group-template';
    self.compareAttrObject = ko.observable();
    self.attributesAvailable = ko.observableArray(get_jsonAttrList());
    self.updateListOneSelection = function() {
      alert("Will now try to set List One to the Comments1 column selection.");
      self.compareAttrObject({
        "dbcolumn": "comments1",
        "display": "comments",
        "fieldtype": "Text"
      });
    };
  }
  exports.Group = Group;
  return exports;
})(window.QueryBuilder || {}, window.ko);

//~~~~~~~~~~view model~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
window.QueryBuilder = (function(exports, ko) {
  var Group = exports.Group;

  function ViewModel() {
    var self = this;
    self.group = ko.observable(new Group());
  }
  exports.ViewModel = ViewModel;
  return exports;
})(window.QueryBuilder || {}, window.ko);

1 Ответ

0 голосов
/ 22 мая 2018

Решение для этого можно увидеть в моей скрипке по адресу: Скрипт решения

Мне пришлось выполнить следующую работу в шаблоне:

1. установить функцию optionAfterRender, чтобы добавить столбец data-dbcolumn в dom для параметров.

2. Затем действие нажатия кнопки (updateListOneSelection) смогло просмотреть значение data-dbcolumn в каждой из опций, чтобы найти индекс опции столбца 'comments1'.

3. Используя найденный индекс, я мог бы затем установить значение selectedIndex.

4. Произошло изменение выбора, но не удалось запустить привязку базы данных к тексту значения «Column Name.type» после поля со списком.Чтобы связать эти данные для обновления, мне нужно было добавить триггер $ ('# attrOne'). ('Change');строка.

html ...

<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~MODEL~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<div class="container">
  <div data-bind="with: group">
    <div data-bind="template: templateName"></div>
  </div>
</div>

<!-- ~~~~~~~~~~~~~~~group-template~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<script type="text/html" id="group-template">
  <center> (--Fixed--)<br>
  pressing the [Try] button will reset the Option-list selection to "comments".  The Column Name.type value will always update to the data for the selected value in the Option-list wether that option changed via selecting it or pressing the button.
  </center>
  <br><br>
  <div>
    <button data-bind='click:updateListOneSelection'>Try</button> sets selection to 'comments' using the dbcolumn value.
  </div>
  <div style="border-style: solid;border-width: 2px;border-color:blue;">
    <b>Option-list: </b>
    <select data-bind="options: attributesAvailable,   
                     optionsText: 'display', 'fieldtype', 'dbcolumn',
                     optionsAfterRender: setOptionDataAttrs,
                     value: compareAttrObject
                    " id='attrOne'>
    </select>
    <br><b>Column Name.type: </b>
    <span data-bind="text:compareAttrObject().dbcolumn + '.' + compareAttrObject().fieldtype"></span>
  </div>
</script>

<script>
  window.addEventListener('load', function() {
    ko.applyBindings(new QueryBuilder.ViewModel());
  }, true);

</script>

JS ...

function get_jsonAttrList() {
  return [{
    "dbcolumn": "fid",
    "display": "id #",
    "fieldtype": "Number"
  }, {
    "dbcolumn": "fname",
    "display": "first name",
    "fieldtype": "Text"
  }, {
    "dbcolumn": "location",
    "display": "location",
    "fieldtype": "Text"
  }, {
    "dbcolumn": "comments1",
    "display": "comments",
    "fieldtype": "Text"
  }, {
    "dbcolumn": "start",
    "display": "emp start date",
    "fieldtype": "Date"
  }]
}

//~~~~~~~~~~~~~~~~~~group~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~creates an instants of the group template.
window.QueryBuilder = (function(exports, ko) {

  function Group() {
    var self = this;
    self.templateName = 'group-template';
    self.compareAttrObject = ko.observable();
    self.attributesAvailable = ko.observableArray(get_jsonAttrList());
    self.updateListOneSelection = function() {
      var cnt = -1;
      $("#attrOne > option").each(function() {
        cnt++;
        //also works//var tmp = this.getAttribute('data-dbcolumn'); 
        var tmp = $(this).data('dbcolumn');
        console.log(this.text + '/' + this.value + ' - ' + tmp);

        if (tmp == 'comments1') {
          document.getElementById('attrOne').selectedIndex = cnt;
          $('#attrOne').trigger('change');
        }
      });
    };
    self.setOptionDataAttrs = function(option, item) {
      $(option).attr('data-dbcolumn', item.dbcolumn); // this  show up on DOM.
      $(option).attr('data-fieldtype', item.fieldtype); // this  show up on DOM.
    };
  }
  exports.Group = Group;
  return exports;
})(window.QueryBuilder || {}, window.ko);

//~~~~~~~~~~view model~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
window.QueryBuilder = (function(exports, ko) {
  var Group = exports.Group;

  function ViewModel() {
    var self = this;
    self.group = ko.observable(new Group());
  }
  exports.ViewModel = ViewModel;
  return exports;
})(window.QueryBuilder || {}, window.ko);
...