Wednesday, October 17, 2007

Spry Slide Not Working - text disappears

Today I was trying to add a simple Spry slide effect to some text on one of my web sites, however the text dissapears in IE7. I managed to cut it down to the most basic code where the problem occurs and it turns out to be a table cell. I took the slide example and cut it down until it doesn't work. This code works fine in Firefox. If you remove the table tags, it also works in IE7. However, with the table tags present, the text doesn't show up at all in IE7 (although the background color does slide up and down). This is using Spry 1.6 prerelease.

Here's the code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional-dtd"&gt; <html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Spry Slide Effects Sample</title>
<link href="../../css/samples.css" rel="stylesheet" type="text/css" />
<script src="../../includes/SpryEffects.js" type="text/javascript"> </script>
<style type="text/css">
.animationContainer

{
height: 220px;
}
.demoDiv

{
background-color: #CCC;
height: 200px;
overflow: hidden;
}
.hideInitially

{
visibility: hidden;
}
</style>
</head>

<body>
<table><tr><td>
<form method="get" action="grow_sample.html"><input type="button" onclick="slide_hidden.start();" value="Slide Example" /></form>
<div class="animationContainer">

<div class="demoDiv hideInitially" id="example5">
<p><strong>Example - Slide from 0% to 100% in 2 seconds</strong>
<br />Lorem ipsum dolor sit amet, consetetur sadipscing elitr, seddiam nonumy eirmod tempor invidunt ut labore et dolore magnaaliquyam erat, sed diam voluptua. At vero eos et accusam etjusto duo dolores et ea rebum. Stet clita kasd gubergren, nosea takimata sanctus est Lorem ipsum dolor sit amet.</p>
</div>
</div>
<script type="text/javascript">

var slide_hidden = new Spry.Effect.Slide('example5', {duration: 500, from: '0%', to: '100%', toggle:true});
</script>
</td></tr></table>

</body>
</html>

It turns out, if you put the <script> tag below the </table>, everything works fine.

Wacky...

By the way, also if you set the .hideInitially div to "display: none" instead of "visibility:hidden", the same error occurs (in IE7 only). In my opinion, display: none would be much more useful than visibility: hidden. I was able to work around it by using two Spry slide effects - one that only happens when the page loads and initially closes the text (setting it to display:none) and the other that the user clicks on to open and close the text after that.

Hopefully they'll get these issues fixed in the next release of Spry.

Wednesday, October 10, 2007

Community Server Blog Post Approval Process

One thing glaringly absent in Community Server is the ability to have multiple blog authors with an approval process. The idea would be to have a blog writers who must submit their blog posts to a blog administrator for publishing. I've been looking into a solution for this and came up with one that should meet our needs for now.

My idea was to add a new role that would be able to save a blog post, but wouldn't have access to the publish button. To do this, I modified the CreateEditBlogPost.ascx file in \ControlPanel\Blogs\ to hide the publish button for everyone except a specific blog administrator role. Here's the code:

<CSControl:ConditionalContent runat="server">
<ContentConditions>
<CSControl:UserInRoleCondition Role="Solutions Blog Administrator" UseAccessingUser="true" runat="server" />
</ContentConditions>
<TrueContentTemplate></TrueContentTemplate>
<FalseContentTemplate><div style="display: none"></FalseContentTemplate>
</CSControl:ConditionalContent>
<strong><CP:resourcelinkbutton id="PostButton" runat="server" resourcename="CP_Blogs_CreateEditBlogPost_Post" CssClass="CommonTextButtonBig" /></strong></div>

This code would go at the bottom of the CreateEditBlogPost.ascx file where the publish button is now. As you can see, I just hid the publish button using a div with display:none in every case except when the user's role is "Solutions Blog Administrator". This allows me to specifically set who can publish to the blog while still allowing everyone else to write to the blog. Now I should be able to write a csmodule that will send an e-mail to the administrator(s) whenever a new blog is posted so they know they need to review the post and publish it.

Ideally there would be a permissions set into Community Server so I wouldn't have to hardcode the admin role. I'm also not sure how it will hold up once we have multiple blogs (and different administrators for each). But, this should work for now.

Tuesday, October 09, 2007

Extending content to the bottom of the window

Here's a nifty little bit of javascript that extends the content of a container (in this case, a td with id "shadow" and a div with id "contentarea") to the bottom of the browser window, regardless of the height of the window. The first function gets the height of the browser and the second function does the extending.

You can see it in action at http://www.equitiesfirst.com.

//Gets the height of the browser window
function getheight() {


var myHeight = 0;


if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myHeight = window.innerHeight;
}
else if( document.documentElement && ( document.documentElement.clientWidth document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myHeight = document.documentElement.clientHeight;
}
else if( document.body && ( document.body.clientWidth document.body.clientHeight ) ) {
//IE 4 compatible
myHeight = document.body.clientHeight;
}
return myHeight;
}

//Extends the content to the bottom of the browser window

