Lakkakula's Blog

July 27, 2009

Developing Web 2.0 Portal using Asp.Net MVC, Microsoft Ajax Client Templates and jQuery with drag and drop widget personalization – Part 3

Filed under: Ajax Client Templates, Asp.Net, Asp.Net MVC, jQuery, MVC — Venkata Uma lakkakula @ 9:33 pm

In this series:
1. Introduction
2. Part 1 – Portal Core Functionality
3. Part 2 – Drag and Drop Widget Personalization
4. Part 3 – Building Widget Gallery
5. Part 4 – Introduce Tabs and Users
6. Part 5 – Enhancements and Conclusion

Working portal at: http://aspspider.info/lakkakula/local.aspx

In this post we will see how to render widget gallery and touch a little bit on CSS. CSS has limited set of keywords on which almost all web pages on the internet are being rendered. As a web programmer every body should spend some to time learning and understanding CSS.

At the beginning of my career I worked as a Desktop Publishing Designer for a short while (Don’t ask me why).  What I use to do is; to take a well designed magazine and try to re-produce a page with same results using PageMaker and Photoshop. After repetitive reworks I started to understand the original designer’s intent and how to design good pages for magazines. Finally I have applied the knowledge I’ve gained to my real work on web development for designing elegant web pages.

Widget gallery is straight forward to implement. Just get the list of (n) widgets per page and render them on the top section of the page, like:

wiz-gal

We would do this by reusing a client template:

<div id=”wizGallery”>
<div class=”left-nav”>
<input type=”text” value=”Search for widgets” style=”width: 150px; />
<button>Go</button>
<ul> <li class=”selected”><a href=”#”>Widget Gallery</a></li>
<li><a href=”#”>Cool Widgets</a></li>
<li><a href=”#”>New Feed Widget</a></li>
</ul>
</div>
<div class=”wiz-lib” style=”float:left;“>
<a href=”#” class=”wiz-close” >X</a>
<h4 style=”margin-left:10px”>Widget Gallery</h4>
<a href=”#” class=”prev” title=”Previous Page” onclick=”javascript:getGallery(‘prev’);” ><</a>
<div style=”float:left;margin-right:5px; width:690px; overflow:hidden; sys:attach=”dataview” dataview:data=”{{gallery}}” class=”sys-template”>
<div class=”wiz-holder”>
<img code:if=”icon!=”” sys:src=”{{‘../../Content/images/’ + icon}}” /><br />
<span>{{name}}</span><br />
<a href=”#” class=”link-button”>Add</a>
<a href=”#” class=”link-button”>Preview</a>
</div>
</div>
<a href=”#” class=”next” title=”Next Page” onclick=”javascript:getGallery(‘next’);”>></a>
</div>
</div>

Here is the CSS for Widget Gallery:

#wizGallery{border-bottom:1px solid #ccc; border-top:1px solid #ccc; background-color:#000;display:block; padding:0px; width:1000px; height:150px; color:#fff; display:none; float:left; }
.left-nav{padding:10px;width:200px;height:130px;background-color:#2E2E2E;float:left;}
.left-nav
ul{line-height:30px;list-style-position:inside;}
.left-nav li.selected {background-color:#424242;}
.left-nav li.selected a{font-size:14px;font-weight:bold;text-decoration:none;color:#fff; }
.left-nav
a{font-size:14px;font-weight:bold;text-decoration:none; }
.left-nav
a:visited{ }
.left-nav a.selected:visited{ }
.page-options
{list-style:none;width:265px; }
.page-options
li {float:left;padding:0px;margin:0px; }
.page-options
li a, .page-options li a:visited{color:#000;text-decoration:none;padding:2px 10px 2px 10px;margin-right:15px;border:1px solid #fff;background-color:#ccc; }
.page-options
li a.selected, .page-options li a:hover {color:#fff;background-color:#666; }
.wiz-lib
{width:775px}
.wiz-lib
.wiz-close {float:right;color:Red; text-decoration:none; padding:10px 5px;}
.wiz-lib
.prev {float:left;text-decoration:none;padding:38px 10px;margin-left:10px;margin-right:10px;background-color:#2e2e2e}
.wiz-lib
.next {float:left;text-decoration:none;padding:38px 10px;background-color:#2e2e2e}
.wiz-lib .wiz-holder{float:left;display:block;background-color:#424242; padding:5px; margin-right:10px; width:75px; }
.wiz-lib
.wiz-holder img{margin-left:auto; margin-right:auto; float:none;}
.wiz-lib
.wiz-holder span{overflow:hidden;}

Server Code:

1 public class LocalController : Controller

2 {

3 IWidget repoWidget;

4 public JsonResult WidgetGallery(int page)

5 {

6 var wiz = repoWidget.WidgetGallery(page);

7 return Json(wiz);

8 }

9 }

repository method:

1 public object WidgetGallery(int page)

2 {

3 return (from wizBase in db.WidgetBases

4 select new {

5 id = wizBase.Id,

6 name = wizBase.Name,

7 icon = wizBase.Icon

8 }).Skip((page-1) * 7).Take(7).ToList();

9 }

Client Code:

1 <script language=“javascript” type=“text/javascript”>

2 var gallery = [];

3 var gallery_page = 1;

4

5 $(function() {

6 getGallery(‘first’); //get first page

7 });

8

9 function getGallery(way) {

10 if (way == ‘next’)

11 gallery_page = gallery_page + 1;

12 else

13 gallery_page = gallery_page – 1;

14

15 if (gallery_page == 0) gallery_page = 1;

16

17 $.getJSON(‘/Local/WidgetGallery?page=’ + gallery_page, null, function(json) {

18 Sys.Observer.clear(gallery);

19 Sys.Observer.addRange(gallery, json);

20 });

21 };

22 </script>

When page loads getGallery(‘first’); //get first page javascript method makes an ajax call to Local controller’s WidgetGallery action. This loads first page JSON to gallery[] array.

Only important thing to notice here is the following lines:

18 Sys.Observer.clear(gallery);

19 Sys.Observer.addRange(gallery, json);

When previous or next page is requested from controller; line 18 clears existing values in gallery[] array and line 19 re-fills with new values. This actions are really magical, because Sys.Observer automatically re-binds the changes in gallery[] to our template. That is all we have to do, really!

Ain’t that cool? 🙂

Shout it

Advertisement

26 Comments »

  1. Thank you, I have been waiting for your next article.

    – Prashant

    Comment by Prashant — July 29, 2009 @ 9:49 am

  2. Any chance you could leave the code, I’m having some difficulty recreating your example.

    Comment by Mario — August 6, 2009 @ 9:13 am

  3. Maximizing widget and then restoring to default size seems to be important. I like Google IG implementation of that, when widget is maximized we may see the list of widgets in a left panel. Is it doable with your framework ?

    Comment by Michael — August 10, 2009 @ 7:12 pm

    • @Michael, I like that feature too. But right now its not implemented into my framework yet. We can do this using Microsoft Ajax Client Templates, I will try to implement it after I am done with users and tabs module. May be I will try to do it different like Tabs on top and widget list on the page as sub tabs!

      Comment by Venkata Uma lakkakula — August 10, 2009 @ 7:51 pm

      • Surely, it is your prerogative how to implement that, but IMHO too many tabs make everything look like Windows Forms application. I mean here , when all tabs at top. Perhaps, main tabs at top, and if possible to have sub tabs for a page at the left side and to give it a different look.

        Comment by Michael — August 10, 2009 @ 8:06 pm

  4. when mouse over what is the first icon from the top widget corner for ( ? , refresh, minimize , delete )

    Comment by Michael — August 10, 2009 @ 9:31 pm

  5. @Michael, I like your idea to have main tabs at top and widget list on left when a widget is maximized! I will implement that. BTW, first icon on widget is for setup: it should show the widget setup for e.g., number of rss items, show more details, show images from rss items. You will see this implemented in my next iteration of code.

    Comment by Venkata Uma lakkakula — August 10, 2009 @ 9:37 pm

  6. Also I understood from your blog that you were familiar with classic ASP.Net + updatepanel + WF + etc… variant of Web 2.0 widgets – dropthings. Despite dropthings is too complicated, and for some reason JavaScript part ( namely resizing a widget ) has not been fixed to work right for ages, there is a nice feature there – inter-widget communication , for example selection of anything in master widget may update all children widgets with respective content ( observer pattern). Would you consider anything like that in your framework ?

    Comment by Michael — August 11, 2009 @ 7:52 am

  7. @Michael, inter-widget communication makes more sense in enterprise portals. For example a visualization business dashboard with graphs and summarized reports would have a parent widget with prompts selection dropdowns and all other child widgets get the report parameters from parent widget to render the graphs and reports accordingly!

    When it comes to start pages I do not see much of a value having inter-widget communication; where all the portal content is collected and rendered through widgets from multiple disconnected sources. Its just my opinion.

    Incidentally, Microsoft Ajax Client Templates use System.Observer api to bind data to templates, which is based on observer pattern. I would guess inter-widget communication would be easy with Client Templates.

    Comment by Venkata Uma lakkakula — August 11, 2009 @ 10:40 am

    • I agree, for portal start page it is not very sensible. But does your code ( if extended ) prevent us from using widget technology ( I mean by that UI + in programmatic sense generic widget which knows how to render arbitrary HTML inside itself ) for dashboards. For example if top tabs are introduced and tab1 always comes first on startup then tab2 widgets could be drill-down view for a particular widget on tab1.

      Basically I want to mimic Silverlight drag drop control, not necessarily with all animation but with html of arbitrary complexity inside each widget.

      Requires Silverlight 3
      http://mightymeaty.members.winisp.net/blacklight.silverlight/

      Visual Controls/Dashboards/Drag Drop Control

      Comment by Michael — August 11, 2009 @ 7:59 pm

      • I meant, Interactive Controls/Dashboards/Drag Drop Control

        Comment by Michael — August 11, 2009 @ 8:02 pm

  8. @Michael, WOW that’s a great Silverlight demonstration! Thanks for sharing the link. Silverlight is very powerful tool for UI on web as it combines the power of web with vector graphics. We can do all things you’ve asked for – using my framework (if extended); nothing stops us, as we are using pure web technologies asp.net MVC, client templates and jQuery, they only make our life easier 🙂

    You seem to have great ideas. If you are developing something related to web 2.0 technologies and you need my participation, please let me know, I would be more than willing to be part-of.

    Comment by Venkata Uma lakkakula — August 12, 2009 @ 10:21 am

    • I don’t know much about ASP.Net MVC, but seeking for ASP.Net MVC analogy of dropthings, ran into this blog entry.

      http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/

      The author who wrote book on ASP.Net MVC subject finds programming independent widgets tricky, you don’t seem to find it tricky. Any comment on that ? Is your approach something new he didn’t consider ?

      Comment by Michael — August 12, 2009 @ 7:20 pm

  9. @Michael,
    I know that blog post. First this post was posted originally in Oct 2008, when Asp.Net MVC was in its initial beta versions. Its interesting to see still there are comments coming to that post asking questions on the solution. Things have changed since then and several options available now. Second, what Steve has explained in his blog is pure MVC server-side programming style for widgets, you can translate it to web-user-controls in asp.net.

    I cannot really compare Steve’s solution with mine as my framework is completely based on AJAX widget rendering. My framework can work with any server technology like asp.net web-services, php, any REST full services, etc.

    Comment by Venkata Uma lakkakula — August 12, 2009 @ 7:41 pm

  10. How do you create the client template? I dont see where that section gets called to build the list of widgets?

    Comment by ClearMind — August 14, 2009 @ 10:58 pm

  11. Okay i got it working now! Thanks.. okay so when i click on add to add the widget how do i make it show up in the middle column?

    Comment by ClearMind — August 14, 2009 @ 11:14 pm

  12. @ClearMind, I am glad it is working for you! I am currently implementing new widget adding with users and tabs, I will post the next version of code in about a week! meanwhile, here is the code for you: (assuming you have a gallery of widgets).


    var newWidget = [];


    function addNewWidget(id) {
    var template = new Sys.UI.Template($get("widget-template"));
    var firstWiz = $get('col2').firstChild;

    $.getJSON('Home/AddWidget?baseId=' + id, null, function(json) {
    Sys.Observer.clear(newWidget);
    Sys.Observer.addRange(newWidget, json);
    template.instantiateIn($get("col2"), newWidget[0], 0, firstWiz, null);
    linksgrid.setHover();
    //get reference to conent node in newly added widget
    var newWizContent = $get('col2').firstChild.firstChild.nextSibling.firstChild;
    //Not sure why ajaxload declarative method is not working(when new widget is added), so force to load widget content
    $.get('/' + newWidget[0].controller + '/' + newWidget[0].action + '/' + newWidget[0].id, function(result) { $(newWizContent).html(result); });
    //$($get('col2').firstChild).effect('highlight', null, 100, null); // need jQuery UI.effects script
    });
    };

    Above code creates a new instance of our widget template and positions it into middle column at first position. Then we create a new widget in database through ajax call. Finally we force to reload the widget content through an ajax call.

    If you need further help please let me know, or if you can wait until next post I would greatly appreciate!

    Comment by Venkata Uma lakkakula — August 15, 2009 @ 12:04 pm

    • This is awesome! Thanks very much for your reply. I will put it in the code now and test it out..

      Comment by ClearMind — August 15, 2009 @ 5:54 pm

    • Thanks for a great article. Do you have any update on when the next installment will be available?

      – AMcCartney

      Comment by Adam McCartney — August 31, 2009 @ 6:33 am

  13. cool, when are you going to publish the next series? can you email it to me?

    thanks

    Comment by Mark — August 18, 2009 @ 2:11 pm

  14. I am almost done with tabs and users, will publish the new post and code ASAP. Sorry for the delay in this series… am keeping little bit busy :). Thanks for all the support.

    Comment by Venkata Uma lakkakula — August 31, 2009 @ 11:52 am

    • patiently waiting….. 🙂 I hope things are going well.

      Comment by ClearMind — September 9, 2009 @ 10:26 am

  15. […] Part 1 – Portal Core Functionality 3. Part 2 – Drag and Drop Widget Personalization 4. Part 3 – Building Widget Gallery 5. Part 4 – Introduce Tabs and Users 6. Part 5 – Enhancements and […]

    Pingback by Developing Web 2.0 Portal using Asp.Net MVC, Microsoft Ajax Client Templates and jQuery with drag and drop widget personalization – Part 1 « Lakkakula's Blog — September 11, 2009 @ 7:55 pm

  16. how is this different then the dropthings portal? It looks like you downloaded that portal and rebranded it.

    Comment by CsharpGuy — March 4, 2010 @ 9:37 am

    • I suggest you to read all my posts before commenting its just a re-branding. Not sure if you have read through all posts, its different because it uses “Ajax Client Templates” and “jQuery’s declarative plugin” and “MVC” and is much simple to implement.

      Comment by Venkata Uma lakkakula — March 4, 2010 @ 12:18 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: