Fogpuppy
Fogpuppy

This may be the wrong place to ask this and if so redirect me to the right place ...

I'm trying to create a page that has two fields that needs to be updated every 15 seconds with the output of php scripts. There is two variants of this.

The first is to update a text area with some content every 15 seconds with the content of a php script.

The second is to change the drop-down list options based on the results of a php script.

I think I know how to the first one with a meta tag to refresh the page every 15 seconds and the onstart command but it keeps clearing out my other fields. Plus redrawing the whole page just to update one field seems crazy. Is there some way to trigger a script/update just one field every 15 seconds.

The second one I don't really know how to handle it because I'm not sure how to update a drop-down dynamically in the October system every x seconds ....

mjauvin
mjauvin

I would use the AJAX JavaScript API to do this:

https://octobercms.com/docs/ajax/javascript-api#javascript-api

Just add a timer in your JavaScript that will trigger the calls below every 15 seconds...

$.request('onUpdateTextField', {
    success: function() {
        console.log('Finished!');
    }
})

$.request('onUpdateDropdownField', {
    success: function() {
        console.log('Finished!');
    }
})

You can add the JavaScript file with the calls above using the page onStart() method like this:

function onStart()
{
    $this->addJs('assets/js/app.js');
}

ref. https://octobercms.com/docs/cms/pages#injecting-assets

Fogpuppy
Fogpuppy

First ... Thank you very much.

Second .... I have a few follow on questions that I hope are not too annoying. I'm sort of a newbie to October and Web development. I have a long and strong tech background but I'm playing around with a new venture during Covid and a lot of this is still new to me ....

So for clarity I put the code you supplied in the file assets/js/app.js (or whatever asset file I want). Then the code in onStart will inject this code into the page. The functions will run when the timer triggers. Now here comes the really stupid questions ...

Where/How do I start the timer and set it to trigger these functions. if I wanted different timers for each update is that possible?

Last updated

mjauvin
mjauvin

You could set the timer in the $(document).ready() like this:

$(document).ready( function() {
    // trigger the text update every 15s
    textField_timeout = setInterval(function(){
      runTextUpdate()
    }, 15000);

    // trigger the text update every 25s
    selectField_timeout = setInterval(function(){
      runSelectUpdate()
    }, 25000);

})

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

Again ... thanks a lot for suffering through my really stupid questions. I love the simplicity of setting up and using OctoberCMS so far. Is there a way to buy a support contract so I can support the efforts by the team and ... to defray the cost of answering my stupid questions?

One more stupid question. In addition to onStart is there a list of standard functions like this that are called and when they are called?

Fogpuppy
Fogpuppy

and yet one more dumb question. I went in thru the UI to "Assets" added my own directory (that worked it created the directory) and then clicked "Add" and added a file. That sort of worked in that I got a UI to enter my javascript but no file was created. And then when I try to save the file it does not save. I must be doing something wrong .... or I've got some sort fo permissions issue. I'm on linux using nginx

mjauvin
mjauvin
mjauvin

Fogpuppy said:

and yet one more dumb question. I went in thru the UI to "Assets" added my own directory (that worked it created the directory) and then clicked "Add" and added a file. That sort of worked in that I got a UI to enter my javascript but no file was created. And then when I try to save the file it does not save. I must be doing something wrong .... or I've got some sort fo permissions issue. I'm on linux using nginx

That should work.

Fogpuppy
Fogpuppy

Ok Thanks thanks thanks ...

I'll look for some sort of permissions problem for the last issue......

Fogpuppy
Fogpuppy

Ok ... I know I'm missing something obvious but I guess I don't understand the interaction between the php functions and the fields on the page. I've verified that the js is getting injected and my onUpdateTextFunction function is getting called by the timer but I must not be doing the right thing in the php functions to update the field.....

If this were JavaScript I'd do something like document.getElementById('myTextarea').value = 'asdgf';

What would equivalent in the php function called by the timer? And does anything else need to be done to get it to refresh the field after the update. I know I must be being really dense ....

mjauvin
mjauvin

Read the docs under "Pushing partial updates" here:

https://octobercms.com/docs/ajax/update-partials

mjauvin
mjauvin

Show your code/markup and we can go from there

Fogpuppy
Fogpuppy

OK sorry for the delay .... I got diverted to a different issue for a few days. I used the Ajax "Calculator" from the OctoberCMS Demo as an example to work form. My page looks basically like this like this:

<div class="panel-body">
    <form role="form" class="form-inline" data-request="onTest" data-request-update="autoresult: '#result'">
        <input type="text" class="form-control" value="15" name="value1" style="width:100px">
        <select class="form-control" name="operation" style="width: 70px">
            <option>+</option>
            <option>-</option>
            <option>*</option>
            <option>/</option>
        </select>
        <input type="text" class="form-control" value="5" name="value2" style="width:100px">
        <button type="submit" class="btn btn btn-primary" data-attach-loading>Calculate</button>
    </form>
</div>
<div class="panel-footer" id="result">
    {% partial "autoresult" %}
</div>

My Partial looks like this:

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

My code looks like this:

function onStart()
{
   $this->addJs('assets/aircraft/timer.js');
   $this['method'] = 'None';
}
function OnTest()
{
    $value1 = input('value1');
    $value2 = input('value2');
    $operation = input('operation');
    $this['method'] = 'Btn';
    switch ($operation) {
        case '+' :
            $this['result'] = $value1 + $value2;
            break;
        case '-' :
            $this['result'] = $value1 - $value2;
           break;
     ...
    }
}
function onUpdateTextField()
{
    $this['method'] = 'Txt Timer';
    $this['result'] = 1;
   return [  '#result' => $this->renderPartial('autoresult')  ];
}
function onUpdateSelectField ()
{
    $this['method'] = 'Select Timer';
    $this['result'] = 2;
    return [  '#result' => $this->renderPartial('autoresult') ];
}

My timers are triggering and my functions are being called. But ... that partial is not being updated after return. It does get updated in the onTest function.

Also as a follow on question: I want to access the values of the form in the timer methods but obviously the input('field') is not the right call because there is no form input at that point.

mjauvin
mjauvin

Unless your timer methods are triggering within the form, the form fields won't be available.

You could pass the form fields value like this:

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

But the better way is to use this method:

$('form').request('onUpdateTextField', ...

That will trigger the ajax request in the form context, thus, passing its fields values in the POST data...

Fogpuppy
Fogpuppy

ok ... I see where you're going on the form fields ...

Can you help me understand why my partial is not being updated after the timer function. I think I was doing the right thing to push the update ....

mjauvin
mjauvin

Yeah, I don't know, it should work. What's the code you used in the onTest() handler to push the update?

Fogpuppy
Fogpuppy

the onTest function is being invoked by the form in

 <form role="form" class="form-inline" data-request="onTest" data-request-update="autoresult: '#result'">

and it works ok. The partial autoresult is getting updated after the button click.

mjauvin
mjauvin

you're PULLING the partial update... you can do the same when calling your timers handler by providing the "update:" options, see the documentation I reference in this thread

mjauvin
mjauvin

Oh, I think I know your problem... remove the success handler in your JSON AJAX request... it will prevent october ajax handler to run

success

a callback function to execute in case of a successful request. If this option is supplied it overrides the default framework's functionality: the elements are not updated, the beforeUpdate event is not triggered, the ajaxUpdate and ajaxUpdateComplete events are not triggered. The event handler gets 3 arguments: the data object received from the server, the text status string and the jqXHR object. However, you can still call the default framework functionality calling this.success(...) inside your function.

1-20 of 33