SpringSys' Happy Land

Enjoy code, enjoy life.

DOM element layout methods based on jQuery

clock December 23, 2009 14:15 by author Jerry Si

Background

 jQuery has some methods to get or set the position or width/height of DOM element. For example, $(..).width(), $(..).outerHeight(). But I still feel it's not that convenient to layout DOM elements in flexible manners.

1) One interesting fact is the  $(..).position() gets the position of DOM element including margin, while the $(..).offset() gets the position excluding the margin. This can be observed by the below sample: 

 

So, it makes us a little twisted when calculating or setting the bounds for DOM element.  

2) $(..).css("border-left-width")  can't get the exact border width in pixel. Because sometimes the value we get might be like "thin", "medium" or "Thick".

3) $(..).width(value) and $(..).height(value) can be used to set the CSS width/height of DOM element. But sometimes we actually need to set the width or height of a element from the displaying point of view, which the DOM element may already has padding or border specified.

4) Similar as above, we need methods to get/sets the bounds a DOM element for different requirement, the portion may include or exclude the margins/borders/paddings etc. 

For the above reasons, I wrote a class that can help user to layout DOM element in flexible and cross-browser ways.

 

What are these methods? 

Layout class defines 4 categories of methods that help developers to get or set the layout for DOM element. User can determine it by passing proper parameters to methods. They are: 

1) Position methods

   1:  Point GetPosition(DOMElement element, bool absolute, bool margin);
   2:  Point GetInnerPosition(DOMElement element, bool absolute);
   3:  Point GetContentPosition(DOMElement element, bool absolute)
   4:  void SetPosition(DOMElement element, int x, int y);

2) Width/Height methods

   1:  int GetWidth(DOMElement element, bool margin);
   2:  void SetWidth(DOMElement element, int width, bool margin);
   3:  int GetHeight(DOMElement element, bool margin);
   4:  void SetHeight(DOMElement element, int height, bool margin);
   5:  int GetInnerWidth(DOMElement element);
   6:  void SetInnerWidth(DOMElement element, int width);
   7:  int GetInnerHeight(DOMElement element);
   8:  void SetInnerHeight(DOMElement element, int height);
   9:  int GetContentWidth(DOMElement element);
  10:  void SetContentWidth(DOMElement element, int width);
  11:  int GetContentHeight(DOMElement element);
  12:  void SetContentHeight(DOMElement element, int height);

3) Bounds methods

   1:  Bounds GetBounds(DOMElement element, bool margin);
   2:  void SetBounds(DOMElement element, Bounds bounds, bool margin);
   3:  Bounds GetInnerBounds(DOMElement element);
   4:  void SetInnerBounds(DOMElement element, Bounds bounds);
   5:  Bounds GetContentBounds(DOMElement element);
   6:  void SetContentBounds(DOMElement element, Bounds bounds);

4) Box utilities

   1:  Box GetMarginBox(DOMElement element);
   2:  Box GetBorderBox(DOMElement element);
   3:  Box GetPaddingBox(DOMElement element);
   4:  bool HasBorder(DOMElement element, BoxSide boxSide); 
   5:  float GetMargin(DOMElement element, BoxSide boxSide);
   6:  float GetBorderWidth(DOMElement element, BoxSide boxSide);
   7:  float GetPadding(DOMElement element, BoxSide boxSide);

 

 jQuery extension

All those functions can be accessed from jQuery extension. To add them to jQuery extension, you can call the below method:

SpringSys.Web.UI.Layout.extendTojQuery();

Example

  Here we write a sample to outlines all the bounds of two DIV elements. Both DIVs has padding, border and margin; The second DIV has border width not in pixel unit.

 

   1:  <html xmlns="http://www.w3.org/1999/xhtml">
   2:  <head runat="server">
   3:      <title></title>
   4:      
   5:  <style type="text/css">
   6:  .target
   7:  {
   8:      width:120px;
   9:      height:120px;
  10:      border:solid 15px #aa2828;
  11:      margin:10px;
  12:      padding:20px;
  13:      position:absolute;
  14:  }
  15:   
  16:  .target2
  17:  {
  18:      width:120px;
  19:      height:120px;
  20:      border-left:solid thin blue;
  21:      border-right:solid 1em blue;
  22:      border-top:solid medium blue;
  23:      border-bottom:solid thick blue;
  24:      margin:10px;
  25:      padding:20px;
  26:      position:absolute;
  27:  }
  28:   
  29:  .markline
  30:  {
  31:      border: solid 1px #55aa55;
  32:  }
  33:   
  34:   
  35:  </style>
  36:      
  37:  </head>
  38:  <body>
  39:      <form id="form1" runat="server">
  40:      
  41:      <asp:ScriptManager ID="ScriptManager1" runat="server">
  42:          <Scripts>
  43:          <asp:ScriptReference Path="~/Scripts/jquery-1.3.2.js"/>
  44:          <asp:ScriptReference Path="~/Scripts/Layout.debug.js"/>
  45:          </Scripts>
  46:      </asp:ScriptManager>
  47:      
  48:      <div>
  49:      
  50:  <script type="text/javascript">
  51:      function OutlineTarget(target) {
  52:          $("<div class='markline'/>").appendTo(document.body).setInnerBounds(target.getBounds(true));
  53:          $("<div class='markline'/>").appendTo(document.body).setInnerBounds(target.getBounds());
  54:          $("<div class='markline'/>").appendTo(document.body).setBounds(target.getInnerBounds());
  55:          $("<div class='markline'/>").appendTo(document.body).setInnerBounds(target.getContentBounds(true));
  56:      }
  57:   
  58:      $(function() {
  59:          SpringSys.Web.UI.Layout.extendTojQuery();
  60:          OutlineTarget($("#target"));
  61:          OutlineTarget($("#target2"));
  62:      });
  63:   
  64:  </script>
  65:      
  66:     
  67:      <div class="target" style="left:20px;top:40px;">Content area is here ...</div>
  68:      <div class="target" id="target" style="left:20px;top:270px;">Content area is here ...</div>
  69:      <div class="target2" style="left:450px;top:40px;">Content area is here ...</div>
  70:      <div class="target2" id="target2" style="left:450px;top:270px;">Content area is here ...</div>
  71:    
  72:      
  73:      </div>
  74:      </form>
  75:  </body>
  76:  </html>

 

We use green line to outline the correct range in DOM element. After run, we can see the browsing result looks like below:

 

 Download

Click here to get the C# source file of Layout.cs. (Need Scrip# to convert to JavaScript)

Click here to get the Script# project file.

To get the JavaScript file directly, please click here.



Support jQuery in Script#

clock December 16, 2009 04:52 by author Jerry Si

Background 

I've been using Script# for a pretty long time. I love it because it is much easier for me to write Ajax based javas-cript code in C# language without losing the powerful functionalities in Visual Studio 2008.   

jQuery becomes so popular in the past year, I decided to move the SpringSys web controls to jQuery base as well.  

Unfortunately, Script# library doesn't support jQuery till now. Why not writing my own jQuery wrapper classes for Script# project? Since I believe new release of Script# will support jQuery at later time, but I really can't wait.  

Introduction 

So, I wrote this set of classes to add jQuery support to my Script# project. It uses jQuery() syntax instead of the shortest $() syntax, because C# compiler doesn't allow $ sign as function name. 

This set of classes are implemented for jQuery_1.3.2 base on it's API reference, that means all the functions described in jQuery_1.3.2 API reference are supported by those classes.  

For more information about the jQuery API, please visit http://docs.jquery.com/Main_Page  

Download 

Source code: http://www.springsys.com/download/jQuery/jQuery_1_3_2.zip   

Sample with source code: http://www.springsys.com/download/jQuery/MyScript.zip 

Sample web project: http://www.springsys.com/download/jQuery/SampleSite.zip  

jQuery entry points 

As we know, jQuery() function is a global function in Java Script, so I have to use a static class JQueryCreator to define all the entry point functions for jQuery in C# code. Script# compiler will translate those static methods in static class into global functions.  

For example, JQueryCreator.jQuery("#btnClick") will be compiled to jQuery("#btnClick") in Java Script. 

You can find multiple jQuery entry point functions that accept variant type of parameters as described in jQuery API reference.   

jQuery instance functions 

All the jQuery instance functions are defined inside the JQuery class. They are organized in the exact same categories used by the jQuery API reference.  

For example: 

JQuery jq = JQueryCreator.jQuery("#mydiv");

jq.css("background-color", "#686868"); 

will be translated to 

var jq = jQuery("# mydiv");

jq.css('background-color', '#686868');  

jQuery ‘static’ functions 

In jQuery API, we can see some 'static' members that are not in jQuery object's instance, for example, jQuery.isFunction(), jQuery.browser etc. They are defined inside the jQuery class in the class set.   

jQuery Event 

jQuery has its owe event object definition, mostly base on the W3C event object, but also has some useful extensions, for example, PreventDefault(), StopPropagation() etc. This jQuery event is defined by the JQueryEvent class in the class set.  

Example

 

