Translate

Sunday 30 November 2014

How to add dynamic rows in Javascript

One of the most curious case has come my way and it pertains to many aspects of software development but most importantly, to testing and the purpose of testers so I think this post becomes necessary as due to online projects and work done more than earlier, many 'unqualified' testers are giving 'opinions' on projects like 'user feedback' on products.

It is also possible that before going 'live' some project owners try to get 'user feedback' to make their system more robust, in which case, it can only be called an 'innovative' approach, but which obviously is more often than not called 'too smart' or 'too stupid' because what is applicable on a 'product development life cycle' is usually not applicable for a 'project development life cycle' and the resulting confusion can only be called 'immaturity' and 'malignant' because it only gives 'support' for 'excuses' made by the project owners to manipulate the 'quality' of delivery to their teams or to vendors or to service providers.

Many testers take it upon themselves to take 'moral' stands, where the issue is either a bug or a feature that may not be working properly. They are 'conveniently' backed by 'time to market' and 'management' theories on how much it costs them if their product is delayed and so undue pressures and compromises and 'jugaads' are initiated.

The whole point is in 'planning' and many get it right and many do not, as happens in the whole software development life cycle of any project.

So, when a solution 'demands' that rows must be added to a table and must be infinite in number upon the click of a user action at the client-side, Javascript and jQuery are the best languages (everybody in the software industry acknowledges this and knows it!) but the problem is how to test a scenario where the events, data and the actions themselves are to be dynamic.

I know, as do many mature Agile developers, that I can use Jasmine to unit test Javascript.

The 'wise' know the pitfalls and prepare a 'plan' to take care of the 'unforeseen' bugs that may occur at runtime for which it becomes important to be 'proactive' enough to identify the 'run time' aspects of the scenario and instead of preparing 'contingency' plans to mitigate the possible delay that may or would be caused by the complexity, they, instead, prepare 'plans' to 'corner' the developers. Seriously !

And many actually 'glare' at others who may know the technique and can do it but they themselves cannot!!

Now, why is such arrogance necessary when you can do your simple work properly by identifying test scenarios and have them tracked in a Google doc or a project management bug tracking system rather than indulging in blame games. The answer could be in the political atmosphere that surrounds a company or some problem totally unrelated to the project or work but which can be identified and best solved by the people themselves.

A question that normal people's culture and etiquette does not allow and some try to take advantage of it all that since the management or the HR are not tech savvy, they can get away with 'bluster' and 'bravado'.

And this is why it is necessary for HRs of organizations to read blogs and consult 'experienced' and 'mature' people before hiring and not rely on Facebook and other 'rigged' references. I remember when working with an organization, I would be called upon plus shared with, the technical and technological plans of projects and the necessary plans for the HR and the teams to make.

Simple thumb of rule for young developers or testers is be humble to ask for help. politely. When you have established yourself then you can go around stomping on everyone's feet but when it is time to learn, do not teach others more capable than yourself ! :)

All that is required is to understand your position and be humble enough to ask for help from other team members, and not 'grand stand' around that such scenarios cannot be tested or even developed !

The greatest disservice anybody could do to their team or even friends and family is to not admit that they were wrong but instead persist with blaming others for their own incapability in either 'testing' or in technique unless of course, hiring 'goons' to enforce that others do it for you without having to pay for the service and without admitting to your own incapability (as happens in Indian movies, where a 'goon' becomes a Doctor by having somebody else taking the medical entrance test to become a MBBS doctor) is an option available for you.

So, it does not even make it lack of knowledge or inexperience or immaturity but sheer 'unprofessional' attitude that does not exist in the IT industry.

I have had this experience and so speak from first hand experience that it is tantamount to a kind of 'cunning' and 'cleverness' that no management would want to associate with, so if you wish to make a career in the IT industry, do not indulge in such practices nor allow others, who may be doing it 'secretively' from 'outside'.

Here is one scenario, where you can add any number of rows to a table, using Javascript (knowledge of Html, JS, jQuery and CSS is required to run the example) and which somebody seems to have professed as 'impossible' and then trying too darned hard to prove themselves right!

// the output as it should be

                          








// Javascript


                        // HTML string to add to table breaks
                        var strBreak = null;
                        var strTxtBreak = null;
                        var rowTxt = null;

                        // used for determining number of rows added to table
                        var xx = 0;

                        // used for calculating distance of textboxes
                        var jk = 5;

                        // used for array index

                        var cell3 = "
";
                        for (var i = 0; i < w; i++) {                      
                            row = table.insertRow(i);
                            strBreak = "
 +
";
                            jk = jk + 5;
                            strTxtBreak = "

";
                            row.innerHTML = strBreak + strTxtBreak;
                            yy = yy + 2;
                            xx = i;
                            jk = jk - 5;
                            jk = jk + 55;
                        }
                        var j = 0;
                     
                        j = xx+1;
                        // Row for Notes
                        var rowN = table.insertRow(j);
                        //var rowN1 = table.insertRow(j+1);

                        // For vertical ruler

                        //var t1cell1 = "
";

                        // Set initial position values of elements
                        notesIconLeftValue = 14;
                        notesIconTopValue = jk;
                        notesAreaLeftValue = 40;

                        // creating style str for Notes
                        styleStrForNotesIcon = "style=" + "'position:absolute;top:" + notesIconTopValue + "px;left:-14px;" + notesIconLeftValue + ";" + "'";
                        styleStrForNotesArea = "style=" + "'position:absolute;top:" + notesIconTopValue + "px;left:" + notesAreaLeftValue + "px;width:310px;height:65px;text-align:left;background-color:lightgray;border-color:lightgray;'"
                        var cell5 = "
";

                        // HTML for Notes box row
                        var strNotesIcon = "
 +

";
                        var strNotesArea = "

"

                        // Inserting Notes row HTML
                        rowN.innerHTML = strNotesIcon + strNotesArea;
                        //rowN1.innerHTML = t1cell1;
                        jk = jk + 50;

                        // HTML for buttons
                                             
                        // Table 'tablebtns' into which to add buttons
                        var table1 = document.getElementById("tablebtns");
                        var k = jk + 55;
                        var l = k + 55;

                        // For continue shift button
                        var m = jk + 30;
                        var nn = m + 25;
                        var t1row1 = table1.insertRow(0);
                        // Table style and position
                        var cell1 = "
 +
Continue Work
";
                        t1row1.innerHTML = cell1;

                        eDiv.appendChild(table);
                        eDiv.appendChild(table1);

                        $('#box1').show();
                        $('#tablebrks').show();
                        $('#tablebtns').show();
                        document.getElementById("continueWork").onclick = clickContinueWork;

// HTML
<html>
     <div id="boxMiddle">
         <table style="position:absolute;top:10px;left:25px;width:305px;display:none" id="tablebrks">
         </table>
     </div>

        <table id="tablebtns" style="display:none"></table>

<style>

#box1 {    position:absolute;
    height:110px;
    top:180px;
    padding: 5px 5px 5px 5px;
    border:none;
    margin:25px;
    background-color:white;
    display:none;
}

#boxMiddle {
    position:relative;
    height:260px;
    /*top:145px;*/
    padding:4px 7px 2px 4px;
    border:none;
    margin:25px;
    background-color:white;
    display:none;
}

div.calloutContinue {
    background-color: #8EC127;
    background-image: -moz-linear-gradient(top, #444, #444);
    position: absolute;
    top:30px;
    left:42px;
    color: #000000;
    padding: 10px;
    border-radius: 3px;
    /*box-shadow: 0px 0px 20px #8EC127;*/
    margin: 25px;
    min-height: 20px;
    /*border: 1px solid #333;*/
    text-shadow: 0 0 1px #000;
    text-align:center;
    height:40px;
    width:145px;
}
.calloutContinue::before {
    content:"";
    width: 0px;
    height: 0px;
    border: 0.4em solid transparent;
    position: absolute;
}

.calloutContinue.right::before {
    left: -16px;
    top: 10%;
    border-right: 10px solid #8EC127;
}
.calloutContinue.right:hover {  
    cursor:pointer;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">

// The javascript code here

<script/>