Entries in programming (7)

Thursday
Sep162010

Restoring SQL Express Databases

When I set up my latest computer, I paid special attention to making sure everything was backed up and I am really glad I did.  I had several issues with bad hard drives fairly early on and recently had another issue with some older drives that I have on the computer dying.  The only purpose these other drives had was to store the log files of my SQL Express Databases.   When they died, I actually didn't notice for several days until I tried to access one of these databases for some work on a development project.  All of my databases were offline.

Luckily I had set up an automated backup off all of the DBs.  Getting this setup using the Free SQL Express isn't obvious and requires (or at least helps to have) a great app that is out there called ExpressMaint.  This lets me run a Scheduled task that automatically backs up all my databases.   Those backups are then backed up by windows backup to a USB hard drive and by Carbonite online.

These databases were easy to restore after I changed the settings on my server to have the logs be on a different drive and made sure to restore to the good drives.   

Wednesday
Feb032010

Transitioning to Java

So my work, in the wisdom of someone that is not me has decided that we should standardize the language and environments that we program in to Java and Eclipse.  I am sure you can already sense my excitement.  I'm not particularly afraid of the Java language or even think it will particularly hard to learn the language.   Its nearly identical to C# in syntax and even a lot of the framework is the same, I think.  I think my biggest transition will be the tools around programming.  This means going from Visual Studio to Eclipse.

Click to read more ...

Monday
Nov092009

A Custom Ellipsis Plug-in for JQuery

I had a requirement to be able to show a long description for an item in a limited space.  The descriptions were coming from a 3rd party database and could be of any length.  The design called for the description area being two lines tall.  There is a CSS attribute called text-overflow: ellipsis.  It had several problems, however.  First of all it only worked on a single line basis. Mostly it had the big issue of not working at all in Firefox as it was a non-standard CSS call.

I found a jquery plugin to duplicate the functionality of the CSS call but like the CSS call it only worked on a single line.  My design spec also called for a More/Less link to be affixed to the block of text to expand it/ contract it.  The More/Less also had to support different cultures.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
(function($) {
    $.fn.ellipsis = function(lines, enableUpdating, moreText, lessText) {
        return $(this).each(function() {
            var el = $(this);
            var resetDescription = function(height, originalText) {
            el.html(originalText);
            el.animate({ "height": height }, "normal", null, function() {
                el.ellipsis(true, true, moreText, lessText);
          });
            }
 
            if (el.css("overflow") == "hidden") {
  
                var originalText = el.html();
                var availWidth = el.width();
                var availHeight = el.height();
  
                var MoreLessTag;
                if (moreText) {
                    enableUpdating = true;
                    MoreLessTag = " <a class='MoreLessTag' href='#' >" + moreText + "</a>";
                }
                else MoreLessTag = "";
  
                var t = $(this.cloneNode(true))
                    .hide()
                    .css({
                        'position': 'absolute',
                        'overflow': 'visible',
                        'max-width': 'none',
                        'max-height': 'none'
                    });
                if (lines) t.css("height", "auto").width(availWidth);
                else t.css("width", "auto");
                el.after(t);
                t.append(" <a class='MoreLessTag' href='#' >" + lessText + "</a>");
  
                var fullHeight = t.height();
  
                var avail = (lines) ? availHeight : availWidth;
                var test = (lines) ? t.height() : t.width();
                var foundMin = false, foundMax = false;
                if (test > avail) {
                    //Binary search style trimming of the temp element to find its optimal size
                    var min = 0;
                    var max = originalText.length;
                    while (min <= max) {
                        var trimLocation = (min + max) / 2;
                        var text = originalText.substr(0, trimLocation);
                        t.html(text + "&hellip;" + MoreLessTag);
  
                        test = (lines) ? t.height() : t.width();
                        if (test > avail) {
                            if (foundMax)
                                foundMin = true;
  
                            max = trimLocation - 1;
                            if (min > max) {
                                //If we would be ending decrement the min and regenerate the text so we don't end with a
                                //slightly larger text than there is space for
                                trimLocation = (max + max - 2) / 2;
                                text = originalText.substr(0, trimLocation);
                                t.html(text + "&hellip;" + MoreLessTag);
                                break;
                            }
                        }
                        else if (test < avail) {
                            min = trimLocation + 1;
                        }
                        else {
                            if (foundMin && foundMax && ((max - min) / max < .2))
                                break;
                            foundMax = true;
                            min = trimLocation + 1;
                        }
                    }
                }
  
                el.html(t.html());
                t.remove();
  
  
                if (moreText) {
                    jQuery(".MoreLessTag", this).click(function(event) {
                        event.preventDefault();
                        el.html(originalText);
                        el.animate({ "height": fullHeight }, "normal", null, function() {
                        });
                        el.append(" <a class='MoreLessTag' href='#' >" + lessText + "</a>");
                        jQuery(".MoreLessTag", el).click(function(event) {
                            event.preventDefault();
                            resetDescription(availHeight, originalText);
  
                        });
                    });
                }
                else {
                    var replaceTags = new RegExp(/<\/?[^>]+>/gi);
                    el.attr("alt", originalText.replace(replaceTags, ''));
                    el.attr("title", originalText.replace(replaceTags, ''));
                }
  
                if (enableUpdating == true) {
                    var oldW = el.width();
                    var oldH = el.height();
                    el.one("resize", function() {
                        if (el.width() != oldW || (lines && el.height != oldH)) {
                            el.html(originalText);
                            el.ellipsis(lines, enableUpdating, moreText, lessText);
                        }
                    });
                }
            }
  
        });
    };
})(jQuery);

The following features are added from the original:

  • More/Less link with expansion
  • multiple lines
  • title and alt text if no more/less text is provided

This hasn't been tested extensively under different conditions.

Things I would do if I had an infinite amount of time:

  • More Testing
  • Ability to override the More/Less text click event

Enjoy – I hope someone finds this useful.  This was my first foray into doing a jQuery plugin.  Even though a good chunk of the code was copied, I still learned quite a bit.

Saturday
May302009

Altering the Look of the DNN FAQ Module

I had an issue with the way that the DNN module for FAQ's was behaving. Some extra space was appearing around my lists of questions and breaking up the way the page was supposed to look.  It turns out that the questions were getting these extra <p> tags around them.

Click to read more ...

Sunday
May242009

SCA Online OP Improvements, Link to Dynamic Forms Module - Part 2

The purpose of all the settings was to enable a link to be made from my Online OP module to the Datasprings Dynamic Forms module I have set up to take Award Reccommendations.   The first part was to customize this form a bit more so that it would even recognize this data.  The Dynamic Forms Module allows for data to come in in several ways, cookie, session, and querystring.   I decided to use the querystring to send this info forward.  In the advanced options of the question I found the setting I was looking for.

Click to read more ...