How to clear the blocks from the Blockly editor?

3,765 views
Skip to first unread message

Jessica McNally

unread,
Jun 19, 2014, 12:43:42 PM6/19/14
to blo...@googlegroups.com
Greetings fellow block-heads,

    I have implemented the original Blockly into my Angularjs controller, and have trimmed down the toolbox options.

I am trying to clear the blocks from the following form div with a "cancel" button:
<div class="form-group" id="editor" data-ng-show="seeEditor" style="height: 500px; width: 1200px;"
        data-ng-class="{'has-error' : saveForm.name.$invalid && saveForm.name.$dirty,
                    'has-error': saveForm.description.$invalid && regForm.description.$dirty}">

I am using Blockly injection and the div should look a little familiar to this:

Here is my js code:

  //cancel new script
    $scope.cancel = function () {
        ClearEditor();
        $scope.seeEditor = false;
    }

//clears blocks from editor
function ClearEditor(form) {
        $scope.scriptName = '';
        $scope.scriptDescription = '';
        $scope.userDomXml = '';
        $scope.userJavascriptCode = '';
        var xml = Blockly.Xml.textToDom('<xml xmlns="http://www.w3.org/1999/xhtml"></xml>');
        Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);
        function discard() {
            var count = Blockly.mainWorkspace.getAllBlocks().length;
            if (count < 2 || window.confirm('Delete all ' + count + ' blocks?')) {
                Blockly.mainWorkspace.clear();
                renderContent();
            }
        }
       
    }

Here is the original Blockly function to clear all blocks:
/**
 * Discard all blocks from the workspace.
 */
Code.discard = function() {
  var count = Blockly.mainWorkspace.getAllBlocks().length;
  if (count < 2 ||
      window.confirm(BlocklyApps.getMsg('Code_discard').replace('%1', count))) {
    Blockly.mainWorkspace.clear();
    window.location.hash = '';
  }
};

Note the only difference is I do not reference "Code.discard" at the very beginning of the function. Doing so causes the following console message in Batarang:
ReferenceError: Code is not defined

I have tried substituting "Blockly.discard" which does not cause an error, but also does not clear the blocks from the editor. Also the two lines
"var xml = Blockly.Xml.textToDom('<xml xmlns="http://www.w3.org/1999/xhtml"></xml>');
        Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);"
do not effect the results either.

Right now, if I select to "cancel" creating a new Blockly script the editor is hidden from view. However if I select a "New" (not shown here) script option the editor appears with the previously selected blocks.

How can I clear the blocks from the editor so that it is completely clear when the user navigates to it again? 

Jessica McNally

unread,
Jun 19, 2014, 1:08:01 PM6/19/14
to blo...@googlegroups.com
I just want to add something,

based on this documentation for Blockly:

Importing and Exporting Blocks

If your application needs to save and store the user's blocks and restore them at a later visit, use this call for export to XML:

  var xml = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace);
 
var xml_text = Blockly.Xml.domToText(xml);

This will produce a minimal (but ugly) string containing the XML for the user's blocks. If one wishes to obtain a more readable (but larger) string, use Blockly.Xml.domToPrettyText instead.

Restoring from an XML string to blocks is just as simple:

  var xml = Blockly.Xml.textToDom(xml_text);
 
Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);

just referencing the two lines 
"var xml = Blockly.Xml.textToDom('<xml xmlns="http://www.w3.org/1999/xhtml"></xml>');
        Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);"

in my function should clear out the editor. Without having to call the Discard all blocks function,
why doesn't this work???
function ClearEditor(form) {
        $scope.scriptName = '';
        $scope.scriptDescription = '';
        $scope.userDomXml = '';
        $scope.userJavascriptCode = '';
        var xml = Blockly.Xml.textToDom('<xml xmlns="http://www.w3.org/1999/xhtml"></xml>');
        Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);
 }

It is important to note that it does not cause any console errors. It also doesn't clear out the editor, so when the user navigates to a "new" script option the block code from before is still present.

