Archive for the ‘Experiments’ Category

Get Table Cell Height’s with Javascript

March 7, 2007

Before I begin, I’ve only tested this using Firefox on a Mac, but it should work in any browser…

I’ve seen a lot of people trying to find out the height of a table cell, and I have on many occasions have tried myself only to give up. You can get the height of a cell, but it’s always going to be the height you set it to, not the height it becomes after data has been placed into it and it expands. What a pain, right? Well, I’ve found a solution to this problem, though it involves a few DIVs and javascript.

So, say you have this:

<td>
	a really long string of text that takes up multiple
	lines and you have no way of knowing how tall this TD
	is.
</td>

Instead of that, change it to:

<td>
	<div id="content_top"></div>
	<div id="content">
		a really long string...
	</div>
	<div id="content_bottom"></div>
</td>

See where I’m going? We have pretty much created two points to measure by… the content_top DIV and the content_bottom DIV. Now, how do we measure them?

Whenever we need the height, we call a function, say getTDHeight(). getTDHeight looks something like this:

function getTDHeight(){
	contentTopDiv = document.getElementById("content_top")
	contentBotDiv = document.getElementById("content_bottom")
	contentTop = getPixelsFromTop(contentTopDiv);
	contentBottom = getPixelsFromTop(contentBotDiv);
	contentHeight = contentBottom - contentHeight;
	alert("The cell height is " + contentHeight);
}

So basically we are asking a function called getPixelsFromTop to give us the number of pixels the element “content_top” is from the top of the browser window. The same for the element “content_bottom”. With this, we’ll have something like content_top = 100 and content_bottom = 350. So we take the top value away from the bottom and that leaves us with the height of the cell… 250px

The getPixelsFromTop function is no biggie either:

function getPixelsFromTop(obj){
	objFromTop = obj.offsetTop;
	while(obj.offsetParent!=null) {
		objParent = obj.offsetParent;
		objFromTop += objParent.offsetTop;
		obj = objParent;
	}
	return objFromTop;
}

All it does is constantly adds the objects location from the top of it’s parent container, then loops up to that parent and repeats until it hits the top of the DOM, then returns the value.

Here is the code working.

Hope this helps. I’ve seen a lot of frustration over this on many forums. I know it’s a pain, but at least it is possible.

Using AJAX to navigate previous/next pages?

November 7, 2006

I was on Digg the other day, scrolling, clicking next, scrolling some more, clicking next again, and then it hit me; with all the really great stuff we can do now with AJAX, why haven’t I seen anything to change this saw tooth process going through lists? This had me thinking and so I decided I wanted to try some things. I created a Digg-like mock site with a bunch of fake data. My only gotcha is that I want to assume the site knew how many items have been added since my last visit, say 150.

oldway_1.jpg

Our main area is a scrollable DIV filled with news (ok, it’s randomly generated letters and numbers just so I could quickly populate a database). There is a slim, timeline-like DIV below it that show us: How much is loaded (the green area), how much we can see (the red area), and what we have yet to see/load (the white area).

oldway_2.jpg

As we scroll down, notice the red area moving to show us where we are in the list of news items.

oldway_3.jpg

As we close in to the end of the list, our request is called to deliver more content. A yellow area now appears in the timeline to show us that something is loading.

oldway_4.jpg

The new request is complete and the new news items are added to our scrollable area. The timeline updates to reflect what’s load and where we are in them.

After developing that, I felt like the only thing I accomplished was duplicating what the scrollbar already does, so that’s not really any help. The only unique thing it does, is gives us a timeline-like measurement of how far we are into the unseen results. However, that information can easily be conveyed with a line of text much like: 30 of 150 items shown. It was overkill.

So, I thought maybe I should simplify it a bit, and only alert the user that something is loading, as such:

newway_1.jpg

Here we have a regular looking page with a regular looking scrollbar.

newway_2.jpg

As your scrolling nears the bottom of the DIV, a loading DIV appears to give the user visual feedback that additional content is loading.

