<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1420624415326144044</id><updated>2010-03-30T21:16:32.434+02:00</updated><title type='text'>BeFruit</title><subtitle type='html'>Discoveries about programming, online earning and sharing.</subtitle><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.befruit.com/atom.xml'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-5544829424611674545</id><published>2008-09-08T16:00:00.004+02:00</published><updated>2008-09-14T00:55:30.967+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>WCF error: "This collection already contains an address with scheme http"</title><content type='html'>I met this error, and wondered what this could be. The explanation is that "WCF services hosted in IIS can have only one Base Address", meaning that in IIS the website hosting the service can not be associated to &lt;span style="font-family:courier new;"&gt;http://www.example.com&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;http://example.com&lt;/span&gt; at the same time.&lt;br /&gt;&lt;br /&gt;I don't know why this prevents a service to work, but I know this is annoying.&lt;br /&gt;I found a couple of bloggers like &lt;a href="http://www.robzelt.com/blog/PermaLink.aspx?guid=b53a709e-cd21-460f-a33b-c7a8e02e8bd6"&gt;Rob&lt;/a&gt; suggesting a solution with a coded custom &lt;span style="font-family:courier new;"&gt;ServiceHostFactory&lt;/span&gt;, which sounds terribly complicated to me as a workaround.&lt;br /&gt;&lt;br /&gt;Fortunately there is a much simpler solution, just by touching the web.config file. Just add the following lines in the &lt;span style="font-family:courier new;"&gt;system.serviceModel&lt;/span&gt; section:&lt;br /&gt;&lt;span style="font-family:courier new"&gt;&amp;lt;serviceHostingEnvironment&amp;gt;&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;baseAddressPrefixFilters&amp;gt;&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;add prefix="http://www.example.com"/&amp;gt;&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/baseAddressPrefixFilters&amp;gt;&lt;br/&gt;&lt;br /&gt;&amp;lt;/serviceHostingEnvironment&amp;gt;&lt;/span&gt;&lt;br /&gt;to only keep the service address.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-5544829424611674545?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/5544829424611674545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=5544829424611674545' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/5544829424611674545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/5544829424611674545'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2008/09/wcf-error-this-collection-already.html' title='WCF error: &quot;This collection already contains an address with scheme http&quot;'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-542893339414496783</id><published>2008-07-22T21:33:00.007+02:00</published><updated>2008-07-22T23:37:45.966+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Clone objects in C#</title><content type='html'>It is simple to clone objects (i.e. make an exact copy of an object) that implement the IClonable interface. It has the Clone() method that you just have to call.&lt;br /&gt;&lt;br /&gt;When the method is not available and the class is serializable (has the Serializable attribute), it is possible to use this feature. There are some examples over the Internet, here is a variant I adapted as a templated method:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;blockquote&gt;private static T Clone&amp;lt;T&amp;gt;(T original)&lt;br /&gt;{&lt;blockquote&gt;BinaryFormatter bf = new BinaryFormatter();&lt;br /&gt;MemoryStream ms = new MemoryStream();&lt;br /&gt;bf.Serialize(ms, original);&lt;br /&gt;ms.Flush();&lt;br /&gt;ms.Position = 0;&lt;br /&gt;return (T)bf.Deserialize(ms);&lt;/blockquote&gt;}&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;You call it this way:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;blockquote&gt;MyClass copy = Clone&amp;lt;MyClass&amp;gt;(original);&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But what to do with a non serializable object? The only way is to use reflection. Here is a simplified but working example. One should take care of readable and writable properties.&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;blockquote&gt;private static T Clone&amp;lt;T&amp;gt;(T original)&lt;br /&gt;{&lt;blockquote&gt;T copy = (T)(typeof(T).GetConstructor(System.Type.EmptyTypes).Invoke(null));&lt;br /&gt;foreach (PropertyInfo pi in typeof(T).GetProperties())&lt;br /&gt;{&lt;blockquote&gt;object originalValue = pi.GetValue(original, null);&lt;br /&gt;pi.SetValue(copy, originalValue, null);&lt;/blockquote&gt;}&lt;br /&gt;return copy;&lt;br /&gt;&lt;/blockquote&gt;}&lt;/blockquote&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-542893339414496783?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/542893339414496783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=542893339414496783' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/542893339414496783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/542893339414496783'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2008/07/clone-objects-in-c.html' title='Clone objects in C#'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-7644305206708336006</id><published>2008-05-30T11:49:00.001+02:00</published><updated>2008-05-30T11:54:17.413+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><title type='text'>Corrupted applicationHost.config file in IIS 7</title><content type='html'>IIS7 stores its parameters in an XML file, located typically at C:\Windows\System32\inetsrv\config\applicationHost.config. This is a nice solution as every parameter is clearly readable. Unfortunately, there are still some bugs (maybe in IIS 7, but some problems with anti virus programs have also been reported) and this file may be corrupted.&lt;br /&gt;What to do when this file is truncated? Reset it and loose all of your settings?&lt;br /&gt;Luckily IIS makes a backup each time you make a change. All those versions are stored in the folder C:\inetpub\history\. All you have to do is to copy a former applicationHost.config file into the C:\Windows\System32\inetsrv\config\ working directory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-7644305206708336006?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/7644305206708336006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=7644305206708336006' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/7644305206708336006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/7644305206708336006'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2008/05/corrupted-applicationhostconfig-file-in.html' title='Corrupted applicationHost.config file in IIS 7'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-1349402883516796609</id><published>2008-05-07T00:13:00.006+02:00</published><updated>2008-05-07T01:15:23.889+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><title type='text'>WPF is all about Panels</title><content type='html'>Have you noticed how most applications' windows behave badly when it comes to adapt their dimensions to content or screen size? When you resize a window, only the center resizes and the other elements (toolbars, menus, ...) remain unchanged. Most popups have fixed size. It is true for local applications and also for HTML pages. HTML is supposed to be flexible and adapt its layout to content, but in real life, it is really difficult to control how HTML behaves. Apart from fixing elements' size, the result is unpredictable.&lt;br /&gt;&lt;br /&gt;Fortunately today we have &lt;acronym title="eXtensible Application Markup Language"&gt;XAML&lt;/acronym&gt;, and the numerous Panels. Panels are in my opinion the most important contribution to complex application screens. But not every panel is equally useful. Forget about Canvas, which is the old fashioned way of placing element giving coordinates. It is all but flexible. Even the Grid panel that represents a table of cells is not as flexible as my favorite: the DockPanel. It fills up the window space starting from borders, and leaving the center for the main content. Be sure to fully understand how each kind of panel behaves, to be able to choose the correct one. Other useful panels are StackPanel, WrapPanel, ...&lt;br /&gt;&lt;br /&gt;Panels come with another important notion: min/max width and height. Instead of fixing a column width, set its MinWidth value. It ensures that it will not render too thin if empty. Avoid at all cost fixing Width or Height, as you never know on what screen your application will be displayed. Test your interface with few or plenty of data, on tiny or huge screens. It should look great in every situation. Panels make it possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-1349402883516796609?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/1349402883516796609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=1349402883516796609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/1349402883516796609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/1349402883516796609'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2008/05/wpf-is-all-about-panels.html' title='WPF is all about Panels'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-1567205106570511916</id><published>2008-04-17T16:55:00.004+02:00</published><updated>2008-04-17T17:08:01.506+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><title type='text'>WCF on Vista raises an AddressAccessDeniedException</title><content type='html'>I was trying the example from the excellent book by Michele Leroux Bustamante about WCF, and cound not start them getting the exception &lt;span style="font-family:courier new;"&gt;AddressAccessDeniedException&lt;/span&gt; on &lt;span style="font-family:courier new;"&gt;ServiceHost.Open()&lt;/span&gt;.&lt;br /&gt;The solution is to start a console as an administrator (right click on the &lt;span style="font-family:courier new;"&gt;cmd.exe&lt;/span&gt; icon and select "Run as administrator") and execute:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;netsh http add urlacl url=http://+:8080/ user=username&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The + is a wildcard for any domain&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;8080 is the port I used for my WCF services, use your own&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;username&lt;/span&gt; is the user you logged in with, and can be preceded by &lt;span style="font-family:courier new;"&gt;DOMAIN\username&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;The problem happens only on Vista (and probably on Windows Server 2008) and not on former systems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-1567205106570511916?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/1567205106570511916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=1567205106570511916' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/1567205106570511916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/1567205106570511916'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2008/04/wcf-on-vista.html' title='WCF on Vista raises an AddressAccessDeniedException'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-3496684377805933339</id><published>2008-04-02T16:14:00.008+02:00</published><updated>2008-04-02T17:22:57.189+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><title type='text'>WPF is the future of HTML</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://blog.befruit.com/uploaded_images/XBAP-project-771641.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://blog.befruit.com/uploaded_images/XBAP-project-771627.jpg" alt="" border="0" /&gt;&lt;/a&gt;I think that all the demos that can be found about WPF and Silverlight are wrong. They are showing how you can make funky animations, include videos and gradient colors everywhere.&lt;br /&gt;But we are professionals and what our clients need is a powerful and robust client, so let's make classical layouts with normal checkboxes and tabbed screens. Nobody needs 3D interfaces where you have to scratch your head to guess how to use it.&lt;br /&gt;&lt;br /&gt;Former HTML interfaces were poor and fragile, mixing many languages and standards. How to validate an e-mail input control? Add a server-side validation after postback or use Ajax? Or write a custom JavaScript? Do it on control blur or on keypress? Depending on the context, one of these solutions may do the job so you end up mixing all of them.&lt;br /&gt;&lt;br /&gt;With WPF and &lt;acronym title="XAML Browser Application - a WPF application hosted by your browser"&gt;XBAP&lt;/acronym&gt;, everything is clear. Keep all the client logic on the client, and in the same language as the rest of your code: C#. If you need some info from your database, call a remote procedure using a Web Service. Designing a perfect interface has never been easier: use panels wisely and drop your controls. Bind the numerous events to your actions and the result is there.&lt;br /&gt;&lt;br /&gt;I intentionally did not talk about Adobe Air, which is having a similar approach to the light client problem. It is clearly promising and the example you can find on the Internet are much better and mature than those of WPF. However, even if Flash will keep its advance compared to Silverlight, the fact that Adobe Air uses JavaScript and the efforts Microsoft put into WPF makes me think that it is the right choice to make for most client developments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-3496684377805933339?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/3496684377805933339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=3496684377805933339' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/3496684377805933339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/3496684377805933339'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2008/04/wpf-is-future-of-html.html' title='WPF is the future of HTML'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-6775473794102294206</id><published>2008-03-21T17:11:00.008+01:00</published><updated>2008-04-02T11:37:20.235+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>COMException when opening WebApplication project</title><content type='html'>&lt;p&gt;I recently go the following error while opening a Visual Studio solution: "System.Runtime.InteropServices.COMException". Not very explicit, is it?&lt;/p&gt;I found a page in &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=317124"&gt;VisualStudio feedback&lt;/a&gt; explaining that this is a bug in Visual Studio 2008, that should be corrected "in the next release"...&lt;br /&gt;&lt;p&gt;The explanation is that VS is trying to locate your Web Application in IIS. Look into your project file *.csproj in the &amp;lt;WebProjectProperties&amp;gt; section, the searched URL is indicated in the &amp;lt;IISUrl&amp;gt; tag.&lt;/p&gt;The solution is simple: in the &amp;lt;UseIIS&amp;gt; tag change "True" to "False" and your project will open like a charm.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-6775473794102294206?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/6775473794102294206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=6775473794102294206' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/6775473794102294206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/6775473794102294206'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2008/03/comexception-when-opening.html' title='COMException when opening WebApplication project'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-2874689361821862563</id><published>2007-07-04T07:55:00.000+02:00</published><updated>2007-07-04T08:14:03.727+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='Form&apos;n&apos;Field'/><title type='text'>Form'n'Field jQuery plug-in published</title><content type='html'>After long nights of fine tuning and restructuring, the first public version of the &lt;a href="http://jquery.com/plugins/project/formnfield"&gt;Form'n'Field&lt;/a&gt; plug-in for jQuery is available.&lt;br /&gt;&lt;br /&gt;It helps JavaScript developers to handle client-side forms by giving access to field values in real types and not only strings as returned by DHTML. Why should the value of a checkbox be a string? Isn't it more natural that it is a boolean?&lt;br /&gt;&lt;br /&gt;The same applies to listboxes. I often generate listboxes when item names are labels and item values are IDs from by database. Why would I have to convert those IDs from and to strings? I want them to be integers, and that's what the Form'n'Field plug-in does.&lt;br /&gt;But what is the most advanced feature about this plug-in is how extensible it is. You can add your own input type (like a date input with pop-up calendar) easily. Or your complex data type (a JavaScript structure) can be associated with any existing input and handle type conversion and validation.&lt;br /&gt;&lt;br /&gt;This plug-in is currently in production in my organization, and I hope that people will understand its value and constructively participate in its development.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-2874689361821862563?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://jquery.com/plugins/project/formnfield' title='Form&apos;n&apos;Field jQuery plug-in published'/><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/2874689361821862563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=2874689361821862563' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/2874689361821862563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/2874689361821862563'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/07/formnfield-jquery-plug-in-published.html' title='Form&apos;n&apos;Field jQuery plug-in published'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-4156930601320834167</id><published>2007-06-27T15:34:00.000+02:00</published><updated>2007-06-27T16:09:25.785+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Methodology'/><title type='text'>Structuring JavaScript libraries: modularity</title><content type='html'>JavaScript pop up calendar is a common need, so why does none of the libraries I found match my needs. With Ajax are we often adding an "auto suggest" feature, so why isn't there a library that works in all the situations like auto complete, JavaScript dropdown lists and on-the-fly search boxes?&lt;br /&gt;&lt;br /&gt;The answer is simple, all those libraries try to conceal the apparently contradictory needs that are generalization and customization.&lt;br /&gt;&lt;br /&gt;We need to generalize to have calendar functions that can be used in all the situations without any modification. To achieve that we strip from the library all the features that are specific to a given case. We end up having a library that does almost nothing, like simply returning days of a month organized in a 7 days &amp;times; 6 weeks grid.&lt;br /&gt;&lt;br /&gt;We need to customize to have calendars displaying week numbers, allowing date range selection or time picking. To achieve that we add the features, and for each of them a flag that we can activate or not, allowing us to enable the feature only when needed. We end up having a library continuously growing, with numerous parameters and difficult to maintain.&lt;br /&gt;&lt;br /&gt;The JavaScript language allows easy integration of multiple libraries with the notions of callbacks and object oriented programming.&lt;br /&gt;&lt;br /&gt;The idea is simple: define core features and write separate libraries for each of them. Define the data structure that will allow communication between them. Define simple default behaviors for features that can be overridden with additional plug-ins.&lt;br /&gt;&lt;br /&gt;If you use only the core library, you have a simple set of features easy to understand and with few parameters. You can plug more features if you need them. You can rewrite your own plug-in - and only this one - if it does not exactly meet your needs.&lt;br /&gt;&lt;br /&gt;For a calendar, the code feature is to display a date grid. The data structure is a date value, with flags indicating if a date range is selected. The additional plug-ins could be week number information, enabling selection of a month or a year, adding a second calendar for range selection, allowing time picking.&lt;br /&gt;&lt;br /&gt;Each of these plug-ins is obviously small, easy to maintain and debug. You reduce the amount of code to download to the client if you don't use all the features.&lt;br /&gt;&lt;br /&gt;A common mistake is mixing HTML rendering with internal logic. Avoid that at all cost, and eventually make the render engine a plug-in.&lt;br /&gt;&lt;br /&gt;Creating modular libraries may seem more complicated at first look, but forcing you to think of the structure before you start will make your ideas clearer and you will actually reach your goal faster.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-4156930601320834167?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/4156930601320834167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=4156930601320834167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/4156930601320834167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/4156930601320834167'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/06/structuring-javascript-libraries_27.html' title='Structuring JavaScript libraries: modularity'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-5170403737299501892</id><published>2007-06-22T20:59:00.000+02:00</published><updated>2007-06-27T16:10:13.251+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Methodology'/><title type='text'>Structuring JavaScript libraries: documentation</title><content type='html'>Very few developer like to write documentation. The library they write is clear to them and when the hard work of programming is finished, it is difficult to decide to write the documentation. Unfortunately, without a documentation, your library is completely unusable.&lt;br /&gt;&lt;br /&gt;The aim is not to write a long documentation, so the first step is to find what kind of documentation is the most efficient. That means: what is the shortest documentation that will be clear and precise enough.&lt;br /&gt;&lt;br /&gt;The easiest one is to write examples. Find a set of symptomatic and concrete usages of you library. This will help users to start using it.&lt;br /&gt;Later when they will need advanced features, another kind of documentation - the technical reference - is a better choice. The reference shortly describes each function, its parameters and call conditions.&lt;br /&gt;Finally I suggest that you write a global description of the library, its philosophy, and general rules that have to be respected. And put it at the beginning.&lt;br /&gt;&lt;br /&gt;All together, you have a complete documentation that is easy to write.&lt;br /&gt;&lt;br /&gt;The best place for the technical reference is within the source code. Each time you add a new function, write a short description. Each time you modify the function, you won't forget to update the documentation.&lt;br /&gt;&lt;br /&gt;Some would say that in JavaScript, the size of the library is critical for download time and interpretation time. Therefore they don't write comments, write compact code stripping spaces and newlines. The code becomes unreadable and difficult to maintain.&lt;br /&gt;This is true but there is an easy solution. Use the &lt;a href="http://dean.edwards.name/packer/"&gt;JavaScript compactor&lt;/a&gt; and provide two versions of your library: the full documented code useful for learning and debugging, and the compacted file for production use.&lt;br /&gt;&lt;br /&gt;You don't have any excuse not to write a good documentation. It is not that difficult and you will be the first to benefit from it when you will later reuse the library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-5170403737299501892?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/5170403737299501892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=5170403737299501892' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/5170403737299501892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/5170403737299501892'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/06/structuring-javascript-libraries_22.html' title='Structuring JavaScript libraries: documentation'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-1744178427795740081</id><published>2007-06-20T17:36:00.000+02:00</published><updated>2007-06-27T16:10:13.251+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Methodology'/><title type='text'>Structuring JavaScript libraries: namespaces</title><content type='html'>When you write a JavaScript library, it is important to respect some rules if you want that the library is widely adopted.&lt;br /&gt;&lt;br /&gt;The first rule is to avoid conflicts with other JavaScript. This is called leaving the smallest footprint. That means that global variables and functions should be avoided, because another library could accidentally use the same name. The best way is to define a single variable which contains all your code like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;var MyNamespace = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myGlobalVariable:23,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myFunction:function(x){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return x * x + this.myGlobalVariable;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You should only choose a unique "MyNamespace" that nobody else will happen to use. And if a conflict happens, you only have to change a single name on one place to resolve it.&lt;br /&gt;Then you call your function like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;var y = MyNamespace.myFunction(4);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There is even a way to leave no footprint at all by hiding your code into an anonymous function:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var tDays=['Monday','Tuesday','Wednesday'];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (var i=0; i&amp;lt;tDays.length; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(tDays[i]);&lt;br /&gt;})();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The drawback is that you can not reference that code from outside.&lt;br /&gt;&lt;br /&gt;The second important rule is to write a documentation, and I will detail it in another post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-1744178427795740081?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/1744178427795740081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=1744178427795740081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/1744178427795740081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/1744178427795740081'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/06/structuring-javascript-libraries.html' title='Structuring JavaScript libraries: namespaces'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-6095549950453658638</id><published>2007-06-14T12:49:00.000+02:00</published><updated>2007-06-27T16:10:13.252+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Methodology'/><title type='text'>Typed variables in JavaScript</title><content type='html'>JavaScript is a rather permissive language, and it lets you write code without annoying you with variable declaration or typing. It is good for simple functions like this:&lt;br /&gt;&lt;pre&gt;function selectOptionByValue(oSelect, value){&lt;br /&gt;    oSelect.selectedIndex = -1;&lt;br /&gt;    for (i = 0; i &lt; oSelect.options.length; i++){&lt;br /&gt;       if (oSelect.options[i].value == value){&lt;br /&gt;          oSelect.selectedIndex = i;&lt;br /&gt;          break;&lt;br /&gt;       }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;with the following HTML:&lt;br /&gt;&lt;pre&gt;&amp;lt;select id="qualitySelect"&amp;gt;&lt;br /&gt;    &amp;lt;option value="0"&amp;gt;Bad&amp;lt;/option&amp;gt;&lt;br /&gt;    &amp;lt;option value="1"&amp;gt;Average&amp;lt;/option&amp;gt;&lt;br /&gt;    &amp;lt;option value="2"&amp;gt;Good&amp;lt;/option&amp;gt;&lt;br /&gt;&amp;lt;/select&amp;gt;&lt;/pre&gt;&lt;br /&gt;if you call:&lt;br /&gt;&lt;pre&gt;selectOptionByValue(document.getElementById('qualitySelect'), 2);&lt;/pre&gt;&lt;br /&gt;the "Good" option is selected.&lt;br /&gt;&lt;br /&gt;But what really happened? The function compared the value "2" associated with "Good" with the integer 2.&lt;br /&gt;This is convenient as you don't have to think of it, it works.&lt;br /&gt;&lt;br /&gt;But in more complex projects, this permissiveness can make debugging extremely difficult. If you assigned a variable that you were considering as an integer with a string value, all your next processing will fail, but JavaScript will not complain. So a bug that could be detected early arises much later, in a completely different place.&lt;br /&gt;&lt;br /&gt;There is not a single solution for this, as JavaScript is not a compiled language where the compiler could signal incorrect type assignments.&lt;br /&gt;The first thing is to declare all variables with "var".&lt;br /&gt;If you want to compare two values in a typed way, use === instead of == and !== instead of !=. '2' == 2 is true where '2' === 2 is false.&lt;br /&gt;&lt;br /&gt;A good starting point is to use a tool like the free &lt;a href="http://www.jslint.com/"&gt;JSLint&lt;/a&gt; that warns you about all the risky code that could hide potential bugs.&lt;br /&gt;This will not eliminate all the bugs from your code, but help you concentrate on the logic instead of the syntax.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-6095549950453658638?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/6095549950453658638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=6095549950453658638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/6095549950453658638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/6095549950453658638'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/06/typed-variables-in-javascript.html' title='Typed variables in JavaScript'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-2531200691969149036</id><published>2007-06-05T13:45:00.000+02:00</published><updated>2007-06-27T16:10:34.655+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Methodology'/><title type='text'>JavaScript Closures and memory leaks</title><content type='html'>You sometimes use techniques unconsciously, and you discover it later when trying to  locate a bug. Closures in  JavaScript is one of those. If you create functions dynamically, you often create a closure:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;function formatMoney(sFormat){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return function(iAmount){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return sFormat.replace('[amount]',iAmount);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;var formatEuro=formatMoney('[amount] €');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;var formatDollar=formatMoney('$[amount]');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;alert(formatEuro(12)+' - 'formatDollar(23));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;displays "&lt;span style="font-family:courier new;"&gt;12 € - $23&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;You can notice that the &lt;span style="font-family:courier new;"&gt;sFormat&lt;/span&gt; variable, declared outside the function definition is still present when the function &lt;span style="font-family:courier new;"&gt;formatEuro&lt;/span&gt; is actually called. This is possible because JavaScript creates an object with the dynamically created function and its context with the local variables.&lt;br /&gt;&lt;br /&gt;Why does this provoke memory leaks? Well, it shouldn't, as JavaScript has a garbage collector, and the objects created on the fly are freed when needed. But some browsers (IE?) are worse than others on that aspect, and circular references, particularly between JavaScript and DOM objects remain locked.&lt;br /&gt;&lt;br /&gt;Taking care of memory leaks becomes more important as we create Ajax applications that do not jump from page to page, and do not give an occasion to the browser to completely flush its working memory. Badly designed Ajax applications can increase the memory used by your browser to a point that locks your computer completely.&lt;br /&gt;&lt;br /&gt;A good article at &lt;a href="http://www.ibm.com/developerworks/library/wa-memleak/"&gt;ibm.com&lt;/a&gt; explains what are the common patterns leading to memory leaks, and a few solutions to avoid them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-2531200691969149036?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/2531200691969149036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=2531200691969149036' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/2531200691969149036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/2531200691969149036'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/06/javascript-closures-and-memory-leaks.html' title='JavaScript Closures and memory leaks'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-2592117726117840825</id><published>2007-05-31T08:54:00.000+02:00</published><updated>2007-07-04T08:20:36.281+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='Form&apos;n&apos;Field'/><title type='text'>Handling forms in the browser</title><content type='html'>With the increased use of Ajax, form handling has evolved. Even if user needs are the same, the developer has new constraints faced repeatedly. There is obviously a need for a JavaScript library solving the following points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;filling a form with data. Now that data is dynamically loaded with Ajax, the HTML form is empty and data, often provided as a complex object, has to be transferred, types converted, etc.&lt;/li&gt;&lt;li&gt;field validation is not a new problem, but calling a server-side validation function on each user action is not a fast enough solution. Calling it when the field loses focus is too late as it forces the user to get back.&lt;/li&gt;&lt;li&gt;extracting data on user submit, converting them again to a complex object to be sent by Ajax.&lt;/li&gt;&lt;/ul&gt;Doing these steps for each form increases the code size and the potential bugs, and quickly becomes boring...&lt;br /&gt;&lt;br /&gt;As I am working with jQuery, I started looking at existing libraries, and some of them actually solve some of these points, but partially.&lt;br /&gt;The first library to look at is the "official" &lt;a href="http://www.malsup.com/jquery/form/"&gt;Form plugin&lt;/a&gt;. Unfortunately the main aim of that library is only to submit forms with Ajax instead of a normal POST request. Sending data with Ajax is for me a separated task, as all forms are not necessary sent to the server.&lt;br /&gt;Other libraries offer form validation, like the recent &lt;a href="http://dnaide.blogspot.com/2007/05/validationaide-easy-as-client-side-form.html"&gt;ValidationAide&lt;/a&gt;, but are either poorly isolated from other functionalities or reduced to a set of regular expressions.&lt;br /&gt;&lt;br /&gt;As often when a need is not satisfied, I decided to build my own library with the following features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;handling of form content filling and reading&lt;/li&gt;&lt;li&gt;field validation&lt;/li&gt;&lt;li&gt;separation between form and field functions&lt;/li&gt;&lt;li&gt;no functions for submission (rather using jQuery+JSON functions or AjaxPro)&lt;/li&gt;&lt;li&gt;no superfluous features&lt;br /&gt;&lt;/li&gt;&lt;li&gt;full customization available, with lot of default behaviors&lt;/li&gt;&lt;/ul&gt;and naturally the library will be offered to the community.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-2592117726117840825?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/2592117726117840825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=2592117726117840825' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/2592117726117840825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/2592117726117840825'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/05/handling-forms-in-browser.html' title='Handling forms in the browser'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-7883847820367558834</id><published>2007-05-29T15:53:00.000+02:00</published><updated>2007-05-30T03:49:26.902+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='AjaxPro'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>A bridge between JavaScript and C#: AjaxPro</title><content type='html'>It is now very common to JavaScript programmers to call remote procedures on the server, either directly using the &lt;span style="font-family:courier new;"&gt;XMLHttpRequest&lt;/span&gt; object or a framework ensuring cross-browser compatibility.&lt;br /&gt;What is then missing is the server-side machinery able to answer the request. You have to parse the request parameters, process data and build a return value as a string or an XML document. It is relatively simple as long as you are using basic types, but gets complicated if you want to pass a custom object or a DataGrid.&lt;br /&gt;If you are lucky enough to be using .NET, here comes &lt;a href="http://www.ajaxpro.info/"&gt;AjaxPro&lt;/a&gt;. You create an .aspx page with a public class &lt;span style="font-family:courier new;"&gt;MyClass&lt;/span&gt;. Add a public method &lt;span style="font-family:courier new;"&gt;MyMethod&lt;/span&gt; with the attribute &lt;span style="font-family:courier new;"&gt;[AjaxPro.AjaxMethod]&lt;/span&gt; and that's all. You are now able to call your remote method from JavaScript &lt;span style="font-family:courier new;"&gt;MyClass.MyMethod(...)&lt;/span&gt; just like if it was locally on client-side.&lt;br /&gt;&lt;br /&gt;The best part for me is the following: the AjaxPro project manager is planning to make it compatible with jQuery, i.e. make AjaxPro generate JavaScript proxies with the jQuery framework. This will lead the ease of programming and abstraction level one step further.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-7883847820367558834?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.ajaxpro.info/' title='A bridge between JavaScript and C#: AjaxPro'/><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/7883847820367558834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=7883847820367558834' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/7883847820367558834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/7883847820367558834'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/05/bridge-between-javascript-and-c-ajaxpro.html' title='A bridge between JavaScript and C#: AjaxPro'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420624415326144044.post-7637442073003136831</id><published>2007-05-26T14:49:00.000+02:00</published><updated>2007-05-30T03:12:49.306+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Discovering jQuery</title><content type='html'>To ensure cross-browser compatibility in my web sites, I used to use the library from &lt;a href="http://www.cross-browser.com/x/lib/"&gt;cross-browser.com.&lt;/a&gt;&lt;br /&gt;It has interesting features, like providing a "compiler" that extracts only the functions your page actually uses from the library and builds a customized compressed JavaScript file. The form of this library is rather classical, you have a set of functions that you call when needed, no classes or object oriented programming.&lt;br /&gt;&lt;br /&gt;I recently discovered &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;, a JavaScript framework that is a bit more complicated to use, but that allows you much shorter and often quicker code. I recommend it for larger projects. The philosophy is rather different, and explanations would be too long here.&lt;br /&gt;&lt;br /&gt;It also has a standardized way of adding libraries, which resulted in a long list of features developed by the community. One of them is &lt;a href="http://interface.eyecon.ro/"&gt;Interface&lt;/a&gt; allowing animation, drag&amp;amp;drop and many other things with incredible ease.&lt;br /&gt;&lt;br /&gt;As I continue using jQuery will I post remarks and tips here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420624415326144044-7637442073003136831?l=blog.befruit.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/7637442073003136831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1420624415326144044&amp;postID=7637442073003136831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/7637442073003136831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420624415326144044/posts/default/7637442073003136831'/><link rel='alternate' type='text/html' href='http://blog.befruit.com/2007/05/discovering-jquery.html' title='Discovering jQuery'/><author><name>BeFruit Team</name><uri>http://www.blogger.com/profile/07166424819143422703</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10520582249882168377'/></author><thr:total>0</thr:total></entry></feed>