Click here to Skip to main content
15,886,857 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
I have created a tab structure as Horizontal tabs group. Each horizontal tab will have number of vertical tabs in it.
In each vertical tab, I am binding a user control using an iframe.
When a page loads, all user controls in all tabs load at the same time which affects he performance of the page.

This is my HTML
HTML
<div ng-app="myApp">
        <div ng-controller="MainCtrl">
    <div class="tabbable padTop10">
      <ul class="nav nav-tabs">
        <li ng-repeat="hTab in horzTabs track by $index" ng-class="{'active':hTab.active}"><a ng-click="setActive(hTab, true)">{{hTab.SSHVSettingsTabGroupName}}</a></li>
      </ul> 

      <div class="tab-content">
        <div class="tab-pane" ng-class="{'active': hTab.active}" ng-repeat="hTab in horzTabs track by $index">
          <div ng-if="hTab.SSHVSettingsTabInfo"  class="tabbable tabs-left">
            <ul class="nav nav-tabs">
              <li ng-repeat="vTab in hTab.SSHVSettingsTabInfo track by $index" ng-class="{'active':vTab.active }">
                  <a ng-click="setActive(vTab, false);">{{vTab.TabCaption}}</a>
              </li>
            </ul>
            <div class="tab-content col-pad-10 borderAll tabContentCustom">
              <div class="tab-pane" ng-repeat="vTab in hTab.SSHVSettingsTabInfo track by $index" ng-class="{'active': vTab.active}">
                <ext-iframe ng-if="vTab.URL" src="{{vTab.URL}}" name="{{vTab.TabName}}" ></ext-iframe>
              </div>
                <div ng-if="hTab.URL">
                    <div class="tab-content">
                    <div class="tab-pane" ng-class="{'active': hTab.active}">
                        <ext-iframe ng-if="hTab.URL" src="{{hTab.URL}}" name="{{hTab.TabName}}" ></ext-iframe>
                    </div>
                </div>
                </div>
            </div>
          </div>
        </div>
      </div>
      
    </div>
  </div>
    </div>


This is my js:
JavaScript
var app = angular.module('myApp', []);

app.controller('MainCtrl', function ($scope, $sce) {
    $scope.iMainTabIndex = 0;

    $scope.horzTabs = tabCollection;
    $scope.currentHTab = $scope.horzTabs[$scope.iMainTabIndex];
    $scope.currentHTab.active = true;
    $scope.currentVTab = $scope.currentHTab.SSHVSettingsTabInfo[0];
    $scope.currentVTab.active = true;
    $scope.iTab1Index = 0;
    $scope.setActive = function (tab, horz) {
        var tabdir;
        if (horz) tabdir = 'H';
        else tabdir = 'V'
        tab.active = true;
        if ($scope['current' + tabdir + 'Tab']) {
            $scope['current' + tabdir + 'Tab'].active = false;
        }
        $scope['current' + tabdir + 'Tab'] = tab;
    }
});


app.directive('extIframe', [

    function () {
        return {
            restrict: 'E',
            scope: {
                "src": "@",
                "name": "@"
            },
            template: '<iframe seamless="seamless" class="dynamicHeight" width="100%" frameborder="0" src="{{\'../SettingControls/ControlViewer.aspx?usName=\' +  name + \'&src=\' + src}}"></iframe>'
        };
    }
])

angular.module('myApp').config(function ($sceDelegateProvider) {
    $sceDelegateProvider.resourceUrlWhitelist(['**']);
});

ControlViewer.aspx page will hold the user controls.
Is it possible to load the user control in iframe only when user clicks on the tab?
Is there any better way to load user control on each tab?

What I have tried:

I am not very much familiar with angularjs. I tried creating isLoaded property for each tab and set it to true only when user clicks on tab.
But all user controls gets loaded when a page loads, so no use of isLoaded property.
Posted
Updated 13-Apr-16 20:36pm

1 solution

