locked
[HTML]Listview removes focus from inputs in it (HTML+ JS) RRS feed

  • Question

  • Hello everybody!

    I have some troubles with listview logic. I made listview, but I can't type any input in list item, I can't focus on it! Because of listview behavoiur.
    Is there any declarative way to solve it? I'm starting use listview because it applies to my project perfectly.

    You can reproduce my problem by this sample:

    <div class="box">
                    <button id="shuffle" class="win-button action secondary">Shuffle tiles</button>
                    <button id="removeSelected" class="win-button action secondary">Remove selected tile</button>
                    <button id="swapSelected" class="win-button action secondary">Swap selected tile</button>
                    <button id="addTile" class="win-button action secondary">Add tile</button>
                    <br />
                    <div class="tileTemplate" data-win-control="WinJS.Binding.Template">
                        <div class="tileTempl">
                            <h6 class="win-h6 counter" data-win-bind="innerText: counter"></h6>
                            <h1 class="letter win-h1" data-win-bind="innerText: letter"></h1>
                            <input type="text" value="" data-win-bind="innerText: letter" />
                        </div>
                    </div>
                    <div id="listView2" class="listBox" data-win-control="WinJS.UI.ListView" data-win-options="{
            selectionMode: 'multi',
            tapBehavior: WinJS.UI.TapBehavior.toggleSelect,
            itemsReorderable: true,
            layout: { type: WinJS.UI.GridLayout, maxRows: 4 }
        }"></div>
                </div>

    var tIndex = 0;
                //Create an array of the letters in the alphabet. Used for generation of tiles
                var letterSrc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
    
                // Our Binding.List
                var lettersList = {};
    
                // Initializes the first set of tiles
                // Uses an array that will be converted into a Binding.List
                function initTiles() {
                    var letters = [];
                    for (var i = 0; i < 15; i++) {
                        letters[i] = generateTile();
                    }
                    lettersList = new WinJS.Binding.List(letters);
    
                    var list2 = document.getElementById("listView2").winControl;
                    list2.itemDataSource = lettersList.dataSource;
                    list2.itemTemplate = document.querySelector(".tileTemplate");
                    list2.forceLayout();
                }
    
                // Generates a tile with a random letter and counter
                function generateTile() {
                    var tile = {
                        letter: letterSrc[Math.floor(Math.random() * letterSrc.length)],
                        counter: tIndex
                    };
                    tIndex++;
    
                    return tile;
                }
    
                // Shuffles the order of the tiles
                function shuffleTiles() {
                    var count = lettersList.length;
                    if (count > 0) {
                        // To shuffle the items, we pick one from the array of items, then move it to the front of the list
                        // and then continue for the remaining items
                        for (var itemIndex = 0; itemIndex < count; itemIndex++) {
                            // find an item from the array
                            var randomIndex = Math.floor(Math.random() * (count - itemIndex));
                            //move the item to the start
                            lettersList.move(randomIndex, 0);
                        }
                    }
                }
    
                // Remove the selected tile
                function removeSelected() {
                    // Get the control
                    var list2 = document.getElementById("listView2").winControl;
    
                    if (list2.selection.count() > 0) {
                        list2.selection.getItems().done(function (items) {
    
                            //Sort the selection to ensure its in index order
                            items.sort(function CompareForSort(item1, item2) {
                                var first = item1.index, second = item2.index;
                                if (first === second) {
                                    return 0;
                                }
                                else if (first < second) {
                                    return -1;
                                }
                                else {
                                    return 1;
                                }
                            });
    
                            //Work backwards as the removal will affect the indices of subsequent items
                            for (var j = items.length - 1; j >= 0; j--) {
                                // To remove the items, call splice on the list, passing in a count and no replacements
                                lettersList.splice(items[j].index, 1);
                            }
                        });
                    }
                }
    
                // Demonstrates how to modify data for the selected items
                function swapSelected() {
                    // Get the control, itemDataSource and selected items
                    var list2 = document.getElementById("listView2").winControl;
    
                    if (list2.selection.count() > 0) {
                        list2.selection.getItems().done(function (items) {
                            // To edit the item, call change on the itemDataSource passing in the key and new data
                            items.forEach(function (currentItem) {
                                lettersList.setAt(currentItem.index, generateTile());
                            });
                        });
                    }
                }
    
                // Adds a new tile to the end of the collection
                function addTile() {
                    //Create the data for the tile
                    var tile = generateTile();
                    lettersList.push(tile);
                }
    
    
                WinJS.UI.processAll().then(function () {
                    var element = document.body;
                    element.querySelector("#shuffle").addEventListener("click", shuffleTiles, false);
                    element.querySelector("#removeSelected").addEventListener("click", removeSelected, false);
                    element.querySelector("#swapSelected").addEventListener("click", swapSelected, false);
                    element.querySelector("#addTile").addEventListener("click", addTile, false);
    
                    initTiles();
                });


    ©KW


    • Edited by Jamles Hez Thursday, July 30, 2015 5:52 AM add title tag
    Tuesday, July 28, 2015 6:28 AM

Answers

  • Hello Kenya-West,

    Normally, when the user interacts with an element, the ListView captures that interaction and uses it to determine whether the user selected or invoked an item or is panning through items. For an interactive element, such as a control, to receive input, you must attach the win-interactive class to the interactive element or one of its parent elements. That element and its children receive the interaction and no longer trigger events for the ListView

    When you attach the win-interactive to an element in a item template, be sure that the element doesn't fill the entire item, otherwise the user won't have a way to select or invoke that item.

    so in your case you could just do

     <div class="tileTemplate" data-win-control="WinJS.Binding.Template">
                        <div class="tileTempl ">
                            <h6 class="win-h6 counter" data-win-bind="innerText: counter"></h6>
                            <h1 class="letter win-h1" data-win-bind="innerText: letter"></h1>
                            <input type="text" value="" class="win-interactive" data-win-bind="innerText: letter" />
                        </div>
                    </div>

    With Regards,

    Krunal Parekh


    Thanks MSDN Community Support Please remember to Mark as Answer the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by Kenya-West Friday, July 31, 2015 8:08 AM
    Wednesday, July 29, 2015 9:11 AM