Friday, January 30, 2009

Selecting a ASP.NET Generated ID with jQuery

I was looking at some of the questions on Stack Overflow this evening and I came across one that had a great tip for selecting a tag whose ID was generated by ASP.NET.  So say you have a label control on your page:
<asp:label id="label1" runat="server"></asp>

The generated output of the html and the ID of that control might look like this:

<span id="ctl00_ContentPlaceHolder1_Label1"></span>

Unfortunately the generated ID of ct100_ContentPlaceHolder1_Label1 isn't always going to be the same from build to build.  So trying to select it like this:

$("#ct100_ContentPlaceHolder1_Label1").hide();
will eventually break and it won't hide the label control.

The trick is to use ASP.NET inside the jQuery selector. Label1.ClientID will return the generated ID everytime. We combine ASP.NET and jQuery into one line like this:
$("#<%= Label1.ClientID %>").hide();

This will get the generated ID of the Label control everytime.



Thursday, January 29, 2009

Building a jQuery-Powered Tag-Cloud with an ASP.NET MVC backend

NETTUTS had a great tutorial by Dan Wellman called "Building a jQuery-Powered Tag-Cloud" The problem for me was that the tutorial showed you how to connect to the database and pull tags and frequencies via PHP.

Because I am currently learning ASP.NET MVC I thought I would try to duplicate the results of the tutorial but with using ASP.NET MVC RC instread of PHP.  Here is how I did it.

I started by creating a Home Controller class.

HomeController.cs

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   5:  using System.Web.Mvc;
   6:  using System.Web.Mvc.Ajax;
   7:   
   8:  namespace MvcApplication5.Controllers
   9:  {
  10:      public class HomeController : Controller
  11:      {
  12:          //
  13:          // GET: /Home/
  14:          public ActionResult TagCloud()
  15:          {
  16:              return View();
  17:          }
  18:   
  19:          public JsonResult JSON()
  20:          {
  21:              List<object> tagcloud = new List<object>
  22:              {
  23:                      new { tag = "jQuery", freq = "10" },
  24:                      new { tag = "asp.net", freq = "3"},
  25:                      new { tag = "programming", freq = "183"},
  26:                      new { tag = "code", freq = "34" },
  27:                      new { tag = "HTML", freq = "58"},
  28:                      new { tag = "javascript", freq = "23"},
  29:                      new { tag = "people", freq = "43" },
  30:                      new { tag = "Google", freq = "3"},
  31:                      new { tag = "Microsoft", freq = "1"},
  32:                      new { tag = "Apple", freq = "10" },
  33:                      new { tag = "iPhone", freq = "38"},
  34:                      new { tag = "MVC", freq = "1"}
  35:              };
  36:              return Json(tagcloud); 
  37:          }
  38:   
  39:      }
  40:  }

What's happening here is that we are making a action for the View we will create and I am calling it TagCloud.  This action isn't going to provide us any data so it's a stub action.  The next Action we create is to provide TagCloud the JSON data.  In here I am creating a static List to send back serialized as JSON.  You could also tie it to a model and use Linq to SQL to build the List.

Our URL for the .getJSON method will be: /Home/JSON

This will return JSON data that looks like this:



Notice the difference in the JSON I am bringing back and the one Dan was bringing back.  I don't have a tags: with the rest of the data nested under it.  We'll need to update a line in the jQuery to make this work now.

Let's create the View for TagCloud.


TagCloud.aspx

   1:  <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
   2:   
   3:      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
   4:      <html>  
   5:        <head>  
   6:          <link rel="stylesheet" type="text/css" href="/content/tagcloud.css" />  
   7:          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
   8:          <title>jQuery Tag Cloud</title>  
   9:        </head>  
  10:       <body>  
  11:         <div id="tagCloud">  
  12:           <h2>Tag Cloud</h2>  
  13:         </div>  
  14:         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>  
  15:         <script type="text/javascript">
  16:             $(function() {
  17:                 //get tag feed  
  18:                 $.getJSON("/Home/JSON",null, function(data) {
  19:                     //create list for tag links  
  20:                     $("<ul>").attr("id", "tagList").appendTo("#tagCloud");
  21:   
  22:                     //create tags  
  23:                     $.each(data, function(i, val) {
  24:   
  25:                         //create item  
  26:                         var li = $("<li>");
  27:   
  28:                         //create link  
  29:                         $("<a>").text(val.tag).attr({ title: "See all pages tagged with " + val.tag, href: "http://localhost/tags/" + val.tag + ".html" }).appendTo(li);
  30:   
  31:                         //add to list
  32:                         li.appendTo("#tagList");
  33:                         //set tag size  
  34:                         li.children().css("fontSize", (val.freq / 10 < 1) ? val.freq / 10 + 1 + "em" : (val.freq / 10 > 2) ? "2em" : val.freq / 10 + "em");  
  35:            
  36:                     });
  37:                 });
  38:             });  
  39:         </script>  
  40:       </body>  
  41:    </html>  

