WSO2 DAS Dashboard - Creating custom gadget - javascript

I am trying to create a custom gadget in WSO2 DAS Dashboard. I already created it. I can drag and drop it in a container in the dashboard designer, and there I can see it moving when I add new data to the table (the gadget is a gauge that shows the latest value introduced in a DAS table).
The problem is, that when i click "view", the gadget disappears from the container. If I reopen the design view of the page, the gadget is not longer there. If I open the Chrome developer console, I have an error saying "draw is not defined". As far as I can understand, you have to define this "draw" function so that the page can render the graphic in runtime.
But, in other already created gadgets, this function uses wso2gadgets.js functions and some kind of wrapper to use VIZGrammar, but you are really limited to only a few type of gadgets(line, bar, pie, number, and perhaps one or two more), and we wanted to use d3 to create better and more complex graphs and gadgets.
Sadly, this thing of "creating a custom gadget" is really poor documented, and even if you follow the WSO2 tutorial here https://docs.wso2.com/display/DAS310/Manually+Creating+a+Custom+Gadget it does not work when you click "view".
I am posting the code for my gadget.xml below.
Thank you all
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Gauge" description="This is a template gadget">
<Require feature="dynamic-height"/>
<Require feature="wso2-gadgets-identity"/>
</ModulePrefs>
<UserPref name="windowSize"
display_name="Window Size"
default_value="10"/>
<Content type="html">
<![CDATA[
<head>
<meta charset="utf-8">
<style>
.label{
font-size:22.5px;
fill:#ffffff;
text-anchor:middle;
alignment-baseline:middle;
}
.face{
stroke:#c8c8c8;
stroke-width:2;
}
.minorTicks{
stroke-width:2;
stroke:white;
}
.majorTicks{
stroke:white;
stroke-width:3;
}
</style>
<svg width="400" height="400"></svg>
<link href="/portal/libs/analytics-wso2-2.0.0/common.css" rel="stylesheet" type="text/css" >
<script src="/portal/libs/jquery_1.11.0/jquery-1.11.3.min.js"></script>
<script src="js/provider-libs/ws-client.js"></script>
<script src="http://vizjs.org/viz.v1.0.0.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/d3.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/vega.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/VizGrammar.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/wso2gadgets.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/chart-utils.js"></script>
<script src="/portal/js/carbon-analytics.js"></script>
<script src="js/core/provider-client.js"></script>
<script src="js/core/gadget-util.js"></script>
<script src="js/core/gadget-core.js"></script>
<script>
var username = "********";
var password = "********";
var server_url = "https://localhost:9445/portal/apis/analytics";
var client = new AnalyticsClient().init(username,password,server_url);
var svg=d3.select("svg");
var g=svg.append("g").attr("transform","translate(200,200)");
var domain = [0,100];
var gg = viz.gg()
.domain(domain)
.outerRadius(150)
.innerRadius(30)
.value(0.5*(domain[1]+domain[0]))
.duration(1000);
gg.defs(svg);
g.call(gg);
var queryInfo = {
tableName : "ROBICON_DEBUG_GENERAL_COMPLETO", //table being queried
searchParams : {
query : "*:*", //lucene query to search the records
start : 0, //starting index of the matching record set
count : 100,
sortBy:
[
{
field: "Timestamp",
sortType: "DESC"
}
]
}
};
d3.select(self.frameElement).style("height", "400px");
setInterval(
function(){
client.tableExists("ROBICON_DEBUG_GENERAL_COMPLETO", function(data) {
console.log (data["message"]);
client.search(queryInfo, function(data) {
var datos = JSON.parse(data["message"]);
console.log (datos[0].values.LineSide_Voltage);
var LSV = datos[0].values.LineSide_Voltage;
gg.setNeedle(parseFloat(LSV).toFixed(2));
}, function(error) {
console.log("error occured: " + error);
gg.setNeedle(domain[0]+Math.random()*(domain[1]-domain[0]));
});
}, function(error) {
console.log("error occured: " + error);
});
},30000);
</script>
</head>
<body>
<div id="canvas"></div>
</body>
]]>
</Content>
</Module>

