Click here to Skip to main content
15,881,882 members
Articles / Web Development / HTML

Build a Google IG like AJAX Start Page in 7 days using ASP.NET AJAX and .NET 3.0

Rate me:
Please Sign up or sign in to vote.
4.80/5 (325 votes)
10 Mar 2010CPOL38 min read 1.8M   7.8K   1.1K  
Build a Start Page similar to Google IG in 7 nights using ASP.NET AJAX, .NET 3.0, LINQ, DLinq, and XLinq.
using System;
using System.Reflection;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Profile;

using System.Query;
using System.Data.DLinq;

using DashboardBusiness;
using DashboardDataAccess;

using AjaxControlToolkit;

using Page = DashboardDataAccess.Page;

public partial class _Default : System.Web.UI.Page
{
    private const string WIDGET_CONTAINER = "WidgetContainer.ascx";

    private UserPageSetup _Setup 
    { 
        get { return Context.Items[typeof(UserPageSetup)] as UserPageSetup; } 
        set { Context.Items[typeof(UserPageSetup)] = value; }
    }

    private int AddStuffPageIndex
    {
        get { object val = ViewState["AddStuffPageIndex"]; if( val == null ) return 0; else return (int)val; }
        set { ViewState["AddStuffPageIndex"] = value; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        
    }

    protected override void CreateChildControls()
    {
        base.CreateChildControls();

        /// Logic for first load of widgets:
        /// If user switches tab, then the widgets on the new tabs get loaded and no need to load the widgets
        /// on the old tab. The new widgets on the new page will get their first load as true, although in ASP.NET's
        /// term, this is a postback. 
        /// For anyother postbacks caused by widgets or add stuff window, it's a regular postback.
        /// But if a new widget is added by the add stuff window, it's postback for the old widgets, but not a 
        /// postback for the newly added widget
        
        this.LoadUserPageSetup();
        this.SetupTabs();
        this.LoadAddStuff();
            
        if( ScriptManager1.IsInAsyncPostBack )
        {
            string updatePanelName = Request[ScriptManager1.ID];

            if( !updatePanelName.Contains(TabUpdatePanel.ID) )
                this.SetupWidgets( wi => false );
            else
            {
                string pageName = Request["PageNameEditTextBox"];
                if( !string.IsNullOrEmpty(pageName) )
                {
                    new DashboardFacade(Profile.UserName).ChangePageName(pageName);
                    _Setup.CurrentPage.Title = pageName;
                    this.SetupTabs();
                }
            }
        }
        else
        {
            // First visit, non postback
            // this.LoadAddStuff();
            this.SetupWidgets( wi => true );
            this.SetupTabs();            
        }

        //bool shouldLoadWidgets = string.IsNullOrEmpty(Request[ScriptManager1.ID]) || (!Request[ScriptManager1.ID].Contains(TabUpdatePanel.ID));
        //if( shouldLoadWidgets ) this.SetupWidgets( wi => !base.IsPostBack );
        
    }

    protected override object LoadPageStateFromPersistenceMedium()
    {
        return base.LoadPageStateFromPersistenceMedium();
    }

    private void LoadUserPageSetup()
    {
        if( Profile.IsAnonymous )
        {
            if( Profile.IsFirstVisit )
            {
                // First visit
                Profile.IsFirstVisit = false;
                Profile.Save();
                
                _Setup = new DashboardFacade(Profile.UserName).NewUserVisit();
            }
            else
            {
                _Setup = new DashboardFacade(Profile.UserName).LoadUserSetup();
            }
        }
        else
        {
            _Setup = new DashboardFacade(Profile.UserName).LoadUserSetup();
        }
    }

    
    private void SetupTabs()
    {
        tabList.Controls.Clear();

        var setup = _Setup;
        var currentPage = setup.CurrentPage;

        foreach( Page page in setup.Pages )
        {
            var li = new HtmlGenericControl("li");
            li.ID = "Tab" + page.ID.ToString();
            li.Attributes["class"] = "tab " + (page.ID == currentPage.ID ? "activetab" : "inactivetab");

            var linkButton = new LinkButton();
            linkButton.ID = page.ID.ToString();
            linkButton.Text = page.Title;
            linkButton.CommandName = "ChangePage";
            linkButton.CommandArgument = page.ID.ToString();

            if( page.ID == currentPage.ID )
                linkButton.Click += new EventHandler(PageTitleEditMode_Click);
            else
                linkButton.Click += new EventHandler(PageLinkButton_Click);

            li.Controls.Add(linkButton);
            tabList.Controls.Add(li);
        }

        var addNewTabLinkButton = new LinkButton();
        addNewTabLinkButton.ID = "AddNewPage";
        addNewTabLinkButton.Text = "new tab";
        addNewTabLinkButton.Click += new EventHandler(addNewTabLinkButton_Click);
        var li2 = new HtmlGenericControl("li");
        li2.Attributes["class"] = "newtab";
        li2.Controls.Add(addNewTabLinkButton);
        tabList.Controls.Add(li2);

    }

    void addNewTabLinkButton_Click(object sender, EventArgs e)
    {
        new DashboardFacade(Profile.UserName).AddNewPage();
        
        this.ReloadPage(wi => true);
    }

    void PageTitleEditMode_Click(object sender, EventArgs e)
    {
        var linkButton = sender as LinkButton;
        Console.WriteLine(linkButton.ID);

        var editTextBox = new TextBox();
        editTextBox.ID = "PageNameEditTextBox";
        editTextBox.Text = linkButton.Text;

        var okButton = new Button();
        okButton.Text = "Save";

        linkButton.Parent.Controls.Add(editTextBox);
        linkButton.Parent.Controls.Add(okButton);
        linkButton.Parent.Controls.Remove(linkButton);
    }

    void PageLinkButton_Click(object sender, EventArgs e)
    {
        var linkButton = sender as LinkButton;
        
        // Get the page ID from the title link button ID
        var pageId = int.Parse(linkButton.ID);

        if( _Setup.UserSetting.CurrentPageId != pageId )
        {
            DatabaseHelper.Update<UserSetting>( _Setup.UserSetting, delegate( UserSetting u )
            {
                u.CurrentPageId = pageId;
            });

            /// If user switched page, then the widgets on the new page are loaded for the
            /// first time. So, it's not really a postback experience for them although in ASP.NET's
            /// term it is a regular postback
            this.ReloadPage(wi => true);
        }
    }

    private void SetupWidgets(Func<WidgetInstance, bool> isWidgetFirstLoad)
    {
        var setup = Context.Items[typeof(UserPageSetup)] as UserPageSetup;

        var columnPanels = new Panel[] { WidgetViewUpdatePanel.FindControl("LeftPanel") as Panel, 
            WidgetViewUpdatePanel.FindControl("MiddlePanel") as Panel, 
            WidgetViewUpdatePanel.FindControl("RightPanel") as Panel};

        // Clear existin widgets if any
        foreach( Panel panel in columnPanels )
        {
            List<WidgetContainer> widgets = panel.Controls.OfType<WidgetContainer>().ToList();
            foreach( var widget in widgets ) panel.Controls.Remove( widget );
        }

        foreach( WidgetInstance instance in setup.WidgetInstances )
        {
            var panel = columnPanels[instance.ColumnNo];
            
            var widget = LoadControl(WIDGET_CONTAINER) as WidgetContainer;
            widget.ID = "WidgetContainer" + instance.Id.ToString();
            widget.IsFirstLoad = isWidgetFirstLoad(instance);
            widget.WidgetInstance = instance;
            
            widget.Deleted += new Action<WidgetInstance>(widget_Deleted);
            
            panel.Controls.Add(widget);
        }

    }

    void widget_Deleted(WidgetInstance obj)
    {
        new DashboardFacade(Profile.UserName).DeleteWidgetInstance(obj);
        
        this.ReloadPage(wi => false);
    }

    private void ReloadPage(Func<WidgetInstance, bool> isWidgetFirstLoad)
    {
        this.LoadUserPageSetup();
        this.SetupTabs();        
        
        this.SetupWidgets(isWidgetFirstLoad);

        this.WidgetViewUpdatePanel.Update();        
    }

    protected void ShowAddContentPanel_Click(object sender, EventArgs e)
    {
        AddContentPanel.Visible = true;
        HideAddContentPanel.Visible = true;
        ShowAddContentPanel.Visible = false;
    }
    
    protected void HideAddContentPanel_Click(object sender, EventArgs e)
    {
        AddContentPanel.Visible = false;
        HideAddContentPanel.Visible = false;
        ShowAddContentPanel.Visible = true;
    }

    private List<Widget> WidgetList
    {
        get
        {
            List<Widget> widgets = Cache["Widgets"] as List<Widget>;
            if( null == widgets )
            {
                widgets = new DashboardFacade(Profile.UserName).GetWidgetList();
                Cache["Widgets"] = widgets;
            }
        
            return widgets;
        }
    }

    private void LoadAddStuff()
    {        
        //this.WidgetDataList.ItemDataBound += new DataListItemEventHandler(WidgetDataList_ItemDataBound);
        this.WidgetDataList.ItemCommand += new DataListCommandEventHandler(WidgetDataList_ItemCommand);

        var itemsToShow = WidgetList.Skip(AddStuffPageIndex*30).Take(30);
        this.WidgetDataList.DataSource = itemsToShow;
        this.WidgetDataList.DataBind();

        WidgetListPreviousLinkButton.Visible = AddStuffPageIndex > 0;
        WidgetListNextButton.Visible = AddStuffPageIndex*30+30 < WidgetList.Count;
    }

    void WidgetDataList_ItemCommand(object source, DataListCommandEventArgs e)
    {
        int widgetId = int.Parse( e.CommandArgument.ToString() );

        new DashboardFacade(Profile.UserName).AddWidget( widgetId );

        /// User added a new widget. The new widget is loaded for the first time. So, it's not 
        /// a postback experience for the widget. But for rest of the widgets, it is a postback experience.
        this.ReloadPage(wi => wi.Id == widgetId);
    }

    void WidgetDataList_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        if( e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem )
        {
            Widget widget = e.Item.DataItem as Widget;

            LinkButton link = e.Item.Controls.OfType<LinkButton>().Single();

            link.Text = widget.Name;

            link.CommandName = "AddWidget";
            link.CommandArgument = widget.ID.ToString();
        }
    }

    void AddWidgetLink_Click(object sender, EventArgs e)
    {
        
    }
    protected void WidgetListPreviousLinkButton_Click(object sender, EventArgs e)
    {
        if( 0 == AddStuffPageIndex ) return;
        AddStuffPageIndex --;

        this.LoadAddStuff();
    }
    protected void WidgetListNextButton_Click(object sender, EventArgs e)
    {
        AddStuffPageIndex ++;
        this.LoadAddStuff();
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Architect BT, UK (ex British Telecom)
United Kingdom United Kingdom

Comments and Discussions