1
\$\begingroup\$

I recently started learning jQuery and JavaScript and put this together for the site I work on here.

/*
 * Manages the error report popups
 *
 * written by Tom Jenkinson
 */


jQuery(document).ready(function($) {


    var bottomTableReport = {

        timer: null,

        init: function() {
            this.mouseover();
            this.mouseout();
        },

        mouseover: function() {
            var self = this;
            $(".report-error").mouseover(function() {

                if(typeof(this.timer) != 'undefined')
                {
                    clearTimeout(this.timer);
                }
                $(this).find('.text').css('display','inherit');

            });
        },

        mouseout: function() {
            var self = this;
            $(".report-error").mouseout(function() {

                var self2 = this;
                this.timer=setTimeout(function() {

                    $(self2).find('.text').css('display','none');

                },300);

            });

        }
    };

    bottomTableReport.init();







    function initialiseProblemQtips()
    {

        var htmlBottomTable= new Array();
        htmlBottomTable[0] ='<div class="error-report-popup-1">';
        htmlBottomTable[0]+='<div class="main-content">';
        htmlBottomTable[0]+='<span class="text-1">Please click on the <img src="images/icons/error.png" /> next to the information in the table that is incorrect.</span>';
        htmlBottomTable[0]+='<span class="text-2">If the error doesn\'t have the symbol next to it please <a class="link">click here</a>.</span>';
        htmlBottomTable[0]+='</div>';
        htmlBottomTable[0]+='</div>';

        htmlBottomTable[1] ='<div class="error-report-popup-1">';
        htmlBottomTable[1]+='<div class="main-content-2">';
        htmlBottomTable[1]+='<span class="title">Report An Error</span>';
        htmlBottomTable[1]+='<span class="text-1">To report an error with this table please click on the e-mail address below to send a message to the manager.</span>';
        htmlBottomTable[1]+='<span class="email">&rarr; <a class="link" href="mailto:'+errorReportEmail+'?subject=Website Table Error">'+errorReportEmail+'</a> &larr;</span>';
        htmlBottomTable[1]+='</div>';
        htmlBottomTable[1]+='</div>';

        var htmlTable='<div class="error-report-popup-2">';
        htmlTable+='<div class="main-content">';
        htmlTable+='<span class="title">Report An Error</span>';
        htmlTable+='<div class="error-id">';
        htmlTable+='<span class="text">Error id: </span><span class="code"><img src="images/icons/code_loading.gif" alt="Loading"></span>';
        htmlTable+='</div>';
        htmlTable+='<span class="text-1">To report an error with this part of the table please click on the e-mail address below to send a message to the manager.</span>';
        htmlTable+='<span class="text-2">Please make sure that the error id above is quoted in your message.</span>';
        htmlTable+='<span class="email">&rarr; <a class="link" onclick="alert(\'Please wait for the error id to be retrieved first.\');return false;" href="">'+errorReportEmail+'</a> &larr;</span>';
        htmlTable+='</div>';
        htmlTable+='</div>';

        $(".report-error-container").css('display', 'block');

        var popupVisible = new Object();

        $(".report-error, .report-error-table").qtip(
        {
            content: '', //set later in api
            position:
            {
                target: false, //it is changed in the 'beforeRender' part in api section
                corner:
                {
                    target: 'bottomMiddle',
                    tooltip: 'topRight'
                }
            },
            show:
            {
                when:
                {
                    event: 'click'    
                },
                delay: 0
            },
            style:
            { 
                name: 'cream',
                tip:
                {
                    corner: 'topRight'
                },
                padding: 0,
                width: 400,
                border:
                {
                    radius: 5,
                    width: 0
                }
            },
            hide:
            {
                when:
                {
                    event: 'unfocus'
                }
            },
            api:
            {
                beforeRender: function() {

                    this.targetThis = $(this.elements.target);
                    this.options.position.target = $(this.targetThis).find('.icon');
                    this.elements.target = this.options.position.target; //update this as well. I don't actually know what it's use is

                    var tableNo= $(this.targetThis).attr('data-tableNo');

                    if($(this.targetThis).hasClass('report-error'))
                    {
                        this.options.position.adjust.screen = false;
                    }
                    else if($(this.targetThis).hasClass('report-error-table'))
                    {
                        this.options.position.adjust.screen = true;
                    }
                },

                onRender: function () {

                    this.qtipThis=$("div[qtip='"+this.id+"']");
                },

                beforeShow: function () {

                    var tableNo= $(this.targetThis).attr('data-tableNo');

                    if($(this.targetThis).hasClass('report-error'))
                    {
                        this.updateContent(htmlBottomTable[0],true);
                    }
                    else if($(this.targetThis).hasClass('report-error-table'))
                    {
                        this.updateContent(htmlTable,true);
                    }

                },

                onShow: function() {

                    var tableNo= $(this.targetThis).attr('data-tableNo');
                    popupVisible[this.id] = true; //creates item in array or updates it
                    showHideIcons(tableNo);
                    this.updatePosition(false,false);
                    if($(this.targetThis).hasClass('report-error'))
                    {
                        var self=this;
                        $(this.qtipThis).find(".link").click(function () {

                            self.updateContent(htmlBottomTable[1],true);

                        })
                    }
                    else if($(this.targetThis).hasClass('report-error-table'))
                    {
                       var self = this;
                       $.post("ajax_requests.php?action=get_error_code", {data:$(this.targetThis).attr('data-errorData')}, function(data) {

                           $(self.qtipThis).find('.code').html(data);

                           $(self.qtipThis).find('.email .link').attr('onclick', '');
                           $(self.qtipThis).find('.email .link').attr('href', 'mailto:'+errorReportEmail+'?subject=Website Table Error (Error id: '+data+')');

                       });

                    }
                },

                onHide: function() {

                    var tableNo= $(this.targetThis).attr('data-tableNo');

                    popupVisible[this.id] = false;
                    showHideIcons(tableNo);

                }
            }
        });

        var iconTimer = new Object();
        function showHideIcons(tableNo)
        {
            action = 'h';
            for (x in popupVisible)
            {
                if (popupVisible[x]===true)
                {
                    action = 's';
                    break;
                }
            }
            if(action=='s')
            {
                if(typeof(iconTimer[tableNo]) != 'undefined')
                {
                    clearTimeout(iconTimer[tableNo]);
                }
                $('.report-error-table-icon[data-tableNo='+tableNo+']').css('display','inline-block');
                $('.report-error-table-icon-inline[data-tableNo='+tableNo+']').css('display','inline');
            }
            else if(action=='h')
            {
                iconTimer[tableNo]=setTimeout(function() {

                    $('.report-error-table-icon[data-tableNo='+tableNo+']').css('display','none');
                    $('.report-error-table-icon-inline[data-tableNo='+tableNo+']').css('display','none');
                }, 2500);         
            }
        }
    }


    initialiseProblemQtips();



});

