jQuery UI Widgets Forums Navigation Tree Knockout Tree DropdownButton

This topic contains 16 replies, has 2 voices, and was last updated by  Akap 9 years, 4 months ago.

Viewing 15 posts - 1 through 15 (of 17 total)
  • Author
  • Knockout Tree DropdownButton #76581

    Akap
    Participant

    Ok My peoples! I am trying to create a knockout tree dropdownbutton scenario. I’ve been able to data-bind an JSON array, and so forth. WHat is not working is the dropdownbutton event ‘open’ is not executing. This event opens up the tree naturally. Below is the rendered html and javascript.

    [Rendered HTML]

    
    <div id="jqxWidget" class="jqxWidget">
                    <div style="background-color: transparent; -webkit-appearance: none; outline: none; width:100%; height: 100%; padding: 0px; margin: 0px; border: 0px; position: relative;" tabindex="0"><div id="dropDownButtonWrapperjqxWidget1ced51d0" style="outline: none; background-color: transparent; border: none; float: left; width:100%; height: 100%; position: relative;" class="jqx-disableselect"><div id="dropDownButtonContentjqxWidget1ced51d0" unselectable="on" style="outline: none; border: none; float: left; position: relative; width: 175px; height: 25px; left: 0px; top: 0px; background-color: transparent;" class="jqx-dropdownlist-content"><div style="position: relative; margin-left: 3px; margin-top: 5px;">Select Category<div data-bind="customTree:{source: $data.dataCategoryItem }" id="jqxWidgetf8114fe1" role="tree" data-role="treeview" tabindex="1" class="jqx-widget jqx-widget-content jqx-tree"><div style="overflow: hidden; width: 109px; height: 252px; background-color: transparent;" id="paneljqxWidgetf8114fe1" class=""><div id="panelWrapperpaneljqxWidgetf8114fe1" style="overflow: hidden; width: 100%; height: 100%; background-color: transparent; -webkit-appearance: none; outline: none; align:left; border: 0px; padding: 0px; margin: 0px; left: 0px; top: 0px; valign:top; position: relative;"><div id="panelContentpaneljqxWidgetf8114fe1" style="-webkit-appearance: none; box-sizing: border-box; width: 100%; height: 100%; outline: none; border: none; padding: 0px; position: absolute; margin: 0px; left: 0px; top: 0px; max-width: 1e+07px; overflow: visible;" class="jqx-widget-content"><ul class="jqx-tree-dropdown-root"><li item-checked="false" id="observable: " d6c2b510-5bf8-467c-998d-cc02548574c3""="" role="treeitem" class="jqx-tree-item-li jqx-disableselect" style="margin-left: 0px; float: none;"><span style="height: 17px; border: none; float: left; clear: both; width: 16px; margin-top: 3px; background-color: transparent;" id="arrowobservable: " class="jqx-tree-item-arrow-collapse jqx-icon-arrow-right jqx-disableselect"></span><div style="display: inline-block;" class="draggable jqx-rc-all jqx-tree-item jqx-item">Agriculture</div><ul class="jqx-tree-dropdown" style="overflow: hidden; display: none;"><li item-checked="false" id="observable: " ae7289a5-9bdc-4bca-8b76-43a14b25edca""="" role="treeitem" class="jqx-tree-item-li" style="margin-left: 16px;"><div style="display: inline-block;" class="draggable jqx-rc-all jqx-tree-item jqx-item">Landscaping</div><ul class="jqx-tree-dropdown" style="overflow: hidden; display: none;"></ul></li></ul></li></ul></li></ul></div><div id="paneljqxWidgetf8114fe1verticalScrollBar" style="left: 0px; top: 0px; position: absolute; visibility: hidden;" class="jqx-scrollbar jqx-widget jqx-widget-content jqx-rc-all"><div id="jqxScrollOuterWrappaneljqxWidgetf8114fe1verticalScrollBar" style="box-sizing: content-box; width:100%; height: 100%; align:left; border: 0px; valign:top; position: relative;" class="jqx-reset"><div id="jqxScrollWrappaneljqxWidgetf8114fe1verticalScrollBar" style="box-sizing: content-box; width: 2px; height: 100%; left: 0px; top: 0px; position: absolute;" class="jqx-reset jqx-scrollbar-state-normal"><div id="jqxScrollBtnUppaneljqxWidgetf8114fe1verticalScrollBar" style="box-sizing: content-box; left: 0px; top: 0px; position: absolute; width: 0px; height: 0px;" class="jqx-scrollbar-button-state-normal jqx-rc-t"><div class="jqx-reset jqx-icon-arrow-up"></div></div><div id="jqxScrollAreaUppaneljqxWidgetf8114fe1verticalScrollBar" style="box-sizing: content-box; left: 0px; top: 2px; position: absolute; height: 0px; width: 10px;" class="jqx-reset"></div><div id="jqxScrollThumbpaneljqxWidgetf8114fe1verticalScrollBar" style="box-sizing: content-box; left: 0px; top: 2px; position: absolute; width: 0px; height: 10px; visibility: inherit;" class="jqx-scrollbar-thumb-state-normal jqx-fill-state-normal jqx-rc-all"></div><div id="jqxScrollAreaDownpaneljqxWidgetf8114fe1verticalScrollBar" style="box-sizing: content-box; left: 0px; top: 12px; position: absolute; height: 0px; width: 10px;" class="jqx-reset"></div><div id="jqxScrollBtnDownpaneljqxWidgetf8114fe1verticalScrollBar" style="box-sizing: content-box; left: 0px; top: -2px; position: absolute; width: 0px; height: 0px;" class="jqx-scrollbar-button-state-normal jqx-rc-b"><div class="jqx-reset jqx-icon-arrow-down"></div></div></div></div></div><div id="paneljqxWidgetf8114fe1horizontalScrollBar" style="left: 0px; top: 0px; position: absolute; visibility: hidden;" class="jqx-scrollbar jqx-widget jqx-widget-content jqx-rc-all"><div id="jqxScrollOuterWrappaneljqxWidgetf8114fe1horizontalScrollBar" style="box-sizing: content-box; width:100%; height: 100%; align:left; border: 0px; valign:top; position: relative;" class="jqx-reset"><div id="jqxScrollWrappaneljqxWidgetf8114fe1horizontalScrollBar" style="box-sizing: content-box; width: 100%; height: 2px; left: 0px; top: 0px; position: absolute;" class="jqx-reset jqx-scrollbar-state-normal"><div id="jqxScrollBtnUppaneljqxWidgetf8114fe1horizontalScrollBar" style="box-sizing: content-box; left: 0px; top: 0px; position: absolute; width: 0px; height: 0px;" class="jqx-scrollbar-button-state-normal jqx-rc-l"><div class="jqx-reset jqx-icon-arrow-left"></div></div><div id="jqxScrollAreaUppaneljqxWidgetf8114fe1horizontalScrollBar" style="box-sizing: content-box; left: 2px; top: 0px; position: absolute; height: 10px;" class="jqx-reset"></div><div id="jqxScrollThumbpaneljqxWidgetf8114fe1horizontalScrollBar" style="box-sizing: content-box; left: 2px; top: 0px; position: absolute; width: 10px; height: 0px; visibility: inherit;" class="jqx-scrollbar-thumb-state-normal-horizontal jqx-fill-state-normal jqx-rc-all"></div><div id="jqxScrollAreaDownpaneljqxWidgetf8114fe1horizontalScrollBar" style="box-sizing: content-box; left: 14px; top: 0px; position: absolute; width: 0px; height: 10px;" class="jqx-reset"></div><div id="jqxScrollBtnDownpaneljqxWidgetf8114fe1horizontalScrollBar" style="box-sizing: content-box; left: -2px; top: 0px; position: absolute; width: 0px; height: 0px;" class="jqx-scrollbar-button-state-normal jqx-rc-r"><div class="jqx-reset jqx-icon-arrow-right"></div></div></div></div></div><div id="bottomRightpaneljqxWidgetf8114fe1" style="align:left; valign:top; left: 0px; top: 0px; position: absolute;" class="jqx-panel-bottomright jqx-scrollbar-state-normal"></div></div></div><input type="hidden" value=""></div></div></div><div id="dropDownButtonArrowjqxWidget1ced51d0" unselectable="on" style="border: none; float: right; position: relative; width: 19px; height: 25px; background-color: transparent;"><div unselectable="on" class="jqx-icon-arrow-down jqx-icon"></div></div></div></div>
                </div>
    

    [Knockout Javascript]

    
    ko.bindingHandlers.customTree = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            var $el = $(element).jqxTree(),
                $btn = $('<div />').jqxDropDownButton({ disabled: false, autoOpen: true, popupZIndex: 20000, enableBrowserBoundsDetection: false, animationType: 'slide', openDelay: 350, closeDelay: 400 }),
                options = ko.unwrap(valueAccessor()),
                src = {
                    datatype: 'json',
                    datafields: [
                        { name: 'id' },
                        { name: 'parentID' },
                        { name: 'label' },
                        { name: 'value' },
                        { name: 'html' },
                        { name: 'disabled' },
                        { name: 'checked' },
                        { name: 'expanded' },
                        { name: 'selected' },
                        { name: 'items' },
                        { name: 'icon' },
                        { name: 'iconsize' }
                    ],
                    id: 'id',
                    localdata: options.source
                },
                dp = new $.jqx.dataAdapter(src, {
                    loadComplete: function (records) {
                        $el = $el.jqxTree({ source: dp.records });
                    }
                });
            dp.dataBind();
            $el.on('select', function (event) {
                var args = event.args,
                    item = $el.jqxTree('getItem', args.element),
                    ddContent = '<div style="position: relative; margin-left: 3px; margin-top: 5px;">' + item.label + '</div>';
                $btn.jqxDropDownButton('setContent', ddContent);
                viewModel.selectedItem(item.value);
            });
            $btn.on('open', function () { if (!$btn.jqxDropDownButton('isOpened')) { $btn.jqxDropDownButton('open'); } });
            $btn.on('close', function () { if ($btn.jqxDropDownButton('isOpened')) { $btn.jqxDropDownButton('close'); } });
            $btn.jqxDropDownButton('setContent', '<div style="position: relative; margin-left: 3px; margin-top: 5px;">Select Category</div>');
            $el.wrap($btn.html());       
            ko.utils.domNodeDisposal.addDisposeCallback($el, function () { $el.jqxTree("destroy"); });
            ko.utils.domNodeDisposal.addDisposeCallback($btn, function () { $btn.jqxDropDownButton('destroy'); });
        }
    };
    
    Knockout Tree DropdownButton #76696

    Dimitar
    Participant

    Hello Akap,

    Please try binding to the open event with the data-bind HTML attribute (more information). If this approach does not work, either, please share your complete source code that we can test locally to determine the source of the issue you experience.

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Knockout Tree DropdownButton #76749

    Akap
    Participant

    So are you implying that I add in a open/close event within the data-bind? For example,

    <div data-bind=”customTree:{ source: $data.dataCategoryItem, open: $data.openDropDownButtonEvent, close: $data.closeDropDownButtonEvent }”)></div>

    Knockout Tree DropdownButton #76752

    Dimitar
    Participant

    Hi Akap,

    You can see the correct approach in some of the Knockout integration demos, such as the one with jqxCalendar, where there is this line of code:

    <input id="getButton" data-bind="click: displayDate, jqxButton: {}" type="button" value="Get Value" />

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Knockout Tree DropdownButton #76868

    Akap
    Participant

    Ok this isn’t working out. Maybe I’m not explaining the problem correctly. I’m in a knockout environment trying to render a jqxTree wrap within a jqxDropDownButton to create a DropDownTree. In the first scenario up above, I was trying to programmatically wrap a jqxDropDownButton using the $(‘jqxTree’).wrap(‘jqxDropDownButton’) technique. This semi-worked in the sense that it did insert the tree within the dropdownbutton contents, but did not allow for the dropdownbutton click/open events to display the contents of the tree. As if the rendering of dropdownbutton click was being impeded on. So I tried a different way but using the Dimitar suggestion above.
    The problem with the below scenario is that is does render the jqxDropDownButton and functionality correctly, but not the jqxTree at all. Actually it removes the entire customTree html all together by overriding the html rendering. So I suppose my question is how can I correct this situation?

    [HTML]

    
     <div class="jqx-widget">
                    <div data-bind="jqxDropDownButton: {}, click: $data.openDropDownBtnEvent">
                        <div data-bind="customTree: {source: $data.dataCategoryItem }, value:  $data.selectedItem"></div>
                    </div>
                </div>

    [Object Prototype]

     openDropDownBtnEvent: function (e) {
                $(this).on('open', function () {
                    if (!$(this).jqxDropDownButton('isOpened')) {
                        $(this).jqxDropDownButton('open');
                    }
                });
            }
    

    [Knockout Binding]

    
    ko.bindingHandlers.customTree = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            var $el = $(element), options = ko.unwrap(valueAccessor()),
                src = {
                    datatype: 'json',
                    datafields: [
                        { name: 'id' },
                        { name: 'parentID' },
                        { name: 'label' },
                        { name: 'value' },
                        { name: 'html' },
                        { name: 'disabled' },
                        { name: 'checked' },
                        { name: 'expanded' },
                        { name: 'selected' },
                        { name: 'items' },
                        { name: 'icon' },
                        { name: 'iconsize' }
                    ],
                    id: 'id',
                    localdata: options.source
                },
                dp = new $.jqx.dataAdapter(src, {
                    loadComplete: function (records) {
                        $el.jqxTree({ source: dp.records });
                    }
                });
            dp.dataBind();
            $el.jqxTree({ disabled: false, checkboxes: false, hasThreeStates: false, allowDrag: false, allowDrop: false });
            $el.on('select', function (event) {
                var args = event.args,
                    item = $el.jqxTree('getItem', args.element),
                    ddContent = '<div style="position: relative; margin-left: 3px; margin-top: 5px;">' + item.label + '</div>';
                //(arguments.callee.caller(options.value === 'selectedItem')) ? viewModel.selectedItem(item.value) : viewModel.selectTemplate(item.value);
            });
            ko.utils.domNodeDisposal.addDisposeCallback($el, function () {
                $el.jqxTree("destroy");
            });
        }
    };
    ko.bindingHandlers.jqxDropDownButton = {
        init: function (element, valueAccessor, allBindings, viewModel) {
            var $el = $(element),
                options = ko.unwrap(valueAccessor());
            $el.jqxDropDownButton({ disabled: false, autoOpen: true, popupZIndex: 20000, enableBrowserBoundsDetection: false, animationType: 'slide', openDelay: 350, closeDelay: 400 });
            $el.on('open', function () {
                ($el.jqxDropDownButton('isOpened')) ? $el.jqxDropDownButton('close') : $el.jqxDropDownButton('open');
            });
            $el.on('close', function () {
                ($el.jqxDropDownButton('isOpened')) ? $el.jqxDropDownButton('open') : $el.jqxDropDownButton('close');
            });
            $el.jqxDropDownButton('setContent', '<div style="position: relative; margin-left: 3px; margin-top: 5px;">Select Category</div>');
            ko.utils.domNodeDisposal.addDisposeCallback($el, function () {
                $el.jqxDropDownButton('destroy');
            });
        }
    };
    Knockout Tree DropdownButton #76888

    Dimitar
    Participant

    Hi Akap,

    Could you, please, share a complete example, including your data, we can test directly? Alternatively, post a jsEditor/JSFiddle solution. Please also note that to correctly initialize a jqxTree, you need a “jqxTree” Knockout binding, as shown in the following demo: http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxknockout/tree.htm?arctic.

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Knockout Tree DropdownButton #76918

    Akap
    Participant

    Dimitar,

    May I email you directly about this problem. Putting my code publicly out there worries me.

    Knockout Tree DropdownButton #76932

    Akap
    Participant

    Dimitar,

    Could you take that example, and place it within a jqxDropDownButton in any which way possible?

    Knockout Tree DropdownButton #76933

    Akap
    Participant

    I’ve also tried setting up a mockup on jsFiddle, as to your request, but since you don’t have your libraries hosted on any CDN I’m unable to render your UI controls appropriately for a proper debug.

    Knockout Tree DropdownButton #76946

    Dimitar
    Participant

    Hi Akap,

    You can email your code to sales@jqwidgets.com or create a JSFiddle and reference the following links to the main files of jQWidgets:

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Knockout Tree DropdownButton #76972

    Akap
    Participant

    Ok So I’ve created three different jsFiddle scenerios for you. https://jsfiddle.net/frborg4u/, http://jsfiddle.net/jyc7zLyo/, http://jsfiddle.net/2s0tj0nt/4/

    Knockout Tree DropdownButton #77022

    Akap
    Participant

    So I came back to these jsfiddles and did some updating by inputting some mock array to cover all my bases. The updated jsFiddles are : https://jsfiddle.net/frborg4u/7/ , http://jsfiddle.net/jyc7zLyo/3/ , http://jsfiddle.net/2s0tj0nt/8/

    When I did an inspection on the render html, I noticed there was an error from jqx-all.js:7 “Uncaught TypeError: Cannot read property ‘jqx’ of undefined.”

    Knockout Tree DropdownButton #77060

    Dimitar
    Participant

    Hi Akap,

    Unfortunately, this is all we can offer you at the moment on the matter:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
        <script type="text/javascript" src="../../scripts/jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="../../scripts/json2.js"></script>
        <script type="text/javascript" src="../../scripts/knockout-3.0.0.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script>
        <script type="text/javascript" src="../../scripts/demos.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxknockout.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxcheckbox.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxpanel.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxtree.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdropdownbutton.js"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                $('#jqxDropDownButton').jqxDropDownButton({ width: 180 });
                $('#jqxDropDownButton').on('open', function () {
                    alert('jqxDropDownButton opened.');
                });
    
                // Define a "Person" class that tracks its own name and children, and has a method to add a new child
                var Person = function (name, items) {
                    this.label = name;
                    this.items = ko.observableArray(items);
                    this.enabled = ko.observable(true);
    
                    this.addItem = function () {
                        if (this.items().length < 4) {
                            this.items.push("New Item");
                        }
                        else if (this.items().length == 4) {
                            this.items.push("Last Item");
                            this.enabled(false);
                        }
                    },
    
                    this.openFunction = function () {
                        alert('Opened');
                    }
                }
    
                // The view model is an abstract description of the state of the UI, but without any knowledge of the UI technology (HTML)
                var viewModel = {
                    people: [
                        new Person("Annabelle", ["Arnie", "Anders", "Apple"]),
                        new Person("Bertie", ["Boutros-Boutros", "Brianna", "Barbie", "Bee-bop"]),
                        new Person("Charles", ["Cayenne", "Cleopatra"])
                    ],
                    disabled: ko.observable(false)
                };
    
                ko.applyBindings(viewModel);
                $("#tree").jqxTree('expandAll');
            });
        </script>
    </head>
    <body style='font-size: 13px; font-family: Verdana;' class='default'>
        <div>
            <div style="float: left;">
                <ul data-bind="foreach: people">
                    <li>
                        <div>
                            <span data-bind="text: label"></span><a href='#' data-bind='click: addItem, visible: enabled'>
                                Add Item</a>
                        </div>
                        <ul data-bind="foreach: items">
                            <li><span data-bind="text: $data"></span></li>
                        </ul>
                    </li>
                </ul>
            </div>
            <div style="float: left; margin-left: 50px;">
                <div id="jqxDropDownButton">
                    <div data-bind="jqxTree: {source: people, disabled: disabled, width: 178}" id="tree">
                    </div>
                </div>
                <div data-bind="jqxCheckBox: {checked: disabled}" style='margin-top: 5px;' id="checkBox">
                    Disabled</div>
            </div>
        </div>
    </body>
    </html>

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Knockout Tree DropdownButton #77073

    Akap
    Participant

    Well I would like to say thank you for all your help Dimitar. Unfortunately this doesn’t solve my problem because I have many instances of this control scenerio, and it needs knockout context management. Maybe I’m not explaining my problem or need correctly.

    Knockout Tree DropdownButton #77101

    Dimitar
    Participant

    Hi Akap,

    I understand your requirement. However, our jqxknockout.js plug-in still has some limitations and, unfortunately, the example I offered is currently the only way to create a dropdown tree with Knockout (used alongside jQuery). We will try our best to improve jqxknockout.js in the future.

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

Viewing 15 posts - 1 through 15 (of 17 total)

You must be logged in to reply to this topic.