I wrote a behavior to associate jQuery operations with target element:
 
   1:  using System;
   2:  using Sys;
   3:  using System.DHTML;
   4:  using Sys.UI;
   5:   
   6:  namespace SpringSys.Sample
   7:  {
   8:      using SpringSys.JQuery132;
   9:   
  10:      public class MyBehavior : Behavior
  11:      {
  12:          private JQuery _jq;
  13:   
  14:          public MyBehavior(DOMElement element)
  15:              : base(element)
  16:          {
  17:              _jq = JQueryCreator.jQuery(element);
  18:              _jq.click(OnClick);
  19:          }
  20:   
  21:          private bool OnClick(JQueryEvent e)
  22:          {
  23:              Script.Alert(String.Format("You clicked me at position: \n\nOffsetX={0}, OffsetY={1}\nClientX={2}, ClientY={3}\nPageX={4}, PageY={5}", 
  24:                  e.OriginalEvent.OffsetX, 
  25:                  e.OriginalEvent.OffsetY,
  26:                  e.ClientX,
  27:                  e.ClientY,
  28:                  e.PageX,
  29:                  e.PageY));
  30:              return true;
  31:          }
  32:   
  33:          public void ChangeSize(int width, int height)
  34:          {
  35:              _jq.width(width);
  36:              _jq.height(height);
  37:          }
  38:   
  39:          public void Slide()
  40:          {
  41:              _jq.slideUp("slow");
  42:              _jq.slideDown("slow");
  43:          }
  44:   
  45:          public void Fade()
  46:          {
  47:              _jq.fadeOut("slow");
  48:              _jq.fadeIn("slow");
  49:          }
  50:   
  51:          public void DetectBrowser()
  52:          {
  53:              if (jQuery.browser.msie != null)
  54:                  Script.Alert("You're using MSIE. Version:" + jQuery.browser.version);
  55:   
  56:              if (jQuery.browser.safari != null)
  57:                  Script.Alert("You're using Safari. Version:" + jQuery.browser.version);
  58:   
  59:              if (jQuery.browser.opera != null)
  60:                  Script.Alert("You're using Opera. Version:" + jQuery.browser.version);
  61:   
  62:              if (jQuery.browser.mozilla != null)
  63:                  Script.Alert("You're using Mozilla. Version:" + jQuery.browser.version);
  64:          }
  65:      }
  66:  }
 
To use it:
   1:  <script type="text/javascript">
   2:      var myBehavior = null;
   3:      $(function() {
   4:          myBehavior = new SpringSys.Sample.MyBehavior($('#Panel1').get(0));
   5:      }
   6:  ) 
   7:  </script>      
   8:          
   9:          <input id="Button1" type="button" value="Change Size" onclick="myBehavior.changeSize(300, 200);" />
  10:          <input id="Button2" type="button" value="Slide" onclick="myBehavior.slide();" />
  11:          <input id="Button3" type="button" value="Fade" onclick="myBehavior.fade();" />
  12:          <input id="Button4" type="button" value="Detect Browser" onclick="myBehavior.detectBrowser();" />
  13:          <asp:Panel ID="Panel1" runat="server" Height="103px" Width="194px" style="border:solid 1px red;background-color:#686868;">Click me!</asp:Panel>

 

Comment? 

You are welcome to use or modify it in your own project. If you have any comment or suggestion, please write it here or email to jsi@springsys.com



A tool that can extract headers from Newsgroup server.

clock November 25, 2009 16:19 by author Jerry Si

For a long time, I was looking for a tool that can extract data from newsgroup server. This may help me analyzing information like what topic people mostly focus on, who are concerning with what content, where they come from, who are the most active people etc. But unfortunately, I could not get a suitable one. So, why not write one myself?

NNTP Wrapper Class

As we know, NNTP defines the communication protocol between the client and newsgroup server. So, internally, we use a helper class NewsgroupClient to communicate withe newsgroup server. This class wraps the methods that can send commands to server and retrieve data correspondingly.

For example, ListGroup() method lists the available newsgroup on the server. SelectGroup() method selects and retrieves article ranges. DownloadHeaders() method retrieve article headers from the current active group.

User Interface

The user interface of this tool can be divided into two parts: the Newsgroups tree on the left side, and the article list on the right. Both of them are actually SpringSys OrchidGrid control. As we know, OrchidGrid can work in tree mode and grid mode.

After adding a Newsgroup server, all the groups on this server will be added as child under that server name node. The data of the tree will be persisted into a text file when the application is closed. When next we run the tool again, and data will be restored from the text file.

Each group has a checkbox, by which we can select the groups that are going to be explored before downloading the article headers. Here we use the check box node feature of the grid. 

When you choose the groups and click the "Download Message Headers" button, the basic message data will be listed on the right side grid.

OrchidGrid has built-in data exporting abilities, calling the grid's methods ExportToDelimitedFile() and ExportToExcel() can export the grid data into text file of excel file. Simple?

You can also write your own exporting code if you'd like. In this application, I commented some code in the source that can export the email address of the article author to a text file. (Search button1_Click method in Form1.cs file), thus, this tool can be extended as an email address extractor.

Try a Sample Server

Let's try a newsgroup server for example – “msnews.microsoft.com”, it has a bunch of newgroups, and some contain thousands of articles.

Input the server address “msnews.microsoft.com” and press the Enter key, the server and the newsgroups on that server are listed on the left tree. Check some newsgroups as you like and click the button “Download Message Headers”, you will get all the headers in the selected newsgroups. Then, you can export the headers to text or Excel file.

Download the code

Click below link to download this tool in source code.

NewsgroupExtractor.zip (475.43 kb)



Welcome to SpringSys' Happy Land

clock November 8, 2009 09:00 by author Jerry Si

Congratulations!!!

SpringSys Weblog is available now.



Page List

    Sign in