29 Replies Latest reply: Dec 3, 2016 12:06 AM by Alan McCreary RSS

    Dynamic DIV-tag integration

    Alexander Karlsson

      With QlikView 11 we introduced a feature with the sexy name DIV-tag integration.

      What this really enables us to do is to reference our JavaScript API and integrate QlikView Objects into web solutions with full functionality.

       

      This is huge. With no extra licenses QlikView users around the world can now enjoy QlikView functionality within non .Net solutions, embedded into their ERP or CRM systems. The community loved it but was also a bit concerned that the amount of objects floating around out there would increase the maintenance of QlikView.

       

      A few lines of JavaScript will eliminate that problem for you

       

      Dynamic DIV-tag integration 1.0

      Now you have 1 solution to maintain that can serve your entire company with embedded QlikView Objects.

       

      Short version:

       

      You will need:

      QlikView Server version 11 installed.

      Some sort of web server.

      A can of coke and a smile on your face.

      NEW: A workbench license.

       

      Installation:

      1. Download the sample at: http://dl.dropbox.com/u/18211954/Extensions/single.zip

      2. If you are running QV Webserver extract the contents to: C:\Program Files\QlikView\Web\

      3. Change the script references in single.htm to match your setup.

      4. And you are done.

       

      How-to:

      The solution accepts input according to the following syntax: http://WebServerUrl/app pool/single.htm?app=your document without qvw&obj=ObjectID

      Optional parameters are w and h to set width and height otherwise default to 100%

       

      On my demo system the following URL will generate the chart below:

      http://localhost/QlikView/single.htm?app=Vinguiden&obj=CH233&w=200&h=400

       

      NOTE: If you get a no connection error message try adding the .qvw extension to your app variable

      single.PNG

       

      This chart has full QlikView functionality. If you for some reason want to disable any interaction with the object, set it to read-only in the QV document.

        • Re: Dynamic DIV-tag integration
          OLEKSANDR NERUSH

          Hello Alexander,

           

          when i start playing with div-tag integration i've always get a message "No connection". But when i've added ".qvw" for the "app" parameter ("app=your document without qvw&obj=ObjectID"), i got a working solution.  So, the "app" parameter should contain application's name including extension, isn't it?

          • Re: Dynamic DIV-tag integration
            Patrick Vinton

            You used the phrase "With no extra licenses," but I want to point out that you need a Workbench license in order for this to work.

             

            If you don't have a Workbench license, you will get a "Failed to Authenticate" error, a "No connection" error, or a blank page on the client side in the browser.

             

            On the server side, you will see this message in the QVWS logs:

               Warning    Failed to get client: WORKBENCH license missing

             

            Just pointing this out so nobody else spends a lot of time troubleshooting their HTML code like I did!

              • Re: Dynamic DIV-tag integration
                Alexander Karlsson

                Hey Patrick,

                 

                When the feature was released we double and tripple checked with out licensing department around it. The word that came back was that no, you do not need a workbench license and I'am fairly sure I tried it without workbench licneses on a fresh QV11 box,

                 

                What version are you running?

                 

                I'll reach out internally again and see if anything has changed regarding this.

                  • Re: Dynamic DIV-tag integration
                    Patrick Vinton

                    Thanks for the response, Alexander.

                     

                    I am using QVS 11.00.11154.0 IR 64-bit Edition.

                     

                    I'll see if I can find an 11SR1 or 11SR2 instance somewhere to see if I can reproduce the issue there.

                     

                    In the meantime, can you double check my HTML code to see if I am doing something incorrect?  I have tried it with and without the "Qv.InitWorkBench" line and got the same results.

                     

                    <HTML>

                    <HEAD>

                      <TITLE> QV Div-tag Test </TITLE>

                      <script type="text/javascript" src="http://192.168.0.41/QvAjaxZfc/htc/QvAjax.js"></script>

                      <script type="text/javascript">Qv.InitWorkBench({ View: 'QlikView Demo'});</script>

                    </HEAD>

                     

                    <BODY>

                       <div style = "width:400px;height:250px;">

                         <div class="qvFrame" avqview="QlikView Demo" avq="object:.Document\CH11" id="Document\CH11" style="width:400px;height:250px;"></div>

                       </div>

                    </BODY>

                    </HTML>

                      • Re: Dynamic DIV-tag integration
                        Martijn ter Schegget

                        Hi Patrick,

                         

                        Isn't the issue in your example a cross-site scripting problem? You fetch the main page from one server, and then try to run some JavaScript on it which comes from another server -> most browsers don't like that very much.

                        (At least, that's what I'm guessing from the 'http://192.168.0.41/' in the source URL for QvAjax.js.)

                         

                        This setup seems to match the '3-tier scenario' (p.39) or '2-tier scenario - WorkBench Web Site on Own Machine' (p.40) in the WorkBench Reference Manual. In both cases you'll need a proxy page on the same webserver that serves your HTML page, which behind the scenes forwards the requests to the QlikView WebServer on another system.

                         

                        You'll end up with something like:

                         

                        [Browser] -> [webserver 1: HTML page and Proxy.aspx] -> [webserver 2: QvWebServer]

                         

                        Regards,

                        Martijn ter Schegget

                        The Implementation Group

                         

                        PS: Another issue you might run into: the NTLM protocol will support passing credentials from a webbrowser to a webserver (1 hop), but not passing credentials from a webbrowser via one webserver to a second webserver (2 hops).

                          • Re: Dynamic DIV-tag integration

                            Hi All,

                             

                            By any chance, is anyone implemeted the below concept part DIV integration with workbench in Java based application

                            [Browser] -> [webserver 1: HTML page and Proxy.aspx] -> [webserver 2: QvWebServer]


                            I trying to integfrate DIV integration with workbench into my java application and struck with CORS errors, for that , I tried to enable CORS on QVWS, but still getting the same  CORS error.


                            I am gave up at the moment, and planned to implement proxy page, but just looking for sample, as I am not sure how to do this and also I need to pass webticket to access the document on QVS.

                            Please share the info, as I need it very urgently.


                            Thanks,



                    • Re: Dynamic DIV-tag integration

                      Hi,

                       

                      I'am trying to use the sample on our server, but it's not working

                      First message "Failed to authenticate" followed by two more ones "No connection"

                       

                      I picked what I suppose to be the version in "QlikView management console"

                      Product nameQlikView Web Server Settings Service
                      Client Build Number11.0.11414.0

                       

                      The installation is not completely standard as the server root directory is not C:\Program Files\QlikView\Web\

                      I have checked single.htm javascripts are correctly loaded

                      On the app side, is there some relative path to specify ? Indeed, changing app name to something fool give the same "crashing" scenario.

                       

                      Thanks for your attention

                      • Re: Dynamic DIV-tag integration
                        Phaneendra Kunche

                        How can we integrate more than one object?

                        your  http://localhost/QlikView/single.htm?app=Vinguiden&obj=CH233&w=200&h=400 shows only one object in the page.

                         

                        i tried even below from this thread to display multiple but no luck.. I have QVSEE & Work Bench License. At least your "single.htm" concept is working but below is not working at all. do i have to save below html file some where? i have saved in my desktop and opening locally though firefox/chrome.

                         

                         

                        <!DOCTYPE html>

                        <html>

                            <head>

                                <script language="javascript" type="text/javascript" src="http://localhost/QvAjaxZfc/htc/QvAjax.js"></script>

                        <script language="javascript" type="text/javascript">

                           Qv.InitWorkBench({

                              View: 'Sales Compass',    

                              Host: 'QVS@local'

                           });

                        </script>

                            </head>

                          

                            <style>

                            .QvInlineObject

                        {

                           position:relative;

                           margin-left:10px;

                           margin-right:10px;

                           float:left;

                        }

                            </style>

                         

                            <body>

                        <!-- Listbox with the Id LB5732 -->

                        <div class="QvInlineObject" avqview="Sales Compass" avq="object:.Document\LB5732"></div>

                         

                        <!-- Chart with the Id CH351 -->

                        <div class="QvInlineObject" avqview="Sales Compass" avq="object:.Document\CH351"></div>

                        </body>

                        </html>

                        • Re: Dynamic DIV-tag integration

                          Hi Alexander,

                           

                          For DIV-tag integration do we need to have Qlikview licenses ?

                          • Re: Dynamic DIV-tag integration

                            Hi Alexander,

                             

                              We are using DIV integration for our application. We have more than 500 qlikview objects, which we embedded in our html pages using DIV integration. Unfortunately we are not able to load the qlikview objects when we needed, so we are loading all these 500 qlikview objects at loading time and using basic html hide and show methodology, we are displaying the qlikview objects in our web pages. This approach is suggested by qlikview guys. But this design taking longer time(10 secs to 20 secs) to load initially when user log-in. Also taking 8 to 15 secs to refresh the page, when we apply any filter. Our qlikview file is very small (10 MB) and we will not have more than 1 million rows

                             

                              Can we have any other design so that we can embed qlikview objects in our html pages and get the quick response time within in 1 sec. We can not go for Opendoc or iFrame as we have custom UI developed in html5 and css3.

                             

                            Thanks,

                            Ram

                              • Re: Dynamic DIV-tag integration
                                Alexander Karlsson

                                oh wow. I'm going to be very blunt here, that is a horrible horrible approach.

                                 

                                500 objects sounds a bit overkill also, I'm guessing a lot of them are duplicates with different dimensions or expressions? That could be solved in QlikView by using conditional dimensions and expressions to cut down on the number of objects you have to maintain.


                                Let's take this offline, feel free to e-mail me at akl@qlik.com and I can provide some code samples.

                              • Re: Dynamic DIV-tag integration
                                Alan McCreary

                                Hi Alexander,

                                 

                                My question doesn't have anything to do with this article, I've just read some of your articles and wanted to email and ask you a question. 

                                 

                                I've implemented div integration, where I have a few individual objects that appear and work. But I'd like for my web page to "be aware" of activities in those objects (if that makes sense). So, for example, if the user scrolls a listbox down to the last row, my javaScript "knows that they did that". I guess a listener,  but I can't figure out how to do that with QlikView objects.

                                 

                                I'm not particular, and have little knowledge of Qlik internals, but would appreciate any guidance you might have.

                                 

                                Thanks,

                                Alan

                                  • Re: Dynamic DIV-tag integration
                                    Alexander Karlsson

                                    As far as I know there are no supported events for QlikView objects. Then again I haven't really worked with the QV APIs for a few years so I could be wrong on that.

                                     

                                    I guess you could target our objects and inject your own listeners to listen for certain type of events such as scroll and clicks.

                                      • Re: Dynamic DIV-tag integration
                                        Alan McCreary

                                        Hi Alexander,

                                         

                                        Thank you for responding to my question.

                                         

                                        What I'm doing is mixing Qlik objects with live web content - you click on a Qlik grid and I call a webApi to get live data and display it on the page.. The problem I was trying to solve was that when you sort or refresh or scroll/other, my listeners weren't attached anymore..live is deprecated and .on doesn't work.

                                         

                                        So I needed a way to know that object/s had been refreshed, then re-attach the listeners to the resulting divs in the refreshed QvContent.

                                         

                                        I figured it out. So here's what I did (the highlights anyway) below. It's not a very elegant solution but it'll work until I find a better one.

                                         

                                            QvReport.PreInitWorkBench = function () {

                                                $(".qlikPane").addClass("Qv" + QvReport.Report);

                                            };

                                         

                                         

                                            QvReport.InitWorkBench = function () {

                                                QvReport.PreInitWorkBench();

                                         

                                                Qv.InitWorkBench({

                                                    View: QvReport.DocumentName,

                                                    Host: QvReport.Host,

                                                    BodyOnLoadFunctionNames: "QvReportOnLoad",

                                                });

                                            };

                                         

                                         

                                            QvReportOnLoad = function () {

                                                // Set callback for QlikView event "OnUpdateComplete" for policy summary grid. When that grid updates, the callback function will be called.

                                                var doc = Qv.GetCurrentDocument();

                                                var policyChart = doc.GetObject("CH37");

                                                policyChart.SetOnUpdateComplete(OnPolicyGridUpdated());

                                            }

                                         

                                         

                                            function OnPolicyGridUpdated() {

                                                setEventListener();

                                            }

                                         

                                         

                                            function setEventListener() {

                                                $('div').on('click', function (event) {

                                         

                                         

                                                    // Click on down arrow of QlikView search box Document\SO07

                                                    if (this.className == "QvContent QvSearchObject ui-helper-clearfix") {

                                                        event.stopPropagation();

                                                        event.stopImmediatePropagation();

                                                        return;

                                                    }

                                         

                                         

                                                    // Clicked and then let go of scroll bar on QlikView grid Document\CH37

                                                    if (this.className == "Qv_ScrollbarBackground") {

                                                        setEventListener();

                                                    }

                                         

                                         

                                                    var target = $(event.target);

                                                    var targetnext = target.next()[0];

                                         

                                         

                                                    // Clicked on web control button "Clear"

                                                    if (target[0].id == "qvClearButton ") {

                                                        event.stopPropagation();

                                                        event.stopImmediatePropagation();

                                                        qvClearButtonClick();

                                                        return;

                                                    }

                                         

                                         

                                                    // Clicked on policy number on QlikView grid Document\CH37

                                                    // Fetch policy detail via webApi and display on page

                                                    var targethtml = targetnext.innerHTML;

                                                    var targetval = $(targethtml).attr('title');

                                         

                                         

                                                    if ((targetval.length == 10 && /^\d+$/.test(targetval) == true)) {

                                                        event.stopPropagation();

                                                        event.stopImmediatePropagation();

                                                        RenderPolicyDetail(targetval);

                                                    }

                                                })

                                            }