tags:

views:

80

answers:

2

On a given page, to let's say to display a window, I may need some JavaScript initialization, some DIVs with certain IDs and it all needs to be linked with each other. The JavaScript may need to know about a DIV's ID, the DIVs may need to be nested in a certain way and so on. Obviously I don't want to worry about this on every single page I use that code. That would make it error-prone and not DRY.

With WebForms I would solve this problem by writing a custom control. How are you guys doing this in your projects? Are you using extension methods spitting out strings, maybe user controls? What's the recommended way?

Thanks.

EDIT:

Here's an example when using master-pages:

  1. In the HEAD content region I would need some jQuery code that sets up some functionality
  2. In one content region I would put some HTML required to show a part of the window
  3. In a different content region I would put the actual HTML that's displayed in the window.

So all these 3 pieces would require 3 different blocks of code but would be logically linked.

EDIT 2

Code example (using a master-page)

<asp:Content ContentPlaceHolderID="HeaderContent" runat="server">
   <script type="text/javascript">
     $(document).ready(function() { DoSomething('div1', 'div2'); });
   </script>
</asp:Content>

<asp:Content ContentPlaceHolderID="TopContent" runat="server">
  <div id='div1'> ... </div>
</asp:Content>

<asp:Content ContentPlaceHolderID="BottomContent" runat="server">
  <div id='div2'> ... </div>
</asp:Content>

div1 and div2 are coupled with the JavaScript function call. If I make a mistake, give the DIV a different ID, the code would break. This is a simple example that proves the point. It gets a lot more complicated when the coupling relies on div1 having a certain structure for example.

+2  A: 

Can you leverage Site.Master for this purpose, or at least another Master of your own creation? All of your views can then reference this Master and gain the benefit of initialized JavaScript and layout elements.

To me, this makes sense if the content is static in nature. If not, I'd go with a custom Html.Init helper method.

I'm envisioning something like the following:

global.js

function doSomething()
{
}

//more code here

master page

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC 
 "-//W3C//DTD XHTML 1.0 Strict//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title>
      <asp:ContentPlaceHolder ID="TitleContent" runat="server" />
    </title>
    <link rel="Stylesheet" href="~/Content/styles.css" />
    <script type="text/javascript" src="global.js"></script>
</head>
<body>
    <div id="customContent">
    </div>
    <div id="content">
        <asp:ContentPlaceHolder ID="MainContent" runat="server" />
    </div>    
</body>
</html>
David Andres
I am using master-pages, so not really, because bits and pieces are separate. The JS code would go in the header section while the html part would be in some place holder.
pbz
@pgz: I've added a sample to this answer. You don't have to go in this direction, but it's fairly straightforward if you do. Note the global.js file included in the script tag at the top of the master file.
David Andres
Right, but that doSomething method would need to accept parameters that are specific to a page (like the IDs of some DIVs). If I call doSomething('div1', 'div2') and I assign, by mistake, different IDs to the div the code would break. What I'm looking for is a way to prevent these types of mistakes. Thanks.
pbz
I'm confused, why couldn't doSomething take element ids? Or, alternatively, you could use classes for your DIVs. as in $("div.window").show().
David Andres
Yes, it can take element IDs. When I do that, let's say doSomething('div1') I couple the function call with the <div id="div1"></div> block. If, by mistake, I assign a different ID to the DIV the code won't work. In effect I'm typing 'div1' twice and hence the possibility of a mistake. Is there a way to eliminate this possibility by somehow allowing the .NET code that writes the doSomething string to "communicate" with the code that writes the DIV so that it would be declared only once? It's not a question of getting it to work, but rather the best (DRYest) way to do it. Thanks.
pbz
The best way would be to not repeat element ids at all. If you're worried about incorrect or duplicate ids, place the necessary divs in the master page or use css class names as mentioned before. At the end of the day, you have to couple to something. Otherwise, your code won't do anything.
David Andres
+1  A: 

The closest you can get to CustomControlls are Partials. They are not as powerfull as CustomControlls because they have no eventhandling (obviously) but are a good way to separate common html.

Malcolm Frexner
The problem with partials is that they (partials/user controls) don't have content place holders, so I can't build a partial that writes some html "header" and "footer" while letting me customize the middle part. HTML extensions have the same issue. I would need two partials or two extension methods, one to render the header and one to render the footer, and more if I need more place holders. Thanks.
pbz