jQWidgets Forums

jQuery UI Widgets Forums Angular Ribbon Bar Errrors when usning in a SPA application

This topic contains 1 reply, has 2 voices, and was last updated by  Martin 6 years, 11 months ago.

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author

  • Koimad
    Participant

    I’m working on building a framework that allows content to be loaded into place holders as different modules are loaded. One of the areas will be a ribbon bar that the tabs are dynamic and added / removed based on modules loaded. I’ve proved this concept for the ribbonbar in a simple angular application, and it works fine. However when I repeat the same in my framework app it errors in the following ways.

    1. If I don’t add atleast a single

  • and <div> for a single tab I get this error
  • RibbonComponent.html:1 ERROR TypeError: Cannot read property ‘className’ of undefined
    at b.(:4200/anonymous function)._render (http://localhost:4200/vendor.js:69282:8154)
    at b.(:4200/anonymous function).createInstance (http://localhost:4200/vendor.js:69282:853)
    at Object.push../node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js.a.jqx.applyWidget (jqxcore.js:14)
    at HTMLDivElement.<anonymous> (jqxcore.js:14)
    at Function.each (jqxcore.js:7)
    at init.each (jqxcore.js:7)
    at init.a.fn.(:4200/anonymous function) [as jqxRibbon] (http://localhost:4200/vendor.js:69263:12021)
    at Object.createInstance (jqxcore.js:14)
    at jqxRibbonComponent.push../node_modules/jqwidgets-scripts/jqwidgets-ts/angular_jqxribbon.ts.jqxRibbonComponent.createComponent (angular_jqxribbon.ts:134)
    at jqxRibbonComponent.push../node_modules/jqwidgets-scripts/jqwidgets-ts/angular_jqxribbon.ts.jqxRibbonComponent.ngOnInit (angular_jqxribbon.ts:50)

    2. If I add

  • and <div> the page loads without error but mouse hover over I get the following error and the tabs don’t react to mouse clicks.
  • core.js:1598 ERROR TypeError: Cannot read property ‘_index’ of undefined
    at HTMLUListElement.b (jqxribbon.js:7)
    at HTMLUListElement.handle (jqxcore.js:7)
    at HTMLUListElement.dispatch (jqxcore.js:7)
    at HTMLUListElement.bB (jqxcore.js:7)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4053)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:496)
    at invokeTask (zone.js:1540)

    3. If I try to add a ribbonitem in code I get the following error.

    core.js:1598 ERROR TypeError: Cannot read property ‘length’ of undefined
    at b.(:4200/anonymous function).addAt (http://localhost:4200/vendor.js:69282:2228)
    at Object.push../node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js.a.jqx.invoke (jqxcore.js:14)
    at Object.push../node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js.a.jqx.jqxWidgetProxy (jqxcore.js:14)
    at HTMLDivElement.<anonymous> (jqxcore.js:14)
    at Function.each (jqxcore.js:7)
    at init.each (jqxcore.js:7)
    at init.a.fn.(:4200/anonymous function) [as jqxRibbon] (http://localhost:4200/vendor.js:69263:12460)
    at jqxRibbonComponent.push../node_modules/jqwidgets-scripts/jqwidgets-ts/angular_jqxribbon.ts.jqxRibbonComponent.addAt (angular_jqxribbon.ts:283)
    at ribbon.component.ts:52
    at Array.forEach (<anonymous>)

    Below I give a complete visual tree of the app and code of some of my classes, Can anyone help.

    <body>
    <app-root _nghost-c0=”” ng-version=”6.0.2″>
    <router-outlet _ngcontent-c0=””></router-outlet>
    <dock-docksite _nghost-c1=””>
    <div _ngcontent-c1=”” class=”ribbon”>
    <!—->
    <dock-ribbon _nghost-c3=””>
    <jqxribbon _ngcontent-c3=”” style=”” class=”” ng-reflect-attr-animation-type=”none” ng-reflect-attr-width=”1200″>
    <div id=”jqxWidget1f00c80b489d” class=” jqx-widget jqx-ribbon” style=”flex: 1 1 auto; width: 1200px; height: auto;”>
    <ul _ngcontent-c3=”” class=”jqx-widget-header jqx-disableselect jqx-ribbon-header jqx-ribbon-header-horizontal jqx-rc-t jqx-ribbon-header-auto jqx-ribbon-header-top”
    style=”float: none;”>
    <ul _ngcontent-c3=”” unselectable=”on” class=” jqx-ribbon-item jqx-ribbon-item-top jqx-rc-t jqx-widget-content jqx-ribbon-item-selected”
    style=”margin-left: 1px; margin-right: 1px;”>Item 1

    <div _ngcontent-c3=”” class=” jqx-widget-content jqx-ribbon-content jqx-ribbon-content-horizontal” style=”padding: 0px;”>
    <div _ngcontent-c3=”” class=” jqx-widget-content jqx-ribbon-content-section jqx-ribbon-content-section-top jqx-rc-b”
    style=”display: block;”>Content 1</div>
    </div>
    <div class=”jqx-widget-content jqx-ribbon-selection-token jqx-ribbon-selection-token-top” style=”top: 30px; left: 3px; width: 54px;”></div>
    <div class=”jqx-ribbon-scrollbutton jqx-ribbon-scrollbutton-top jqx-ribbon-scrollbutton-both jqx-widget-header jqx-ribbon-scrollbutton-lt”
    style=”height: 29px; display: none;”>
    <div class=”jqx-ribbon-scrollbutton-inner jqx-icon-arrow-left”></div>
    </div>
    <div class=”jqx-ribbon-scrollbutton jqx-ribbon-scrollbutton-top jqx-ribbon-scrollbutton-both jqx-widget-header jqx-ribbon-scrollbutton-rb”
    style=”height: 29px; display: none;”>
    <div class=”jqx-ribbon-scrollbutton-inner jqx-icon-arrow-right”></div>
    </div>
    </div>
    </jqxribbon>
    </dock-ribbon>
    </div>
    <div _ngcontent-c1=”” class=”main”>
    <!—->
    </div>
    <div _ngcontent-c1=”” class=”status”>
    <!—->
    <dock-status _nghost-c2=””>
    <div _ngcontent-c2=””>
    <p _ngcontent-c2=””> </p>
    </div>
    </dock-status>
    </div>
    </dock-docksite>
    </app-root>

    <script type=”text/javascript” src=”runtime.js”></script>
    <script type=”text/javascript” src=”polyfills.js”></script>
    <script type=”text/javascript” src=”styles.js”></script>
    <script type=”text/javascript” src=”vendor.js”></script>
    <script type=”text/javascript” src=”main.js”></script>
    </body>

    ————————————————————————————-
    //Ribbon Bar Component
    ————————————————————————————–

    import { IRibbonTabComponent } from ‘./../../infrastructure/contentEvents/IRibbonTabComponent’;
    import { RequiredInfoAction } from ‘./../../infrastructure/reducers/actions/requiredInfoAction’;
    import { StatusComponent } from ‘./../status/status.component’;
    import {
    Component,
    OnInit,
    ViewChild,
    ViewContainerRef,
    Injector,
    ComponentFactoryResolver,
    AfterViewInit
    } from ‘@angular/core’;
    import { Store, Action } from ‘@ngrx/store’;
    import { IAppState } from ‘../../infrastructure/contentEvents/IAppState’;
    import { IRequiredItem } from ‘../../infrastructure/contentEvents/IRequiredItem’;
    import { ContainerFactory } from ‘../../infrastructure/baseClasses/containerFactory’;
    import { ViewFactory } from ‘../../infrastructure/baseClasses/viewFactory’;
    import { RibbonTabGeneralComponent } from ‘./ribbon-tab-general/ribbon-tab-general.component’;
    import { IRibbonTab } from ‘../../infrastructure/contentEvents/IRibbonTab’;
    import { RibbonTabsAction } from ‘../../infrastructure/reducers/actions/ribbonTabsAction’;
    import { jqxRibbonComponent } from ‘jqwidgets-scripts/jqwidgets-ts/angular_jqxribbon’;
    import { createHostListener } from ‘@angular/compiler/src/core’;

    @Component({
    selector: ‘dock-ribbon’,
    templateUrl: ‘./ribbon.component.html’,
    styleUrls: [‘./ribbon.component.css’]
    })
    export class RibbonComponent implements AfterViewInit {
    private toggle: boolean;

    @ViewChild(‘ribbonBar’) ribbonBar: jqxRibbonComponent;

    public items: IRibbonTab[] = [];

    constructor(
    private store: Store<IAppState>,
    private componentFactory: ComponentFactoryResolver,
    private viewContainerRef: ViewContainerRef
    ) {}

    ngAfterViewInit() {
    this.store.select(f => f.ribbonTabs).subscribe(a => {
    if (a) {
    for (let index = 10; index >= 0; index–) {
    // this.ribbonBar.removeAt(index);
    }
    let position = 1;
    a.sort(f => f.order).forEach(element => {
    const factory = this.componentFactory.resolveComponentFactory(element.component);
    const component = factory.create(this.viewContainerRef.parentInjector);
    this.ribbonBar.addAt(position++, component.instance.getHtmlContent());
    });
    }
    });
    }

    onUpdate(): void {
    const item: IRequiredItem = {
    entityType: !this.toggle ? ‘PRODUCT’ : ‘CATEGORY’
    };

    this.store.dispatch<RequiredInfoAction>(new RequiredInfoAction(‘OPEN’, item));
    this.toggle = !this.toggle;
    }
    }

    <jqxRibbon [width]=’1200′ #ribbonBar [animationType]=”‘none'” style=”flex:1 1 auto”>

      Item 1

    <div>
    <div>Content 1</div>
    </div>
    </jqxRibbon>

    ———————————————————————–
    Ribbon Tab
    ———————————————————————–

    import { IRibbonTabComponent } from ‘./../../../infrastructure/contentEvents/IRibbonTabComponent’;
    import { RequiredInfoAction } from ‘./../../../infrastructure/reducers/actions/requiredInfoAction’;
    import { IRibbonTab } from ‘./../../../infrastructure/contentEvents/IRibbonTab’;
    import { Component, OnInit, Renderer2, ElementRef } from ‘@angular/core’;
    import { IRequiredItem } from ‘../../../infrastructure/contentEvents/IRequiredItem’;
    import { Store } from ‘@ngrx/store’;
    import { IAppState } from ‘../../../infrastructure/contentEvents/IAppState’;
    import { TabStripComponent } from ‘@progress/kendo-angular-layout’;

    @Component({
    selector: ‘nav-ribbon-tab-general’,
    templateUrl: ‘./ribbon-tab-general.component.html’,
    styleUrls: [‘./ribbon-tab-general.component.css’]
    })
    export class RibbonTabGeneralComponent implements IRibbonTabComponent, OnInit {
    order: number;

    private toggle: boolean;

    constructor(private store: Store<IAppState>, private elementRef: ElementRef) {}

    ngOnInit() {}

    onUpdate(): void {
    const item: IRequiredItem = {
    entityType: !this.toggle ? ‘PRODUCT’ : ‘CATEGORY’
    };

    this.store.select(f => f.requiredItem).dispatch<RequiredInfoAction>(new RequiredInfoAction(‘OPEN’, item));
    this.toggle = !this.toggle;
    }

    getHtmlContent(): string {
    return this.elementRef.nativeElement.innerHTML;
    }
    }

    <div>
    <button (click)=’onUpdate()’>Update</button>
    </div>

    ————————————————————————————————————
    Dock Site
    ————————————————————————————————————

    import { RibbonTabGeneralComponent } from ‘./../ribbon/ribbon-tab-general/ribbon-tab-general.component’;
    import { RibbonTabsAction } from ‘./../../infrastructure/reducers/actions/ribbonTabsAction’;
    import { IAppState } from ‘./../../infrastructure/contentEvents/IAppState’;
    import { IContainer } from ‘./../../infrastructure/interfaces/IContainer’;
    import { RibbonComponent } from ‘./../ribbon/ribbon.component’;
    import {
    Component,
    OnInit,
    Injector,
    ComponentFactoryResolver,
    ViewChild,
    ViewContainerRef,
    Type,
    AfterViewInit,
    AfterContentInit
    } from ‘@angular/core’;
    import { StatusComponent } from ‘../status/status.component’;
    import { Store } from ‘@ngrx/store’;

    import { ContainerFactory } from ‘../../infrastructure/baseClasses/containerFactory’;
    import { ViewFactory } from ‘../../infrastructure/baseClasses/viewFactory’;

    @Component({
    selector: ‘dock-docksite’,
    templateUrl: ‘./docksite.component.html’,
    styleUrls: [‘./docksite.component.css’]
    })
    export class DocksiteComponent implements OnInit {
    @ViewChild(‘ribbonRegion’, { read: ViewContainerRef })
    ribbonRegion: ViewContainerRef;

    @ViewChild(‘statusRegion’, { read: ViewContainerRef })
    statusRegion: ViewContainerRef;

    @ViewChild(‘containerRegion’, { read: ViewContainerRef })
    containerRegion: ViewContainerRef;

    private currentContainer: Type<any>;
    private currentComponent: any;
    constructor(
    private injector: Injector,
    private componentFactory: ComponentFactoryResolver,
    private store: Store<IAppState>,
    private containerFactory: ContainerFactory,
    private viewFactory: ViewFactory
    ) {}

    private insertView(viewContainer: ViewContainerRef, component: Type<any>): any {
    const factory = this.componentFactory.resolveComponentFactory(component);
    const compRef = factory.create(this.injector);
    viewContainer.clear();
    viewContainer.insert(compRef.hostView);
    return compRef.instance;
    }

    public ngOnInit() {
    this.store.select(‘requiredItem’).subscribe(item => {
    if (item) {
    const container: Type<IContainer> = this.containerFactory.generateContainer(item);
    if (!this.currentContainer || container.name !== this.currentContainer.name) {
    this.currentContainer = container;
    this.currentComponent = this.insertView(this.containerRegion, container);
    }

    this.currentComponent.insertsView(this.viewFactory.generateViews(item));
    }
    });
    this.insertView(this.statusRegion, StatusComponent);
    this.insertView(this.ribbonRegion, RibbonComponent);
    }
    }

    <div class=”ribbon”>
    <ng-container #ribbonRegion></ng-container>
    </div>
    <div class=”main”>
    <ng-container #containerRegion></ng-container>
    </div>
    <div class=”status”>
    <ng-container #statusRegion></ng-container>
    </div>


Martin
Participant

Hello Koimad,

Please, have a look at the suggestion at the other Topic that you have posted.
Thank you!

Best Regards,
Martin

jQWidgets Team
http://www.jqwidgets.com/

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.