I did it like this.
I removed the frame template completely. Removed ControlViewer.aspx page also.
Added one div on my Settings.aspx page and loaded the user controls in the div using ajax call on tab click.

This is HTML
HTML
<div ng-app="myApp">
        <div ng-controller="MainCtrl">
    <div class="tabbable padTop10">
      <ul class="nav nav-tabs">
        <li ng-repeat="hTab in horzTabs track by $index" ng-class="{'active':hTab.active}"><a ng-click="setActive(hTab, true);">{{hTab.SSHVSettingsTabGroupName}}</a></li>
      </ul> 

      <div class="tab-content">
        <div class="tab-pane" ng-class="{'active': hTab.active}" ng-repeat="hTab in horzTabs track by $index">
          <div ng-if="hTab.SSHVSettingsTabInfo" class="tabbable tabs-left">
            <ul class="nav nav-tabs">
              <li ng-repeat="vTab in hTab.SSHVSettingsTabInfo track by $index" ng-class="{'active':vTab.active }">
                  <a ng-click="setActive(vTab, false);">{{vTab.TabCaption}}</a>
              </li>
            </ul>
            <div id="dvUserControl" class="tab-pane active tab-content col-pad-10 borderAll tabContentCustom"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
    </div>


In .js file
JavaScript
app.controller('MainCtrl', function ($scope, $sce) {
    $scope.iMainTabIndex = 0;

    $scope.horzTabs = tabCollection;
    $scope.currentHTab = $scope.horzTabs[$scope.iMainTabIndex];
    $scope.currentHTab.active = true;
    $scope.currentVTab = $scope.currentHTab.SSHVSettingsTabInfo[0];
    $scope.currentVTab.active = true;
    $scope.iTab1Index = 0;
    //$scope.setActive($scope.currentHTab, true);

    $scope.setActive = function (tab, horz) {
        var tabdir;
        if (horz) tabdir = 'H';
        else tabdir = 'V'
        tab.active = true;
        if ($scope['current' + tabdir + 'Tab']) {
            $scope['current' + tabdir + 'Tab'].active = false;
        }
        $scope['current' + tabdir + 'Tab'] = tab;

        if(horz && tab.URL.length > 0)
            $scope.loadTab(tab.Type, tab.URL);
        else if(horz && tab.URL.length == 0)
            $scope.loadTab($scope.currentVTab.Type, $scope.currentVTab.URL);
        else
            $scope.loadTab(tab.Type, tab.URL);
    }

    angular.element(document).ready(function () {
        $scope.loadTab($scope.currentVTab.Type, $scope.currentVTab.URL);
    });

    $scope.loadTab = function (type, url) {
        if (url != 'undefined' && url.length > 0)
            var controlName = url.substring(2, url.length);

        if (type == '0') {
            $.ajax({
                type: "POST",
                url: "../AdminView/Settings.aspx/Result",
                data: "{ controlName:'" + controlName + "'}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (response) {
                    $('#dvUserControl').html(response.d);
                },
                error: function (msg) {
                    alert(msg);
                    $('#dvUserControl').html(msg.d);
                }
            });
        } else {
            $('#dvUserControl').load(url);
        }
    }
});


In Settings.aspx.cs
C#
[WebMethod]
		public static string Result(string controlName)
		{
			return Results(controlName);
		}

		public static string Results(string controlName)
		{
			try
			{
				
	 
				Page page = new Page();
				UserControl userControl = (UserControl)page.LoadControl(@"~\SettingControls\" + controlName);
				userControl.EnableViewState = false;
				HtmlForm form = new HtmlForm();
				form.Controls.Add(userControl);
				page.Controls.Add(form);

				StringWriter textWriter = new StringWriter();
				HttpContext.Current.Server.Execute(page, textWriter, false);
				return textWriter.ToString();

			}
			catch (Exception ex)
			{
				return ex.ToString();
			}


		}


It worked. :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900