newway_3.jpg

Now that the additional content is loaded, it is placed in the scrolling DIV after the existing content (notice the scroll bar change) and the loading DIV hides.

Each new delivered segment is wrapped in a DIV as well, so if I wanted to keep the list from getting too long, I could just remove the older DIVs and re-fetch them if the user scrolls up.

I want to think about this some more, I’ve a few other ideas. I hope putting this out there will spark some really good ideas. What’s yours?

Edit

Here’s some ideas from Ajaxian.

LinkPut – Wiki’d Search Results

November 4, 2006

A little over a year ago I was really getting frustrated with search results. I consider myself a pretty good searcher, it’s not often that I have to go beyond a page or two to find what I’m looking for, but the “blurbs” that describe the link are sometimes so cryptic they border on pointless. Also at the time, I was really fascinated with wikis and loved the way their community comes together to develop something very understanding about any topic. One afternoon, will searching around on Google, I had the idea of combining a search engine with a wiki… what would happen if the result blurbs could be publicly modified to better reflect the content of the site? With that in mind, I began experimenting with a project I called LinkPut – Input for Links.

Project Technicals

  • This project was originally written in ASP/SQL Server, and then rewritten in PHP/MySQL. Because it was my first PHP project, once I began learning more and more, I decided to rewrite it once again, taking into account all the new stuff I learned from my first round.
  • The search results use the Yahoo API. Yahoo allowed for more requests per day than Google; at least at the time, I don’t know if that is still true.
  • Originally it was called WikiSearch, but that sounded too much like a search engine that crawled wikis, which is misleading. The database is still named after this original title.

LinkPut Homepage

1-homepage.jpg

This is the LinkPut homepage. Not a typical search engine homepage interface, but I wanted to display recent activity of the site. With that in mind, I display:

bullet_1 The last URL that has been wiki’d
bullet_1 The last comment made to a URL
bullet_1 Various site stats such as number of sites wiki’d, request made to Yahoo, click throughs, tags, etc.
 

LinkPut Search Results

2-searched.jpg

After you perform a search, the Yahoo results come through. They are parsed and displayed. However, if we find that our database has an edited blurb, it is displayed instead of the normal one returned from Yahoo, as indicated by displaying the LinkPut logo versus the Yahoo logo.

bullet_1 Logo displaying where blurb is coming from
bullet_1 The wiki’d blurb
bullet_1 Other information about the site that has been collected, such as your last visit, tags, who edited the blurb last… this information is customizable so that you can show whatever you wish, including both Yahoo and LinkPut’s blurbs.
bullet_1 User controls for this URL:

  • Link to comments about this URL
  • Link to the wiki editor for this URL
  • Link to bookmark this site with Delicious
  • Link to an RSS feed so that you can monitor edits to this URL
bullet_1 Other results
 

Visited Site Questionnaire

3-site_review.jpg

If you visit a site via LinkPut, on your next visit, you are asked to rate various aspects of the site. This data is collected to help better define sites. Of course, answering these questions is completely optional.

