Fogpuppy
Fogpuppy

So for clarity my js currently looks something like this:

function runTextUpdate()
{
    $.request('onUpdateTextField', {
          success: function() {
           console.log('Text field updated.');
          }
    })
}

and it need to be:

function runTextUpdate()
{
    $.request('onUpdateTextField')
}

Is that correct? And I'm also assuming this might be a good place to try to grab values of the page and just pass them as parameters to onUpdateTextField ... could I just use something like

$.document.getElementById("someTxtField")

and then pass it somehow to the onUpdateTextField function?

Last updated

Fogpuppy
Fogpuppy

BTW I tried the code above for runTextUpdate and the partal is STILL not being updated.

I also tried this:

function runTestUpdate()
{
   $.request('onUpdateTextField',{
        update: { autoresult: '#result' }
    });
}

No joy with that either ... What am I doing wrong?

mjauvin
mjauvin

I would try the following:

function runTextUpdate()
{
    $('form').request('onUpdateTextField');
}

with:

function onUpdateTextField()
{
    return [  
      '#result' => $this->renderPartial('autoresult', ['method'=>'Txt Timer', 'result'=>1]),
    ];
}

If that doesn't work, there is something I am missing... If I could see the full code in a github repo, that might make it easier to debug.

Last updated

Fogpuppy
Fogpuppy

OK I figured out why I was seeing such strange behaviors we could not understand. The primary problem that I was having was that the CMS backend was acting like it was saving my JS updates but it wasn't. I had walked away and left my Backend session running and when it came back it asked me if I wanted to leave the page (I said "No") and then after that it was acting like it was saving but it wasn't. And just closing the browser window didn't seem to cut it. Rebooting the system fixed my editing issues and after that stuff started to act more sensible.

I do have a final writeup for the various different ways to make this work and the subtle differences. Do you want me to post it here? Or do we want a separate "tutorial" kind of post?

Last updated

mjauvin
mjauvin

I suggest posting it here AND creating a trick at https://octobertricks.com

Fogpuppy
Fogpuppy

Ok here is the final solution. Much thanks to @mjauvin for help with this.

To get parts of a page to update periodically you need to use a combination of JS and partials. The first part is to add a JS "asset" to your site to setup the timer(s) and then include that in the page startup. The timer.js to setup this example looks like this:

$(document).ready( function() {
    T1_timeout = setInterval(runT1, 5000);  // trigger every 5s
    T2_timeout = setInterval(runT2, 7000);  // trigger every 7s
    T3_timeout = setInterval(runT3, 9000);  // trigger every 9s
});

function runT1()
{
    //Basic  - The function called must use return to make partial render
    $.request('onT1');
}
function runT2()
{
    //Form based invocation - Inputs of the form are available to the function
    //partials mentioned in the form's data-request-update are automatically invoked.
     $('form').request('onT2');
}
function runT3()
{
    //Partial update built in
    $.request('onT3',{
        update: { autoresult: '#result' }
    });
}

The function runT1 is the generic example and requires onT1 define the partial to render in it's return. The function runT2 invokes onT2 with the form on the page so the form inputs are available to the function. It will also automatically rendered any partial defined in the data-request-update of the form. The function runT3 has an a built in update to render a specific partial. This could be useful if you want to always render a specific partial after a timer runs.

The partial we're going to use is really simple and looks like this:

<span class="lead">
    Triggered by  <span class="label label-success">{{ method }}</span> <br/>
    The result is: {{ result }}
</span>

The page that is used looks like this:

<div class="panel-body">
        <form role="form" class="form-inline" data-request="onBtn" data-request-update="autoresult: '#result'">
            <input type="text" class="form-control" value="Value 1" name="v1" style="width:100px"><br/>
            <input type="text" class="form-control" value="Value 2" name="v2" style="width:100px">
            <button type="submit" class="btn btn btn-primary" data-attach-loading>Btn</button>
        </form>
</div>

<div class="panel-footer" id="result">
   {% partial "autoresult" %}
</div>
<div class="panel-footer" id="result2">
   {% partial "autoresult" %}
</div>

with code that looks like this:

function onStart()
{
    //load the timers
   $this->addJs('assets/aircraft/timer.js'); 
   $this['method'] = 'None';
}
function onBtn()
{
    $this['method'] = 'Btn';
    $this['result'] =  input('v1') . '+'. input('v2'); 

}
function onT1()
{
    $this['method'] = 'T1';
    $this['result'] = "General Txt";
    return [  
        '#result' => $this->renderPartial('autoresult'),
    ];
}
function onT2 ()
{
    $this['method'] = 'T2';
    $this['result'] = input('v1');
}
function onT3 ()
{
    $this['method'] = 'T3';
    $this['result'] = "P1";
    //make it also update the second partial
     return [  
      '#result2' => $this->renderPartial('autoresult', ['method'=>'P2 Txt', 'result'=>"P2"]),
    ];
}

Note in the onStart $this->addJs('assets/aircraft/timer.js'); to start the timers and invocations of the the various onT# functions.

Note in onT1 it is the return that causes the partial with ID 'result' to render. This is required to cause the partial to update.

Note in onBtn and onT2 there is no return to update the partials. That is because the form on the page has data-request-update="autoresult: '#result'" which will cause the update of the partial to happen automatically.

Note in onT3 that a second partial with the ID 'result2' that is updated via the return statement with totally different values from those stored in $this. This is addition to the standard partial 'result' defined in the timer JS.

I hope this is helpful to other people. Let me know if there are any questions or errors.

mjauvin
mjauvin

Nicely documented Post!!!

Did you submit this on OctoberTricks as well? That would be awesome!

Fogpuppy
Fogpuppy

I am going to but I have not yet. I wanted to see if you (or anyone) else had comment or questions before submitting it. I was going to give it a day or two to see if there was any feedback.

BTW do we change the original topic in the forum to "Solved: xxx" or some such thing when we solve a problem so people know it has a solution?

mjauvin
mjauvin

It's always a good idea to mark it solved, yes!

Fogpuppy
Fogpuppy

BTW I didn't put it in my example but I'd like to clarify one thing. Earlier I asked about accessing data on the page. Your idea of $('form').request('onT2'); works for a lot of cases where you want to get data on the form element but ... if I wanted to get arbitrary (non-form) data fyou had suggested

$value = <fetch form field value wih jquery here>;
$.request('onUpdateTextField', {data: {field: $value}});

I didn't try this yet but i'm assuming that in my function I use something like $val = input('field'); is this correct? And if I need more than one value, I just do something like:

$v1 = <fetch some element value wih jquery here>;
$v2 = <fetch some other element value wih jquery here>;
$.request('onUpdateTextField', {data: {f1: $V1},{f2: $v2}});

then in my function i use input('f1') and input('f2') BTW I might have the syntax wrong on the request...

mjauvin
mjauvin

It depends where the value you want to get is located... I don't think input('field') is going to work in javascript...

But using jQuery syntax, you could do:

v1 = $('form input[name="myField"]').val();
v2 = $('form input[name="myField"]').val();

The request call would be like:

$.request('onUpdateTextField', {data: {f1: v1, f2: v2}})
Fogpuppy
Fogpuppy

Not sure I follow this ... How does it "know" that v1 is supposed to be from f1 on the request? Should it be

v1 = $('form input[name="f1"]').val();
v2 = $('form input[name="f2"]').val();

And as one last follow on question. How does this work if there is more than one form on the page? Ho opdes it know which form is which?

mjauvin
mjauvin

those were just examples, you can use whatever css selector is needed to find the proper field/form

21-33 of 33