How to add own JavaScript functions?

Previously in versions up to 2019 the following small script worked to pull up a small window with directory display - by just including it in the Global Client Scripts: -

function cdpics(cd) {
PicsWindow=window.open(cd,'pics','resizable=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,width=700,height=700');
PicsWindow.focus();                                                                                                                         
}

It was called from the menu with the following statement: -
javascript: cdpics(‘…/…/db/audiog_data/charts’)I have read the help file for 2020 and https://www.hkvforums.com/viewtopic.php?f=4&t=45593#p144291.
I’m still left confused and the script doesn’t work after trying many ‘stabs’ at the code - eg

loadjs.ready("load", function() {
function cdpics(cd) {
PicsWindow=window.open(cd,'pics','resizable=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,width=700,height=700');
PicsWindow.focus();                                                                                                                         
}

I’m still using the same menu statement to call it - doesn’t work

You may change:function cdpics(cd) {

}towindow.cdpics = function(cd) {

};

acollee wrote:
it - doesn’t workPlease post the error message that shown from “Console” section after pressing [F12] from your browser, for more discussion.

Hi Mobhar
Tried arbel’s suggestion and that didn’t work either.
Put everything back to the original as in my first post.(a) Console error message: -

VM2446:1 Uncaught ReferenceError: cdpics is not defined at :1:1
(anonymous) @ VM2446:1(b) Generated script in file header: -

loadjs.ready(“head”, function() {

// Global client script
// Write your client script here, no need to add script tags.
// To include another .js script, use:
// ew.clientScriptInclude("my_javascript.js");

loadjs.ready("load", function() {

function cdpics(cd){
PicsWindow=window.open(cd,'pics','resizable=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,width=700,height=700');
PicsWindow.focus();                                                                                                                         
}

});

acollee wrote:
Uncaught ReferenceError: cdpics is not definedThat means, the cdpics function is not recognized, since it was now wrapped inside this following block:loadjs.ready(“head”, function() {

});So, the solution for your case is, you need to make your function can be seen/called from outside that block.

Fortunately, PHPMaker has provided the Javascript global variable named “ew.vars”. Then, simply change your code below:
function cdpics(cd){to:
ew.vars.cdpics = function(cd){After that, to call that function, you may simply change your code:
javascript: cdpics(‘…/…/db/audiog_data/charts’)to:
javascript: ew.vars.cdpics(‘…/…/db/audiog_data/charts’)And one more thing, always put/declare your own functions in “Client Script” section and not in “Startup Script” under the “Client Scripts” that related to your desired scope/page.

To be honest, I found this after doing some experimental action a few hours ago, and I am happily to share this with you. :slight_smile:

Brilliant!
Works perfectly now.
Thank youGlobal Client Script: -
// Write your client script here, no need to add script tags.
// To include another .js script, use:
// ew.clientScriptInclude(“my_javascript.js”);ew.vars.cdpics = function(cd){
PicsWindow=window.open(cd,‘pics’,‘resizable=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,width=700,height=700’);
PicsWindow.focus();
}Calling Script (in menu): -
javascript: ew.vars.cdpics(‘…/…/db/audiog_data/charts’)

arbei wrote:
You may change:function cdpics(cd) {

}towindow.cdpics = function(cd) {

};You better use window.cdpics so that you can simply call it by:javascript:cdpics(‘…/…/db/audiog_data/charts’)

acollee wrote:
Tried arbel’s suggestion and that didn’t work either.@arbei, I and @acollee have tried your suggestion, unfortunately, it did not work. So, please try to use ew.vars. I and @acollee have tried, and it works properly.

It does work. Note that if you put the function in global client script, you need to wait until the global script is loaded (after spinner stops). If you want the function available earlier, do not put it in global script, you may put it in, for example, Page_Head server event with script tag, e.g.
cdpics() {

}// orwindow.cdpics = function() {

};

In this case, we are not talking about “Page_Head” server event, but we are talking about “Client Script” under the “Client Scripts” → “Global” → “Pages with header/footer” section. That’s why your code does not work if put in “Client Script” section.

Remember, since first post above, @acollee informed us that the code is wrapped inside this following block:
loadjs.ready(“load”, function() {

});So, the solution should be the code that related to that “Client Script” event.

loadjs.ready(“load”, function() { … }) means the function will be called after “load” is ready (all the scripts are loaded), if a function is added to an existing object inside the function, the function will only be available until all the scripts are loaded, no matter what the object is.

Server Events - Table-Specific - Common - Row_Rendered

// Row Rendered event
function Row_Rendered()
{
    // To view properties of field class, use:
    //var_dump($this-><FieldName>);

    $this->Jumlah->EditAttrs["onkeyup"] = "Calculate(this, ".$this->RowIndex.");";
    $this->Nilai->EditAttrs["onkeyup"] = "Calculate(this, ".$this->RowIndex.");";
}

Client Scripts - Table-Specific - List Page - Startup Script

// Write your table-specific startup script here, no need to add script tags.

Calculate = function(thisObject, rowIndex) {
    var form = thisObject.form;
    var jumlah = form.elements["x"+rowIndex+"_Jumlah"];
    var nilai = form.elements["x"+rowIndex+"_Nilai"];
    var nominal = form.elements["x"+rowIndex+"_Nominal"];
    jumlah.value = jumlah.value.replaceAll(',', '');
    nilai.value = nilai.value.replaceAll(',', '');
    nominal.value = parseFloat(jumlah.value.replaceAll(',', '')) * parseFloat(nilai.value.replaceAll(',', ''));
};

result ::

<script>
loadjs.ready("load", function () {
    // Startup script
    // Write your table-specific startup script here, no need to add script tags.
    Calculate = function(thisObject, rowIndex) {
        var form = thisObject.form;
        var jumlah = form.elements["x"+rowIndex+"_Jumlah"];
        var nilai = form.elements["x"+rowIndex+"_Nilai"];
        var nominal = form.elements["x"+rowIndex+"_Nominal"];
        jumlah.value = jumlah.value.replaceAll(',', '');
        nilai.value = nilai.value.replaceAll(',', '');
        nominal.value = parseFloat(jumlah.value.replaceAll(',', '')) * parseFloat(nilai.value.replaceAll(',', ''));
    };
});
</script>

it works for me