Announcement

Collapse
No announcement yet.

Timerto update div in FeaturePage?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Timerto update div in FeaturePage?

    How do I add a timer to update div in FeaturePage?

    If I add js:

    setInterval(function(){ $('#plugin').load('" + FileName + @"'); }, 2000);

    then it loads whole page. But how do I return just a content of single div? AbstractFeaturePage has virtual GetHtmlFragment - can I use that?

    #2
    I am using

    Code:
     document.getElementById(reply.ElementID).innerHTML = reply.content;
    Instead of your

    Code:
    $('#plugin').load('" + FileName + @"');
    This wil only update the div (element ID) you want. In this case both .content and .ElementID are an JSON attribute name returned by the plugin.

    Maybe this helps you on track?

    Wim
    -- Wim

    Plugins: JowiHue, RFXCOM, Sonos4, Jon00's Perfmon and Network monitor, EasyTrigger, Pushover 3P, rnbWeather, BLBackup, AK SmartDevice, Pushover, PHLocation, Zwave, GCalseer, SDJ-Health, Device History, BLGData

    1210 devices/features ---- 392 events ----- 40 scripts

    Comment


      #3
      Hmm, not really, I need to make ajax call from timer and update div.

      It was implemented in HS3:

      pageCommands.Add("starttimer", "");

      Comment


        #4
        Hi Alex, I'm by far NO expert on HTML but I ended up writting my own code to update individual divs. Recall asking Rich about it, how I would use the AJAX functions, meaning the functions that HS used/delivered and he told me to write my own because they could always change theirs. So I looked at their code and realized (something probably many people just know) that AJAX is nothing more than a periodic check in with the server (and you can send data along with that to be specific about what you want from the server), write functions on the server that do something based on the data that was provided in the server call, respond in a specific way so the client side can understand what needs updating.

        Example:
        - my player html code, uses a JQuery AJAX call, 2 seconds periodicity, that triggers a post to my (through HS3) registered URL, the HS3 embedded server calls my PI
        - In the PI, the call has data indicating this is an AJAX call, the PI quickly checks if any state of the player has changed and if it did, it generate the inner HTML of the div that changed and return that in a sort of list of key (div id) and value (inner HTML) back to the client
        - In the client, you go throught the list (javascript), take the div id and inner HTML value and use that to update the div on your page.

        This is how that code looks like:

        Code:
          $('#' + sResponse[i]).empty();
          $('#' + sResponse[i]).html(sResponse[i+1]);


        To make this all work, the divs you want updated needs to have a unique ID. Secondly, whatever info is in the DIV, your server needs to generate exactly the same content (inner HTML) and it is the latter that makes generic use of AJAX updates hard and why I think you cannot rely on HS procedures. If you study the code in say the devices.html code, you see that the HS team is using the reference ID as DIV ids, so they can in a more generic way, when a device changed state/value, do updates. This is "generic" but comes with major limitations if you want to do more complex things. Example: say my player would like to present different buttons depending on what it is doing ....

        I hope this helps, this was new to me. Here is an example of AJAX processing Javascript (called every 2 seconds by the timer on the client). If you do some digging you would see that this is a a copy from what HS is doing but with changes and renamed so only my PI would use this.


        Code:
            function AjaxPost_(data,page){
            $.ajax({
                type: "POST",
                async: "true",
                url: '/'+page,
                cache:false,
                data: data,
                success: function (response) {
        
                    if (response == '') {
                        after_postback();
                        return;
                    }
                    var sResponse;
                    sResponse = eval('(' + response + ')');
                    //alert(response);
                    for(i=0; i<sResponse.length; i+=2) {
                        if(sResponse[i]==null) continue;
                        if(sResponse[i].substr(0,5) == 'PAGE_') {
                            var pageCmd=sResponse[i].substr(5);
                            switch(pageCmd.toLowerCase()) {
                                case 'popmessage':
                                    alert(sResponse[i + 1]);
                                    after_postback();
                                    break;
                                case 'newpage':
                                    location.assign(sResponse[i+1]);
                                    //window.location.replace(sResponse[i+1]);
                                    break;
                                case 'refresh':
                                   // alert(sResponse);
                                    if(sResponse[i+1].toLowerCase() == 'true') {
                                        returnTrue = true;
                                        location.reload();
                                    }
                                    break;  
                                 //   case '':                          
                            }
                        }
        
        // this is my PI's code, but note how you can use response tags to show little messages etc (above here w popmessage) or open a new page or complete reload (refresh) the current page
        
                        else {
                            if(sResponse[i].substr(0,13) == 'navigatemore_') {
                                var itemTable = document.querySelector ("#sonosplayernav > tbody ");
                                itemTable.removeChild (itemTable.lastChild);
                                itemTable = itemTable.innerHTML + sResponse[i+1];
                                $('#sonosplayernav > tbody ').empty();
                                $('#sonosplayernav > tbody ').html(itemTable);
                            }
                            else{
                                if ( (muteSliderUpdates > 0) && ((sResponse[i].substr(0,22) == 'playertrackpositiondiv') || (sResponse[i].substr(0,29) == 'playertrackcurrentpositiondiv') || (sResponse[i].substr(0,20) == 'playertracklengthdiv')) ) {
                                    // no updating!
                                }
                                else {
                                    $('#' + sResponse[i]).empty();
                                    $('#' + sResponse[i]).html(sResponse[i+1]);
                                    after_postback();
                                }
                            }
                        }
                    }            
                },
                error: function(){
                  //  alert("Error");
                }
            });
        I hope this is helpful, for me it hasn't been an easy ride, and now I start running into yet more issues and complexity (Bootstrap related)

        Comment


          #5
          by the way, this is to set up the periodic timer

          Code:
          
                  function docready() {
                      refreshID = setInterval(deviceUpdateAjax, 2000);
          
                  }
          
          
                  function deviceUpdateAjax() {
                      if (muteSliderUpdates > 0 ) { 
                          muteSliderUpdates = muteSliderUpdates - 1;
                      }
                      else 
                      {
                          muteSliderUpdates = 0;
                      }
                      AjaxPost_("deviceudn="+deviceUdn+"&nav-item=refresh","SonosV4/sonos-player.html");
                      //console.log("Ajax Refresh :" + muteSliderUpdates);
                  }

          Comment


            #6
            Thanks dcorsus , I did it simpler, still not best, but looks cleaner.

            I have two separate html files - one for whole page where in addition to the ususal headers, liguid, bootstrap, etec. I have only a div for my stuff, and the whole HTML page is created in C#:

            Code:
            <div id="plugin">
                 {{ plugin_function 'AKGoogleCast' 'GetHTML' ['my-devices'] }}
            </div>

            And for the timer html I have only one line:
            Code:
            {{ plugin_function 'AKGoogleCast' 'GetHTML' ['my-devices'] }}
            In JS I start the timer using
            Code:
            $(window).on('load', function() {
                setInterval(function(){ $('#plugin').load('my-timer.html'); }, 2000);
            });

            Comment


              #7
              Note that for the timer ajax callback the html file name doesn't include plugin subfolder, only the file name.

              And the best part is - since I generate HTML in C# code - I can reuse both html files between all my plugins, just need to change the plugin name in the plugin_function call

              Comment


                #8
                That's whole html file:

                Click image for larger version  Name:	html.jpg Views:	0 Size:	106.8 KB ID:	1443267

                C#

                Click image for larger version  Name:	html1.jpg Views:	0 Size:	90.2 KB ID:	1443269


                Result:

                Click image for larger version

Name:	mydevices.jpg
Views:	118
Size:	77.6 KB
ID:	1443508

                Comment


                  #9
                  I started out that way as well when I first began converting HS3 to HS4. Only problem with that is that you can only regenerate a whole page if anything on it is dynamic, no?

                  Click image for larger version

Name:	player.png
Views:	132
Size:	306.9 KB
ID:	1443274

                  Comment


                    #10
                    I guess nothing prevent you from creating your pages in your PI and still use AJAX to update sections of it, principle is the same as above, you need some mechanism to tell the client side what to update. For some stupid reason, I do a bit of both, some parts in HTML, some generated in the PI .... It is easier to test and develop just manipulating an HTML page and just hit "refresh" over changing the PI code but on the other hand, if you want to make very context aware pages, doing it on the client side isn't perhaps a good idea to start with.
                    I can tell that whatever I'm doing is WAY too effort intensive and I wish there was a much easier way

                    Comment


                      #11
                      You can have multiple divs and separate html file to update each div.
                      But my main question is - instead of multiplying html files - there should be away to pass div id to the ajax call - and then handle it in the C#

                      Comment


                        #12
                        Sure, see this code, it sends data back to the PI (lgname and lgindex) and upon return updates the body in a modal window. Maybe I'm missing your point. You can make this generic in that you post the devid to your PI, generate new HTML and upon return update that DIV

                        Code:
                          $('#editLGButton').on('show.bs.modal', function (e) {
                            var button = $(e.relatedTarget);
                            var datatarget = button[0].attributes.getNamedItem("lgname").value
                            // transfer content to modal body
                            // get the LinkgroupInfo and populate the body
                            $("#editLGbtn").attr("lgname",datatarget);
                            var lgindex = button[0].attributes.getNamedItem("lgindex").value
                            $("#editLGbtn").attr("lgindex",lgindex);
                            data = "editlgname="+datatarget+"&lgindex="+lgindex;
                            $.ajax({
                                    type: "POST",
                                    async: "true",
                                    url: 'SonosV4/sonos-settings.html',
                                    cache: false,
                                    data: data,
                                    success: function(response){
                                        if (response !== "") {
                                          $('#modalBodyEditLGButton').html(response);
                                          return;
                                        }
                                    },
                                    error: function(){
                                        alert("Unable to edit Linkgroup : Unknown Error");
                                    }
                                });
                          })




                        Comment


                          #13
                          Thinking of your last remark, maybe a clarification:

                          Two very destinct sources to trigger an update:

                          1/ you do something on the client side, say click a button, image, pull a slider etc. In this case the change happened on the client so you write some javascript (assuming you want to do something non standard) which passes enough information, typically a unique id or a class to your PI, your PI processes the POST and return update information. The information typically updates something in between tags, could be divs but could be anything you wrote in your javascript.

                          2/ the server has a change but can't tell your client, hence you use a periodic ajax call from your client and IF there is a change on the server, the server, in its response will inform the client what has changed. Again, totally under your control how you want to do that but typically some new HTML (or plain text) that goes between some existing tags. If you give the tags a unique id and the server knows that id (like in your case where the server generated all the html code), the server can send any key/value update to your client to update whatever part you want.

                          Is this helpful or known or still missing the point?

                          Comment


                            #14
                            Originally posted by dcorsus View Post
                            Is this helpful or known or still missing the point?
                            Thank you. I do both. I lost my point now, I will have to re-think what exactly was my problem.

                            Comment


                              #15
                              BTW, dcorsus - how do you create a combpbox and handle selection?

                              Comment

                              Working...
                              X