Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display blockly workspace for each div it belongs #33

Closed
niketgosrani opened this issue Dec 10, 2020 · 10 comments
Closed

Display blockly workspace for each div it belongs #33

niketgosrani opened this issue Dec 10, 2020 · 10 comments
Labels
help wanted Extra attention is needed

Comments

@niketgosrani
Copy link

I have a list of files of type JSON and XML. XML files have blockly data. I am enumerating through each file and identifying if those are blockly or non-blockly and want to display accordingly in their respective div. The problem here is I am not able to have the blockly workspace display correctly under its own div and it stacks up against one below another. how do I map each workspace with its div it should display under.

This is how the view looks and few have tabular data and few need to display blockly workspace.
image
image
image

Here's my HTML

<div>
  <div *ngIf="!isBlocky">
    <ag-grid-angular style="width:100%;"
                        class="ag-theme-material"
                        [gridOptions]="jobViewGridOptions"
                        [rowData]="jobDetailData"></ag-grid-angular>
  </div>
  <div *ngIf="isBlocky" >
    <mat-card>No visual available for a script file.</mat-card> 
    <ngx-blockly [config]="blockConfig" [customBlocks]="customBlocks"></ngx-blockly>
  </div>
</div>

I understand customBlocks array will have all the workspaces but how should I do a for each and display workspace specific to each div and not all at once as one below another as you see in picture 3 ScriptTest has all the workspaces and not just it's own.
I tried a for each on customBlocks but it did not do the work and said cannot read type of undefined.

and my function where I prepare the data to display

public ngOnInit(): void {
        this.initializeJobTable();
        this.customBlocks = [
            new SendCommandBlock(),
            new SendCommandExpectResponseBlock(),
            new RunAfterBlock(),
        ];
        this.ngxToolboxBuilder.nodes = [
            new Category("CommandTron", "#FF00FF", this.customBlocks, undefined),
            LOGIC_CATEGORY,
            LOOP_CATEGORY,
            MATH_CATEGORY,
            TEXT_CATEGORY,
            new Separator(),
            LISTS_CATEGORY,
            // COLOUR_CATEGORY,
            VARIABLES_CATEGORY,
            FUNCTIONS_CATEGORY,
        ];
        this.blockConfig = {
            disable: true,
            sounds: false,
            readOnly: true,
            grid: {
                spacing: 20,
                length: 2,
                colour: "#ccc",
                snap: false,
            },
        };
        this.blockConfig.toolbox = this.ngxToolboxBuilder.build();
        this.jobDataService.get(this.inputJobId)
        .subscribe((data) => {
            this.job = data;
            try {
                if (!this.isBlocky){
                    const commands = (ObjectUtils.deserializeJson(this.job.jobFile) as ICommandResponsePair[]);
                    for (const cmd of commands) {
                        this.jobDetailData.push({
                            command : cmd.command,
                            response : cmd.response,
                        });
                    }
                } else {
                    console.log("hfs" + StringUtils.b64DecodeUnicode(this.job.jobFile));
                    setTimeout(() => {this.blockWorkspace.fromXml(StringUtils.b64DecodeUnicode(this.job.jobFile));}, 0);
                }
            }   catch (e) {
                    this.notificationService.showErrorNoTimeout("Error parsing job file contents.");
            }
        });

    }

Not sure where I am wrong and stuck on this.

@roroettg
Copy link
Owner

Let's see if I understood you correct.

Your first issue is that the blockly component does not stay within the div?

This can be solved with css. Maybe this older issue helps #25

Your second issue is that you want to have multiple workspaces with different custom blocks?

I guess the easiest solution would be to use one blockly-component per workspace and give each is own custom blocks.

@roroettg roroettg added the help wanted Extra attention is needed label Dec 13, 2020
@niketgosrani
Copy link
Author

For the second issue, can you elaborate more on how to use one blockly-component per workspace.
I had tried a ngFor to iterate through customBlocks array but that does not help. I am not sure if that is what you meant but will appreciate it if you can explain with an example.

@roroettg
Copy link
Owner

Not really sure why you would need to iterate through customblocks. Customblocks are blocks you defined and want to be available within the blockly component.

You can have multiple ngx-blockly components and give each its on config and customBlocks

HTML

<ngx-blockly 
    [config]="config" 
    [generatorConfig]="generatorConfig" 
    [customBlocks]="customBlocks"
    (javascriptCode)="onCode($event)">
