1

I would like to link multiple inputs via VueJS and compute the values.

The inputs are to track vehicle mileage, and therefore any given day's value, cannot be less than the previous day's value.

Linked Inputs

So far I have come up with the following (it's very convoluted and I know it can be tidied up but I'll improve on that later). It doesn't work, as you can't change any value apart from Monday Start.

https://jsfiddle.net/mstnorris/qbgtpm34/1/

HTML

<table id="app" class="table">
    <thead>
    <tr>
        <th>Day</th>
        <th>Start</th>
        <th>End</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <th scope="row">Mon</th>
        <td>
            <input type="number" class="form-control" v-model="mon_start" number id="mon_start" placeholder="Monday Start Mileage">
        </td>
        <td>
            <input type="number" class="form-control" v-model="mon_end" number id="mon_end" placeholder="Monday End Mileage">
        </td>
    </tr>
    <tr>
        <th scope="row">Tue</th>
        <td>
            <input type="number" class="form-control" v-model="tue_start" number id="tue_start" placeholder="Tuesday Start Mileage">
        </td>
        <td>
            <input type="number" class="form-control" v-model="tue_end" number id="tue_end" placeholder="Tuesday End Mileage">
        </td>
    </tr>
    <tr>
        <th scope="row">Wed</th>
        <td>
            <input type="number" class="form-control" v-model="wed_start" number id="wed_start" placeholder="Wednesday Start Mileage">
        </td>
        <td>
            <input type="number" class="form-control" v-model="wed_end" number id="wed_end" placeholder="Wednesday End Mileage">
        </td>
    </tr>
    <tr>
        <th scope="row">Thu</th>
        <td>
            <input type="number" class="form-control" v-model="thu_start" number id="thu_start" placeholder="Thursday Start Mileage">
        </td>
        <td>
            <input type="number" class="form-control" v-model="thu_end" number id="thu_end" placeholder="Thursday End Mileage">
        </td>
    </tr>
    <tr>
        <th scope="row">Fri</th>
        <td>
            <input type="number" class="form-control" v-model="fri_start" number id="fri_start" placeholder="Friday Start Mileage">
        </td>
        <td>
            <input type="number" class="form-control" v-model="fri_end" number id="fri_end" placeholder="Friday End Mileage">
        </td>
    </tr>
    <tr>
        <th scope="row">Sat</th>
        <td>
            <input type="number" class="form-control" v-model="sat_start" number id="sat_start" placeholder="Saturday Start Mileage">
        </td>
        <td>
            <input type="number" class="form-control" v-model="sat_end" number id="sat_end" placeholder="Saturday End Mileage">
        </td>
    </tr>
    <tr>
        <th scope="row">Sun</th>
        <td>
            <input type="number" class="form-control" v-model="sun_start" number id="sun_start" placeholder="Sunday Start Mileage">
        </td>
        <td>
            <input type="number" class="form-control" v-model="sun_end" number id="sun_end" placeholder="Sunday End Mileage">
        </td>
    </tr>
    </tbody>
</table>

VueJS

new Vue({
    el: "#app",
    data: {
        mon_start: '',
        mon_end: '',
        tue_start: '',
        tue_end: '',
        wed_start: '',
        wed_end: '',
        thu_start: '',
        thu_end: '',
        fri_start: '',
        fri_end: '',
        sat_start: '',
        sat_end: '',
        sun_start: '',
        sun_end: ''
    },
    computed: {
        mon_end: function() {
            return this.mon_start
        },
        tue_start: function () {
            return this.mon_end
        },
        tue_end: function() {
            return this.tue_start
        },
        wed_start: function () {
            return this.tue_end
        },
        wed_end: function() {
            return this.wed_start
        },
        thu_start: function () {
            return this.wed_end
        },
        thu_end: function() {
            return this.thu_start
        },
        fri_start: function () {
            return this.thu_end
        },
        fri_end: function() {
            return this.fri_start
        },
        sat_start: function () {
            return this.fri_end
        },
        sat_end: function() {
            return this.sat_start
        },
        sun_start: function () {
            return this.sat_end
        },
        sun_end: function() {
            return this.sun_start
        }
    }
})

1 Answer 1

3

Why does this not work so far?

You are mixing data property names with computed properties, so the value will be read from the computed property (get) and it will try to write it back to the same computed property, which wont work since you haven't assigned a setter.

Also, always showing the value of mon_start in mon_end etc. will not allow you to show the updated value of mon_end in mon_end.

Computed: Getters and Setters

What you actually want is a custom action to happen when a new value is set (e.g. mon_start is set to 2, thus all other fields should be set to 2).

Now we could just say: If mon_start is updated, update mon_end. If mon_end is updated, update tue_start. And so on.

This can be achieved using computed setters:

    mon_start_model: {
        get: function() {
              return this.mon_start
            },
        set: function(val) {
            this.mon_start = val
            this.mon_end_model = this.mon_start
        }
    },

I've simplified the example a little bit (using only Monday and Tuesday).

Avoiding confusing the user

As an extra condition for user-friendliness, you probably only want the next value to update if the next value is smaller or equal to the previous value.

Eg. mon_start is 1 at the beginning, then you update mon_end to 5, then you update mon_start to 3. You probably want mon_end to keep the value 5, right?

new Vue({
    el: "#app",
    data: {
        mon_start: 0,
        mon_end: 0,
        tue_start: 0,
        tue_end: 0,
    },
    computed: {
        mon_start_model: {
            get: function() {
                  return this.mon_start
                },
            set: function(val) {
                this.mon_start = val
                this.mon_end_model = Math.max(this.mon_end, this.mon_start)
            }
        },
        mon_end_model: {
            get: function() {
                return this.mon_end
            },
            set: function(val) {
                this.mon_end = val
                this.tue_start_model = Math.max(this.tue_start, this.mon_end)
            }
        },
        tue_start_model: {
            get: function () {
                return this.tue_start
            },
            set: function(val) {
                this.tue_start = val
                this.tue_end_model = Math.max(this.tue_end, this.tue_start)
            }
        },
        tue_end_model: {
            get: function() {
                return this.tue_end
            },
            set: function(val) {
                this.tue_end = val
            }
        }
    }
})

https://jsfiddle.net/qbgtpm34/5/

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.