bullet_1 The site questionnaire. Questions include:

  • Did this page contain the information you were looking for?
  • Would you recommend this site to other users?
  • Did the description accurately reflect the contents of the page?
  • How were the ads/pop-ups on this page?
  • What type of site was this? (Arts/Humanities, Business, Computers, Health, etc.
  • Add your own tags.
 

More Information

4-more-info.jpg

Clicking on more information about a site brings you to this page. Here, you can read a more detailed description of the site, tag it, or leave a comment.

bullet_1 Site title and URL
bullet_1 LinkPut also performs a URL shortening service to give you shorter links for long, complex URLs.
bullet_1 Wiki’d entry for URL
bullet_1 Common tags and input area for you to tag the URL
bullet_1 Link to wiki editor or submit URL to Delicious
bullet_1 Commenting area
 

Wiki Editor

5-edit-info.jpg

This is the Wiki Editor page. Here the user finds a very simplified wiki type editor for making changes to the entry.

bullet_1 Description/Blurb area
bullet_1 Pointer Area: If this page shares many characteristics of another page, a pointer could be set up so that this page uses the Wiki entry of another. The pointer must point to a URL from the same domain.
bullet_1 Notes about the last edit
bullet_1 Notes about the edit you are currently doing
bullet_1 Change History with links to roll back to previous versions
 

Search History

6-search-history.jpg

This is the history of sites you’ve visited via LinkPut.

bullet_1 Delete option
bullet_1 Date visited
bullet_1 Site information
bullet_1 Query you used at the time
bullet_1 Links to:

  • Add to Delicious
  • Monitor via RSS
  • Edit wiki entry
 

Tag Search

7-tag-search.jpg

You can search LinkPuts tagged sites from this page. Since this site is a search engine, I wanted to do a little something different with the tag search rather than duplicating the normal search functionality of the site.

bullet_1 Tags you are currently filtering with. Tags are weighed from left to right, so controls under each tag allow you to rearrange (or remove) them.
bullet_1 Add a new tag to the filter and specify if you want to look at just your tagged sites, or the communities tagged sites.
bullet_1 The results of the search that displays all LinkPut gathered information for a URL.
 

Tag Marks – Collapsed

8-tag-marks.jpg

TagMarks, a name I came up with because this page sorts your tagged URLs much like you would manage your bookmarks in your browser. You create a hierarchy of tags like you would a folder structure. Say for instance you create a tag folder called Politics and one called Tech. Any URL you tagged with Politics will appear in that folder, and all URLs tagged Tech appear when you expand that folder. Inside the Tech folder, you can create sub folders, say Web and OS, so anything you tagged Tech, Web appears in the appropriate folder. I found it to be a great way to browse through your tagged items.

bullet_1 Root level tag folders
bullet_1 Input to add another tag folder
bullet_1 Controls for this folder:

  • Number of sites in this folder
  • RSS feed of links in this folder
  • Edit tag(s) used for this folder
  • Ability to delete a folder
 

Tag Marks – Exapnded

9-tag-marks-expanded.jpg

This is the tagged folder expanded to show its contents. Users could have up to 5 levels of folders to really focus their tagged content.

Finally

I’ve had some ideas lately on how to improve LinkPut and wanted to have this post available to reference you to when I start going into some of them. In any case, I hope you found some of these ideas interesting.

dID: Fill out any form, any where, with one click

October 26, 2006

There are countless rants about every web site out there requiring you to create an account. Who isn’t turned off with creating logins, logging in, requesting lost passwords and the like? Yeah, I know… most places I could click the “remember me” button, but I’m a developer, I’m constantly clearing my cache and cookies. Hey, I’m easily forgettable… and I think only once in my professional career have I ever written down a password. It’s a big mess.

Ok, so what about other things that I’m constantly doing out over and over and over again like my address? What if I had a system that had all the data I wanted to put in there, then when I went to any form, on any site, I just clicked a button and my info is there, submitted, and I’m moving on. Yeah, that’s exactly what I wanted… so I thought about it for a few days and then developed for about 2 weeks, calling the project danielID, or dID for short.

dID consisted of three major parts:

  • There was the dID web site, where you would ::gulp:: log in and create your profile. It was broken down into various areas such as personal, business, etc. Also, here you could find logs where you’ve sent your data, who is requesting your data, etc.
  • The dID Firefox extension. My first attempt at writing an extension, and while I didn’t get far (just enough to get it to work) it was very interesting stuff. Basically, the extension runs in your tool bar and anytime you are on a page with a form, clicking it would analyze the form and fit as much as your info into it that it could.
  • The third piece was just a pretty interface, launched by a bookmarklet, which would give you greater control over the forms on a page. It was geared towards volunteers wanting to help the project by aligning data at dID to data at a site. For instance, dID may have you first name mapped to fname and firstname, the site you are on has a form with a first name field, but its named first_name. With this control panel, a volunteer could map that field name to our field for first names.

So, that last bullet also tells you a bit about how the system worked. At the dID site, you fill in as much information about yourself as you like. Each field, like above, fname, is mapped to various possibilities of what that field is called (at other sites). When you are at some other site, on a form page, the form DOM is collected and sent to dID, which is parsed, associated with dID fields, and the real data is sent back, into the proper form fields. Here’s an example:

form_01.jpg

Above is a mock up web site, with two form fields in it. Also in the shot is the Firefox extension. Currently, it displays two options; Button to fill in the form, or a drop down to select which form you want to focus on. If you don’t focus, dID will try to fill in both.
 

form_02.jpg

bullet_1 We drop down and mouse over a form on the page with the name of “search”.
bullet_2 The search form highlights to show us which one it is.
 

form_03.jpg

bullet_1 Ok, that wasn’t the form we wanted to fill out, so we select the contact form.
bullet_2 The contact form highlights
 

form_04.jpg

bullet_1 Now we click on the button to fill in the form. The extension sends the form object back to us, we analyze it, and return associated data.
bullet_2 Data that we have mapped populates itself into the form.
bullet_3 Fields that are not mapped are highlighted to the user so that they can fill them out. If the form fills out 100%, it is automatically submitted.
 

When I was building this, and I saw it work for the first time, I was completely blown away. Don’t you love those moments?

The bookmarklet opened a small version of the dID site. With the popup, you could monitor your information, fill out forms, or contribute to the dID mapping system. For instance, here are a few screenshots:

popupwin-good-ready-to.jpg   Here we see the control panel that is looking at a page that has a form we recognize (noted by the green checkmark). We get a bit of info about the site and form. We also have tabs here so we can easily update our data, prefs, etc.
 
popupwin-unknown-form.jpg   Now we have surfed to a page were dID is not familiar with the form. Maybe there is no form; maybe the form is in flash… In any case, if there is a form here that we are not seeing, the user has the option to report it to us.
 
popupwin-broken-link.jpg   Now we are back on a page with a form we “kind of” know about, but someone has reported it as broken.
 

One other big plan for dID was having a user PIN number, called an idSN, that you can give sites that they would use to get your information from us. They could do away with their forms and request data about you (that you specify is ok for such uses) whenever they needed it. With that, the following ideas were on the drawing board.

  • If you want to unregistered from a service: We can’t guarantee a service will remove you from there system, we can block further requests of your data from them.
  • If you wanted a site to have access to a block of your information for a limited period of time, you could set up an idSN that would expire – you choose data you wish to give and expire time, idSN is generated…
  • Allow site owners to pull info about users that are members of their site. Nothing that is identifiable to a single person, but trends and demographics to make their support of dID worthwhile.
  • Users can report abuses from services accessing their data…

There was a ton of other ideas, all very interesting stuff, but eventually I dropped the project. Once I saw that I COULD do (that’s the fun part to me), I decided the security issues involved with it would be over my head. And yeah, cookies, and browser auto-fills do ‘some’ of this, but that wasn’t the point. The point was it sounded like an interest idea and a cool challenge, and I like those! :)