As we start to loop through the JSON data Dan was telling jQuery to start inside tags with data.tags, since we don't have tags we can just use the variable data like so: $.each(data, function(i, val) {

The rest of setting this up is the same as NETTUTS article.  All that remains is the css.




Download the Source

jQuery-TagCloud_source.zip (44.82 KB)



Wednesday, January 28, 2009

ASP.NET MVC Release Candidate - No Codebehinds on Views

Check out Scott Guthrie's mammoth blog post on what's changed in this release of the ASP.NET MVC RC that was pushed to the public today.  A lot has changed in my opinion.  One change that I wasn't expecting was that Views and View User Controls do not have code-behinds any more.

The problem was the only way to have strongly typed Views was to inherit in the code behind.  This caused an issue with intellisense in the aspx/ascx pages. You would need to create and immediately build in order to have intellisense work.

No one was using the code-behinds anyways.  The code should be in the Controllers.

Here is the write up from Scotts Blog:

Views without Code-Behind Files

Based on feedback we’ve changed view-templates to not have a code-behind file by default.  This change helps reinforce the purpose of views in a MVC application (which are intended to be purely about rendering and to not contain any non-rendering related code), and for most people eliminates unused files in the project.

The RC build now adds C# and VB syntax support for inheriting view templates from base classes that use generics.  For example, below we are using this with the Edit.aspx view template – whose “inherits” attribute derives from the ViewPage<Product> type:

One nice benefit of not using a code-behind file is that you'll now get immediate intellisense within view template files when you add them to the project.  With previous builds you had to do a build/compile immediately after creating a view in order to get code intellisense within it.  The RC makes the workflow of adding and immediately editing a view compile-free and much more seamless.

Important: If you are upgrading a ASP.NET MVC project that was created with an earlier build make sure to follow the steps in the release notes – the web.config file under the \Views directory needs to be updated with some settings in order for the above generics based syntax to work.

Tuesday, January 27, 2009

In case you missed it: #jQuery Twitter posts

My #jQuery related twitter posts for the week of January 20th - January 26th:

Monday, January 26, 2009

Evolution of Brand Management (video)

Great viral video on the dramatic shift in the marketing reality has been floating around on twitter the last few days.  Video was developed by a German Ad Agency named Scholz & Friends.



This video highlights how important it is for your company to convey your brand seamlessly and in one voice.  In this downmarket, now is the best time to invest in strengthening your brand and reinforcing the same voice from your employees.  The services of BrandLogic along with our BrandEnsemble product will help you build your brand and effectively communicate to your employees the correct way to position your brand to your target market.

Contact BrandLogic today to learn more.

BarCamp Rochester 4

BarCamp Rochester 4 has been announced for April 18th at RIT.  I missed last years and wish I could of attended.  This year I kicked myself in the butt and signed up to present on ASP.NET MVC.  This will force me to do a couple of things.  It'll force me to really understand MVC and it'll force me to be prepared.

Now if it'll force me to rewrite my blog in ASP.NET MVC by then who knows. Would be a good talking point.

Anyway, here is an initial structure of my presentation I am thinking about:

  • Introduction
  • MVC
    • Current uses (ruby on rails, CakePHP, etc.)
    • MVC in the wild (StackOverflow)
    • Status of MVC
  • MVC vs Web Forms
  • Demo (perhaps build a simple blog)
Any suggestions?

Friday, January 23, 2009

jQuery vs Prototype and jQuery.noConflict()

While helping people out on twitter with jQuery lately I've found one of the most common asked questions is, "why won't jQuery work when I include prototype as well?" Well the answer to the why is simple.  jQuery and prototype are both competing for how $() is going to be used.

I set out to understand how this would break and how to call jQuery.noConflict(); and make both work.

noConflict_test.html (2.41 KB)

If you look at my code you'll see that I was having a hard time just trying to get a single line of prototype to work as it should.  I tried to display a div that was hidden with css.  A very simple task in jQuery.  Unfortunately, it states right on the Element.show documentation page that prototype is not capable of displaying elements that are hidden with css. 

Next I tried to color the text of the other element on the page.  Which to my bad luck I was injecting into the DOM and I was finding that this is impossible to do in both jQuery and Prototype.

In the end all I wanted to do was fire one prototype command and have it update the DOM in some way.  Needless to say this gave me a bad taste in my mouth for prototype.

Wednesday, January 21, 2009

Apple comments on "netbooks"

In their Quarterly financial conference call today:

Cook also continued to downplay Apple's interest in the "netbook" market:

We're watching that space, but from our [point of view] the products are based on hardware that's much less powerful, software technology that's not good, cramped displays. We don't think that people are going to be pleased with those type of products. It's a category we watch, we have some ideas here, but we think the products there now are inferior and won't provide the kind of experience people want.

They obviously aren't paying much attention to the demand of it's customers.  If I had the money to buy a new machine I would of bought a Samsung NC10 right after MacWorld due to the nonannouncement of a netbook at MacWorld.

Netbooks are cheap and trending.  Recession proof in my opinion.

Update: John Gruber lays into Brian Chen for noticing the same thing as I.  What I think John does not understand is that the more Apple waits and sees the more money they are losing.  In my head, I don't have the confidence that they can pull something out now.  Any netbook that comes out in the future may not have the Steve Jobs stamp of approval.  At this point, it might be a year or more until we see a release of a netbook product from Apple. 

Apple played the wait and see game back when customers were demanding an iPod with video.  Apple's statement then was, we aren't going to make a video iPod, customers don't want to watch video on a little screen.  But a year later they released their first iPod video.  And they were right we didn't want to watch video on a little screen.  It took a couple more years for them to get it right and come out with the iPod Touch. 

Frankly, I am not going to wait and see if Apple is going to come out with a netbook the market is too saturated with netbooks. 

Tuesday, January 20, 2009

In Case you Missed it: #jQuery Twitter posts

My #jQuery related twitter posts for the week of January 13th - January 19th:

Follow me to see what I'll twitter next about jQuery.

President Barack Obama



The inauguration speech transcript:

My fellow citizens:

I stand here today humbled by the task before us, grateful for the trust you have bestowed, mindful of the sacrifices borne by our ancestors. I thank President Bush for his service to our nation, as well as the generosity and cooperation he has shown throughout this transition.

Forty-four Americans have now taken the presidential oath. The words have been spoken during rising tides of prosperity and the still waters of peace. Yet, every so often, the oath is taken amidst gathering clouds and raging storms. At these moments, America has carried on not simply because of the skill or vision of those in high office, but because We the People have remained faithful to the ideals of our forebearers, and true to our founding documents.

So it has been. So it must be with this generation of Americans.

That we are in the midst of crisis is now well understood. Our nation is at war, against a far-reaching network of violence and hatred. Our economy is badly weakened, a consequence of greed and irresponsibility on the part of some, but also our collective failure to make hard choices and prepare the nation for a new age. Homes have been lost; jobs shed; businesses shuttered. Our health care is too costly; our schools fail too many; and each day brings further evidence that the ways we use energy strengthen our adversaries and threaten our planet.

These are the indicators of crisis, subject to data and statistics. Less measurable but no less profound is a sapping of confidence across our land -- a nagging fear that America's decline is inevitable, and that the next generation must lower its sights.

Today I say to you that the challenges we face are real. They are serious and they are many. They will not be met easily or in a short span of time. But know this, America: They will be met.

On this day, we gather because we have chosen hope over fear, unity of purpose over conflict and discord.

On this day, we come to proclaim an end to the petty grievances and false promises, the recriminations and worn-out dogmas, that for far too long have strangled our politics.

We remain a young nation, but in the words of Scripture, the time has come to set aside childish things. The time has come to reaffirm our enduring spirit; to choose our better history; to carry forward that precious gift, that noble idea, passed on from generation to generation: the God-given promise that all are equal, all are free, and all deserve a chance to pursue their full measure of happiness.

In reaffirming the greatness of our nation, we understand that greatness is never a given. It must be earned. Our journey has never been one of shortcuts or settling for less. It has not been the path for the fainthearted -- for those who prefer leisure over work, or seek only the pleasures of riches and fame. Rather, it has been the risk-takers, the doers, the makers of things -- some celebrated, but more often men and women obscure in their labor -- who have carried us up the long, rugged path toward prosperity and freedom.

For us, they packed up their few worldly possessions and traveled across oceans in search of a new life.

For us, they toiled in sweatshops and settled the West; endured the lash of the whip and plowed the hard earth.

For us, they fought and died, in places like Concord and Gettysburg; Normandy and Khe Sahn.

Time and again, these men and women struggled and sacrificed and worked till their hands were raw so that we might live a better life. They saw America as bigger than the sum of our individual ambitions; greater than all the differences of birth or wealth or faction.

This is the journey we continue today. We remain the most prosperous, powerful nation on Earth. Our workers are no less productive than when this crisis began. Our minds are no less inventive, our goods and services no less needed than they were last week or last month or last year. Our capacity remains undiminished. But our time of standing pat, of protecting narrow interests and putting off unpleasant decisions -- that time has surely passed. Starting today, we must pick ourselves up, dust ourselves off, and begin again the work of remaking America.

For everywhere we look, there is work to be done. The state of the economy calls for action, bold and swift, and we will act -- not only to create new jobs, but to lay a new foundation for growth. We will build the roads and bridges, the electric grids and digital lines that feed our commerce and bind us together. We will restore science to its rightful place, and wield technology's wonders to raise health care's quality and lower its cost. We will harness the sun and the winds and the soil to fuel our cars and run our factories. And we will transform our schools and colleges and universities to meet the demands of a new age. All this we can do. And all this we will do.

Now, there are some who question the scale of our ambitions -- who suggest that our system cannot tolerate too many big plans. Their memories are short. For they have forgotten what this country has already done; what free men and women can achieve when imagination is joined to common purpose, and necessity to courage.

What the cynics fail to understand is that the ground has shifted beneath them -- that the stale political arguments that have consumed us for so long no longer apply. The question we ask today is not whether our government is too big or too small, but whether it works -- whether it helps families find jobs at a decent wage, care they can afford, a retirement that is dignified. Where the answer is yes, we intend to move forward. Where the answer is no, programs will end. And those of us who manage the public's dollars will be held to account -- to spend wisely, reform bad habits, and do our business in the light of day -- because only then can we restore the vital trust between a people and their government.

Nor is the question before us whether the market is a force for good or ill. Its power to generate wealth and expand freedom is unmatched, but this crisis has reminded us that without a watchful eye, the market can spin out of control -- and that a nation cannot prosper long when it favors only the prosperous. The success of our economy has always depended not just on the size of our gross domestic product, but on the reach of our prosperity; on our ability to extend opportunity to every willing heart -- not out of charity, but because it is the surest route to our common good.

As for our common defense, we reject as false the choice between our safety and our ideals. Our Founding Fathers, faced with perils we can scarcely imagine, drafted a charter to assure the rule of law and the rights of man, a charter expanded by the blood of generations. Those ideals still light the world, and we will not give them up for expedience's sake. And so to all other peoples and governments who are watching today, from the grandest capitals to the small village where my father was born: Know that America is a friend of each nation and every man, woman and child who seeks a future of peace and dignity, and that we are ready to lead once more.

Recall that earlier generations faced down fascism and communism not just with missiles and tanks, but with sturdy alliances and enduring convictions. They understood that our power alone cannot protect us, nor does it entitle us to do as we please. Instead, they knew that our power grows through its prudent use; our security emanates from the justness of our cause, the force of our example, the tempering qualities of humility and restraint.

We are the keepers of this legacy. Guided by these principles once more, we can meet those new threats that demand even greater effort -- even greater cooperation and understanding between nations. We will begin to responsibly leave Iraq to its people, and forge a hard-earned peace in Afghanistan. With old friends and former foes, we will work tirelessly to lessen the nuclear threat, and roll back the specter of a warming planet. We will not apologize for our way of life, nor will we waver in its defense, and for those who seek to advance their aims by inducing terror and slaughtering innocents, we say to you now that our spirit is stronger and cannot be broken; you cannot outlast us, and we will defeat you.

