Tutorial > Sketcher: Listening to User Changes
The sketcher in the ChemDoodle Web Components allows your users to describe and submit chemical information to your systems. But there may be times where you need to provide your users with immediate feedback as they are drawing their figures. This tutorial describes how to achieve this functionality.
Demonstration
The following sketcher will tell you how many atoms and bonds are present in your structure after each edit.
Programmatically Listening to Actions
All of the edits a user performs in the sketcher are logged in the history manager (mySketcher.historyManager) for that sketcher. These could be adding bonds, changing atom labels, moving structures, etc. This facilitates the undo and redo functionality associated with these types of content editors. In the ChemDoodle Web Components, the Action class will notify the associated sketcher of its forward or reverse execution. We can listen to these notifications by overriding the SketcherCanvas.checksOnAction() function.
The SketcherCanvas.checksOnAction() is already used by the core SketcherCanvas class to react to changes, such as updating numbers on atom mappings or correctly orienting dynamic brackets. So it is essential that we still call the parent function even if we are overriding it to add our own listener. This can be done in the following manner:
let sketcher = new ChemDoodle.SketcherCanvas('sketcher', 500, 300, {});
// ... set up your sketcher
// now we override the checksOnAction function, making sure to save the old one and also call it
sketcher.oldFunc = sketcher.checksOnAction;
// using force improves efficiency, so changes will not be checked until a render occurs
// you can force a check by sending true to this function after calling check with a false
sketcher.checksOnAction = function(force){
// call the old checksOnAction function
this.oldFunc(force);
// add in your functionality
for(let i = 0, ii = this.molecules.length; i<ii; i++){
// do calculations on each molecule
}
};
Full Example
First we create the HTML element within the DOM that we will update with our information, using feedback as its id:
<span id="feedback" style="font-size:24px;"></span>
Now we create the sketcher and override the checksOnAction function:
<script>
ChemDoodle.ELEMENT['H'].jmolColor = 'black';
ChemDoodle.ELEMENT['S'].jmolColor = '#B9A130';
let sketcher = new ChemDoodle.SketcherCanvas('sketcher', 550, 300, {useServices:true, oneMolecule:true});
sketcher.styles.atoms_useJMOLColors = true;
sketcher.styles.bonds_clearOverlaps_2D = true;
sketcher.oldFunc = sketcher.checksOnAction;
// using force improves efficiency, so changes will not be checked until a render occurs
// you can force a check by sending true to this function after calling check with a false
sketcher.checksOnAction = function(force){
// call the old checksOnAction function
this.oldFunc(force);
// there will only be one molecule because this is a single molecule sketcher
let m = this.getMolecule();
// update the DOM element with the information
document.getElementById('feedback').innerHTML = '<strong>Atoms</strong>: ' + m.atoms.length + ', <strong>Bonds</strong>: ' + m.bonds.length;
};
sketcher.repaint();
</script>
There you have it, simple as that!