If your requirement is to write a custom gadget,you don't need to include any of the libraries with script tags unless you use them in your gauge gadget. WSO2 DAS is capable of rendering any gadget which is written following the google open social spec
So one thing you can try is try removing unused script tags from below.
<script src="/portal/libs/jquery_1.11.0/jquery-1.11.3.min.js"></script>
<script src="js/provider-libs/ws-client.js"></script>
<script src="http://vizjs.org/viz.v1.0.0.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/d3.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/vega.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/VizGrammar.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/wso2gadgets.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/chart-utils.js"></script>
<script src="/portal/js/carbon-analytics.js"></script>
<script src="js/core/provider-client.js"></script>
<script src="js/core/gadget-util.js"></script>
<script src="js/core/gadget-core.js"></script>

Related

How can I change default backround color of botman.io widget

Im using botman.io package for chatboot widget.
Everything works perfectly but problem is that i can't change default background color of chat widget. On inspect console it shown that boman widget calls ( https://cdn.jsdelivr.net/npm/botman-web-widget#0.0.20/build/assets/css/chat.css ) link, but i cant find that call on my localhost project. If anyone know solution i would appreciate.
<script src="{{ asset('/js/webflow.js') }}"></script>
<script>
var botmanWidget = {
title:'Scarletbot',
introMessage: 'Hello, I am a Scarlet! I am here to assist you and answer all your questions about our products and services!',
mainColor:'#c02026',
aboutText:'',
bubbleBackground:'#c02026',
headerTextColor: '#fff',
};
</script>
<script id="botmanWidget" src="{{ asset('/js/widget.js') }}"></script>
You may add frameEndpoint in
var botmanWidget = {
frameEndpoint: '<?php echo base_url('botdemo/chatserver1');?>',
title:'Scarletbot',
introMessage: 'Hello, I am a Scarlet! I am here to assist you and answer all your questions about our products and services!',
mainColor:'#c02026',
aboutText:'',
bubbleBackground:'#c02026',
headerTextColor: '#fff',
};
frameEndpoint is nothing but source of iframe loaded by botman-widget
frameEndpoint source is like :
<!doctype html>
<html>
<head>
<title>BotMan Widget</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/botman-web-widget#0/build/assets/css/chat.min.css">
</head>
<body>
<script id="botmanWidget" src='https://cdn.jsdelivr.net/npm/botman-web-widget#0/build/js/chat.js'></script>
</body>
</html>
Here you may use own css as well.
I quickly checked out the web widget on the botman github.
There is a simple link to the chat.css in the head of chat.html located in the src folder.
This points to assets/css/chat.css, which you can edit freely and add a background-color to.
I use brute force in the iframe to change background with jquery
$(document).on('click', '.desktop-closed-message-avatar img', function() {
var iframe = document.getElementById("chatBotManFrame");
iframe.addEventListener('load', function () {
var htmlFrame = this.contentWindow.document.getElementsByTagName("html")[0];
var bodyFrame = this.contentWindow.document.getElementsByTagName("body")[0];
var headFrame = this.contentWindow.document.getElementsByTagName("head")[0];
var image = "https://images.unsplash.com/photo-1501597301489-8b75b675ba0a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1349&q=80"
htmlFrame.style.backgroundImage = "url("+image+")";
bodyFrame.style.backgroundImage = "url("+image+")";
});
});

JavaScript does not work on pages other than my MasterPage and pages that aren't linked to it

