Recently in Javascript Category

Coolite - File Upload Dialog & other breaking changes

|
I think I've mentioned the custom File Upload Dialog for Coolite previously which sadly doesn't seem to work with Coolite v0.8 due to a breaking change that's not mentioned in the Version 0.8.0 -BREAKING CHANGES forum post. In summary, the ParameterCollection object no longer has a "ToJsonObject" method, but this has been replaced/renamed with "ToJson". Changing the source for the file upload dialog and re-compiling resolves this.

I also found that, as mentioned in ScriptContainer location not honoured in 0.8 against 0.7, the behaviour of the Coolite ScriptContainer has changed as it now seems to have been split-out into the ScriptContainer and StyleContainer controls. Easily solved, but no less annoying that I had to spend time doing so.

extJs: Combobox .getValue oddity

| | Comments (2)
At least in extJs version 2.2.1 (the version baked into Coolite v0.8), the getValue function on the Ext.form.ComboBox appears to be thus:

function()
{
  if (this.valueField&&this.forceSelection)
  {
    return typeof this.value!="undefined"?this.value:"";
  }
  else
  {
    return Ext.form.ComboBox.superclass.getValue.call(this);
  }
}
Of interest is the fact that differing code-paths are taken based on the "forceSelection" property. If it's set (i.e. thou shalt choose something from this combo and not enter free-text), then the .value property is used as the return value of the call to getValue, otherwise a call is made to superclass.getValue, which returns something quite entirely different!

Instead of, as expected, returning the "key" value, it returns the displayed value. This is thanks to superclass.getValue being defined as:

function()
{
  if (!this.rendered)
  {
    return this.value;
  }
  var v=this.el.getValue();
  if (v===this.emptyText || v===undefined)
  {
    v='';
  }
  return v;
}
Whilst I've logged this as an "oddity", it is (seemingly) "by-design" as the combo-box allows for user-entered values, which is what the "forceSelection" code-branch causes. That said, I firmly believe that if the "selected value" is one that has been chosen from the contained items, then getValue should return in the same way as it does with forceSelection being false.

Coolite - Colour Picker

| | Comments (2)
(How much effor goes into writing Colour with a U after spending time coding,... argh!)

There's a pretty nice one, that improves on the one that comes with Coolite (the <ext:ColorPalette>) to be found here: Ext.ux.ColorPicker, Ext.ux.ColorPanel and Ext.ux.ColorDialog for ExtJS 2.1

Coolite - "breaks" the IE7/8 X-UA-Compatible meta-tag

|
Coolite, by default will "break" any page that has the <meta http-equiv="X-UA-Compatible" content="IE=7" /> tag in  it, as IE requires the tag to be pretty much the first one in the <head> tag.

Any page that has Coolite components loaded will thus have the Coolite script/CSS tags inserted right at the top of the <head> element. Fear not though, the Coolite ScriptContainer comes to the rescue! By adding this into the <head> element in your page/master page, you can tell Coolite where to insert its tags which thus stops it from breaking the X-UA-Compatible meta-tag.

The blogs.msdn.com/JScript blog

|
Or an exercise in uselessness as it may also be known.

Take a look at the "What's new in JScript for IE8" entry on the Internet Explorer blog, then take a look at the corresponding entry on the JScript blog, they're identical. Except that comments are switched off on the JScript blog as they are on the prior two entries, which aren't even directly related to JScript. In fact, there hasn't been "fresh" (or, original) content on the JScript blog since September 2008's entry on the new JScript debugger. Even that got re-published on the IE blog.

If nothing new or original is being published on the JScript blog, is there any point it being there?

Resolving Coolite objects in client script - 2

|
Previously: Resolving Coolite objects in client script.

There's an attribute you can set (as a proprerty in code, or declaratively in markup) called IDMode on all Coolite components. The valid settings are "Inherit", "Legacy" and "Static". The only one I care about right now is "Static".

With the IDMode set to static the value set as "ID" is persisted, un-mutated, all the way through to the client so it can be used as written in script. Hurrah!

ASP.net Client IDs