function adjustHeight()
{

if (document.getElementById) {
var targetElement=document.getElementById('shadow');

//extend the shadows
targetElement.style.height=String(getheight())+'px';

//extend the content area (minus the header area)
targetElement=document.getElementById('contentarea');
targetElement.style.height=String(getheight()-413)+'px';
}
}

window.onresize=adjustHeight;
window.onload=adjustHeight;

Tuesday, March 06, 2007

Flex 2 Custom Preloader and Flash Integration

I still see a lot of people using the default preloader for Flex in their Flex 2 applications (including me). However, it's possible to customize the loading screen before your Flex app appears. Ted Patrick has a post with some nice examples of using gif, png or even swf files as a preloader:

Flex 2 Preloaders

Ted's examples just use simple graphics and animation, however you can integrate Flash into Flex to create a really nice preloader. You can also integrate Flash throughout your Flex application for consistency (or for added pizzazz). Jesse Randall Warden has a good article on this as well as a nice example on the third page of his article:

Integrating a Flash Interface into Flex 2

Monday, March 05, 2007

Blog posts to remember

Rather than taking up space in my crowded bookmarks folder, I thought I'd just blog these two posts and reference them from here.

Sean Moore has posted an Actionscript 2.0 to Actionscript 3.0 migration cheatsheet which I may find very useful in the near future. He's also got a lot of other cheatsheets on his site. If you haven't gotten a chance to check them out I recommend you do.

Actionscript Migration Cheatsheet

Also, Alex Ulhmann has updated his distortion effects component. I made some modifications to the first version of his component to create a iTunes-type image scroller in Flex (sorry, it's not online... yet). I'm looking forward to seeing what he's done to improve it and what new things I can do with it.

Distortion Effects

Monday, February 26, 2007

Unable to connect to endpoint: {wsdl path}

I was getting this obscure error while trying to insert data from Flex 1.5 into a database using a WebService and a stored procedure. Despite the error message, it likely has nothing to do with connection issues between Flex and your WSDL. More likely, it is due to a coding error. You may be trying to pass a complex object into a simple data type (either in your WSDL or in SQL). For me though, I don't think this was the case.

The problem for me ended up being that I was passing null data (the user, me, had left the input box blank), into a stored procedure that expected data. The weird thing was that if I put a space (or any other character) into that field and then deleted that space before submitting the form, it would go through fine. The error would only occur if I never entered (or deleted) anything in that field at all.

Anyways, I was able to fix it simply by putting a default value into my input variable in the stored procedure (in this case, a space):

@city varchar(100) = '  '

Thursday, February 22, 2007

Could not load WSDL: 500 java.net.SocketException: Connection reset

I'm in the process of building a Flex 1.5 app that calls two web services on another server. Frequently while testing the app, I would get hit with this error:

Could not load WSDL: 500 java.net.SocketException: Connection reset

It seemed to happen most often when first loading the app, although it occasionally happened while in the middle of using the app as well. I'm pretty sure it happened every time I made a change to the mxml code. Sometimes none of the data would load in the app when the error occurred and sometimes the data from one of the WSDLs would load (but not the other). To fix it, sometimes I could refresh the page or retry the action and it would work fine, but other times nothing I would do would fix it except for... clearing my browser cache, which would fix it every time. However, in a production environment, that wouldn't do.

The Internet was pretty quiet on the issue. One suggestion I found for related issues was to update the flex-config.xml file and set the <maxconnections> in the proxy section to 0 (unlimited - the default is 50). That didn't seem to help me though. However, I did find a way you can turn the WSDL proxy off, by adding useProxy="false" to the <mx:Webservice> tag. This did the trick for me. Make sure if you do this that you create a cross domain policy file on your WSDL server otherwise you won't be able to access them anymore. Adobe recommends that you use the proxy unless you have a good reason not to.

Writing a session variable or cookie from Flex

One limitation of Flex is that you're not able to create session variables or cookies using actionscript. Flex and Flash do have their own cookie substitute, Local Shared Objects, however LSOs can only be used within the Flex app that created them and they definitely can't be read by the browser itself.

But let's say you have a situation where you have a user login in your Flex app and you want that login to carry over to other pages on your site. The website already contains it's own login which creates a session variable or cookie to determine whether the user has been logged in. What you want to do is create that same variable when the user logs into your Flex app so that when they browse to other pages in your site they stay logged in.

This can be solved pretty easily using a hidden frame on the same page as your Flex app. Just add a simple iframe tag to your page:

<iframe name="loginHide" frameborder="0" width="700" scrolling="no" height="0"></iframe>

Then create a page that accepts login info in the query string and uses that info to create the session or cookie (the same as your login page). When the user logs in to your Flex app, send the login info to the page you created and target the hidden iframe:

getURL("loginHidden.aspx?userName="+userName+"&password="+password, "loginHide");

Voila! The variable is created. Of course, this is only one way to do it. If your Flex app exists in a popup window, you could just use javascript in your getURL function to refresh the popup's parent page, sending it the login info in the query string the same way. Or you could even send the login info to any page (target="_blank"), if you don't mind a new web browser window opening when the user logs into your flex app. The hidden frame gets around this problem though.