Loader gif in top of table?

Hello!

Can I put an image in top of a table?

image

I just figured out how to add a loader to my table while loading data. On the button that triggers the load I added:

# Set the loading state to True (show loader)
	
	self.getSibling("TabContainer").custom.isLoading = True  

and at the end of the code when table is loaded:

finally:
	    # Set the loading state to False (hide loader) after the query is completed
	    self.getSibling("TabContainer").custom.isLoading = False

then my custom.isLoading property is binded to the meta.visible of the container in wich I added the loader.

image
image

Just use a popup.

Here's a simplified version of what I use:

decorator
from functools import wraps

def loading(message="MESSAGE"):
	def _loading(func):
		@wraps(func)
		def wrapper(*args, **kwargs):
			system.perspective.openPopup(
				id = 'loader',
				view = "components/loader/popup",
				position = {'width': "300px", 'height': "300px"},
				showCloseIcon = False,
				draggable = False,
				modal = True,
				resizable = False,
				overlayDismiss = False,
				params = {
					'message': message
				}
			)
			popup_open = True
			
			try:
				ret = func(*args, **kwargs)
			except:
				raise
			finally:
				system.perspective.closePopup('loader')
				return ret
		return wrapper
	return _loading
popup view json
{
  "custom": {},
  "params": {
    "message": "loading..."
  },
  "propConfig": {
    "params.message": {
      "paramDirection": "input",
      "persistent": true
    }
  },
  "props": {
    "defaultSize": {
      "height": 300,
      "width": 300
    }
  },
  "root": {
    "children": [
      {
        "meta": {
          "name": "spinning-circles"
        },
        "position": {
          "basis": "80px"
        },
        "props": {
          "elements": [
            {
              "elements": [
                {
                  "elements": [
                    {
                      "cx": "42.601",
                      "cy": "11.462",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "1;0;0;0;0;0;0;0"
                        }
                      ],
                      "fill": {
                        "opacity": "1",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    },
                    {
                      "cx": "49.063",
                      "cy": "27.063",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "0;1;0;0;0;0;0;0"
                        }
                      ],
                      "fill": {
                        "opacity": "0",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    },
                    {
                      "cx": "42.601",
                      "cy": "42.663",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "0;0;1;0;0;0;0;0"
                        }
                      ],
                      "fill": {
                        "opacity": "0",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    },
                    {
                      "cx": "27",
                      "cy": "49.125",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "0;0;0;1;0;0;0;0"
                        }
                      ],
                      "fill": {
                        "opacity": "0",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    },
                    {
                      "cx": "11.399",
                      "cy": "42.663",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "0;0;0;0;1;0;0;0"
                        }
                      ],
                      "fill": {
                        "opacity": "0",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    },
                    {
                      "cx": "4.938",
                      "cy": "27.063",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "0;0;0;0;0;1;0;0"
                        }
                      ],
                      "fill": {
                        "opacity": "0",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    },
                    {
                      "cx": "11.399",
                      "cy": "11.462",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "0;0;0;0;0;0;1;0"
                        }
                      ],
                      "fill": {
                        "opacity": "0",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    },
                    {
                      "cx": "27",
                      "cy": "5",
                      "elements": [
                        {
                          "attributeName": "fill-opacity",
                          "calcMode": "linear",
                          "dur": "1.3s",
                          "name": "animate",
                          "repeatCount": "indefinite",
                          "type": "animate",
                          "values": "0;0;0;0;0;0;0;1"
                        }
                      ],
                      "fill": {
                        "opacity": "0",
                        "paint": "#fff"
                      },
                      "name": "circle",
                      "r": "5",
                      "type": "circle"
                    }
                  ],
                  "name": "group",
                  "stroke": {
                    "paint": "#FFF",
                    "width": "1.5"
                  },
                  "transform": "translate(2 1)",
                  "type": "group"
                }
              ],
              "fill": {
                "paint": "transparent",
                "rule": "evenodd"
              },
              "name": "group",
              "type": "group"
            }
          ],
          "viewBox": "0 0 58 58"
        },
        "type": "ia.shapes.svg"
      },
      {
        "meta": {
          "name": "Label"
        },
        "propConfig": {
          "props.text": {
            "binding": {
              "config": {
                "path": "view.params.message"
              },
              "type": "property"
            }
          }
        },
        "props": {
          "textStyle": {
            "color": "white"
          }
        },
        "type": "ia.display.label"
      }
    ],
    "meta": {
      "name": "root"
    },
    "props": {
      "alignItems": "center",
      "direction": "column",
      "justify": "center",
      "style": {
        "gap": "20px"
      }
    },
    "type": "ia.container.flex"
  }
}
css
#popup-loader {
	border: none;
	outline: none;
	background: transparent;
	box-shadow: none;
	text-shadow: 2px 2px 3px black;
	font-size: 1.3em;
}

Here's how to use it:

When you have a function that may take time to run, put it in your library, and decorate it with the loading decorator.
It should look like this:

@some_module.loading("message")
def slow_function():
    sleep(20)

Now call that function in your transforms or whatever. That's it.
You can replace the loading animation by just replacing the svg in the popup. You can find some here: GitHub - SamHerbert/SVG-Loaders: Loading icons and small animations built with pure SVG.
I also have a version of that popup that uses css for the animation if you prefer.

3 Likes

Thanks Pascal for your answer!, I will try this method.