LinkPost – April 2009
It's that time again... Another month has gone by, another post to tell you what you may have missed.
This month I decided to actually group the links into categories to make it easier to find what you are interested in (go me!). The offerings of links this month include two CMS options that aren't WordPress, fonts, fonts, and you guessed it more fonts, some free themes, some jQuery offerings, Web-Server testing and security links, Some adobe AIR goodness, and more. So get your ctrl-click (command-click for you mac'ies), or for you talents mouse users, your middle-click ready.
Print This Post
Pop-ups, the interweb, and you
The problem*: You have a page with a pop-up, and when you click a link on it, it needs to change the page that spawned it.
I searched everywhere and every result listing let me down. Site after site was bitter disappointment, I searched for 'pop-up close child window redirect parent', then 'pop up change parent', and 'pop up child link change parent window'. I did find some useful code like the 'onunload' event (we'll cover that another time
). I finally stumbled onto the solution by mashing up a few different solutions that were posted for javascript events and the mysterious 'window' method built into the base js library*².
The solution (#1): This solution is for those who want to keep the pop-up open, or just want parent only manipulation (yeah, you can always manipulate the child (pop-up), but solution 2 is soooo much easier for that).
First, let's build a method to handle pop-ups.
function popWindow(url, myWidth, myHeight, myScrollbars, myTop, myLeft, myMenubar, myResize) { window.name = "main"; /* setting this is the key to letting you manipulate the parent window */ window.open(url, "","width="+myWidth+",height="+myHeight+",scrollbars="+myScrollbars+",top="+myTop+",left="+myLeft+",menubar="+myMenubar+",resizable="+myResize+",bgcolor=#ffffff"); } |
Note that we used "window.name" and set it to "main". This allows me to reference the parent window from any child windows (pop-ups). Now that we've done that, in our pop-up window we just need to make the link have a target of "main". Like so:
<a href="http://fakedoman.com/newpage.html" target="main">Change the parent window!</a> |
Now this comes together on your parent page, you click a link that uses the popWindow function that creates the pop-up that can now reference the parent by the name "main".
The solution (#2): This is the show, the heat, the expletive, the new hotness, and the fresh burnination. Ok, fine, it's old code that's been around forever that everyone on the internet forgot about (or at least didn't blog, write, post, etc).
In your pop up window, build a method like this in your script section (or included js file).
function openParent(webAddress){ opener.location.href=webAddress; window.close(); }; |
Wow... 2 lines (4 if you count the open and closer of the function), simple, easy. Why has no one told anyone else about this*³ ? Now the only thing left is to call that function in an "onclick" event in your a-tag.
<a href="javascript:void(null);" onclick="javascript:openParent('http://fakedomain.com/newpage.html');"/> |
Yes, I pointed the href to "javascript:void(null);", the onclick event will overwrite the original href call anyway, so this is how you build the link to keep the code valid to W3c standards.
And that, my friends, is how you code a pop-up window that will change the parent window with a link from the pop-up window.
* Yes I heard all of you grumblers in the back saying 'change the target in the a-tag to "_top" and that'll solve your problem. And you know what? yeah, in 1998 that would have worked. However these days our pop-ups are javascript based, and not so frames/iframe-y.
*² This statement could very well be false... in fact it's made up, I'm not sure if it's built in, I really can't back that up, yeah, total b.s. and yet the code works in IE6, IE7, IE8, Opera 9.63, Safari 3, Firefox 2, Firefox 3, and Chrome... so that kinda seems "built-in", or at least understood and interpreted correctly by most browsers.
*³ It could be that pop-ups in legitimate sites really aren't all that common, and generally the people who use them on their sites are spammers/malware/spyware vendors and should be dragged out in the street and beaten while having their selling slogans chanted and shouted at them (isn't that a pleasant picture you just painted in your head? your welcome).
Print This Post
Extracting Email Addresses in Outlook with a macro
So for the last few days I've been working on a problem that seems fairly common throughout the e-marketing world. The problem arises when you send out your marketing email blasts and then all the bad email addresses (but they're not all bad!) come bouncing back. Obviously we want to remove those from the mailing list, but we don't want to walk through thousands of emails to get the bad addresses, but at the same time not all the emails bounced back were bad (out of office replys, etc).
So I've found some programs that allow you to extract email addresses from the different fields of your emails, but all the ones I've tried ONLY can get the address from an actual MailItem. What if there is a message that isn't a MailItem? Well, that was my problem so that option didn't work. I'm not sure exactly what kind of Item it is but it is an Item. (just for the record MailItem and Item are actual VB objects in outlook for more info Go Here)
So here is some code that I've come up with after overhauling some examples that I saw. This macro will:
- Look in the currently open folder
- Will open up an Excel worksheet
- Check for some common keywords that show up only in the bad emails(they are easy to change)
- and stick all the email addresses it finds from those emails in the Excel sheet.
It also has a little progress count in Excel's status bar so you know it's still thinking (I hate it when you can't tell a script is running).
Note: So far this has only been tested in Outlook 2007, but I don't see any reason why it won't work in 2003. We'll be testing that shortly.
Sub Extract_Invalid_To_Excel()
Dim olApp As Outlook.Application
Dim olExp As Outlook.Explorer
Dim olFolder As Outlook.MAPIFolder
Dim obj As Object
Dim stremBody As String
Dim stremSubject As String
Dim i As Long
Dim x As Long
Dim count As Long
Dim RegEx As Object
Set RegEx = CreateObject("VBScript.RegExp")
Dim xlApp As Object 'Excel.Application
Dim xlwkbk As Object 'Excel.Workbook
Dim xlwksht As Object 'Excel.Worksheet
Dim xlRng As Object 'Excel.Range
Set olApp = Outlook.Application
Set olExp = olApp.ActiveExplorer
Set olFolder = olExp.CurrentFolder
'Open Excel
Set xlApp = GetExcelApp
xlApp.Visible = True
If xlApp Is Nothing Then GoTo ExitProc
Set xlwkbk = xlApp.Workbooks.Add
Set xlwksht = xlwkbk.Sheets(1)
Set xlRng = xlwksht.Range("A1")
xlRng.Value = "Bounced email addresses"
'Set count of email objects
count = olFolder.Items.count
'counter for excel sheet
i = 0
'counter for emails
x = 1
For Each obj In olFolder.Items
xlApp.StatusBar = x & " of " & count & " emails completed"
stremBody = obj.Body
stremSubject = obj.Subject
'Check for keywords in email before extracting address
If checkEmail(stremBody) = True Then
'MsgBox ("finding email: " & stremBody)
RegEx.Pattern = "\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b"
RegEx.IgnoreCase = True
RegEx.MultiLine = False
Set olMatches = RegEx.Execute(stremBody)
For Each match In olMatches
xlwksht.Cells(i + 2, 1).Value = match
i = i + 1
Next match
'TODO move or mark the email that had the address extracted
Else
'To view the items that aren't being parsed uncomment the following line
'MsgBox (stremBody)
End If
x = x + 1
Next obj
xlApp.ScreenUpdating = True
MsgBox ("Invalid Email addresses are done being extracted")
ExitProc:
Set xlRng = Nothing
Set xlwksht = Nothing
Set xlwkbk = Nothing
Set xlApp = Nothing
Set emItm = Nothing
Set olFolder = Nothing
Set olNS = Nothing
Set olApp = Nothing
End Sub
Function GetExcelApp() As Object
' always create new instance
On Error Resume Next
Set GetExcelApp = CreateObject("Excel.Application")
On Error GoTo 0
End Function
Function checkEmail(ByVal Body As String) As Boolean
Dim keywords(25) As String
keywords(0) = "Delivery to the following recipients failed"
keywords(1) = "user unknown"
keywords(2) = "The e-mail account does not exist"
keywords(3) = "undeliverable address"
keywords(4) = "550 Host unknown"
keywords(5) = "No such user"
keywords(6) = "Addressee unknown"
keywords(7) = "Mailaddress is administratively disabled"
keywords(8) = "unknown or invalid"
keywords(9) = "Recipient address rejected"
keywords(10) = "disabled or discontinued"
keywords(11) = "Recipient verification failed"
keywords(12) = "no mailbox here by that name"
keywords(13) = "This user doesn't have a yahoo.com account"
keywords(14) = "No mailbox found"
keywords(15) = "not our customer"
keywords(16) = "mailbox unavailable"
keywords(17) = "Mailbox disabled"
keywords(18) = "mailbox is inactive"
keywords(19) = "address error"
keywords(20) = "unknown recipient"
keywords(21) = "unknown user"
keywords(22) = "mail to the recipient is not accepted on this system"
keywords(23) = "no user with that name"
keywords(24) = "invalid recipient"
'Default value
checkEmail = False
For Each word In keywords
If InStr(1, Body, word, vbTextCompare) > 1 Then
checkEmail = True
Exit For
End If
Next word
End Function |
PS - I also learned a valuable lesson to not trust regular expressions that people post in forums, but that's another story.
Print This Post
Time for more jQuery goodness
No, it's not what you think. I'm not posting some grand tutorial on how to re-animate the dead with jQuery... at least not yet. What I am going to do is post a few things that I either stumbled into, or had to figure out for myself while using jQuery.
1st - Sometimes you may find yourself writing huge functions, or the like, in which you continually use the selector " $(this) ". There's nothing wrong with that, I use it all the time. However something you really should keep in mind is that every time you call that selector, you are throwing more drag on the cpu/browser/rendering of your site. How do you alleviate this problem? simple, just set the $(this) selector into a variable.
/* how not to code */ $(document).ready(function(){ $(this).doSomething(); $(this).click(function(){ $(this).runMore(); }); $(this).yepEvenMore(); }); /* how you should code */ $(document).ready(function(){ var $this = $(this); $this.doSomething(); $this.click(function(){ $this.runMore(); }); $this.yepEvenMore(); }); |
2nd - This really should be a no-brainer, but after spending over 15 minutes trying to get the selector to work (and browsing several jQuery sites, checking my cheat sheets, etc.) I finally found the answer to using a selector within a selector. I believe the answer came from the jQuery google-group. It was as simple as the following example.
$("#left label[for=" + $this.attr("id") + "]").addClass('active'); |
You can see that I had a div with an id of 'left' and I wanted a particular label inside that div to have a class of 'active' applied to it. This worked with a click event (not shown).
3rd - What happens when you have some images that when clicked you want to change the value of a form? Say for example that you have some logo's of credit cards that when clicked on you want to change a select box in your form to show the value of that credit card? The solution for this one I couldn't find anywhere on the interweb, so I spent plenty of time figuring this one out. It works, and I'm fairly happy with it. NOTE: you must be using jQuery 1.3+ to make this work, the changes made in this version of jQuery allow you to do this type of selector.
$("#payment-type-ful img").click(function(){ var card = $(this).attr('alt'); $("#policyId").val(card); }); |
Yep, there's a div with an id of 'payment-type-ful' and I need any images under it, and when clicked on I set up a variable called 'card' that is set to the alternate text of the clicked-on image. I then select the input select and set the current value to 'card'. Simple? oh yeah, easy, absolutely.
That sums up a few quick little jQuery gems that I've been using recently. As per usual, if you have any questions, comments, or tips of your own, feel free to throw them in the comments, thanks!
Print This Post