Sorry for the bad english :P
I'm using ASP.NET
I'm trying to use a JavaScript that I've found on the Internet to set masks to my telephone and cellphone text fields, but the JS code just work at the fields that are located at my MasterPage. I don't have much experience with JS (almost none) and I have no idea how to resolve this since there is no error at my Logcat.
I tried to reference it at my MasterPage's head, body and inside the ContentPlaceHolder.
Here is the JS code:
function mascara(o, f) {
v_obj = o
v_fun = f
setTimeout("execmascara()", 1)
}
function execmascara() {
v_obj.value = v_fun(v_obj.value)
}
function mtel(v) {
v = v.replace(/\D/g, "");
v = v.replace(/^(\d{2})(\d)/g, "($1)$2");
v = v.replace(/(\d)(\d{4})$/, "$1-$2");
return v;
}
function id(el) {
return document.getElementById(el);
}
window.onload = function () {
id('txtTelefone').onkeypress = function () { //Located at MasterPage - working
mascara(this, mtel);
}
id('txtCelular').onkeypress = function () { //Located at MasterPage - working
mascara(this, mtel);
}
id('telefoneContato').onkeypress = function () { //Located at Contact Page - not working
mascara(this, mtel);
}
id('txtCelularUser').onkeypress = function () { //Located at User Page - not working
mascara(this, mtel);
}
id('txtTelefoneUser').onkeypress = function () { //Located at User Page - not working
mascara(this, mtel);
}
}
As I said before I tried to reference my JS file in some places, the codes that I tried were:
<script src="<%# Page.ResolveClientUrl("../Componentes/js/mascaras.js") %>"></script>
<script src="../Componentes/js/mascaras.js"></script>
As you can see, the fields are located in diferent pages, I also tried to put the code directly at the pages but I had no luck.
I think that I don't need to post my entire MasterPage here, then I'll put just the head, but if exists a need I will edit the post.
<head runat="server">
<title></title>
<link rel="shortcut icon" href="../imagens/icone.ico" type="image/x-icon" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="utf-8" />
<link href="../Componentes/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen" />
<link href="../Componentes/fontawesome/css/font-awesome.min.css" rel="stylesheet" media="screen" />
<link href="../Componentes/css/MasterPage.css" rel="stylesheet" />
<link href="../Fontes/Fontes.css" rel="stylesheet" />
<script src="../Componentes/bootstrap/js/jquery-1.12.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/ScrollMagic.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/debug.addIndicators.min.js"></script>
<script src="../Componentes/bootstrap/js/bootstrap.min.js"></script>
<%--Mask Scripts--%>
<script src="<%# Page.ResolveClientUrl("../Componentes/js/mascaras.js") %>"></script>
<script src="../Componentes/js/mascaras.js"></script>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
EDIT 1
Tried this:
id('<%= txtTelefoneContato.ClientID %>').onkeypress = function () { //Located at Contact Page - Still not working
mascara(this, mtel);
}
id('<%= txtCelularUser.ClientID %>').onkeypress = function () { //Located at User Page - Still not working
mascara(this, mtel);
}
id('<%= txtTelefoneUser.ClientID %>').onkeypress = function () { //Located at User Page- Still not working
mascara(this, mtel);
}
The reference to the script is at MasterPage head. But the problem still the same
EDIT2
Im receiving this when I inspect my page:
Error image 1
Error image 2
Resolved
As VDWWD explained, I just put the JS code directly at the .aspx pages with this modification:
from:,
id('txtCelularUser').onkeypress = function () {
mascara(this, mtel);
}
to:
id('<%= txtCelularUser.ClientID %>').onkeypress = function () {
mascara(this, mtel);
}
Thank you in advance
You have to use it like this when accessing elements with JavaScript that have master pages. And it's also better to use it even without master pages. If you should change the ID in you don't have to change it also in your script.
id('<%= txtTelefoneUser.ClientID %>').onkeypress
If you look at the HTML source you will see that the ID of the element has been changed from txtTelefoneUser to something like this ContentPlaceHolder_txtTelefoneUser. Aspnet adds a prefix to ensure every element has a unique ID.
You will see the same usage of prefix in elements that repeat data like GridView/Repeater/DataList etc.
UPDATE
If you put the javascript in an external file you can put a reference to it on the master page like this (assuming Componentes is a folder in the root):
<script src="/Componentes/js/mascaras.js" type="text/javascript"></script>
However putting <%= txtTelefoneUser.ClientID %> in an external file will not work, only on an .aspx page. To make that work declare those elements as variables an assign them on the aspx page while using them in the external js file.
Below a demo:
In the external javascript file:
var myElement;
function myFunction() {
myElement.value = "Success!";
}
and then on the .aspx page:
<script type="text/javascript">
myElement = document.getElementById("<%= TextBox1.ClientID %>");
</script>
After a long time I found that the elements that area inside the Content to be found in javascript must have the name of the content ID in front more undeline and the name of the element ID, you are looking for.
example:
document.querySelector("#ContentPlaceHolder1_img1").setAttribute("src", 123);

How to load different html files in QUnit?