|
Finally: ASP.NET 4.0 ClientID Overview.

After having previously moaned about the hassle that ClientID mangling has caused me and trying to work out ways around it, the fact that the ASP.net team are doing something about it is a big fat hurrah from me. So, hurrah!!

Another solution: How-to use ClientIDs in Javascript without the ugliness.

Javascript frameworks and global namespace pollution

|
How cool is this: Global is the new private.

A real-time always up-to-date display of just how much each of the current javascript frameworks pollute the global namespace. Genius.

Miscellanea 1

| | Comments (2)
Why QA is Important, from the people behind Fog Creek Copilot. I really couldn't have put it better myself. My only query with the whole entry would be; why on earth don't the staging servers have SSL on them? A self-generated certificate would be sufficient to avoid the hassle of splashing the cash for staging boxes.

The isFiltered() method of the Ext.data.Store class returns "undefined" when no filter is set or one has been set and cleared, rather than False. Either a duff copy in the Coolite assembly, or what smells like a bug in the implementation. Unless of course a return type of Boolean is now a tri-state of true, false and undefined?

Error on rejectChanges() call on ExtJs store

|
I have an ExtJs store that causes an error to raise when its rejectChanges() method is called. It looks like (from stepping through) that the rowIndex that the underlying ExtJs code is trying to hit is out of bounds. Why, I'm not sure. The closest search result I find took me to Commit/Reject changes in EditorGrid from the ExtJs forums, which was *not* helpful :(

I haven't worked out why it worked (as my code *does* already clear the filter earlier in the execution path), but, adding:

store.clearFilter(true);
Immediately before the call to rejectChanges() works a treat. Go figure!

Resolving Coolite objects in client script

| | Comments (2)
Has anyone found a good way to do this? Or, indeed, is there a trick I'm missing from Coolite? There doesn't appear to be a "Coolite." namespace declared in the same way there's an "Ext" namespace declared/provided when the components are used on a page.

What I want to be able to do is write arbitrary client side javascript (event handlers and suchlike) inside a script block rather than inside an attribute of the server-side tag. The different ways I've discovered are:

Inside tag attributes
This is the tidiest way of writing the code as you get "nice" shortcut referencing of the server-side components like:

  <ext:GridPanel Title="My Grid of Items" ID="myGrid" runat="server" StoreID="itemStore" >
      <ColumnModel>
          <Columns>
              <ext:Column Header="Id" DataIndex="ItemId"/>
              <ext:Column Header="Name" DataIndex="ItemName">
              </ext:Column>
          </Columns>
      </ColumnModel>
      <SelectionModel>
          <ext:RowSelectionModel runat="server" SingleSelect="true">
              <Listeners>
                  <RowSelect Handler=
"#{modifyItemButton}.enable();
#{deleteItemButton}.enable();" /> <RowDeselect Handler=
"if (!#{myGrid}.hasSelection())
{
#{modifyItemButton}.disable();
#{deleteItemButton}.disable();
}" /> <Show Handler=
"if (!#{myGrid}.hasSelection())
{
#{modifyItemButton}.disable();
#{deleteItemButton}.disable();
}" /> <SelectionChange Handler=
"if (!#{myGrid}.hasSelection())
{
#{modifyItemButton}.disable();
#{deleteItemButton}.disable();
}" /> </Listeners> </ext:RowSelectionModel> </SelectionModel> <Buttons> <ext:Button Text="Refresh" runat="server" ID="refreshGridButton"> <Listeners> <Click Fn="refreshGridButton_Click" /> </Listeners> </ext:Button> <ext:Button Text="New" runat="server" ID="createItemButton"> <Listeners> <Click Fn="createItemButton_Click" /> </Listeners> </ext:Button> <ext:Button Text="Delete" runat="server" ID="deleteItemButton" Disabled="true"> <Listeners> <Click Fn="deleteItemButton_Click" /> </Listeners> </ext:Button> <ext:Button Text="Modify" runat="server" ID="modifyItemButton" Disabled="true"> <Listeners> <Click Fn="modifyItemButton_Click" /> </Listeners> </ext:Button> </Buttons> </ext:GridPanel>