For we know that our patchwork heritage is a strength, not a weakness. We are a nation of Christians and Muslims, Jews and Hindus -- and nonbelievers. We are shaped by every language and culture, drawn from every end of this Earth; and because we have tasted the bitter swill of civil war and segregation, and emerged from that dark chapter stronger and more united, we cannot help but believe that the old hatreds shall someday pass; that the lines of tribe shall soon dissolve; that as the world grows smaller, our common humanity shall reveal itself; and that America must play its role in ushering in a new era of peace.

To the Muslim world, we seek a new way forward, based on mutual interest and mutual respect. To those leaders around the globe who seek to sow conflict, or blame their society's ills on the West: Know that your people will judge you on what you can build, not what you destroy. To those who cling to power through corruption and deceit and the silencing of dissent, know that you are on the wrong side of history; but that we will extend a hand if you are willing to unclench your fist.

To the people of poor nations, we pledge to work alongside you to make your farms flourish and let clean waters flow; to nourish starved bodies and feed hungry minds. And to those nations like ours that enjoy relative plenty, we say we can no longer afford indifference to suffering outside our borders; nor can we consume the world's resources without regard to effect. For the world has changed, and we must change with it.

As we consider the road that unfolds before us, we remember with humble gratitude those brave Americans who, at this very hour, patrol far-off deserts and distant mountains. They have something to tell us today, just as the fallen heroes who lie in Arlington whisper through the ages. We honor them not only because they are guardians of our liberty, but because they embody the spirit of service; a willingness to find meaning in something greater than themselves. And yet, at this moment -- a moment that will define a generation -- it is precisely this spirit that must inhabit us all.

For as much as government can do and must do, it is ultimately the faith and determination of the American people upon which this nation relies. It is the kindness to take in a stranger when the levees break, the selflessness of workers who would rather cut their hours than see a friend lose their job which sees us through our darkest hours. It is the firefighter's courage to storm a stairway filled with smoke, but also a parent's willingness to nurture a child, that finally decides our fate.

Our challenges may be new. The instruments with which we meet them may be new. But those values upon which our success depends -- hard work and honesty, courage and fair play, tolerance and curiosity, loyalty and patriotism -- these things are old. These things are true. They have been the quiet force of progress throughout our history. What is demanded then is a return to these truths. What is required of us now is a new era of responsibility -- a recognition, on the part of every American, that we have duties to ourselves, our nation and the world; duties that we do not grudgingly accept but rather seize gladly, firm in the knowledge that there is nothing so satisfying to the spirit, so defining of our character, than giving our all to a difficult task.

This is the price and the promise of citizenship.

This is the source of our confidence -- the knowledge that God calls on us to shape an uncertain destiny.

This is the meaning of our liberty and our creed -- why men and women and children of every race and every faith can join in celebration across this magnificent Mall, and why a man whose father less than 60 years ago might not have been served at a local restaurant can now stand before you to take a most sacred oath.

So let us mark this day with remembrance, of who we are and how far we have traveled. In the year of America's birth, in the coldest of months, a small band of patriots huddled by dying campfires on the shores of an icy river. The capital was abandoned. The enemy was advancing. The snow was stained with blood. At a moment when the outcome of our revolution was most in doubt, the father of our nation ordered these words be read to the people:

"Let it be told to the future world ... that in the depth of winter, when nothing but hope and virtue could survive... that the city and the country, alarmed at one common danger, came forth to meet [it]."

America. In the face of our common dangers, in this winter of our hardship, let us remember these timeless words. With hope and virtue, let us brave once more the icy currents, and endure what storms may come. Let it be said by our children's children that when we were tested, we refused to let this journey end, that we did not turn back, nor did we falter; and with eyes fixed on the horizon and God's grace upon us, we carried forth that great gift of freedom and delivered it safely to future generations

Blog Posts by:

The Official jQuery Podcast

with Ralph Whitbeck & Rey Bango

You can subscribe to the show in iTunes or via the raw RSS feed

My Twitter Updates

View Twitter Page