0

I am using knockoutJS for data binding. I am looping through a list of comments and using mdl-menu for each comment to provide admin options on comment like edit and delete and also setting each comment's menu icon's id according to corresponding comment id. So id for 1st comment will be "comment-1" and 'for' attribute in mdl menu list will be "comment-1". On clicking the menu icon, I am using componentHandler.upgradeDom() to register the elements again, but still the menu is not opening.

1 Answers1

0

I made an attempt at it using a binding handler. click the menu icon to see the menu. click the add button to add a new menu item.

you can run below, or if you want to modify it in jsfiddle it is here https://jsfiddle.net/7zop2n9j/7/

ko.bindingHandlers.mdmemenu = {
  init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    ko.bindingHandlers.value.init(element, valueAccessor, allBindings);
    var source = allBindings.get('menuOptions');
    var sourceUnwrapped = ko.unwrap(source);
    var myId = valueAccessor()();
    var myHtml = '<button id = "'
    myHtml = myHtml + myId;
    myHtml = myHtml + '"'
    myHtml = myHtml + 'class="mdl-button mdl-js-button mdl-button--icon">';
    myHtml = myHtml + ' <i class="material-icons">more_vert</i>'
    myHtml = myHtml + '</button>'
    myHtml = myHtml + ' <ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect"'
    myHtml = myHtml + 'for = "'
    myHtml = myHtml + myId;
    myHtml = myHtml + '"'

    myHtml = myHtml + '</ul>'
    $(element).append(myHtml);
    componentHandler.upgradeDom();
  },
  update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var value = valueAccessor();
    ko.bindingHandlers.value.update(element, valueAccessor);
    $(element).empty();
    var source = allBindings.get('menuOptions');
    var sourceUnwrapped = ko.unwrap(source);
    var myId = valueAccessor()();
    var myHtml = '<button id = "'
    myHtml = myHtml + myId;
    myHtml = myHtml + '"'
    myHtml = myHtml + 'class="mdl-button mdl-js-button mdl-button--icon">';
    myHtml = myHtml + ' <i class="material-icons">more_vert</i>'
    myHtml = myHtml + '</button>'
    myHtml = myHtml + ' <ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect"'
    myHtml = myHtml + 'for = "'
    myHtml = myHtml + myId;
    myHtml = myHtml + '"'
    $.each(sourceUnwrapped, function(i, item) {
      myHtml = myHtml + '<li class="mdl-menu__item">' + item.myText() + '</li>'
    });
    myHtml = myHtml + '</ul>'
    $(element).append(myHtml);
    componentHandler.upgradeDom();
  }
};

function menuOption(myText) {
  var self = this;
  this.myText = ko.observable(myText);
}

function model() {
  var self = this;
  this.menuOptions = ko.observableArray()
  this.myId = ko.observable('demo-menu-lower-left');
  this.addRow = function() {
    self.menuOptions.push(new menuOption('new menu item'));
  }

}

var myViewModel = new model();

$(document).ready(function() {
  ko.applyBindings(myViewModel);
  myViewModel.menuOptions.push(new menuOption('Some Action'));
  myViewModel.menuOptions.push(new menuOption('Another Action'));
  myViewModel.menuOptions.push(new menuOption('Disabled Action'));
  myViewModel.menuOptions.push(new menuOption('Yet Another Action'));
});
<link href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.getmdl.io/1.3.0/material.min.js"></script>

<div data-bind="mdmemenu: myId, menuOptions: menuOptions "></div>

<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
  <i class="material-icons" data-bind="click:addRow">add</i> 
</button>
Bryan Dellinger
  • 4,724
  • 7
  • 33
  • 79