I am able to execute external JS file (which is used to render chemical molecules) inside jQuery. However, when the external JS file is loaded, it overwrites everything from my initial file.
How am i supposed to insert the external JS file into the appropriate DOM (in this case, the last available class with className "render") without overwriting the existing HTML file?
I use an URL to get data in JSON format and parse it using .each() function as mentioned below.
$(document).ready(function(){
$.get("someURL", function (json){
var obj = $.parseJSON(json);
$(".container").append("<ul class =\"items\">");
$.each(obj, function(i){
name = obj[i].name;
mol = obj[i].mol;
script = $(document.createElement('script')).attr('type', 'text/javascript').attr('src','js/external.js');
$('ul.items').append('<li><div class="render">');
$(script).appendTo(".render:last");
});
});
});
My external js file is,
transform = new ChemDoodle.TransformCanvas(name, 150, 150, true);
transform.loadMolecule(ChemDoodle.readMOL(mol));
Also, please note that I have no programming experience and trying to learn JS/jQuery on my own for a couple of months.
Any help/guidance is much appreciated.
Thanks in advance,
Kaushik
I could solve the above problem.
The problem was in the external.js (chemdoodle JS which renders chemical compounds) file that I was using. It renders chemical compound structure inside . Due to an inherent problem in chemdoodle's JS component, it used to overwrite my file (irrespective of if I call it as external script or internal function). I had to explicitly insert DOM with the same id as the chemdoodle was using. Here is what I did and that solved the problem. It might help someone who is working with chemdoodle too!
$(document).ready(function(){
function canvasCall(name, mol){
transform = new ChemDoodle.TransformCanvas(name, 150, 150, true);
transform.specs.bonds_useJMOLColors = true;
transform.specs.set3DRepresentation('Stick');
transform.specs.atoms_display = false;
transform.specs.backgroundColor = 'black';
transform.specs.bonds_clearOverlaps_2D = true;
transform.loadMolecule(ChemDoodle.readMOL(mol));
};
$(".container").append("<ul class =\"items\">");
$.getJSON(someURL, function (obj){
$.each(obj, function(i){
var name = obj[i].name;
var mol = obj[i].mol;
$('ul.items').append("<li><div class=\"render\"><canvas id=\"" + name + "\">");
$("#"+name).append(canvasCall(name, mol));
});
});
});
Related
Pardon me if this is a very silly question. I'm brand new to JS and I was wondering how I can use this function in other parts of my code. I looked at tutorials and other websites, but the way they define functions seems to be different than what I have here. Could anyone please nudge me in the right direction?
$('.message_div').each(function message_function()
{
console.log("One liner");
var th = $(this);
var ih = $(this).outerHeight(); // outer height
var oh = $(this).find('.message').outerHeight();
console.log("Oh", oh);
var txt = $(this).find('.message').html();
console.log("Ih", ih);
if (oh > ih)
{
th.html('');
th.html('<marquee class="message" direction="up" scrollamount="1" scrolldelay="0">' + txt + '</marquee>')
}
});
//message_function(); -----> Is this the right way?
There are several intricacies here with regards to what jQuery does. The simple way of referencing this function later on would be to store it in a variable:
function message_function()
{
console.log("One liner");
var th = $(this);
//... (rest of function omitted for brevity)
}
$('.message_div').each(message_function);//note that the function handle is used here,
//and not the result of the function which would
//have used the () to call it
///and then later on
message_function();
However, the problem here is with this. jQuery will bind this behind the scenes (which means it works fine in each), however in order to properly call the message function separately, you would need to have an element ready to bind. For example,
var element = document.querySelector("div");
message_function.call(element);
alternatively:
var element = document.querySelector("div");
var elementMessage = message_function.bind(element);
elementMessage();
Here is a broader explanation of what this is, and how jQuery interacts with it: https://stackoverflow.com/a/28443915/1026459
Inside the same file :
Move that code inside a function
Call the function
Outside of that file :
Move the function (you just created) to a .js file
Include the .js file in the desired document
Make sure the DOM elements properties match what's in the script
I am using GeckoWebBrowser within my VB.NET (Windows Form App) program. The GeckoWebBrowser loads a local html file. This html has embed in-line a svg file (human body diagram with bones and internal organs) with a javascript function for picking up all the "ids" of the elements from the svg document. I'd like to call the aforementioned javascript function from VB.NET (Windows form app), but I don't know how to do so. Can anyone help me, or give me a source code example please? All the stuff I've found is based in C#...
This is my javascript function in my html file:
<script type="text/javascript">
(funcion () {
// Function to be called in VB.NET when the DOM is loaded
var SVGHandler = function () {
// Picking up the id Root Node="CUERPO_HUMANO" into svg variable
var svg = document.querySelector('#CUERPO_HUMANO');
// In Items we save all the <g> which have an ID
var items = svg.querySelectorAll('g[id], path[id]');
//var items = svg.querySelectorAll('g[id]');
// We loop all the nodes saved in Items and add them to click event listener
forEach(items, function (index, value) {
value.addEventListener('click', function (event) {
event.preventDefault();
//We avoid the spread of events
event.stopPropagation();
return event.currentTarget.id
// console.log(event.currentTarget.id)
});
});
}
// https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/
var forEach = function (array, callback, scope) {
for (var i = 0; i < array.length; i++) {
callback.call(scope, i, array[i]); // passes back stuff we need
}
};
// With this method, we call a SVGHandler when DOM is totally loaded
document.addEventListener('DOMContentLoaded', SVGHandler);
})();
</script>
What code should I use in VB.NET for calling my javascript function each time I click on a specific bone or organ in the human body diagram loaded in GeckoWebBrowser?
I want to save the "id" picked up with the calling into a string variable in order to use it as a parameter in a SQL statement and populate a DataGridView.
I've been searching and all that I could find was related to C#, not a single VB.NET example. Even though I was trying to figure out the equivalence in VB.NET trying to convert the C#'s examples to VB.NET, I have some doubts on how to do the javascript call. According to my javascript function It could be something like this:
browserControl.Navigate("javascript:void(funcion())");
Please, Can anyone help me to solve this? I would be very thankful...
Well since you have set click EventListener's I think that you're not looking for a way to call the eventual function from VB.NET but this is quite unclear according to your post so I'll give you examples on how to call a javascript function and how to trigger a reaction in your VB.NET code through javascript using GeckoWebBrowser.
Your code snippet of your attempt to call a js function from your vb code is correct. The only problem is that you haven't defined any callable js function in your html file. In your case you should do this to trigger your main js function from vb:
//Sorry I don't know vb. I'll give example in c# keeping it as simple as possible so that you can easily convert it to vb
Gecko.GeckoHtmlElement humanBodyPart = (Gecko.GeckoHtmlElement) browserControl.Document.GetElementById("your id");
humanBodyPart.Click();
The above code finds the element with the matching id in the GeckoWebBrowser and clicks it. Since you've set click EventListener's, by clicking one of the elements this will trigger the function assigned to them to run.
Moving on, in order to save the id of the elements to a string variable in your vb code you'll need to add this little bit of js code in to the code that you pass as 'callback' parameter in your forEach function:
var event = document.createEvent('MessageEvent');
var origin = window.location.protocol + '//' + window.location.host;
var event = new MessageEvent('jsCall', { 'view': window, 'bubbles': false, 'cancelable': false, 'data': 'YOUR EVENTUAL ID AS A STRING (THIS STUFF GOES BACK TO THE VB/C# CODE)' });
document.dispatchEvent (event);
Then the above snippet should be handled in your vb code like this:
browserControl.AddMessageEventListener("jsCall", (id) =>
{
//Here in the variable id you have your clicked id as a string. Do what you wanted to do...
});
VB side :
you need wait until the document is completed to add listeners
for example : _DocumentCompleted
Private Sub GeckoWebBrowser1_DocumentCompleted(sender As Object, e As Gecko.Events.GeckoDocumentCompletedEventArgs) Handles GeckoWebBrowser1.DocumentCompleted
GeckoWebBrowser1.AddMessageEventListener("my_function_name JS_side", AddressOf my_sub_for_treatment)
End Sub
JS side :
var event = document.createEvent('MessageEvent');
var origin = window.location.protocol + '//' + window.location.host;
var event = new MessageEvent('my_function_name JS_side', { 'view': window, 'bubbles': false, 'cancelable': false, 'data': my_data_to transfer });
document.dispatchEvent (event);
I'm trying to edit the default "link" plugin within CKEditor such that the plugin will display a selection of links that I have stored in a MySQL database.
I've essentially taken the code from the anchor selector portion of the plugin and copied it over to my "article" snippet.
The problem that I'm having is that I don't know how to specifically get the data from the php (which is a JSON array) into the javascript within the confines of the plugin as shown below.
The source:
setup: function (a) {
this.clear(); //Clears the dropdown menu
this.add("");
var data; //Initialize the variable data where I want the JSON from PHP to go.
//This is where I want to obtain the data and spit it out!!
$.post("titles.php", function (result) {
//A Data-handler function call here doesn't work?
//data = result also won't work because of scope
//Something has to happen here though...
});
data = JSON.parse(data);
for (var i = 0; i < data.length; i++) {
data[i]["title"] && this.add(data[i]["title"]); //Add each item to dropdown
}
a.article && this.setValue(a.article.name);
(a = this.getDialog().getContentElement("info", "linkType")) && "email" == a.getValue() && this.focus()
}
Sidenote: This code does work if I hardcode the exact output from the PHP file to a variable.
I might be missing something as silly as a commonly known "best practice" in JS as JS is not my forte, so please let me know if I'm ignorant or stupid!
Thanks in advance!
header.php
<script src="ckeditor.js"></script>
<script>
var Globalvars = {
myvar: '<?php echo $myvar; ?>'
}
</script>
Now, you can use this myvar variable in your .js file as:
alert(Globalvars.myvar);
I have a jQuery function on a separate functions.js file, that is in charge of making a SQL update by posting some info. This is working properly, here you can see it:
Function being called on my php file, passing just element's ID info:
$('.tableContent').on('click', '.discontinueIcon', function() {
turnId = $(this).attr('data-id');
discontinueRow();})
Function working properly on a separate functions.js file:
function discontinueRow(){
row = '#' + turnId;
$.post('config/forms/turn_conf/turn_discontinue.php', { tu_id:turnId }).success(messageOKKKK);}
As I will need to create many more functions updating info from many tables, I was trying to have a unique function, and provide it with needed info being sent with parameters from the php files. As I am new to this, do not even know if it is possible, and if it is I definitely can't get the way to.
I tried to store the needed values on several variables on my php file:
$('.tableContent').on('click', '.discontinueIcon', function() {
turnId = $(this).attr('data-id');
action = "'config/forms/turn_conf/turn_discontinue.php'";
elements = "tu_id:turnId";
discontinueRow(action,elements);})
And using these parameters on the separate functions.js file as this shows:
function discontinueRow(action,elements){
row = '#' + turnId;
$.post(+action+,{ +elements+ }).success(messageOKKKK);}
But this does not work. Is it possible to pass by this way parameters to a function? In this case, what is going wrong here?
You can do it like this:
$('.tableContent').on('click', '.discontinueIcon', function() {
turnId = $(this).attr('data-id');
discontinueRow('config/forms/turn_conf/turn_discontinue.php', { tu_id:turnId });
});
you also need to set up your function with input parameters:
function discontinueRow(url, params){
row = '#' + turnId;
$.post(url, params).success(messageOKKKK);}
}
I am trying to copy some data from one processed web page into a new one that I want to export. The background is that I need to scrape parts of a page and need to build a new page with parts of the original page.
The problem seems that phantomJs includeJs() and evaluate() methods are sandboxed and I can't see a proper way to import DOM from one page to another.
I have some test code that looks like this, with page being the original and out the new page:
....
var title = page.evaluate(function() {
return title = document.getElementById('fooo').innerHTML;
});
console.log('page title:' + title);
//fs.write('c:/Temp/title.js', "var title = '" + title + "';", 'w');
var out = new WebPage;
out.viewportSize = page.viewportSize;
out.content = '<html><head></head><body><div id="wrapper"></div><p>done</p></body></html>';
out.includeJs('c:/Temp/title.js', function() {
var p = document.createElement('p');
p.appendChild(document.createTextNode(title));
document.getElementById('wrapper').appendChild(p);
});
...
The function in your last includeJs call here won't work - as you note, it's sandboxed, and that means that closures won't work, so title won't be defined. A method of passing variables to page.evaluate is noted as a feature request, but isn't available as of PhantomJS v.1.4.1.
The general way I get around this is by using the Function constructor, which allows you to create a function using a string:
var myVar = {some:"values", I:"want to pass into my page"},
test = new Function("window.myVar = " + JSON.stringify(myVar));
page.evaluate(test);
Now you can evaluate a function like the one you have, referencing myVar in the sandbox, and your data will be available in the client scope.