Select dmx-on:changed doesn't run function but dmx-on:blur does

Can anyone explain why this works using dmx-on:blur

<select id="select2" class="form-control" dmx-bind:options="sc_tripbits_list.data.query1" optiontext="title" optionvalue="tripbit_id" dmx-bind:value="context.custom.tripbit_id" dmx-on:blur="updateImage('{{public_id}}','{{select2.value}}')"></select>

but dmx-on:changed doesn’t?

<select id="select2" class="form-control" dmx-bind:options="sc_tripbits_list.data.query1" optiontext="title" optionvalue="tripbit_id" dmx-bind:value="context.custom.tripbit_id" dmx-on:changed="updateImage('{{public_id}}','{{select2.value}}')"></select>

dmx-on:updated doesn’t work either.

Thanks,
Heather

Hi,

I used the changed event recently, and its working fine. Can you check if there are any errors in the console or network tab in the browser dev tools?
Also, updateImage… is it a JS function? That could be a reason why this is not working.

If you could share the link to your page, it would be helpful.

If you are using custom javascript functions you should call them using static events, not dynamic events.

It simply doesn’t run when it’s in the changed. It is a custom javascript function.

Putting it in a static event doesn’t pass the dynamic values so if I log say the public_id in the console I get {{public_id}}, rather than the value, when putting the call into onupdated.

<select id="select2" class="form-control" dmx-bind:options="sc_tripbits_list.data.query1" optiontext="title" optionvalue="tripbit_id" dmx-bind:value="context.custom.tripbit_id" onupdated="updateImage('{{public_id}}','{{select2.value}}')"></select>

There are no errors or any other messages logged in the console.

Well you need to use dmx.parse if you want to use dynamic values with js functions.

So, like Teodor says, you cannot call JS functions like this.
You need to use FLOWS.
With Run Javascript option, you can pass dynamic values to the javascript function.

I would recommend to use FLOW instead of dmx parse. Since dmx.parse won’t work if you need to do this in a repeat. It would just be a more uniform code everywhere using FLOWS.

@Heather_Mann dynamic events are used only for running component actions and NOT custom js code.
Custom js code should only be called using static events or as Sid explains using flows > run JS.

Example use of static event:

onupdated="alert(dmx.parse('select2.value'))"

maybe if you explain the exact function and use case we would be able to help you.

If I do this…

<select id="select2" class="form-control" dmx-bind:options="sc_tripbits_list.data.query1" optiontext="title" optionvalue="tripbit_id" dmx-bind:value="context.custom.tripbit_id" onchanged="updateImage(dmx.parse('public_id'),dmx.parse('select2.value'))"></select>

This returns undefined - undefined in the console.

function updateImage(public_id, tripbit_id){
console.log(public_id + " - " + tripbit_id);
$.post( “update_meta.php”, { public_id: public_id, tripbit_id: tripbit_id, bgcolor: bgcolor })
.done(function( data ) {
});
}

I’m working with the Cloudinary API (which is awesome if you haven’t run across it). The function runs an ajax call to update the meta data of the image on Cloudinary.

This is in a repeat - and it does work using dmx-on:blur which I find odd.

I haven’t worked with FLOWS at all so perhaps I should look into that as a better option?

Thanks!

I haven’t used FLOW before. Will look into that now. Thanks.

Flow looks cool, but I’m getting the same result. (undefined - undefined in the console). Here’s the code…

<body is="dmx-app" id="flow_test">
<dmx-api-datasource id="api_images" is="dmx-fetch" url="https://res.cloudinary.com/tripmakers/image/list/51.json"></dmx-api-datasource>
<script is="dmx-flow" id="flow1" type="text/dmx-flow">{
  exec: {
steps: {
  runJS: {
    function: "updateImage",
    args: ["{{masonry1[0].public_id}}", "{{masonry1[0].select_tripbit.value}}"],
    name: "update_image_flow",
    output: true 
  }
},
catch: {
  bootbox.alert: {title: "Alert", message: "Something went wrong"}
}
  }
}</script>
<dmx-serverconnect id="sc_tripbits_list" url="dmxConnect/api/Tripbits/tt_tripbits_list.php" dmx-param:trip_id="51"></dmx-serverconnect>
<div class="container">
    <div class="row" is="dmx-masonry" id="masonry1" dmx-bind:repeat="api_images.data.resources">
        <div class="col">
            <div class="card">
                <img class="card-img-top" alt="Card image cap" dmx-bind:src="'https://res.cloudinary.com/tripmakers/image/upload/w_300/v1602453360/'+public_id+'.'+format">
                <div class="card-body">
                    <select id="select_tripbit" class="form-control" dmx-bind:options="sc_tripbits_list.data.query1" optiontext="title" optionvalue="tripbit_id" dmx-bind:value="context.custom.tripbit_id" dmx-on:changed="flow1.run()"></select>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="bootstrap/4/js/popper.min.js"></script>
<script src="bootstrap/4/js/bootstrap.min.js"></script>

<script>
    function updateImage(public_id, tripbit_id){
	        console.log(public_id + " - " + tripbit_id);
	        // $.post( "update_meta.php", { public_id: public_id, tripbit_id: tripbit_id})
  	        // .done(function( data ) { });
	 }
</script>

