Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Tile List Widget not working

ANSWERED

Hi,

 

I am building an app where I fetch a list of items from a web server and display them on the app using Virtual tile list. The fetch part is working fine. I am having trouble with virtual tile list. Nothing shows up on the Fitbit OS Simulator when I start up the app. I am using versa 3 (Atlas) in Fitbit OS Simulator. 

 

Here is the code: 

resources/widget.defs

 

 

 

 

 

 

<svg>
  <defs>
    <link rel="stylesheet" href="styles.css" />
    <link rel="import" href="/mnt/sysassets/system_widget.defs" />

    <link rel="import" href="/mnt/sysassets/widgets/baseview_widget.defs" />
    <link rel="import" href="/mnt/sysassets/widgets/scrollbar.defs" />
    <link rel="import" href="/mnt/sysassets/widgets/tile_list_widget.defs" />

    <symbol id="my-header" href="#tile-list-header" class="list-item  header">
      <text id="text">HEADER</text>
      <rect class="line" />
    </symbol>

    <symbol id="my-item" href="#tile-list-item" class="list-item" display="none">
      <rect class="bg" />
      <text id="text" text-length="32"/>
      <rect class="line" />
      <rect id="touch" pointer-events="all" />
    </symbol>
  </defs>
</svg>

 

 

 

 

 

And this is my app/index.js

 

 

 

 

 

import * as messaging from "messaging";
import { FitSagaUI } from "./ui.js";

let ui = new FitSagaUI();

// Listen for the onopen event
messaging.peerSocket.onopen = function() {
  console.log("Peer socket opened");
  ui.updateUI("loading");
  messaging.peerSocket.send("Hi!");
}

// Listen for the onmessage event
messaging.peerSocket.onmessage = function(evt) {
  ui.updateUI("loaded", evt.data);
}

// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
  // Handle any errors
  ui.updateUI("error");
}

FitSagaUI.prototype.updateUI = function(state, challengeNames) {
  if (state === "loaded") {
    setupList(challengeNames);    
  } 
}

function setupList(challenges) {
  console.log("challenges: " + challenges);
  let myList = document.getElementById("myList");
  let NUM_ELEMS = challenges.length;
  
  myList.delegate = {
    getTileInfo: (index) => {
      return {
        type: "my-pool",
        value: challenges[index],
        index: index
      };
    },
    configureTile: (tile, info) => {
      if (info.type == "my-pool") {
        tile.getElementById("text").text = `${info.value} ${info.index}`;
        let touch = tile.getElementById("touch");
        touch.onclick = function(evt) {
          console.log(`touched: ${info.index}`);
        };
      }
    }
  };

 

 

 

 

And here is my resources/index.view file

 

 

 

 

 

<svg class="background">
  <use id="myList" href="#tile-list">
    <var id="virtual" value="1" />
    <var id="reorder-enabled" value="0"/>
    <var id="peek-enabled" value="0"/>
    <var id="separator-height-bottom" value="2" />

    <use id="my-pool" href="#tile-list-pool">
      <use id="my-pool[0]" href="#my-item" />
      <use id="my-pool[1]" href="#my-item" />
      <use id="my-pool[2]" href="#my-item" />
      <use id="my-pool[3]" href="#my-item" />
      <use id="my-pool[4]" href="#my-item" />
      <use id="my-pool[5]" href="#my-item" />
      <use id="my-pool[6]" href="#my-item" />
      <use id="my-pool[7]" href="#my-item" />
      <use id="my-pool[8]" href="#my-item" />
      <use id="my-pool[9]" href="#my-item" />
      <use id="my-pool[10]" href="#my-item" />
      <use id="my-pool[11]" href="#my-item" />
      <use id="my-pool[12]" href="#my-item" />
      <use id="my-pool[13]" href="#my-item" />
      <use id="my-pool[14]" href="#my-item" />
    </use>
  </use>
</svg>

 

 

 

What am I doing wrong? I copied the exact code that I found in the docs. See the image below for what I am getting 

 

Screen Shot 2022-08-04 at 5.53.08 PM.png

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

I found the issue. I forgot to add css for all the elements. That is why they didn't show up 

.list-item {
  height: 112;
}

.list-item text {
  fill: "white";
  x: 50%;
  text-anchor: middle;
  font-size: 24;
}

.line {
  height: 6;
  width: 100%;
  fill: #222222;
  y: 100%-6;
}

.header text {
  font-weight: bold;
  fill: fb-cyan;
  font-size: 30;
}

.footer text {
  font-weight: bold;
  fill: fb-green;
  font-size: 30;
}

View best answer in original post

Best Answer
6 REPLIES 6

I didn't study closely, but try setting myList.length. I think this needs to be done after other list config, as it seems to trigger a redisplay.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

I have tried setting it, but still doesn't work. 

 

function setupList(challenges) {
  console.log("challenges: " + challenges);
  let myList = document.getElementById("myList");
  let NUM_ELEMS = challenges.length;
  
  myList.delegate = {
    getTileInfo: (index) => {
      return {
        type: "my-pool",
        value: challenges[index],
        index: index
      };
    },
    configureTile: (tile, info) => {
      if (info.type == "my-pool") {
        tile.getElementById("text").text = `${info.value} ${info.index}`;
        let touch = tile.getElementById("touch");
        touch.onclick = function(evt) {
          console.log(`touched: ${info.index}`);
        };
      }
    }
  };
  
  // length must be set AFTER delegate
  myList.length = NUM_ELEMS;
}
Best Answer
0 Votes

Does the console.log at the start of setupList() display a list of strings?

If so, try adding some console.log lines for debugging in getTileInfo and configureTile.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Yes, it does. I also added console.log statement to the if block inside configureTile. The console.log statements print correctly. 

 

configureTile: (tile, info) => {
      if (info.type == "my-pool") {
        tile.getElementById("text").text = `${info.value} ${info.index}`;
        console.log("title text: " + tile.getElementById("text").text);
        let touch = tile.getElementById("touch");
        touch.onclick = function(evt) {
          console.log(`touched: ${info.index}`);
        };
      }
    }

 I am wondering if something is wrong with my widget.defs file. 

Best Answer
0 Votes

I had a quick skim of your widget.defs and it seemed okay.

 

I'm currently working on an app that uses VTL. It does work but can be finicky. I'll load up your code soon and see if I can get it to work.

 

In the meantime, maybe verify that you've got appropriate CSS for the relevant elements and CSS classes in your code. You may need to use some of the CSS from the non-virtual example in Fitbit's documentation.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

I found the issue. I forgot to add css for all the elements. That is why they didn't show up 

.list-item {
  height: 112;
}

.list-item text {
  fill: "white";
  x: 50%;
  text-anchor: middle;
  font-size: 24;
}

.line {
  height: 6;
  width: 100%;
  fill: #222222;
  y: 100%-6;
}

.header text {
  font-weight: bold;
  fill: fb-cyan;
  font-size: 30;
}

.footer text {
  font-weight: bold;
  fill: fb-green;
  font-size: 30;
}
Best Answer