</ngx-blockly>

<ngx-blockly
        [config]="config2"
        [generatorConfig]="generatorConfig"
        [customBlocks]="customBlocks2"
        (javascriptCode)="onCode($event)">
</ngx-blockly>

Typescript

    public customBlocks = [
        new ExampleBlock(null, new ExampleMutator('example_mutator'))
    ];
    public customBlocks2 = [
        new ExampleBlock(null, new ExampleMutator('example_mutator'))
    ];
    public config: NgxBlocklyConfig = {
        toolbox: '<xml id="toolbox" style="display: none">' +
            '<category name="Logic" colour="%{BKY_LOGIC_HUE}">' +
            '<block type="controls_if"></block>' +
            '<block type="controls_repeat_ext"></block>' +
            '<block type="logic_compare"></block>' +
            '<block type="math_number_property"></block>' +
            '<block type="math_number"></block>' +
            '<block type="math_arithmetic"></block>' +
            '<block type="text"></block>' +
            '<block type="text_print"></block>' +
            '<block type="example_block"></block>' +
            '</category>' +
            '</xml>',
        scrollbars: true,
        trashcan: true,
        search: {
            enabled: true
        }
    };
    public config2: NgxBlocklyConfig = {
        toolbox: '<xml id="toolbox" style="display: none">' +
            '<category name="Logic" colour="%{BKY_LOGIC_HUE}">' +
            '<block type="example_block"></block>' +
            '</category>' +
            '</xml>',
        scrollbars: true,
        trashcan: true,
        search: {
            enabled: true
        }
    };

@niketgosrani
Copy link
Author

I would have done the above if there was a fixed number of Blockly components and I knew which were they, but the way I have it is I get a list of jobs from DB and I iterate through them and find out which are Blockly and want to display them accordingly. So it's more dynamic and only known at runtime. The one you suggested above will only work in a situation where I know the number of blockly components to display. I hope this makes sense, also, look at my Init function in my first post which will give you some idea.

@roroettg
Copy link
Owner

roroettg commented Dec 16, 2020

This is not really a blockly issue, but an angular issue:

You could solve it probably like this.

<div *ngFor="item of list">
    <div *ngIf="!isBlocky(item)">
        <ag-grid-angular style="width:100%;"
                         class="ag-theme-material"
                         [gridOptions]="jobViewGridOptions"
                         [rowData]="jobDetailData"></ag-grid-angular>
    </div>
    <div *ngIf="isBlocky(item)" >
        <mat-card>No visual available for a script file.</mat-card>
        <ngx-blockly [config]="blockConfig" [customBlocks]="customBlocks"></ngx-blockly>
    </div>
</div>
  • Notice the list, which is a list of your items to be shown.
  • ngFor iterates through the list and will create the underlying html code in each iteration.
  • I added a method isBlockly(), that can check for an item of the list if it is a blockly element
  • The ngIf will create the div only if the condition is true

Further Information:
https://angular.io/api/common/NgForOf
https://angular.io/api/common/NgIf

@roroettg
Copy link
Owner

Seems solved. If you have further questions feel free to reopen this.

@evdigitech
Copy link

evdigitech commented Sep 15, 2021

Hi @roroettg , I am trying to create multiple workspace in my angular 7 inside tabs but getting error while using ngx-blockly component more than one time:

image

Can you please help me, how can I use multi workspace in my project using ngx-blockly?
I have tried the code suggested above but still getting the same error.

@roroettg
Copy link
Owner

Hi @evdigitech,

first of all I would highly recommend to use Angular in a more current version, since Angular 7 has already reached end of life . I am not sure if any ngx-blockly version does actually work with Angular7.

Which ngx-blockly version are you currently using?

Could you provide your code snippet or an example where it is not working?

@evdigitech
Copy link

I am using ngx-blockly version 10.1.4 and every thing related to blockly is working fine but I want to implement multiple workspace dynamically in my project. If I am using 2 workspace together then its not giving any error but whenever I am trying to integrate it inside the tab or show hide with the help of ngIf then it gives me error.
I am sending you the screenshot of my code, I hope it can help you to understand the issue:
image

@roroettg
Copy link
Owner

This issue is coming from blockly itself.

google/blockly#1114

Your tabs probably try to inject the workspace into shadow-dom, which does not work with blockly at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants