Saturday, January 31, 2015
Date Arithmetic
I am working this weekend on a major data migration. I have several millions records to manipulate, store, and index. I needed a way to calculate how long the process was going to take. Once I had it in hours, I still needed an easy way to figure out the end time. Instead of trying to do the math in my head, I figured there had to be a site that would calculate that for me. Sure enough there is and it's nicely done. Here's a link: http://www.timeanddate.com/date/timeadd.html.
Labels:
Data Migration,
Utilities
Thursday, December 11, 2014
Making Lists into To-Do Lists with jQuery
I have a folder containing several procedures that are in written with HTML lists. I wanted a way to quickly modify them so that I could check off each line item as I went through the procedure. And as I checked off the line items, I wanted it to strike through the text to make it clearer that that step had been done.
The first thing I did was define a CSS class:
.strikethrough {
text-decoration: line-through;
}
Then I added this JavaScript to my header file:
function strikethrough(element) {
var $checkbox = $(element);
if ($checkbox.prop("checked")) {
$checkbox.parent().addClass("strikethrough");
}
else {
$checkbox.parent().removeClass("strikethrough");
}
}
$(function() {
var checkboxCode = "<input type='checkbox' onclick='strikethrough(this)' style='margin-right: 10px' title='Mark this item done' />";
$("li").each(function() {
$(this).html(checkboxCode + $(this).html());
});
});
Here is a demo on CodePen along with the source.
Tuesday, September 23, 2014
A Better Geolocation Prompt
Derek Featherstone makes a good point: The current implementation of the geolocation prompt on most browsers does not give enough information. Wouldn't it be nice if we could provide more information to the user as to why we need this information from them? I would love to see something in JavaScript like this:
if (navigator.geolocation) {
var geolocationApproved =
navigator.geolocation.prompt("This information will be used to provide you with directions to xyz.");
}
would produce something like this:
Labels:
Geolocation,
JavaScript
Friday, September 19, 2014
Show "loading" icon for long running AJAX calls only.
If an AJAX call is slow, then I want to present a "loading" overlay to let the user know the process is still working. However, on short calls, it is distracting to the user to flash the "loading" overlay and then immediately remove it. This code allows me to specify a time (in milliseconds) for how long to wait before showing the spinning wheel.
http://codepen.io/clarmond/pen/mvalt
http://codepen.io/clarmond/pen/mvalt
Tuesday, October 29, 2013
Oracle Equivalent of MySQL's LIMIT (Or how to page results in Oracle)
I'm really just posting this for my own benefit but if you're reading this and it has been helpful, drop me a comment to let me know.
SELECT
*
FROM (
SELECT
a.*,
ROW_NUMBER() OVER (ORDER BY column_to_sort) rn
FROM
my_table a
WHERE
my_column_to_filter = 'my_value_to_filter'
)
WHERE
rn >= my_starting_row AND rn <= my_ending_row
Thursday, September 26, 2013
Evaluating Backreferences in Oracle REGEXP_REPLACE
Here's the problem. I want to use Oracle's REGEXP_REPLACE function to replace a string of digits with a zero-padded string. In Perl I would do it like this:
So to get around this, I wrote another function called evalpad. With this, I do the replacement in 2 steps. The first is to replace the string with an embedded pad psuedo-function. Then I call a second function to do the actual replacement. Here's the code:
#--- Change xyz123 to xyz000123
my $string = "xyz123";
$string =~ s/(\d+)$/sprintf("%06d", $1)/e;
So here is what I started with in Oracle PL/SQL:
my_string := 'xyz123'
regexp_replace(my_string, '(\d+)$', lpad('\1', 6, 0));
And what I got was xyz0000123. What I discovered was that the LPAD function was being evaluated before the backreference (\1) was. So no matter what I did, the LPAD function always saw the string to be padded as 2 characters long.
So to get around this, I wrote another function called evalpad. With this, I do the replacement in 2 steps. The first is to replace the string with an embedded pad psuedo-function. Then I call a second function to do the actual replacement. Here's the code:
create or replace function evalpad (
strIn in varchar
)
return
varchar
as
retval varchar(255);
arg1 varchar(50);
arg2 varchar(50);
padded_number varchar(100);
begin
retval := strIn;
while (regexp_instr(retval, 'pad\((\d+)') > 0) loop
arg1 := regexp_substr(retval, 'pad\((\d+)');
arg1 := regexp_replace(arg1, 'pad\(', '');
arg2 := regexp_substr(retval, 'pad\((\d+),\s*(\d+)');
arg2 := regexp_replace(arg2, 'pad\((\d+),\s*', '');
padded_number := lpad(arg1, arg2, 0);
retval := regexp_replace(retval, 'pad\((\d+),\s*(\d+)\)', padded_number, 1, 1);
end loop;
return retval;
end;
Then in my original function I do this:
my_string := 'xyz123' regexp_replace(my_string, '(\d+)$', 'pad(\1, 6)'); my_string := evalpad(my_string);
Thursday, April 18, 2013
Catching and Logging JavaScript Errors
As browser-based applications become more JavaScript centric, it becomes harder to debug user issues. For years I have been logging and handling server side errors, but only recently have I started logging JavaScript errors. And it turns out the solution was very simple.
First, the JavaScript code. Near the top of my main JavaScript file that I include on every page of my application, I put this code that I found online and modified for my own use. I should note here that I am using jQuery (and you should to).
For now this will blindly send me error reports in the background. But in the future I would like to pop up a form to the user to get more information such as asking what they were trying to do when they got the error. I built a prototype using the jQuery UI dialog module. However, I need to work out some more UX questions like:
- How often do I ask for input especially if it's an error they are getting on every page?
- Should I pilot this dialog to select users first?
- Would a live chat with tech support be an option (using web sockets)?
First, the JavaScript code. Near the top of my main JavaScript file that I include on every page of my application, I put this code that I found online and modified for my own use. I should note here that I am using jQuery (and you should to).
window.onerror = function(m,u,l){
$.post(
basePath + "/js_error.cfm",
{
msg: m,
url: u,
line: l,
window: window.location.href
}
);
return true;
}
All this code is doing is catching untrapped errors and posting them to a page on the server. Now for the server-side code:
The ColdFusion script write the error to a log file and then emails me the report.#errorReport#
For now this will blindly send me error reports in the background. But in the future I would like to pop up a form to the user to get more information such as asking what they were trying to do when they got the error. I built a prototype using the jQuery UI dialog module. However, I need to work out some more UX questions like:
- How often do I ask for input especially if it's an error they are getting on every page?
- Should I pilot this dialog to select users first?
- Would a live chat with tech support be an option (using web sockets)?
Labels:
ColdFusion,
Error Handling,
JavaScript,
jQuery