Which shows using the "#" shortcut to resolve client-side control names. This doesn't actually do anything client-side, but instead is processed by Coolite as part of the controls rendering and converted into fully qualified names. It also makes for code that's quite difficult to work on as you get no Intellisense/Syntax highlighting, etc, inside the attribute.

<%=ServerControl.ClientID=> jiggery-pokery

The other option is to have a block of code inside your javascript that says something like:

function getMyGrid() { return <%=myGrid.ClientID%>; }
which causes the ASP.net rendering engine to emit the relevant reference. This, rather than using "document.getElementById" works for Coolite created ExtJs components as they're javascript objects that render markup, rather than markup elements with associated javascript. Or at least, that's how it appears from my perspective (Your viewpoint may vary).

The code snippet above seems to generally upset the crap out of the Javascript parsing engine in Visual Studio 2k8 and means you get an irritating yellow warning in the Error List. Changing it to be the following code (yes, eval bad, etc,..) removes the warning:

function getMyGrid() { return eval('<%=myGrid.ClientID%>'); }
What I want

Something similar to "document.getElementById" or ASP.net AJAX's $get/$find pair but for Coolite. It may already be in the Coolite code, but if not, it's going to get written (if at all possible) by me very soon. So, I'll be able to write:

var myGrid = Coolite.getComponent('myGrid');
if (myGrid.hasSelection())
{
// Do something here
}
Without having to worry about the fact that 'myGrid' is stuck in several ASP.net naming containers and is thus actually called ctl00_mainArea_subArea_ctl02_myGrid, or something equally obscure.

extJs: Combobox drop-down is half width

|
I've been battling (on and off) with an extJs combobox not being wide enough for the past few days and finally google has come up trumps for me. The hint about setting "hideMode" to "offsets" seems to solve the problem.

It does seem to cause a new rendering oddity though, the combobox suffering the issue is contained inside of an anchor inside of a form layout inside of the fifth of a set of tab panels. Multiple comboboxes on the first tab (which incidentally is default visible) don't seem to exhibit the problem. The tab the combo is on contains the combo, and a grid with two associated buttons:

<tab>
    <form>
        <anchor>
            <combo />
        </anchor>
        <anchor>
<label />
            <grid>
                <columnModel />
                <buttons>
                    <button1 />
                    <button2 />
                <buttons>
            <grid>
        </anchor>
    </form>
</tab>

When initially rendered, the label for the combo doesn't appear, nor do the buttons for the grid, they in fact do't render until the combo's drop-down is triggered. There's also a noticable lag when the tab is selected between the drop-down button part of the combobox appearing (show straight away) and the main text-box part showing (shows after a second). Grrrr!

extJS: VType for validating a time

|

I needed a VType for validating a time using the extJs framework in the format HH:MM (24 hour clock, no ‘AM’ or ‘PM’) and couldn’t find one that quite fit the bill, so a tweaked version is:

Ext.form.VTypes[“timeVal”] = /^([0-9]|1[0-9]|2[0-3]):([0-5][0-9])$/i;
Ext.form.VTypes[“timeMask”] = /[\d\s:amp]/i;
Ext.form.VTypes[“timeText”] = ‘Not a valid time.  Must be in the format hh:mm”.’;
Ext.form.VTypes[“time”] = function(v)
{
    return Ext.form.VTypes[“timeVal”].test(v);
}

Related Linkage:

Javascript Intellisense, finally!

|

It looks like Visual Studio 200n (aka: Orcas) is finally going to have rich Javascript intellisense, hurrah!

Why, oh why wasn't this implemented in 2005 and I'm not saying that for any reason other than a purely selfish one. If I'd had rich Javascript intellisense it would've made the project I've been working on for the past 6 or so weeks massively less painful!

A Dictionary object in Javascript - Part 2

|
UPDATE (12/2008): Take a look at http://www.4guysfromrolla.com/webtech/100800-1.shtml#postadlink as there were a couple of, erm, bugs in my implementation!