I have a web application that is structured as the following:
Server is written in Python. It serves the client an HTML page with
about 100 different tables (grids) and matching JS files. Every grid is a DIV with JS code that initializes it:
page.html:
<script type="text/javascript" src="static/assets/js/grid_type_1.js"></script>
<script type="text/javascript" src="static/assets/js/grid_type_2.js"></script>
<script type="text/javascript" src="static/assets/js/grid_type_3.js"></script>
<div id="grid_type_1" style="width: 100%; height: 200px;"></div>
<div id="grid_type_2" style="width: 100%; height: 200px;"></div>
<div id="grid_type_3" style="width: 100%; height: 200px;"></div>
grid_type_1.js:
$(function () {
w2utils.settings['dataType'] = 'JSON'
$('#grid_type_1').w2grid({
// configuration here
});
All the JS files use the same UI framework (W2UI) but each grid is of different configuration and structure. After the page loads, each grid makes a POST request to the server and it replies with a JSON that is used to populate that grid with entries.
I'm already using Jinja2 to template the HTML files and 80% of the code in the JS files is the same, so I was thinking if it would be better to generate the JS files as well, instead of duplicating 80% of the JS grid code 100 times.
Is it a viable approach to this issue?
Related
I have made a webpage on Sharepoint with bootstrap and the content is populated with javascript. I am using popover in a table. The table is generated via javascript. The strange thing is that the popover works only after I made a refresh of the page/reloaded it with F5.
A popover outside of the table works fine and by first load. As well as the code runs fine without problems on my local machine, but on sharepoint it breaks down.
Here some code - initialization:
<script src="jquery-3.5.1.slim.min.js"></script>
<script src="popper.min.js"></script>
<script src="bootstrap.min.js"></script>
then the function for generating the table is called:
<body onload="javascript: GenerateTable();">
followed by the popper call:
$(function () {
$('.example-popover').popover({
})
})
The result is a table which contains the following line with the popper:
<td>Here is a question which needs a popper as info!
<div class="row justify-content-end">
Info
</div>
</td>
It seems to me like it an issue with the loading order - but can't figure out why it works locally but not on Sharepoint.
I import js from CDN, it works well in my environment.
Test code for your reference:
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<body >
<td>Here is a question which needs a popper as info!
<div class="row justify-content-end">
Info
</div>
</td>
</body>
<script>
$(function () {
$('.badge').popover();
})
</script>
Test result:
If you need further assistance,please share the full code.
The problem was the order of the javascript execution. As the code is loaded from an external javascript file the order how the code is loaded is not known.
Thus it is recommended to put the javascript function from the html file into an explicit function into the javascript file. Then the function has to be called explicitly.
Javascript File:
function PopperCall(){
$('.example-popover').popover({});
$('.popover-dismiss').popover({trigger: 'focus'});
$('[data-toggle="popover"]').popover();
}
In the HTML the loading is done by:
<body onload="javascript: GenerateTable(); PopperCall();">
i'm trying to implement google sign in functionality in my website using handlebars.
i want to include my script in a file and load it when the https://apis.google.com/js/api:client.js? loads because it creates an object gapi which i use in my js.
The problem is that handlebars doesn't give any help to load js files.
i tried using helpers but the problem is that gapi gets undefined in the registered helper as gapi is loaded when client library loads.
i tried doing
<script src="https://apis.google.com/js/api:client.js?onload=after_load"></script>
<script>
function after_load(){
{{helper_name gapi}}
}
</script>
but still the error persists, is there any way to load a js file in hbs? or i just have to put my code in the script tag itself?
To my mind you're confusing handlebar with something else.
Instead of doing such things try to do something like this :
load normally your api in your html.
once loaded you can call your handlebar part (for example jquery has a nice on ready function).
after the handlebar result has been processed inject it in your html.
if you need to launch another script then do it afterwards
Here is one example:
$(document).ready(function () {
var context = { "form" : "<div class='input-container'><div class='label'>User :</div><div class='input'><input type='text' id='username' name='username'></div></div><div class='input-container'><div class='label'>Password :</div><div class='input'><input type='password' id='password' name='password'></div></div>" };
var source = $("#sourceTemplate").html();
var template = Handlebars.compile(source);
var html = template(context);
$("#resultPlaceholder").html(html);
alert("Load is done place your additional scripts calls here");
});
.input-container { display: inline-block; }
.label { float: left; width: 100px;}
.input { float: left; width: 300px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js"></script>
<script src="https://apis.google.com/js/api:client.js?onload=after_load"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script id="sourceTemplate" type="text/x-handlebars-template">
<div class="container">
{{{form}}}
</div>
</script>
<br/>
<div id="resultPlaceholder">
</div>
I wan to display a code with JavaScript then load it using jQuery load.
Here is my codes :
<div class="noti"><span name="creator">::creator::</span></div>
<script type="text/javascript"> creators=document.getElementsByName('creator'); for(i=0;i<creators.length;i++){creator=document.getElementsByName('creator')[i].innerHTML; :userstats:d=ru,o=dl,s=1,l=50::if(creator=='%name%'){document.getElementsByName('avatar')[i].innerHTML='<img src="%urlpicture%" width="40" height="43" style="background: url(http://wapkaimage.com/400207/400207380_d4c2093a7f.PNG);" width: 40; height: 43;"/>';}:: :/userstats:}</script>
Then in another url, load with this :
<div class="title">NOTIFICATION</div><div id="noti">Loading notification...</div>
<script type="text/javascript"> $('#noti').load('/popup_0.xhtml .noti',function(data){$(this).find('.noti').css({"width":"96%","margin":"auto"}); }); </script>
The problem is the result of span name creator is not displayed in the JQuery load but it displays in the 1st url.
That because the changes made by your javascript doesn't affect source/original file popup_0.xhtml, but still affected just the DOM loaded in the browser, when the load() function get the code inside the source file.
Hope this helps.
This is my file graph.json
{
"nodes":[
{"data":{"id": "Node 1"}},
{"data":{"id": "Node 2"}}
],
"edges":[
{"data":{"source":"Node 1", "target":"Node 2"}}
]
}
which I am trying to visualize with cytoscape.js in the CoSE layout using the code below. Unfortunately I only get an empty graph without any nodes. It does work however if I use the 'concentric' or 'grid' layout, or if I write the graph data directly into the cytoscape.js initialization part. Why does it not work the way I did it: with the 'CoSE' layout and a graph loaded from a JSON file?
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.js"></script>
<script>
$(function () {
$('#cy').cytoscape({
layout: {name: 'cose'},
style: cytoscape.stylesheet()
.selector('node')
.css({'content': 'data(id)'}),
ready: function () {window.cy = this;}
});
$.getJSON('graph.json', function(data) {cy.load(data)});
});
</script>
</head>
<body>
<div id="cy" style="height: 100%; width: 100%; position: absolute; left: 0; top: 0;">
</div>
</body>
</html>
(1) Cytoscape is doing exactly what you're telling it to do. You initialise with no elements, running CoSE on them. You load additional elements asynchronously, which will certainly happen after init.
(2) This blog seems to have a decent description of sync/async. You may want read a book on JS if you're new to the language or if you're new to programming in general.
(3) If you want to keep things simple, pass a fetch promise as options.elements. Read the init section for more info: http://js.cytoscape.org/#core/initialisation
I am building a demo to use Durandal to work with D3.js. I modified on the Starter Kit.
It has two views: Welcome and Flickr. I added a new view Chart and copied some d3js visualization javascript code inside my view:
<section>
chart demo
<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
//more scripts
<div id="container" style="height: 500px; min-width: 500px"></div>
<script type="text/javascript">
d3 visualization code here.
</script>
chart end
</section>
But I find that in a Durandal view, JavaScript code cannot be included. The above code can only display something like:
chart begin
a empty box of size style="height: 500px; min-width: 500px"
chart end
It seems that all the javascirpt code are removed automatically by Durandal.
My question is how to use JavaScript inside a Durandal view? Thanks!
You could leverage the viewAttached function of your durandal view model to execute d3 code. Like so:
define(function (require) {
var vm = {};
vm.viewAttached = function (view) {
// d3 visualization code here
// use class names to find the container instead of id and you can have multiple instances on the same page
d3.select(view).select(".d3container")
.classed("well", true)
.text('I just styled this div using the magic of D3.');
};
return vm;
});