</body>

This all works except for passing the correct values when changing the select.

Thanks for your help!!
Heather

Maybe @patrick can help here more.

You can’t access the data like that.

Try one of the following expression instead of {{masonry1[0].public_id}}.

{{ masonry1.items[0].public_id }}

or

{{ api_images.data.resources[0].public_id }}

Thanks Patrick!!

{{ masonry1.items[0].public_id }} worked, however the code I was using was generated by Wappler so I think that might be a bug?

You can see when I select public_id in the Data binding it reverts to masonry1[0].public_id.

Hmmm - I thought this was working, but it’s returning the public_id and the tripbit_id information for the first record in the json file no matter which item I pick.

    <body is="dmx-app" id="flow_test">
    <script is="dmx-flow" id="flow2" type="text/dmx-flow"></script>
    <dmx-api-datasource id="api_images" is="dmx-fetch" url="https://res.cloudinary.com/tripmakers/image/list/51.json"></dmx-api-datasource>
    <script is="dmx-flow" id="flow1" type="text/dmx-flow">{
  exec: {
    steps: {
      runJS: {
        function: "updateImage",
        args: ["{{masonry1.items[0].public_id }}", "{{masonry1.items[0].select_tripbit.value}}"],
        name: "update_image_flow",
        output: true 
      }
    },
    catch: {
      bootbox.alert: {title: "Alert", message: "Something went wrong"}
    }
  }
}</script>
    <dmx-serverconnect id="sc_tripbits_list" url="dmxConnect/api/Tripbits/tt_tripbits_list.php" dmx-param:trip_id="51"></dmx-serverconnect>
    <div class="container">
        <div class="row" is="dmx-masonry" id="masonry1" dmx-bind:repeat="api_images.data.resources">
            <div class="col">
                <div class="card">
                    <img class="card-img-top" alt="Card image cap" dmx-bind:src="'https://res.cloudinary.com/tripmakers/image/upload/w_300/v1602453360/'+public_id+'.'+format">
                    <div class="card-body">
                        <select id="select_tripbit" class="form-control" dmx-bind:options="sc_tripbits_list.data.query1" optiontext="title" optionvalue="tripbit_id" dmx-bind:value="context.custom.tripbit_id" dmx-on:changed="flow1.run()"></select>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="bootstrap/4/js/popper.min.js"></script>
    <script src="bootstrap/4/js/bootstrap.min.js"></script>

    <script>
        function updateImage(public_id, tripbit_id){
	        console.log(public_id + " - " + tripbit_id);
	        // $.post( "update_meta.php", { public_id: public_id, tripbit_id: tripbit_id})
  	        // .done(function( data ) { });
	 }
    </script>

</body>

Thanks!

I got this working, but it seems a little dicky to do it this way. I created two variables to hold the selected public_id and tripbit_id’s and update those on data changed, followed by the flow that runs the javascript.

<body is="dmx-app" id="flow_test">
    <dmx-value id="var_public_id"></dmx-value>
    <dmx-value id="var_tripbit_id"></dmx-value>
    <dmx-api-datasource id="api_images" is="dmx-fetch" url="https://res.cloudinary.com/tripmakers/image/list/51.json"></dmx-api-datasource>
    <script is="dmx-flow" id="flow1" type="text/dmx-flow">{
  exec: {
    steps: {
      runJS: {
        function: "updateImage",
        args: ["{{var_public_id.value}}", "{{var_tripbit_id.value}}"],
        name: "update_image_flow",
        output: true
      }
    },
    catch: {
      bootbox.alert: {title: "Alert", message: "Something went wrong"}
    }
  }
}</script>
    <dmx-serverconnect id="sc_tripbits_list" url="dmxConnect/api/Tripbits/tt_tripbits_list.php" dmx-param:trip_id="51"></dmx-serverconnect>
    <div class="container">
        <div class="row" is="dmx-masonry" id="masonry1" dmx-bind:repeat="api_images.data.resources">
            <div class="col">
                <div class="card">
                    <img class="card-img-top" alt="Card image cap" dmx-bind:src="'https://res.cloudinary.com/tripmakers/image/upload/w_300/v1602453360/'+public_id+'.'+format">
                    <div class="card-body">
                        <select id="select2" class="form-control" dmx-bind:options="sc_tripbits_list.data.query1" optiontext="title" optionvalue="tripbit_id" dmx-bind:value="context.custom.tripbit_id"
                            dmx-on:changed="var_tripbit_id.setValue(value);var_public_id.setValue(public_id);flow1.run()"></select>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="bootstrap/4/js/popper.min.js"></script>
    <script src="bootstrap/4/js/bootstrap.min.js"></script>

    <script>
        function updateImage(public_id, tripbit_id){
	        console.log(public_id + " - " + tripbit_id);
	        $.post( "update_meta.php", { public_id: public_id, tripbit_id: tripbit_id})
  	        .done(function( data ) { });
	 }
    </script>

</body>

This is an ok solution. A better solution would be to use params. Or a local flow.

Since you have created a page level flow, you can just pass the current two values to the flow as params, and then pass them to the Run JS call.

OR

If this is a one off use of this JS call, you can just create a local flow on the event itself, and there, pass the two values in the Run JS call.

Both options eliminate the requirement of variable.