I'm using QUnit for unit testing js and jquery.
My HTML looks like this:
<!DOCTYPE html>
<html>
<head>
<title>QUnit Test Suite</title>
<script src="../lib/jquery.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.16.0.css" type="text/css" media="screen">
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<!--This is where I may have to add startPage.html--->
<script src="../login.js"></script>
<script src="../test/myTests.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
Currently, I'm adding login.js as shown and I'm getting references correctly to objects defined in login.js.
However, functions in login.js contains references to some dom elements defined in startPage.html which is located elsewhere.
So, if I say $('#login-btn'), it is throwing an error. Is there any way to fix this?
Can I
(a) refer to startPage.html to my qunit page given above?
(b) refer to or load startPage.html in the file where I'm running tests (myTests.js):
QUnit.test( "a test", function( assert ) {
assert.equal( 1, "1", "String '1' and number 1 have the same value" );//works
assert.equal( login.abc, "abc", "Abc" );//works with attributes
assert.equal(($("#userid").val()),'', 'Userid field is present');//fails
assert.equal( login.ValidUserId(), true, "ValidUserId" );//fails with functions
});
Does QUnit provide any method to load Html/php files so they'll be defined prior to testing. Like 'fixtures' in jasmine?
EDIT: Please also tell what to do in case I have startPage.php
There are a couple of ways you can do this. The simplest is just to use the built-in QUnit "fixtures" element. In your QUnit HTML file, simply add any HTML you want in the div with the id of qunit-fixture. Any HTML you put in there will be reset to what it was on load before each test (automatically).
<html>
...
<body>
<div id='qunit'></div>
<div id='qunit-fixture'>
<!-- everything in here is reset before each test -->
<form>
<input id='userid' type='text'>
<input id='login-btn' type='submit'>
</form>
</div>
</body>
</html>
Note that the HTML in the fixture doesn't really have to match what you have in production, but obviously you can do that. Really, you should just be adding the minimal necessary HTML so that you can minimize any side effects on your tests.
The second option is to actually pull in the HTML from that login page and delay the start of the QUnit tests until the HTML loading is complete:
<html>
<head>
...
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<script>
// tell QUnit you're not ready to start right away...
QUnit.config.autostart = false;
$.ajax({
url: '/path/to/startPage.html',
dataType: 'html',
success: function(html) {
// find specific elements you want...
var elem = $(html).find(...);
$('#qunit-fixture').append(elem);
QUnit.start(); // ...tell QUnit you're ready to go
}
});
</script>
...
</head>
...
</html>
Another way to do this without using jquery is as follows
QUnit.config.autostart = false;
window.onload = function() {
var xhr = new XMLHttpRequest();
if (xhr) {
xhr.onloadend = function () {
if(xhr.status == 200) {
var txt = xhr.responseText;
var start = txt.indexOf('<body>')+6;
var end = txt.indexOf('</body>');;
var body_text = txt.substring(start, end);
var qunit_fixture_body = document.getElementById('qunit-fixture');
qunit_fixture_body.innerHTML = body_text;
}
QUnit.start();
}
xhr.open("GET", "index.html");
xhr.send();
} else {
QUnit.start(); //If getting the html file from server fails run tests and fail anyway
}
}

jqxGrid fails with error "Object [object Object] has no method 'jqGrid'"

