Hi, Bob!
I've been on double vacation - one was kind of planed, the other one was
forced on me by some flu (can you imagine, in the middle of the summer?) :(
Anyhow, I've updated jQuery Jmol plugin accordingly:
1. Events now receive raw attributes as an array. Probably, we need to
do some cleanup, as for example, we should remove the first argument,
which is the name/id attribute of Java object tag. Or maybe transfer
these arguments as normal (for now they will remain an array, and
documentation has been linked to your site).
2. Changed the name to jQuery-Jmol on GitHub
3. Added new commands to jQuery plugin - hide, show, destroy. Hide and
show works according to your code - it does not use display:none,
instead it sets width and height to 2px. Destroy on the other hand needs
a little help from you. There is no public method in the applet's
interface to call for destruction, so that we could gracefully destroy
Jmol and remove it from browser when needed (Google Chrome is OK with
simply removing an element and creating new one, but IE on the other
hand ... well ... it's IE - Java get's stuck somewhere in RAM and I
don't know any other solution to get rid of it without killing the
browser). Why I see this as a very important issue? It might be very
helpful for building modern web applications, that do not reload the
page, just mangle the DOM tree around (also a problem for IE, if I move
Java applet's <object> tag from one parent to another) or do partial
loading through AJAX.
Also I've started some work on jQuery-JME -
http://dev.gusc.lv/code/jmol/jme.html - this one initializes JME in the
same manner as Jmol and loads one MOL file after ready callback (using
AJAX). I haven't tested it yet on any other browser than Google Chrome
(my primary browser). But as it looks now, it might just work. Also I've
already some ideas, how to implement switching between Jmol and JME.
Answers to your questions bellow...
On 2012.07.20. 6:31, Robert Hanson wrote:
On Thu, Jul 19, 2012 at 11:51 AM, Gusts Kaksis <gusts.kak...@gmail.com
<mailto:gusts.kak...@gmail.com>> wrote:
Hi, Bob!
I put together a little example on the same development PC
(http://dev.gusc.lv/code/jmol/simple2.html) and documented it in
the source. It's not a JmolApi.js replacement yet, but there are
some new ideas I wanted you to look at and give me some feedback.
Basically, there is a Jmol class, that can be initialized like
this var my_jmol = new Jmol(placeholder, options); Where
placeholder can be anything - either jQuery selector or
document.getElementById('some_div'); And then you can call those
other methods on my_jmol. Like my_jmol.addScript(element,
script_source); This gives the same opportunity of multiple
instances as your solution, except for the need of bringing jmol
reference all around as it's stored already internally.
How does one then specify which applet of several is being targeted?
Is that part of the initialization with the placeholder, basically?
What's the role of the placeholder, exactly? Not where the applet is
to appear, or is it?
It's the game of CSS selectors and jQuery. For example, you have 4 divs
that have a class name "jmol-viewer". When you initialize Jmol, it will
work with all of them at once. But afterwards, you can simply use
jQuery-Jmol to specify, which object are you working with or create new
Jmol instance with one specific object (it will not re-initialize it, as
it's already initialized).
Example:
var my_jmol = new Jmol('.jmol-viewer', ... some options ...);
var first_jmol = new Jmol($('.jmol-viewer').eq(0)); // no options,
because we don't want to update anything either
Now my_jmol has an internal reference to all of the <div
class="jmol-viewer"></div> objects, but first_jmol only refers to the
first one. No re-initializations happen, just some filtering for
specific usage. And mostly (as I've seen on the web), developers tend to
use ID's, so it will most likely look like this:
var first_jmol = new Jmol('#jmol1', ... some options ...);
var second_jmol = new Jmol('#jmol2', ... some other options ...);
The placeholder is an element INTO which the Jmol <object> tag should be
placed (not replaced with). The trick here is that, jQuery does not
allow binding events to <object> tags - as some browsers might crash
doing so. So I'm binding all the events to placeholder (usually a <div>)
and set up <object> tag with a name and id as "_" + the id of
placeholder (which by the way get's generated, if there is none provided).
Method summary:
1st level methods - for hardcore developers :)
addEventListener(event_name, callback) - add a listener to Jmol
events (currently: hover, pick, measure, load, animate, resize)
removeEventListener(event_name, callback) - remove listener
So then these transmit the appropriate set xxxCallback calls to Jmol
via applet.script()? Presumably now you can have multiple functions
instead of just one that is a listener? Or is it still 1:1?
Yes and no. First you have to tell jQuery-Jmol, that you will be
listening for these events (see: initialization options -> events
property), so the callbacks are set beforehand. Second as the event
mechanism goes its 1:n, so you can have multiple event listeners on the
same event. I've added to my TODO list the need for initialization
option update, whereas events could be prepared and released, but there
is still no solution to catch a bind() call, so that is why I have to
prepare these events before anyone can bind them. On the other hand,
usually a developer will know, if he'll be using any of these events,
and it can ask them to be enabled on initialization.
script(script_source) - execute a script. Same as Jmol.script() in
your solution
2nd level methods - abstract jQuery bind() methods and some
element type checkings
bindClickScript(element, options) - bind a script to some element
that can receive click events. Options here can be many things:
a) a script source as a string
b) a callback funciton that returns script source as a string (I
followed your advice and added those 2 parameters - Jmol object
and the clicked element itself - in that order)
And the function parameters. Third parameter, perhaps. This is very
useful, because it allows one function to process clicks from a
variety of elements and conditions.
I quite didn't get you here. What third parameter?
c) nothing - in that case if it's a link and it has a href
attribute, that is not '#' or does not start with 'javascript:'
will perform as a script loader.
"script loader"? To me "script" and "load" are apples and oranges. You
mean it will load a model or set of models with parameters, or run a
script?
it will look for a href attribute and if it's value is not '#' and it's
value does not start with 'javascript:', then it will use the value of
href as an URL and call "script URL" on Jmol. Assuming that the URL will
hold the script's source. It does not use "load" command here, as you
pointed out earlier, that I should use "script" command instead.
If it's not a link, then data-script attribute will be used.
What's the significance of the difference there? Say, between a button
and an anchor?
Button does not have a href attribute. Also buttons are
one-hell-of-a-pain-in-the... to do proper styling on. That's why I
prefer anchors, and also they usually point to a real file (in my case),
so that's why I'm using them.
bindChangeScript(element, options, options_off) - used for
checkboxes, radio buttons and selects. options_off is only for
checkbox and if it's not specified data-script-reset will be
looked up in attributes
good -- where options can be a script or a function call, with
parameters, right?
Yes
3rd level methods - shorthand methods abstracting over
bindClickScript()
addScript(element, script_source) - simply add a script on click
for an element
addCallbackScript(element, callback) - same, just with a callback
method
"callback" meaning from jQuery or from Jmol?
Think of a jQuery-Jmol as a brick wall between JavaScript (in this case
more specifically jQuery) developer and Jmol. So this callback is
provided by JavaScript developer to jQuery-Jmol plugin. All
JavaScript<->Jmol callbacks are masqueraded uunderneath the jQuery plugin.
addDataScript(element) - read href or data-script (same as
bindClickScript)
addURLLoader(element) - load model data from a file specified in a
href attribute
Are all these distinctions necessary? A simple script in each case
should be able to handle any of this.
1. is used to perform "script" command in Jmol
2. is used to perform "load" command in Jmol
addAJAXLoader(element) - same as previous, just use AJAX and call
"load inline" in Jmol - actually this might be a great alternative
for signed applet. Just a thought.
Well, not really. The thing is, we can't depend upon XHR2 because it's
just not out there reliably and won't be for several years, probably.
So one needs either a server-side app (jmolcd2.php) or the signed applet.
Well, I've been using AJAX (and by AJAX it does not really matter,
weather it's XHR1, XHR2 or XDR, all I'm doing is making an asynchronous
GET request to server) for couple of years now, without a problem. So
I'd like to disagree to your statement. :)
By "load inline" you probably mean the LOAD DATA statement. You should
never call applet.loadInline() anymore. It's not thread-safe.
Sorry, I meant <select> elements.
I'm referring to Jmol scripting commands, not actual applet's interface
methods. The only method jQuery-Jmol uses is script() method.
I think, jQuery has nothing under the hood for that - just
plain-default behavior. Or do you have some specific needs, then,
I think, something can be done (probably).
I mean moving up and down a selection set using the up/down arrow
keys. If that isn't handled properly, the selection box gets out of
sync, because it's not a click. I'm pretty sure Jmol handles this
properly; at least I do it on my pages usually, but I have to resort
to timeouts to do it right. I was wondering if that had been handled
gracefully in jQuery.
It might get handled by "change" event or "keyup". "Click" is just for
mouse click.
One thing I can see useful with jQuery is that we often have
use for form resets. Very annoying when a page is reloaded
and the controls are not reset.
Umm ... $('input, select, textarea').val(''); should do the
trick.
That's too specific. The way it "used" to be done is
form.reset()
This is what Jmol does right now automatically if you have
included your objects in a <form> wrapper. I know that sounds
terribly antiquated, but form.reset() is particularly useful.
And form resets thing in jQuery can be done like this:
$('form').each(function(i, item){
item.reset();
});
Why not just do
form.reset()?
What is "form" variable? A DOM node or a jQuery object? If it's jQuery,
then jQuery does not have a shorthand for reset. It has a method for
submit(), but it's actually a shorthand for submit event triggering, not
an actual submit() method.
An alternative of this in pure JavaScript would look like this (I think):
var forms = document.getElementsByTagName('form');
for (var i = 0; i < forms.length; i ++){
forms[i].reset();
}
With this demo I've made it would look like this:
var my_jmol = new Jmol(...something something...);
my_jmol.addScript('#link1', 'wireframe 0');
my_jmol.addScript('#link1', 'script myscript.spt');
my_jmol.addScript('#link1', function(jmol, el){
return 'echo "yes!"';
});
Yes, that sounds good. In my implementation, where you can have
jmol = Jmol.getApplet("jmol",....)
jmol is a new Jmol._applet(), so that's basically the same thing, I
think.
Some of the more sophisticated aspects of Jmol objects, such as linked
2D rendering and information panels would be nice to plug in here. As
well as all the 2D and WebGL options. If you could build from JmolCore
and mostly provide a new jQuery-based interface (replacing JmolApi but
not all the Jmol objects), that would be more sensible, it seems to
me. Can't we do that? I hate to see you recreate all this from scratch.
From now on I think, I'll stick to jQuery-Jmol only. I'll finish
jQuery-JME and then I'll take a look into GLmol. And after that, I'll
try to create one unified library, that can switch between three of them
- GLmol for iOS devices, Jmol for all other and JME where possible to
add some editing capabilities.
Still not sure how that would work for selects or check boxes...
Q: Is it pretty simple to set up checkbox groups in jQuery?
JmolApi makes that relatively easy.
Not sure what you mean by that. Do you have some demo, that I
could look at, to see it in real world situation?
Angél Herráez probably does. It's been a while since I looked at
that. Basically you click one "master" box off and all its boxes in
sub-levels are unchecked as well. Hierarchically.
It would be nice if Angel could send me some demos.
Bob
--
Robert M. Hanson
Larson-Anderson Professor of Chemistry
Chair, Chemistry Department
St. Olaf College
Northfield, MN
http://www.stolaf.edu/people/hansonr
If nature does not answer first what we want,
it is better to take what answer we get.
-- Josiah Willard Gibbs, Lecture XXX, Monday, February 5, 1900
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Jmol-developers mailing list
Jmol-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-developers
--
Gusts Kaksis
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Jmol-developers mailing list
Jmol-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-developers