Event handler problem when feeding HTML chart via wix code - javascript

I'm feeding an HTML element (pie chart) on a wix page. I pull data from local storage for 7 variables and pass the information to the HTML element via Postmessage.
My code works fine when it's part of a button (export function). However I would like to trigger the event from the onReady function (i.e. when the page is loaded). I use the exact same code but it simply doesn't work with the OnReady function (i.e. I'm unable to trigger the event programatically).
Wix pagecode for Export Function with button (works fine):
export function button1_click(event) {
var data = [introdeo, intcalypso, intbalthazar, intluna, intkiara, intmistral, intsaya];
console.log(data);
var labels = ["Rodeo", "Calypso", "Balthazar", "Luna", "Kiara", "Mistral", "Saya"];
let info = {data:data, labels:labels};
$w("#html1").postMessage(info);
}
Wix pagecode for onReady function (doesn't work):
$w.onReady(function () {
var data = [introdeo, intcalypso, intbalthazar, intluna, intkiara, intmistral, intsaya];
var labels = ["Rodeo", "Calypso", "Balthazar", "Luna", "Kiara", "Mistral", "Saya"];
let info = {data:data, labels:labels};
$w("#html1").postMessage(info);
} );
HTML code (the chart code in the HTML element on wix page):
<!DOCTYPE html>
<html lang="en-US">
<body>
<canvas id="myChart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('myChart').getContext('2d');
var myPieChart = new Chart(ctx,{
type: 'pie',
data: {
labels:[],
datasets: [{
data: [],
backgroundColor: ["#f97a03", "#52aff0", "#35a11d", "#f052e4", "#853fc2", "#f0f712", "#092978"],
}]
},
options: {}
});
window.onmessage = function(event){
myPieChart.data.datasets[0].data = event.data.data;
myPieChart.data.labels = event.data.labels;
myPieChart.update();
};
</script>
</body>
</html>
With the button Export function, I get an updated pie chart on my web page. With the OnReady code, I get a blank space in the HTML element.

Seems like the html element might not be ready to receive that POST. Try wrapping $w("#html1").postMessage(info); in a setTimeout.
$w.onReady(function () {
var data = [introdeo, intcalypso, intbalthazar, intluna, intkiara, intmistral, intsaya];
var labels = ["Rodeo", "Calypso", "Balthazar", "Luna", "Kiara", "Mistral", "Saya"];
let info = {data:data, labels:labels};
setTimeout(function() {
$w("#html1").postMessage(info);
}, 1000)
});

I will suggest to use a promise
and resolve the promise when the HTMl component is ready to use
So, in this code we are sending the data for every 500ms to check if the HTML is ready
and if it's ready updating the global variable and resolving the promise
$w.onReady(()=>{
let isHTMLready = false;
async function sendHTMLData() {
await isHTMLReady(); // this line will wait until the HTML component is ready
// then your code here
}
$w('#htmlID').onmessage(e=>{
let {data} = e;
if(data.isReady) {
// html is ready
isHTMLReady = true; //updating the gloable variable
} else if(data.someOtherCondition) {
// do something
}
});
function isHTMLReady() {
return new Promise((res,rej)=>{
let i = 0;
let intervalID = setInterval(()=>{
$w('#html').postMessage({
isHTMLReady : true
});
if(isHTMLready) { // checking if the global variable is changed to true
// stop the time interval
clearInterval(intervalID);
// resolve the promise
res("ready");
}
i++;
if(i > 28) { // waiting until 14 second before rejecting the promise
// rejecting the promise
rej("no response from HTML");
}
},500);
});
}
});
on the HTML component add this following code
It will check if the data sent is "isHTMLReady" then (if the HTML component is ready) we will send it back to wix site
from there we will update the variable and stop the interval and resolve the promise
window.onmessage = e => {
let {data} = e;
if(data.isHTMLReady) {
messageWixSite({isHTMLReady: true});
}
else if(data.isGraphData) {
// write your code here
}
}
function messageWixSite(data) {
let msg = {
"isCropper" : true,
}
msg = {...msg, ...data};
// console.log("message : " , msg);
window.parent.postMessage(msg, "*");
}
This way we ensure that both the wix site and the HTML element is ready to use before sending the data

Related

How to change this onload function so that this script runs as soon as the button id elements are loaded on page?

<script type="text/javascript">
window.onload = function () {
const signInBtn = document.getElementById("sign-in-btn");
appendUtmsToButton(signInBtn);
const signUpBtn = document.getElementById("sign-up-btn");
appendUtmsToButton(signUpBtn);
};
function appendUtmsToButton(button) {
// Read utm params from url:
const pageSearch = window.location.search;
const urlParams = new URLSearchParams(pageSearch);
// Build new params for the button combining the button' params with the utm:
const buttonUrl = new URL(button.href);
let newButtonParams = new URLSearchParams(buttonUrl.search);
urlParams.forEach(function(value, key) {
newButtonParams.append(key, value);
});
// Build new url for the button attaching the params:
buttonUrl.search = "";
const newSearchString = newButtonParams.toString();
buttonUrl.search = newSearchString;
const newHref = buttonUrl.toString();
// Replace the button's url:
button.href = newHref;
// For debugging log final button link to console:
// console.log(button.href);
};
</script>
This above code works well but because it is an onload function it takes a long time for it to run and the button URL's to update. I want to run this as soon as the buttons (with those ID's) are loaded on page.
Here's example that demonstrate "right after", "domcontentloaded" and then "load" in that order.
window.addEventListener('DOMContentLoaded', function (ev) {
console.log('DOM fully loaded and parsed');
});
window.addEventListener('load', function (ev) {
console.log('all assets downloaded');
});
<h1>html</h1>
<button id="test" style="color:red">what color?</button>
<script>
document.querySelector("#test").style.color = 'blue';
console.log ("i am first in order of appearance")
</script>

How to assign getFieldValues("Custom.RevisionCount", returnOriginalValue) to a variable in VSTS custom Extension html file?

I am very new to Javascript and VSTS extension creation.I am looking to create an extension calculate the revision count of a Work Item in VSTS. For this I am trying with sample java script in Work Item form extension.In the java script I am not able get the current value of the revision count, and assign it variable to make increment for each state transition.
From VSTS I found this method to get the field value, but How to implement it
getFieldValues("Custom.RevisionCount", returnOriginalValue);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Work item form page sample</title>
</head>
<body style="overflow:auto;">
<script src="node_modules/vss-web-extension-sdk/lib/VSS.SDK.min.js"></script>
<script>
VSS.init({
explicitNotifyLoaded: true,
usePlatformScripts: true,
//usePlatformStyles: true
});
//VSS.ready(function () {
VSS.require(["TFS/WorkItemTracking/Services"], function (_WorkItemServices) {
// VSS.require(["VSS/Service", "TFS/Core/RestClient"], function(VSS_Service, Tfs_Core_WebApi) {
// var client = VSS_Service.getCollectionClient(Tfs_Core_WebApi.CoreHttpClient4);
// Get the WorkItemFormService. This service allows you to get/set fields/links on the 'active' work item (the work item
// that currently is displayed in the UI).
function getWorkItemFormService()
{
return _WorkItemServices.WorkItemFormService.getService();
}
var project=VSS.getWebContext().project.name;
var teamid=VSS.getWebContext().team.id;
// Register a listener for the work item page contribution
VSS.register(VSS.getContribution().id, function () {
return {
// Called when the active work item is modified
onFieldChanged: function(args) {
if(project=="TFS_Training")
{
//alert(args);
var data=JSON.stringify(args);
var a2=JSON.parse(data);
var a3 = a2["changedFields"];
//var i = getFieldValues("Custom.RevisionCount", returnOriginalValue);
getWorkItemFormService().then(function(service)
//{
// Get the current values for a few of the common fields
// service.getFieldValues("Custom.RevisionCount").then(
// function (value) {
// $(".events").append($("<div/>").text("onLoaded - " + JSON.stringify(value)));
// });
var i = 0
if(a3.hasOwnProperty("System.State"))
{
function myFunction(i) {
return i+1;
}
getWorkItemFormService().then(function (service)
{
{
//service.setFieldValue("System.Title", "Requirment changed");
service.setFieldValue("Custom.RevisionCount", myFunction(i));
}
// errorMessage="statechanged";
// service.setError(errorMessage);
});
}
}
},
}
});
VSS.notifyLoadSucceeded();
});
//});
</script>
</body>
</html>
Still showing value 1 for each state transition
You do not need to define i, you could directly use value in the setFieldValue. After you fetch the value from workitem service. Kind of this (not familiar with js part),change your code based on your needs:
getWorkItemFormService().then(function(service)
{ // get work item service first
function getWorkItemFormService()
{
return _WorkItemServices.WorkItemFormService.getService();
}
// Get the current values for a few of the common fields
// get filed value here then use below function
function (value) {
// $(".events").append($("<div/>").text("onLoaded - " + JSON.stringify(value)));
//service.setFieldValue("System.Title", "Requirment changed");
service.setFieldValue("Custom.RevisionCount", value+1;)
}
}
More details please refer this official tutorial here: setFieldValue()

html() function with variables

I'm attempting to inject some html code with variables in it into a JQM UL Listview. The problem I am running into is it seems the variables are throwing off the code because when I remove them, it injects the HTML perfectly.
Here is the snippet:
$(document).on("pageinit", "#vendorMessages", function() {
var listView = "";
pubnub.subscribe(
{
channelGroup: getChannelGroup()
},
function (status, response) {
alert("test");
console.log(status, response);
}
);
pubnub.channelGroups.listChannels(
{
channelGroup: getChannelGroup()
},
function (status, response) {
response.channels.forEach( function (channel) {
var channelFormatted = String(channel).split("_");
var channelMember = channelFormatted[1];
var temp = "<li onClick='loadChannel("+channel+")'>"+channelMember+"</li>";
var temp = String(temp);
listView = listView.concat(temp);
})
alert(listView);
}
)
var elem = $("#channels");
elem.html(elem.text(listView));
$("#channels").listview("refresh");
})
The alert(listView) returns the correct string format but the code still will not get added to the <ul>. I've tried a few suggested things, even switching back to javascript innerHTML but no avail. Any thoughts?
Change
elem.html(elem.text(listView));
to
elem.html(listView);
elem.text cannot handle html..

How to start a GtkApplication from inside a gnome-shell-extension?

My goal is to start a new GtkApplication when the user presses a button in the topbar of Gnome.
The button in the topbar can be done by a gnome-shell-extension, but I have difficulties opening up the GtkApplication.
Therefore, for now the following code should just start the GtkApplication.
Enabling this extension after putting the code inside ~/.local/share/gnome-shell/extensions/test#test/extension.js always results in a SIGSEGV signal of gnome-shell.
const Lang = imports.lang;
const Gtk = imports.gi.Gtk;
const TestApp = new Lang.Class({
Name: 'TestApp',
Extends: Gtk.Application,
_init: function() {
this.parent({ application_id: 'testapp.apptesttt' });
},
vfunc_activate: function() {
//this.window.present();
},
});
function init() {
}
let _app;
function enable() {
_app = new TestApp();
_app.register(null);
}
function disable() {
_app.quit();
}
I am probably a bit late to the party, but in case someone else ends up here:
The answer most likely lies within imports.misc.util:
const Util = imports.misc.util;
Util.spawn()

Passing parameters to a event listener function in javascript

Hello I have some code in which I take user input through in html and assign it to,two global variables
var spursscoref = document.getElementById("spursscore").value;
var livscoref = document.getElementById("livscore").value;
Which next show up in this addeventlistener function as parameters of the whowon function
var d = document.querySelector("#gut2");
d.addEventListener("click", function () {
whowon(spursscoref, livscoref, spurs, liverpool)
}, false);
The click event is meant to trigger the whowon function and pass in the parameters
function whowon(FirstScore, SecondScore, FirstTeam, SecondTeam) {
if (FirstScore > SecondScore) {
FirstTeam.win();
SecondTeam.lose();
} else if (FirstScore < SecondScore) {
SecondTeam.win();
} else {
FirstTeam.draw();
SecondTeam.draw();
}
}
However the values are null,as I get a cannot read properties of null error on this line
var spursscoref = document.getElementById("spursscore").value;
I am pretty sure the problem is coming from the addlistener function,any help would be appreciated
Well you could do something like this -
$( document ).ready(function() {
var d = document.querySelector("#gut2");
d.addEventListener("click", function () {
var spursscoref = document.getElementById("spursscore").value;
var livscoref = document.getElementById("livscore").value;
whowon(spursscoref, livscoref, spurs, liverpool)
}, false);
});
Wrap your code in $(document).ready(function(){}). This will ensure that all of your DOM elements are loaded prior to executing your Javascript code.
Try putting all of your code inside this
document.addEventListener("DOMContentLoaded", function(event) {
//Your code here
});
My guess is that your code is executed before the html actually finished loading, causing it to return null.

Categories

Resources