I am trying to embed jqxgrid into my HTML page.
This are the libraries that I import:
<script src="./wicket/resource/org.apache.wicket.resource.JQueryResourceReference/jquery/jquery-1.10.1-ver-1379671500000.js"></script>
<script src="./wicket/resource/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/res/js/wicket-event-jquery-ver-1379671500000.js"></script>
<script src="./wicket/resource/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/res/js/wicket-ajax-jquery-ver-1379671500000.js"></script>
<script src="/jquery/jquery-ui.min.js"></script>
<script src="/jqwidgets/jqxcore.js"></script>
<script src="/jqwidgets/jqxdata.js"></script>
<script src="/jqwidgets/jqxbuttons.js"></script>
<script src="/jqwidgets/jqxscrollbar.js"></script>
<script src="/jqwidgets/jqxmenu.js"></script>
<script src="/jqwidgets/jqxcheckbox.js"></script>
<script src="/jqwidgets/jqxlistbox.js"></script>
<script src="/jqwidgets/jqxdropdownlist.js"></script>
<script src="/jqwidgets/jqxgrid.js"></script>
<script src="/jqwidgets/jqxgrid.columnsresize.js"></script>
<script src="/jqwidgets/jqxgrid.edit.js"></script>
<script src="/jqwidgets/jqxgrid.filter.js"></script>
<script src="/jqwidgets/jqxgrid.pager.js"></script>
<script src="/jqwidgets/jqxgrid.selection.js"></script>
<script src="/jqwidgets/jqxgrid.sort.js"></script>
I omitted type="text/javascript" for simplicity reasons. As you can see the whole think is a wicket application, so I can't really influence the first three imports.
I implemented the jqxgrid as follows:
<script type="text/javascript">
$(document).ready(function() {
var theme = "smoothness";
var dataAdapter = new $.jqx.dataAdapter(data);
$("#jqxgrid").jqxGrid({
width : "99%",
autoheight: true,
theme : theme,
// many more configuration options
columns: [ /* column declaration */ ]
});
// events
$("#jqxgrid").on('cellendedit', function(event) {
var args = event.args;
$.post("EditResponse", {
id: $('#jqxgrid').jqGrid('getCell',args.rowindex,'Name'),
value: args.value
});
});
});
</script>
Again I omitted (in my opinion) unnecessary details, as the initializaton of jqxgrid works fine, I see the table with every data I want it to show.
But when I edit a cell and end editing, the row
$('#jqxgrid').jqGrid('getCell',args.rowindex,'Name')
yields an error in the console:
TypeError: Object [object Object] has no method 'jqGrid'
I did some research but could not fine a clear explanation. Any experiences what could be wrong? Any import I forgot? Anything in the wrong order?
type Error, change
$('#jqxgrid').jqGrid(...
to
$('#jqxgrid').jqxGrid(...

Multiple google maps on a single page -- can only load one at a time

I'm very new to HTML and Javascript (less than a week of experience) and am stuck in the following situation. I created 6 google map visualizations using the googleVis package for R (simple stuff--just markers on a map). I've extracted the Javascript out of the googleVis objects in R and have included them in a simple site that contains 6 divs for each of the 6 different maps.
Each Javascript file includes a function to create a JSON object, a function to draw the map, and a function to display the map:
//define JSON
function gvisDataWest ()
{
var data = new google.visualization.DataTable();
var datajson =
[
[
33.5313,
-112.1774,
"<p>2005-2009 Poverty Rate: 40.7%</p> <p>2000 Poverty Rate: 34.3%</p> <p>Significant difference: 0.0 points </p>"
],
... many rows of data ...
];
data.addColumn('number','Latitude');
data.addColumn('number','Longitude');
data.addColumn('string','tip');
data.addRows(datajson);
return(data);
}
//draw chart
function drawChartWest() {
var data = gvisDataWest();
var options = {};
options["showTip"] = true;
options["enableScrollWheel"] = true;
options["width"] = 400;
var chart = new google.visualization.Map(
document.getElementById('West')
);
chart.draw(data,options);
}
//display chart
function displayChartWest()
{
google.load("visualization", "1", { packages:["map"] });
google.setOnLoadCallback(drawChartWest);
}
Each javascript file includes functions and data for a different region of the country (e.g. there would be definitions for gvisDataMidwest(), givsDataSouthEast(), etc.).
Here's roughly what my HTML looks like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta content="text/xml; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=8" />
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script src="../povscripts/map1.js" type="text/javascript"></script>
<script src="../povscripts/map2.js" type="text/javascript"></script>
<script src="../povscripts/map3.js" type="text/javascript"></script>
<script src="../povscripts/map4.js" type="text/javascript"></script>
<script src="../povscripts/map5.js" type="text/javascript"></script>
<script src="../povscripts/map6.js" type="text/javascript"></script>
</head>
<body>
...a bunch of divs, headers, <p>'s, etc...
...then six divs like this, each with an appropriate id:
<div class="anncdiv">
<div class="bannertitle">
<p class="btxt">West</p>
</div>
<div class="anncdivIn" id="West">
<script type="text/javascript"> displayChartWest() </script>
</div>
</div>
<div class="anncdiv">
<div class="bannertitle">
<p class="btxt">Midwest</p>
</div>
<div class="anncdivIn" id="Midwest">
<script type="text/javascript"> displayChartMidwest() </script>
</div>
</div>
THE PROBLEM: With the way I've currently cobbled this site together, if there are two dsplayChart**() functions being called anywhere on the site (as in this example, with displayChartWest() and displayChartMidwest()) all divs appear blank. But, if I were to just include one of these function calls, then the map displays fine in the appropriate div. Somehow calling two or more of these functions results in a conflict, though I just don't know why. Your help is GREATLY appreciated. Cheers, AR
I think you might need to wait until the DOM is loaded before firing up your charts. Without using a library like jQuery, you could do it using the body onload event:
<body onload="displayCharts()">
...page source...
<script type="text/javascript">
function displayCharts() {
displayChartWest();
displayChartMidwest();
}
</script>
</body>
Instead of doing this:
google.load("visualization", "1", { packages:["map"] });
google.setOnLoadCallback(drawChartWest);
try this instead:
google.load("visualization", "1", { packages:["map"],callback: drawChartWest});

Categories