Click here to Skip to main content
Click here to Skip to main content
Articles » Web Development » Ajax » Atlas » Downloads
 
Add your own
alternative version

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

, 10 Mar 2010 CPOL
Build a Start Page similar to Google IG in 7 nights using ASP.NET AJAX, .NET 3.0, LINQ, DLinq, and XLinq.
dashboard.zip
src
bin
AjaxControlToolkit.dll
CustomDragDrop
Dashboard
App_Code
App_Data
App_Themes
Default
google.gif
HeaderBack.PNG
Logo.png
max_blue.gif
max_blue_highlight.gif
min_blue.gif
min_blue_highlight.gif
x_blue.gif
x_blue_highlight.gif
Bin
AjaxControlToolkit.dll
CSharp3CodeDomProvider.dll
Global.asax
indicator.gif
vwd.webinfo
Widgets
FlickrIcon.gif
rss.gif
DashboardBusiness
Activities
CreateDeafultWidgetsOnPageActivity.rules
DashboardBusiness.csproj.user
NewUserSetupWorkflow.rules
Properties
UserVisitWorkflow.rules
DashboardData
Properties
Dashboard.bak
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)

Share

About the Author

Omar Al Zabir
Architect BT, UK (ex British Telecom)
United Kingdom United Kingdom

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411028.1 | Last Updated 10 Mar 2010
Article Copyright 2007 by Omar Al Zabir
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid