1

I want to fetch records from a database, to which I want the data to be displayed on the screen.

From the code below you can already see that the query I have is that if the database contains LIKE (data input) then alert user with "Event Found", if no data found then "No event!".

However, now I want to actually display the results on the screen on a table or which ever way that is presentable.

I know you can create and display the table within the javascript function, but I am not quite sure how to go about this. Can someone give me a helping hand? :)

function fetchEvent()
         {
      db = window.openDatabase("SoccerEarth", "2.0", "SoccerEarthDB", 2*1024*1024);
      db.transaction(foundEvent, errorCB);
     }

      function foundEvent(tx)
        {
        var TitleT = document.getElementById("texttitle").value;
       tx.executeSql("SELECT * FROM SoccerEvents WHERE Title LIKE '%" + TitleT + "%'", [], renderEvent);

                    }
       function renderEvent(tx,results) {
       if (results.rows.length > 0) {
       navigator.notification.alert("Event found");
        }
       else
        {
        navigator.notification.alert("No event!");
                        }
      }

HTML -

 <form>
            <div class="ui-field-contain">
                <label for="texttitle">Title</label>
                <input type="text" id="texttitle">
                <label for="select-native-2">Location</label>
                <select name="select-native-2" id="select-native-2" data-mini="true">
                    <option value="" disabled selected>Select your option</option>
                    <option value="1">Tower Hamlets</option>
                    <option value="2">Greenwich</option>
                    <option value="3">Islington</option>
                    <option value="4">Bromley</option>
                    <option value="4">Hackney</option>
                    <option value="4">Lewisham</option>
                </select>
                <br>
                <label for="dateD" data-position="left">Date</label>
                <input type="date" id="dateD"   />
                <br>
                <input type="submit" value="submit" onclick="return fetchEvent(); return false;">
            </div>
    </form>
Mahdi
  • 153
  • 2
  • 16

2 Answers2

1

Tables consist of complex tree of nodes, so, to make this process comfortable and easy, you create Javascript-generated table on your page, by inserting to your page a DOM element generated from String, that contains a normal HTML markup.

And there are two general ways to accomplish this.


1.

First one: use .innerHTML of your DOM element.

Drawback of this approach - in certain situations it will cause unexpected behavior in old IE. They are mentioned here: Why does .html work and not innerHTML or appendChild It must be said that many reasonable companies have dropped support for IE < 9, but I had to mention that as drawback - as your requirements for browser are unspecified so perhaps that could be important consideration for your project.

Here is implementation (without bug-protection - I skipped it to improve readability of code):

<!DOCTYPE html>
<html>
    <head>
        <title>Example: inserting new HTML to DOM</title>
    </head>
    <body>
        <div id="js-insert-dom-here"></div>

        <script>

            /*
            *   Input:
            *       inHtml - string that MAY contain HTML-tags
            *       inDomEl - DOM element.
            *   
            *   Result:
            *       inHtml will be inserted inside inDomEl;
            *       attention: this will rewrite all HTML
            *       that was previously situated inside inDomEl
            *   
            */
            function outputHtmlToDom( inHtml, inDomEl ) {
                inDomEl.innerHTML = inHtml;
            }

            function getOutputDiv() {
                var id = 'js-insert-dom-here';
                var div = document.getElementById( id );
                if ( div === null ) {
                    throw new Error( 'div ' + id + ' was not found on your page' );
                }
                return div;
            }

            // sugar for outputHtmlToDom
            function outputHtml( inHtml ) {
                outputHtmlToDom( inHtml, getOutputDiv() )
            }

        </script>

        <!-- example -->
        <script>

            // testing (static):
            outputHtml(
                '<b>bold</b> <i>italic</i> ' +
                '<div>div</div>' +
                '<table><tbody><tr><td>table</td></tr></tbody></table>'
            );

        </script>
        <!-- /example -->
    </body>
</html>

2.

You can use any Javascript library that abstracts you from bugs. Personally I prefer jQuery for tasks of DOM manipulation.

Once upon a time a really nice guy called John Resig decided to create abstraction layer and syntax sugar for manipulating DOM with Javascript. He created jQuery. This library's goal is to abstract from weird browser-specific behavior of Javascript implementation - it makes behavior cross-browser by providing cross-browser API, and hacks to counter those bugs are hidden under jQuery's hood.

It's site jquery.com has a stunningly well-done online documentation.

Drawback of this approach - jQuery's syntax is alien for vanilla Javascript programmer - so you'll need to learn it if you want to use it, but it is beautifully expressive for domain of DOM manipulation.

You mentioned that you use jQueryMobile - it requires jQuery to work at all, so that means you have jQuery included on your page.

Here is implementation of outputHtml, using jQuery:

<!DOCTYPE html>
<html>
    <head>
        <title>Example: inserting new HTML to DOM with jQuery</title>

        <!--
            This includes jQuery from online resourse.
            Perhaps for some applications you would want to move that to your own server
            so that you are not dependent on availability of jquery.com site.
        -->
        <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
    </head>
    <body>
        <div id="js-insert-dom-here"></div>

        <script>
            function outputHtml( inHtml ) {
                $( '#js-insert-dom-here' ).html( inHtml );
            }
        </script>

        <!-- example -->
        <script>

            // testing (static):
            outputHtml(
                '<b>bold</b> <i>italic</i> ' +
                '<div>div</div>' +
                '<table><tbody><tr><td>table</td></tr></tbody></table>'
            );

        </script>
        <!-- /example -->
    </body>
</html>

Generating HTML for table:

Now that you know how to insert your HTML to DOM, you need to generate HTML for your table. You can do it by hand, but I'd recommend using a specialized function to keep things manageable.

Below, I provide code for sample function that could make your job done.

You could use it like this:

// actually, you should populate tableData
// with data extracted from your database
var tableData = [
    [ 'header 1',   'header 2',   'header 3'  ],
    [ '(x:1,y:1)',  '(x:2,y:1)',  '(x:3,y:1)' ],
    [ '(x:1,y:2)',  '(x:2,y:2)',  '(x:3,y:2)' ]
];

outputHtml(
    generateTableHtml( tableData )
);

Code for generateTableHtml:

<script>

    /*
    *   Purpose:
    *       Sometimes you need to generate HTML for simple table
    *       This is a helper function that does just that
    *           (simple table means that each cell spans 1 row and 1 column)
    *   
    *   Input:
    *       aasCellValues - array of arrays of strings
    *           example:
    *           [     // column      // column      // column
    *               [ 'header 1',   'header 2',   'header 3'  ], // row
    *               [ '(x:1,y:1)',  '(x:2,y:1)',  '(x:3,y:1)' ], // row
    *               [ '(x:1,y:2)',  '(x:2,y:2)',  '(x:3,y:2)' ]  // row
    *           ]
    *       
    *       bFirstIsHead - bool
    *           if === true, then first row will be rendered as Table Header
    *           default: true;
    *           
    *       bFirstIsFoot - bool
    *           if === true, then first row will be rendered as Table Footer
    *           default: false
    *       
    *   Output:
    *       String that contains HTML-markup that can be easily
    *       yanked into DOM
    *       
    *       if array is empty or aasCellValues is not array,
    *           output will return '' which is still yankable to DOM
    *   
    *   Bugs (#security):
    *       This function trusts that strings inside input array
    *           are correct and valid,
    *           thus no sanitation is performed for any of sCellValues.
    *       Thus
    *           </td> </th> </tr> </tbody> </thead> </table>
    *           provided in cell values
    *           would definely break your markup.
    *       Any Javascript would be inserted as it is was provided which will
    *           create opportunity for XSS-attack, if used with
    *           poisoned input (i.e. input from untrusted source -
    *           for example
    *               - user request,
    *               - data from database
    *           and any of that input is poisoned
    *           if it wasn't tested with criteria
    *           of purity: is it pure or not).
    *       
    *       example:
    *           [
    *               ['<' + 'script' + '>alert("Hello, XSS-attack!");</' + 'script' + '>'],
    *               ['<b onload="alert(111);">Another XSS vector</b>']
    *           ]
    *       
    *       example:
    *           [
    *               ['</table>Here breaks a table... Ruuun!!'],
    *           ]
    *       
    *       How to counter this vulnerability?
    *           Either check poisoned values before sending
    *           them to this function as input,
    *           
    *           or modify generateTableHtml code
    *           to allow another input value: function that will
    *           conduct testing for your specific purity criteria.
    *           
    */
    function generateTableHtml( aasCellValues, bFirstIsHead, bFirstIsFoot ) {
        var ou = '';

        //  you can add here error logging
        //  or alert if you feel that appropriate
        if (
            ( typeof aasCellValues === 'undefined' )
            ||
            !( aasCellValues.length > 0 )
        ) {
            return ou;
        }

        var thead = '';
        var tfoot = '';
        var tbody = '';

        // setting defaults
        if ( typeof bFirstIsHead === 'undefined' ) {
            bFirstIsHead = true;
        }
        if ( typeof bFirstIsFoot === 'undefined' ) {
            bFirstIsFoot = false;
        }

        // start of programm

        if ( bFirstIsHead || bFirstIsFoot ) {
            var firstRow = aasCellValues.shift();
            firstRow = generateTableRowHtml.th( firstRow );

            if ( bFirstIsHead ) {
                thead = '<thead>' + firstRow + '</thead>';
            }
            if ( bFirstIsFoot ) {
                tfoot = '<tfoot>' + firstRow + '</tfoot>';
            }
        }

        var i = 0;
        var L = aasCellValues.length;
        for ( var i = 0; i < L; i++ ) {
            tbody +=
                '<tr>' +
                    generateTableRowHtml.td( aasCellValues[i] ) +
                '</tr>'
            ;
        }

        if ( tbody !== '' ) {
            tbody = '<tbody>' + tbody + '</tbody>';
        }

        ou = '<table>' + thead + tfoot + tbody + '</table>';

        return ou;
    }

    // helper for function generateTableHtml
    var generateTableRowHtml = {
        th: function( asCellValues ) {
            return '<th>' + asCellValues.join('</th><th>') + '</th>';
        },
        td: function( asCellValues ) {
            return '<td>' + asCellValues.join('</td><td>') + '</td>';
        }
    }
</script>

Update: Answer to comments:

First of all - if you don't have enough experience with JS and HTML to intuitively know how to fit pieces of puzzle that I gave you - you are in for a world of trouble. Because those can't be explained in a simple manner. To explain them - they a require to write/translate a few books and a few blogs.

Or you could spend a week or two for online tutorials. -_^ And that would be much more cost-effective.

I have my own life to live ^ ^ And you need to train your own wings to learn how to fly. Helping too much would cripple us both in the long run. Thus, this is a good place to bid a farewell.

P.S.

Your best bet to get fast results - is to find some javascript library that can output result of WebSQL query reliably for those browsers that you intend to support. Perhaps you can find something like that on GitHub.

But, to finish what I begun - here is example of how you could weave code to output your request to table. I give you two blocks: scripts + html. Html is basically form from your own listing + div for outputting table. In scripts block - you have your script in the last scriptblock - and in this implementation you must provide names of fields manually. Scripts must go before your form - otherwise code wouldn't work.

I implemented no security measures as those are quite individial for each project.

Scripts:

    <script>

        // this scriptblock allows you to use outputHtml

        /*
        *   Input:
        *       inHtml - string that MAY contain HTML-tags
        *       inDomEl - DOM element.
        *   
        *   Result:
        *       inHtml will be inserted inside inDomEl;
        *       attention: this will rewrite all HTML
        *       that was previously situated inside inDomEl
        *   
        */
        function outputHtmlToDom( inHtml, inDomEl ) {
            inDomEl.innerHTML = inHtml;
        }

        function getOutputDiv() {
            var id = 'js-result';
            var div = document.getElementById( id );
            if ( div === null ) {
                throw new Error( 'div ' + id + ' was not found on your page' );
            }
            return div;
        }

        // sugar for outputHtmlToDom
        function outputHtml( inHtml ) {
            outputHtmlToDom( inHtml, getOutputDiv() )
        }
        /*

            //basic test:
            outputHtml('<b>bold</b> <i>italic</i>');
        */

    </script>
    <script>

        // this scriptblock allows you to use generateTableHtml

        /*
        *   Purpose:
        *       Sometimes you need to generate HTML for simple table
        *       This is a helper function that does just that
        *           (simple table means that each cell spans 1 row and 1 column)
        *   
        *   Input:
        *       aasCellValues - array of arrays of strings
        *           example:
        *           [     // column      // column      // column
        *               [ 'header 1',   'header 2',   'header 3'  ], // row
        *               [ '(x:1,y:1)',  '(x:2,y:1)',  '(x:3,y:1)' ], // row
        *               [ '(x:1,y:2)',  '(x:2,y:2)',  '(x:3,y:2)' ]  // row
        *           ]
        *       
        *       bFirstIsHead - bool
        *           if === true, then first row will be rendered as Table Header
        *           default: true;
        *           
        *       bFirstIsFoot - bool
        *           if === true, then first row will be rendered as Table Footer
        *           default: false
        *       
        *   Output:
        *       String that contains HTML-markup that can be easily
        *       yanked into DOM
        *       
        *       if array is empty or aasCellValues is not array,
        *           output will return '' which is still yankable to DOM
        *   
        *   Bugs (#security):
        *       This function trusts that strings inside input array
        *           are correct and valid,
        *           thus no sanitation is performed for any of sCellValues.
        *       Thus
        *           </td> </th> </tr> </tbody> </thead> </table>
        *           provided in cell values
        *           would definely break your markup.
        *       Any Javascript would be inserted as it is was provided which will
        *           create opportunity for XSS-attack, if used with
        *           poisoned input (i.e. input from untrusted source -
        *           for example
        *               - user request,
        *               - data from database
        *           and any of that input is poisoned
        *           if it wasn't tested with criteria
        *           of purity: is it pure or not).
        *       
        *       example:
        *           [
        *               ['<' + 'script' + '>alert("Hello, XSS-attack!");</' + 'script' + '>'],
        *               ['<b onload="alert(111);">Another XSS vector</b>']
        *           ]
        *       
        *       example:
        *           [
        *               ['</table>Here breaks a table... Ruuun!!'],
        *           ]
        *       
        *       How to counter this vulnerability?
        *           Either check poisoned values before sending
        *           them to this function as input,
        *           
        *           or modify generateTableHtml code
        *           to allow another input value: function that will
        *           conduct testing for your specific purity criteria.
        *           
        */
        function generateTableHtml( aasCellValues, bFirstIsHead, bFirstIsFoot ) {
            var ou = '';

            //  you can add here error logging
            //  or alert if you feel that appropriate
            if (
                ( typeof aasCellValues === 'undefined' )
                ||
                !( aasCellValues.length > 0 )
            ) {
                return ou;
            }

            var thead = '';
            var tfoot = '';
            var tbody = '';

            // setting defaults
            if ( typeof bFirstIsHead === 'undefined' ) {
                bFirstIsHead = true;
            }
            if ( typeof bFirstIsFoot === 'undefined' ) {
                bFirstIsFoot = false;
            }

            // start of programm

            if ( bFirstIsHead || bFirstIsFoot ) {
                var firstRow = aasCellValues.shift();
                firstRow = generateTableRowHtml.th( firstRow );

                if ( bFirstIsHead ) {
                    thead = '<thead>' + firstRow + '</thead>';
                }
                if ( bFirstIsFoot ) {
                    tfoot = '<tfoot>' + firstRow + '</tfoot>';
                }
            }

            var i = 0;
            var L = aasCellValues.length;
            for ( var i = 0; i < L; i++ ) {
                tbody +=
                    '<tr>' +
                        generateTableRowHtml.td( aasCellValues[i] ) +
                    '</tr>'
                ;
            }

            if ( tbody !== '' ) {
                tbody = '<tbody>' + tbody + '</tbody>';
            }

            ou = '<table>' + thead + tfoot + tbody + '</table>';

            return ou;
        }

        // helper for function generateTableHtml
        var generateTableRowHtml = {
            th: function( asCellValues ) {
                return '<th>' + asCellValues.join('</th><th>') + '</th>';
            },
            td: function( asCellValues ) {
                return '<td>' + asCellValues.join('</td><td>') + '</td>';
            }
        }
        /*

            //basic test:
            generateTableHtml(
                [     // column      // column      // column
                    [ 'header 1',   'header 2',   'header 3'  ], // row
                    [ '(x:1,y:1)',  '(x:2,y:1)',  '(x:3,y:1)' ], // row
                    [ '(x:1,y:2)',  '(x:2,y:2)',  '(x:3,y:2)' ]  // row
                ]
            );
        */
    </script>
    <script>

        // this scriptblock allows you to use adaptRowsTo2DArrays

        function adaptRowsTo2DArrays( sqlResult, aFields ) {
            var ou = [];

            if ( ! ( sqlResult.rows.length > 0 ) ) {
                return ou;
            }

            var i = 0;
            var L_i = sqlResult.rows.length;

            var j = 0;
            var L_j = aFields.length;

            for ( i = 0; i < L_i; i++ ) {
                var tmpARow = [];
                for ( j = 0; j < L_j; j++ ) {
                    var fieldName = aFields[j];
                    tmpARow.push( sqlResult.rows[i][fieldName] );
                }
                ou.push( tmpARow );
            }

            return ou;
        }
        /*
            // basic test:
            adaptRowsTo2DArrays(
                {
                    rows: [
                        {'animalType': 'wolf', 'color': 'red+gray',           'sound': 'auuu...+rrr'   },
                        {'animalType': 'cat',  'color': 'black+white+orange', 'sound': 'meow+hisss...' }
                    ]
                },
                ['animalType', 'sound', 'color']
            );
        */

    </script>
    <script>

        // your functions:

        function fetchEvent() {
            db = window.openDatabase("SoccerEarth", "2.0", "SoccerEarthDB", 2*1024*1024);
            db.transaction(foundEvent, errorCB);
        }

        function foundEvent(tx)
        {
            var TitleT = document.getElementById("texttitle").value;
            tx.executeSql("SELECT * FROM SoccerEvents WHERE Title LIKE '%" + TitleT + "%'", [], renderEvent);
        }

        /*
            I assume that any rrow of reult consists of fields:
            'TitleT', 'LocationL', 'PeopleP', 'DateD', 'DescriptionD'
        */
        function renderEvent(tx,results) {
            if (results.rows.length > 0) {
                var aFields = ['TitleT', 'LocationL', 'PeopleP', 'DateD', 'DescriptionD'];
                var aaTable = adaptRowsTo2DArrays( adaptRowsTo2DArrays, aFields );
                var aaTable.unshift( ['Title:', 'Location:', 'People:', 'Date:', 'Description:'] )
                var tableHtml = generateTableHtml( aaTable );
                outputHtml( tableHtml );
            } else {
                navigator.notification.alert("No event!");
            }
        }

    </script>

HTML:

    <!-- insert scripts here -->

    <form>
            <div class="ui-field-contain">
                <!-- ... -->
                <input type="submit" value="submit" onclick="fetchEvent(); return false;">
            </div>
    </form>

    <div id="js-result"></div>
Community
  • 1
  • 1
Jaiden Snow
  • 852
  • 5
  • 5
  • Edited my answer - there was a bug in generateTableHtml - td rows were piled in one single long row. Fixed it, now it will work correctly. – Jaiden Snow Mar 19 '16 at 10:10
  • Wow, thank you for this in-depth reply. However, i'm going to be honest and say that most of this went over my head (due to my lack of knowledge on tables). Struggling to understand how my results from the database will be inserted into the tables created? Is there not a way that I can have the same javascript function that looks for the data, produce a table with the data found? – Mahdi Mar 21 '16 at 10:23
  • Hmm. I found is no helper functions to output tables that's built in WebSQL http://www.w3.org/TR/webdatabase/ (Wow! A dead standard! It feels like meeting remains of dead giant. Wow.). So I guess you'd have to use the code I gave in my answer. I'll post later (if ninjas wouldn't suddenly attack me) a working example how you could mix it all together to make something useful... – Jaiden Snow Mar 21 '16 at 18:31
1

Thank you for your response and answer Joan, it's extremely helpful. I had already resolved the issue but forgot to post the answer.

function foundEvent(tx) {
  var TitleT = document.getElementById("texttitle").value;
  tx.executeSql("SELECT * FROM SoccerEvents WHERE Title LIKE '%" + TitleT + "%'", [], renderEvent);
}

function renderEvent(tx, response) {
  var div = document.getElementById("responsediv");

  var temp = "<table border=\"1\"><tr><th>Title</th><th>Location</th><th>NoPeople</th><th>Date</th><th>Description</th></tr>";
  alert(response.rows.length);
  for (var i = 0; i < response.rows.length; i++) {
    temp += "<tr><td>" + response.rows.item(i).Title + "</td><td>" + response.rows.item(i).Location + "</td><td>" + response.rows.item(i).NoPeople + "</td><td>" + response.rows.item(i).Date + "</td><td>" + response.rows.item(i).Description + "</td></tr>";
    div.innerHTML = temp;
  }
}
Vikasdeep Singh
  • 20,983
  • 15
  • 78
  • 104
Mahdi
  • 153
  • 2
  • 16