All posts by Pavel Chuchuva

About Pavel Chuchuva

I help coaches to deliver group programs.

Using Asual jQuery Address plugin for photo gallery

Click here to view demo

Let’s say you want to build photo gallery. Something like this:

You want to open next and previous photos without page reload, using Ajax. One problem with this is that browser’s back button stops working. Fortunately, it’s easy to fix with jQuery Address plugin from Asual. I tried using this plugin and it worked very well. I’ve put together a simple demo.

For simplicity, let’s display just a number instead of actual photo:

Every time you click right arrow the number increases; left arrow decrements the number by one. Simple! Back and forward buttons should work. Also, it would be nice to have different titles in the history:

The code:

$(function () 
{
  $.address.strict(false);
  $.address.externalChange(function(e)
  {
    switchTo(e.value);
  });

  $("#lnk_prev").click(function(e)
  {
    e.preventDefault();
    var i = $("#number").text() * 1 - 1;
    switchTo(i);
    $.address.value(i);
  });

  $("#lnk_next").click(function(e)
  {
    e.preventDefault();
    var i = $("#number").text() * 1 + 1;
    switchTo(i);
    $.address.value(i);
  });
});

function switchTo(i)
{
  $("#number").text(i);
  $.address.title(i);
}

The magic happens in click handler. $.address.value method changes page address and adds browser history point. You need to cancel navigation by calling e.preventDefault() — otherwise browser would follow the link and two history entries would get created.

Note that you need to disable plugin’s strict option, otherwise it would add slash symbol immediately after hash symbol, like this: #/11.

Enhancement to launching PowerShell scripts from Far Manager

The method of launching PowerShell scripts from Far Manager I have described previously has 2 important drawbacks:

  1. You can’t pass arguments to the script, and
  2. You can’t launch script in a separate window

Here’s how to fix this:

  1. Start regedit, open HKCR\Microsoft.PowerShellScript.1\shell\Open\command key
  2. Set it to
    "C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" %*

Now you can press Shift+Enter to start PowerShell script in a new window.

As a bonus, you can now double-click .ps1 files in Windows Explorer to launch them. Why is this not a default behaviour? Most likely Microsoft decided to be extra cautious here.

Make sure you have Powershell version 2.0 or higher for this to work. How to check Powershell version.

How to redirect output of console program to a file in PowerShell

At some stage I decided I need backup plan for my virtual server. After some intensive web surfing I found brilliant command line tool – s3.exe. The next step was to schedule to run it periodically, every night, when everybody is sleeping.

Night

I decided to use PowerShell. It’s new, it’s powerful, it comes pre-installed with Windows Server 2008. PowerShell is very popular among system administrators.

Also, I got an idea to save output of backup application to log file so that I could see results later. And this is where things didn’t work as I expected. Here’s how to redirect console program output to a file:

s3.exe > log.txt

If you run this you will be surprised to find that log.txt is empty. As it turns out s3.exe, being a good Windows citizen, writes errors to STDERR stream. To redirect error output to the same file you need to add magic string 2>&1:

s3.exe 2>&1 > log.txt

Two new problems appear. First, errors appear as exceptions in log file:

s3.exe : s3.exe version 1.6 - check for updates at http://s3.codeplex.com
At PS Logging.ps1:4 char:43
+ s3.exe <<<<  2>&1 > log.txt
    + CategoryInfo          : NotSpecified: (s3.exe version ...s3.codeplex.com
   :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

PowerShell helpfully wraps STDERR output into exceptions. This is nice but I don’t need it! All I want is to see how a program worked by examining log file. Do this to unwrap exceptions and show plain text:

s3.exe 2>&1 | foreach-object {$_.ToString()} | Out-File log.txt

And second, errors are out of order with normal output. They could appear before or after normal lines emitted by a program, making it hard to diagnose problem. To confirm that, I created a simple console program:

static void Main(string[] args)
{
   for (int i = 0; i < 10; i++)
   {
      Console.WriteLine("Hello");
   }
   Console.Error.WriteLine("Bah bah");
   for (int i = 0; i < 10; i++)
   {
      Console.WriteLine("2");
   }
}

If you run this program from PowerShell and redirect output to a file, error message (bah bah) could appear anywhere in the log file:

Hello
Bah bah
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
2
2
2
2
2
2
2
2
2
2

The solution I came up with is to let old reliable cmd.exe to do the work:

cmd /c s3.exe `>log.txt 2`>`&1

Note backsticks – I use them to prevent PowerShell from parsing redirect operators.

Links

PowerShell ABC’s – O is for Output
How to capture exe output to a PowerShell variable
Another approach to unwrap exceptions: use add-content cmdlet.

How to open .docx and .xlsx files from Far Manager

If you try to open Office 2007 document (.docx or .xlsx) in Far Manager it will simply open them as a ZIP archive. Clearly, that’s not what you want. Here’s how to fix it:

  1. Go to Commands › File association.
  2. Create a new association by pressing Ins.
  3. Enter *.doc;*.docx;*.xlsx;*.pptx as a mask.
  4. Enter @"!.!" as Execute command (used for Enter).

File associations in Far Manager

You can still open docx file as an archive by pressing Ctrl+PgDn.

Idea for my business

Idea for my business is quite simple: web gallery for wedding photographers. Here’s how it works:

  1. Photographer uploads photos after the wedding.
  2. Friends and relatives view photos. Some of them order reprints generating extra money for photographer.
  3. Photographer pays me a monthly fee.

How did I come up with this idea? I was looking for an idea for my own software product for a long a time. Then, in one of the books I read an interview with Joel Spolsky where he recommended creating a niche product. As an example he suggested creating a photo manager specifically for wedding photographers instead of photo manager for everybody. And I thought to myself: heck, that’s not a bad idea, I’ll try to execute it.

Surely, there are other products that do the same thing. This doesn’t stop me. If my execution is at least half-good, I should get some clients. I’m aiming at creating a small Italian restaurant on the web, not a global chain of fast food franchises.

Middle-click in Far Manager 2

In Far Manager 1.70 you could browse folders with mouse wheel. Rotating wheel would scroll up and down. Middle-click would open a folder. But version 2.0 disables middle-click. Boo! Never take away features from users.

Mouse wheel

Fortunately it’s very easy to restore this functionality:

  1. Launch [C:\Program Files\Far2\Addons\Macros\MiddleClickAsEnter.reg]. If you don’t have this folder re-install Far and add Addons » Macros feature.
  2. Restart Far Manager.

How to add context menu to Far Manager

Sometimes I need to do something with file that Far Manager can’t help me with. Good example is changing file permissions. In these cases Windows Explorer context menu comes handy:

far-context-menu

If you want context menu in Far Manager you need EMenu plugin. Fortunately, it is included with Far by default. Here’s how to set it up:

  1. Execute [C:\Program Files\Far\Plugins\EMenu\Hotkey.reg]
  2. Restart Far Manager
  3. Open Options menu, then Plugins configuration. Select EMenu in the list.
  4. Uncheck “Show message after execution”.

Now Menu key should invoke context menu. Nice trick is to select Send To – Mail Recipient to quickly open new email with the file attached.

How to use ClientScriptManager.RegisterForEventValidation method

Have you ever encountered this error:

Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation=”true”/> in configuration or <%@ Page EnableEventValidation=”true” %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

That’s pretty long error message. I get this exception if I add items to drop-down control from JavaScript. The question is how to use ClientScriptManager.RegisterForEventValidation method?

First, let’s reproduce the problem. Create a new website and copy/paste this code:

<asp:DropDownList ID="dd" runat="server">
  <asp:ListItem>One</asp:ListItem>
  <asp:ListItem>Two</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" Text="Test" />

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
  type="text/javascript"></script>
<script type="text/javascript">
  $(function()
  {
    $("#<%= dd.ClientID %>").append($("<option />")
      .val(3)
      .text("Three!"));
  });
</script>

If you select option “Three” sure enough, exception is thrown. To prevent it you need to supply all possible values for drop-down control:

protected override void Render(HtmlTextWriter writer)
{
  Page.ClientScript.RegisterForEventValidation(dd.UniqueID, "3");
  Page.ClientScript.RegisterForEventValidation(dd.UniqueID, "4");
  Page.ClientScript.RegisterForEventValidation(dd.UniqueID, "11");
  // and so on
  base.Render(writer);
}

The exception is fixed but server variable for drop-down control is useless – it has no idea that you’ve added new item so dd.SelectedValue will give One, not 3. You need to read POST variable directly instead, like this:

protected void Page_Load(object sender, EventArgs e)
{
   if (IsPostBack)
      Response.Write(Request.Form[dd.UniqueID]);
}