Blake

unread,
Jun 19, 2014, 1:18:09 PM6/19/14
to blo...@googlegroups.com
Maybe I am missing the point, but Blockly.mainWorkspace.clear()should remove all of the blocks from the workspace


--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mark Friedman

unread,
Jun 19, 2014, 1:18:46 PM6/19/14
to blo...@googlegroups.com
The call which you need to actually clear the contents is Blockly.mainWorkspace.clear().  I see that you are defining a function called discard() which makes that call but I don't see that you are actually calling your discard() function anywhere.

-Mark


--

Mark Friedman

unread,
Jun 19, 2014, 1:21:04 PM6/19/14
to blo...@googlegroups.com
The Blockly.Xml functions you are calling do not clear the workspace.  If you had any actual blocks described in your XML they would just get added to your workspace.

-Mark


--

Jessica McNally

unread,
Jun 19, 2014, 5:24:06 PM6/19/14
to blo...@googlegroups.com
Taking into account both Mr. Bourque's and Mr. Fieldman's replies, here is my latest adaptation:

 function ClearEditor(form) {
        $scope.scriptName = '';
        $scope.scriptDescription = '';
        $scope.userDomXml = '';
        $scope.userJavascriptCode = '';
        //var xml = Blockly.Xml.textToDom('<xml xmlns="http://www.w3.org/1999/xhtml"></xml>');
        //Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);
        Blockly.mainWorkspace.clear();
       // discard();
    }

And here is the error message from the console:
TypeError: Cannot read property 'clear' of null

I have tried several different ways to define my function and I am wondering why "Blockly.mainworkspace" is coming up as null? Any ideas?

On Thursday, June 19, 2014 12:43:42 PM UTC-4, Jessica McNally wrote:

Mark Friedman

unread,
Jun 19, 2014, 5:31:44 PM6/19/14
to blo...@googlegroups.com
Do you get the same result if you just evaluate Blockly.mainWorkspace.clear() in your browser's Javascript console?

-Mark


--

Jessica McNally

unread,
Jun 19, 2014, 5:47:11 PM6/19/14
to blo...@googlegroups.com
When I place the Blockly.mainWorkspace.clear(); by itself I get the following error:
TypeError: Cannot read property 'clear' of null

As it appears in my application:

function ClearEditor(form) {
        $scope.scriptName = '';
        $scope.scriptDescription = '';
        $scope.userDomXml = '';
        $scope.userJavascriptCode = '';
        //var xml = Blockly.Xml.textToDom('<xml xmlns="http://www.w3.org/1999/xhtml"></xml>');
        //Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);
        //Blockly.mainWorkspace.clear();
       // discard();
    }

    Blockly.mainWorkspace.clear();

I believe this is how to just evaluate the one line of code?

On Thursday, June 19, 2014 12:43:42 PM UTC-4, Jessica McNally wrote:

Mark Friedman

unread,
Jun 19, 2014, 6:00:31 PM6/19/14
to blo...@googlegroups.com
Jessica,

  That's not quite what I meant.  I really meant using the Javascript console.  Here's a page which describes how to access that in various browsers (at least on Windows).  I can't guarantee that that page's information is current, though.  You may also be able to access the Javascript console via some browser menu item, as well.

-Mark


--

Jessica McNally

unread,
Jun 19, 2014, 6:31:58 PM6/19/14
to blo...@googlegroups.com
Fixed!!!

Before Blockly is injected, Blockly exists but Blockly.mainworkspace does not. This is why I kept getting null error on my page load.

The fix:

var clearEditor = function () {
        $scope.scriptName = '';
        $scope.scriptDescription = '';
        $scope.userDomXml = '';
        $scope.userJavascriptCode = '';

        if (Blockly.mainWorkspace !== null) {
            Blockly.mainWorkspace.clear();
        }
    }

On Thursday, June 19, 2014 12:43:42 PM UTC-4, Jessica McNally wrote:
Reply all
Reply to author
Forward
0 new messages