My slideshow application for a Web 2.0 Office

October 13, 2006

A recent post on Techcrunch about Preezo, which looks GREAT by the way, and all the talk lately of Zoho/Google Office had me reminiscing of a slideshow tool I was working on very recently.

The slideshow project was born from a web based courseware development tool I’m developing for work. It started as a concept of what a version 2 would be like; in the current tool, you have to select predefined page layouts, but I want users to place content elements where ever they wished.

Once I had a great div positioning, scaling, content defining system, I thought it would be great as a way to set up slide shows… and from there, in any spare time I had, I developed my prototype slideshow builder.

Slideshows Directory
This is a directory of all your current slideshows. The link will take you to the editor for that slideshow. In the future, there would be controls to allow live sharing of the show (collaborative viewing) and ways to embed the slideshow in a blog or social network.
1.jpg

bullet_1 Icon to open control panel for adding a new slideshow.
 

Slideshows Directory w/Control Panel to add a new show
This is the directory page again, showing the “add show” control panel.
2.jpg

bullet_1 Close/Cancel adding a new slideshow.
bullet_2 Save Slideshow.
 

The Slideshow work area
The work area for a slide show. It consists of 3 parts: A list of slides in this show, general comments for this show, and the slide work area.
3.jpg

bullet_1 Icon to add slides.
bullet_2 Icon to add comments.
bullet_3 Icon to add container elements to a slide and the current slide selected name.
bullet_4 Icons to play slide show, debug (for testing) and to go back to Presentation Directory.
 

Adding a slide to a show
Clicking the green (+) in the slides area will open the New Slide Control Panel.
4.jpg

bullet_1 New Slide dialog.
bullet_2 Slide title.
bullet_3 Slide type: Normal Slide (Text/Images/Etc.) or RSS Slide (talked about below).
bullet_4 Save Slide Icon.
 

Adding a comment to a slide show
Clicking the green (+) in the comment area will open a New Comment Control Panel.
5.jpg

bullet_1 Slides that have been added.
bullet_2 Controls for the slides include: Delete, Sorting and Preferences for each Slide.
bullet_3 A comment window for collaborating on slideshow creation.
 

A successfully added comment
Displays a comment added to the current slide, or in reference to the entire slideshow if no slide is currently selected. The Slides and Comments area constantly looks for new data and refreshes as needed to make sure two or more people working on a show always see the latest work from their collaborators.
6.jpg

bullet_1 Comment added at Presentation root level. Comments appear only where they are taken. A comment taken on slide “Introduction” will not appear on slide “Summary”.
 

The work area for a selected slide
Now that a slide is selected, the slide work area becomes active so we can begin to build our slide.
7.jpg

bullet_1 Selected slides title appears over the work area.
bullet_2 New Icons appear for help creating the slideshow.
 

Preferences Control Panel for a slide
Each slide has a preferences control panel that you can use to define that slide (or set as a global for all slides)
8.jpg

bullet_1 Slide Preferences have been click for the current slide.
bullet_2 Preference include: Time, Background and Duplicate Slide with room to add more functionality as needed.
 

Preferences Control Panel – Time Controls
Accessing the time controls for a slide in the slide control panel.
9.jpg

bullet_1 Time Preference selected.
bullet_2 Option for when to change slide: On click, or based on number of seconds.
bullet_3 Option to specify number of seconds to wait until the slide changes, if option selected.
bullet_4 Option to apply these settings to all slides.
 

Preferences Control Panel – Background Controls
Accessing the background (image/color) controls for a slide in the slide control panel.
10.jpg

bullet_1 Background Preference selected.
bullet_2 Option to use an HTML color code for background.
bullet_3 Option to specify an image hosted on the web as the background.
bullet_4 Option to apply these settings to all slides.
 

Adding a Container to a slide
The data on a slide is made up of various containers. For example, you may have a container for each bullet point, or for an image.
11.jpg

bullet_1 Adding a container to the slide.
bullet_2 Container Name.
bullet_3 Container Type: Text, Image, Flash, Video.
bullet_4 Background has been set to the image we linked to above.
 

A successfully added container
The container shows up onscreen after being added with controls to modify it.
12.jpg

bullet_1 Our container now appears.
bullet_2 Option to delete the container.
bullet_3 Options to edit content of container / drag it elsewhere on screen.
bullet_4 Option to scale container to desired size.
 

The container alignment grid
To help align items properly, there is a grid that can be displayed behind all containers.
13.jpg

bullet_1 We can turn on a grid to help us align our containers.
 

Editing content (text) of a container
A rich text editor is available for creating the perfect copy for the presentation.
14.jpg

bullet_1 Our container is aligned where we want it.
bullet_2 The Edit Container Content button.
bullet_3 The Edit Container Content Control Panel. This container is a text element, so it brings up the text editor.
 

A container with it’s content
15.jpg

bullet_1 Our text content is saved in the container.
 

Adding an image container
16.jpg

bullet_1 Adding another container with type set to Image.
bullet_2 The Edit Container Content button.
bullet_3 The Edit Container Content Control Panel. This container is an image element, so it brings up the image link area.
 

Successfully showing an image container
17.jpg

bullet_1 The image is now loaded into the container.
 

Scaling container media content
18.jpg

bullet_1 As the container scales, so does the image.
 

Container Control Panel
Kind of like Layers in Photoshop, each container on this slide is listed out here.
19.jpg

bullet_1 The container management (for this slide) button.
bullet_2 The container management window, displaying all containers and their settings.
bullet_3 Type.
bullet_4 Location (from top).
bullet_5 Location (from left).
bullet_6 Width.
bullet_7 Height.
8.jpg Edit Icon.
 

Editing containers from the Control Panel
Each container can be hidden, or its settings edited.
20.jpg

bullet_1 The image container was hidden.
bullet_2 The Text container is being edited so all settings become editable.
bullet_3 Save Icon.
 

Setting up an RSS based slide
A pretty unique feature, I think, is the ability to use RSS to populate slide content. With this, the presentation could be a live document that is always changing based on current, for instance, sales figures.
21.jpg

bullet_1 This page is an RSS generated page, as specified when created.
bullet_2 RSS Icon, grayed out because no feed has been selected for this page.
bullet_3 RSS Feed Control Panel.
bullet_4 URL of RSS feed.
bullet_5 Number of ITEMs from the RSS feed to display – effectively, how many times this slide will loop with different data from the feed.
bullet_6 Save button.
 

RSS nodes creating containers
Slide showing all nodes of and item element defined as containers. This examples used a feed from Digg.
22.jpg

bullet_1 Now that the Feed has been selected and saved, it is checked out and a container is created for each items node. Now you can arrange the feeds data as you wish.
 

Deleting a container
Example shows how a user would delete a container.
23.jpg

bullet_1 Nodes (or any container) that you don’t wish to use can be deleted. Confirmation is required.
bullet_2 The system highlighting the container you are about to delete so no mistakes are made.
 

RSS Node Containers positioned as needed
With the nodes aligned as wished, the next step would be to set font size, colors, etc for the elements. Unfortunately, that step is still on the to-do list. Also, until the slideshow is ran, placeholder data populates the container, it is also noted what node is related to which container.
24.jpg

bullet_1 Slide now as all feed elements desired arranged to the users liking.
bullet_2 The nodes are specified so the user knows what data from the feed is in what container.
 

Adding a comment with a pointer
To help with collaborative commenting, I thought it would be neat to allow a comment to point to an area onscreen that it was talking about.
25.jpg

bullet_1 A comment is added to this slide.
bullet_2 The comment pointer, a tool to help specify what the comment is about, is selected.
bullet_3 A drag-able, rotate-able arrow is displayed on screen to the person leaving the comment and point to the area of the slide he is talking about.
 

Seeing the Comment Pointer
When I am looking at a comment left by someone else, and I mouse over it, the pointer becomes visible so I have a better idea of what is being said in the comment.
27.jpg

bullet_1 When the mouse is over the comment, it highlights and;
bullet_2 The comment pointer appears.
 

The slideshow playing (first slide)
The first slide as seen when the slideshow is playing.
28.jpg

The slideshow playing (RSS slide)
The RSS (first item) slide as seen while slideshow is playing. Formatting needs to be applied to the data.
29.jpg

There is still a ton of work to be done on this. However, I am particularly happy about its progress so far. I really like the RSS feed integrating; I don’t believe anyone else has done that with a slideshow.

Anyone want to fund me finishing this?!? :)