The script location is here. You can see it working by clicking on an exclamation mark under a table.

Is there a better way of doing this or are there any improvements that could be made to it?

\$\endgroup\$
  • 1
    \$\begingroup\$ [] instead of new Array() \$\endgroup\$ – ThiefMaster Jun 18 '12 at 14:00
  • \$\begingroup\$ @ThiefMaster I've seen that the current best-practice is to avoid = new array(), but can you provide some detail as to why [] is preferable? \$\endgroup\$ – msanford Jun 18 '12 at 14:37
  • 1
    \$\begingroup\$ @ThiefMaster Indeed! Are there any other improvements? I admit that it's also cleaner when creating arrays through loops (which a great many are) since you don't need to allocate an empty array just to fill it. \$\endgroup\$ – msanford Jun 18 '12 at 14:56
  • 2
    \$\begingroup\$ @ANeves That is recommended against by Google. Besides, then you're mixing your code indentation into the data it's dealing with. \$\endgroup\$ – delete me Jun 19 '12 at 0:15
  • 1
    \$\begingroup\$ @st-boost thank you, I misunderstood what he meant. To continue a statement in the next line one can leave a hanging operand at the end of the sentence, like a +. To have linebreaks inside strings one can use line 1\nline 2 or a backslash at the end of the line and continue on the next. \$\endgroup\$ – ANeves wants peace for Monica Jun 19 '12 at 12:02
5
\$\begingroup\$

[] instead of new Array()

Initialize arrays with [] instead of new Array() - it looks better, and when creating a single-element array [5] works while new Array(5) would create an array containing 5 undefined elements;

Long strings in multiple lines, rather than concat

Do

var str = "The quick brown fox" +
        " jumped over the lazy dog.";

instead of

var str = "The quick brown fox";
str += " jumped over the lazy dog."

=== instead of ==

Use === instead of ==, and !== instead of !=. == is not transitive:

'' == 0; // true
0 == "0"; // true
'' == "0"; // false!

Avoid using inline styles

Ideally JS would be used to add or remove classes, and those classes styled through CSS.

Separate responsibilities.

Pick names carefully

var htmlBottomTable= [];

Its name should be pluralized, since it holds a set of things.

bottomTableReport.mouseover

I would use a more suggesting name: bottomTableReport.setMouseover.

Reuse $('foo') when possible

Instead of repeatingly getting $(".report-error"), you can store it once and reuse it:

var bottomTableReport = {
    timer: null,
    target: $(".report-error"),
    // ...
    mouseover: function() {
        // ...
        this.target.mouseover(function() { // Reusing.
        // ...
\$\endgroup\$
  • \$\begingroup\$ +1 all a very valid points that should be considered. The inline styles would have to be my favorite, separating the logic from the design. \$\endgroup\$ – kwelch Jun 28 '12 at 16:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.