Jan Zikmund
Jan Zikmund

Reputation: 686

Alpine.js - sync computed field back to model

I have a form with some dynamic inputs, and I need to define a readonly computed field, which will have a value count from other fields. This I am doing using x-bind:value='myFormulaFunction()' and it shows the value on the field correctly, and it even updates live if the variables change.

The problem is how to sync this count value back to the model. Even when I define x-model on the field, it doesn't update with the value. And apparently no functions like @change and @input are triggered on the value update either, neither does x-effect.

I made a quick fiddle here: https://jsfiddle.net/janzikmund/cm3zqeyj/12/

I know I should probably make a get function to achieve this, but I am doing this within x-for of dynamically generated array and having the logic on the field itself would just be much more convenient. Anything I am missing?

Upvotes: 0

Views: 1282

Answers (1)

Dauros
Dauros

Reputation: 10577

For that purpose you can use the $watch magic method that actually supports watching for multiple variables. So when one of the variables changes, it updates the value of count.sum.

Note: $watch checks for each child attribute, so don't watch the whole count variable because it will cause an infinite loop.

<script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>
  <div x-data="{ count: { f1: 0, f2: 0, sum: 0} }"
       x-init="$watch('count.f1,count.f2', () => {count.sum = !isNaN(count.f1) && !isNaN(count.f2) ? parseInt(count.f1) + parseInt(count.f2) : 0})">
  <input type="number" x-model="count.f1">
  <input type="number" x-model="count.f2">
  <input type="text" readonly x-model="count.sum">
  <h2 x-text="count.sum"></h2>
</div>

Upvotes: 1

Related Questions