0

I want to change table values when a user selects a value from the dropdown menu. By default, the values are in Metric. If a user selects Standard then I want to run some math on each value and to convert metric to standard. Also being able to switch back to Metric.

https://jsfiddle.net/tmun9cxa/13/

html

<div class="form-filter">
  <select name="type" v-model="filter_unit" v-on:change="onSelectUnitChange">
    <option value="metric">Metric</option>
    <option value="standard">Standard</option>
  </select>
</div><!-- /filter -->

  <table style="text-align: center;">
    <thead>
      <tr>
        <th v-for="column in columns">
          <a 
            href="#"
            v-on:click="sort(column.shortcode)">{{column.label}}
          </a>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(product) in showProducts">
        <td>{{product.pn}}</td>
        <td>{{product.od}}</td>
        <td>{{product.id}}</td>
        <td>{{product.thickness}}</td>
        <td>{{product.lo}}</td>
        <td>{{product.weight}}</td>
      </tr>
    </tbody>
  </table>
</div><!-- /app -->

Javascript

    var vm = new Vue({
        el: '#app',
        data: {
            currentSort: 'pn',
            currentSortDir: 'asc',
            category: 'all',
            filter_unit: 'metric',
            search: '',
            columns: [
                { label: 'P/N', shortcode: 'pn' },
                { label: 'OD (De,mm)', shortcode: 'od' },
                { label: 'ID (De,mm)', shortcode: 'id' },
                { label: 'Thickness (De,mm)', shortcode: 'thickness' },
                { label: 'LO', shortcode: 'lo' },
                { label: 'Weight (kg/1000)', shortcode: 'weight' },
            ], // columns
            products: [
                { 
                    pn: 170158,
                    od: 13,
                    id: .44,
                    thickness: 1,
                    lo: .45,
                    weight: .7,
                    category: 'chrome',
                },{ 
                    pn: 1803561,
                    od: 12,
                    id: .8,
                    thickness: .7,
                    lo: .11,
                    weight: .5,
                    category: 'chrome',
                },{ 
                    pn: 170149,
                    od: 9,
                    id: .64,
                    thickness: .6,
                    lo: .75,
                    weight: .3,
                    category: 'stainless',
                },{ 
                    pn: 150149,
                    od: 15,
                    id: .22,
                    thickness: .3,
                    lo: .55,
                    weight: .9,
                    category: 'chrome',
                },
            ], // products
        },
        computed: {
            showProducts(){         
                return this.products
                .filter(a => {
                    return (a.pn + '').includes(this.search)
                })
                .sort((a, b) => {
                    if (this.currentSortDir === 'asc') {
                        //console.log( this.currentSort );
                        return a[this.currentSort] >= b[this.currentSort];      
                    }
                    return a[this.currentSort] <= b[this.currentSort];
                })
            }
        },
        methods: {
            sort:function(col) {
                // if you click the same label twice
                if(this.currentSort == col){
                    // sort by asc
                    this.currentSortDir = this.currentSortDir === 'asc' ? 'desc' : 'asc';
                }else{
                    this.currentSort = col;
                }
            }, // sort

        onSelectUnitChange:function(){
                if(this.filter_unit == 'standard'){
                // change values of OD using this equation. current OD value * 0.0393701
                // change table header OD(De,mm) to OD(De,in)
                // also will be doing a similar process to ID and Thickness
                console.log('standard change');
                }
            },

        }, // methods
    }); // vue
2
  • 1
    not sure what metrix will do, but you could add some codes into computed property=**showProducts** to implement addition calculation, like this fiddle. Commented Aug 13, 2018 at 18:22
  • Could you elaborate on the units? What each one of them are supposed to be in Metric and Standard (I assume you meant Imperial, right?) Commented Aug 13, 2018 at 19:19

2 Answers 2

5

You may add the logic on your computed property and check the v-model of the dropdown. I've updated your sample see https://jsfiddle.net/tmun9cxa/74 With my example I didn't change your existing computed but you can simply add your logic to that

filteredProducts() {
  let filteredProducts = []
  let _product
  this.showProducts.forEach(product => {
    _product = product
    // do the logic here
    if (this.filter_unit === 'metric') {
      _product.displayWeight = _product.weight * 25
    } else if (this.filter_unit === 'standard') {
      _product.displayWeight = _product.weight + 10
    }
    filteredProducts.push(_product)
  })
  return filteredProducts
}

Update: Another option is to use Vue filters. I've updated your example using filters http://jsfiddle.net/eywraw8t/274069

filters: {
    convertOd(val, type) {
      if (type === 'metric') {
          return val * 0.0393701
      } else if (type === 'imperial') {
        return val
      }
    }
}

or

Vue.filter('convertOd', function (val, type) {
  if (type === 'metric') {
    return val * 0.0393701
  } else if (type === 'imperial') {
    return val
  }
})

and to use it in html

<td>{{ product.od | convertOd(filter_unit) }}</td>
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks this answers my main question. Now I have a problem with it remembering my past values for the column OD. When you select imperial it does the conversion... but then why doesnt it switch back to normal when you select metric again? Heres a more updated fiddle: jsfiddle.net/eywraw8t/272176
don't touch your main attributes, create new attribute where you display your fields with logic. check my example above with the displayWeight
I've updated my answer, another option is to use filters
Thanks these filters are really simple and cool. But when you select Imperial from the dropdown, the other filters no longer work correctly with the new conversion. For example: if you select imperial, then filter OD min by .2 and by max of 1. its still looking for the default metric numbers Updated fiddle: jsfiddle.net/bghouse/eywraw8t/278615
1

You could use computed properties but your code could work as it is.

I just applied conversions on values in the onSelectUnitChange function and it worked.

onSelectUnitChange:function(){
  if(this.filter_unit == 'standard'){
    this.products.forEach(p => {
      p.od *= 0.0393701
      p.id *= 0.0393701
      p.thickness *= 0.0393701
    })
    this.columns[1].label = "OD(De,in)"
    this.columns[2].label = "ID(De,in)"
    this.columns[3].label = "Thickness(De,in)"
  } else {
    this.products.forEach(p => {
      p.od /= 0.0393701
      p.id /= 0.0393701
      p.thickness /= 0.0393701
    })
    this.columns[1].label = "OD(De,mm)"
    this.columns[2].label = "ID(De,mm)"
    this.columns[3].label = "Thickness(De,mm)"
  }
}

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.