ratiw / vuetable-2

data table simplify! -- datatable component for Vue 2.x. See documentation at
https://vuetable.com
MIT License
2.16k stars 400 forks source link

Refresh Field Titles.. #186

Open jdriesen opened 7 years ago

jdriesen commented 7 years ago

Hi,

First of all, CONGRATZ with the development of this great component ! It works like a charm, and the documentation is super self explaining. Thanks.

I've a question about updating the field titles... My application is supporting multiple languages...

The 'title' of each field can be set in the 'data' function of a component. (at that moment I'm using the default language (english) for 'title'. => My table is loaded...

The user has the possibility to change the language... I'm able to load the new 'title' values...

Though, how can I "force" your vue-table to 'redraw' (or update) the title field values ? I was hoping a 'nexttick' would help me out, but that doesn't seem to be the case...

Anybody here who's willing to give me a help ?

Thanks in advance,

Johnny

XjeaxaxX commented 7 years ago

Mind you, I am using vuetable-2 in a manner which is probably different than most...

In my setup, I have:

Vue.component('data-table', { ... methods: { ... refreshTable() { Vue.nextTick(() => this.$refs.vuetable.refresh()); } } });

Then, I create the Vue:

VM = new Vue({ ... methods: { doRefresh (id) { this.$refs[id].refreshTable(); } } });

Then, when I do something elsewhere in javascript land, I update the underlying datatable(s)... setting new titles, fields, etc... and then I call:

VM.doRefresh('my__datatable');

Dunno if this helps at all... but here's to hoping!

ratiw commented 7 years ago

@jdriesen Try calling normalizeFields() again after you've modified the fields definition in fields prop.

jdriesen commented 7 years ago

@ratiw : normalizeFields() did the trick. Thanks !

@XjeaxaxX : I'm using more or less the same approach... Though, a Vue.nextTick(() => this.$refs.vuetable.refresh()); isn't enough to refresh the 'titles'. You still need to perform the normalizeFields() function....

Grtz & THANKS both for your time to reply. Johnny (Belgium)

XjeaxaxX commented 7 years ago

Ooops. I forgot to put that in my post. I call that in my transform method. If I don't pre-define my fields, I set them dynamically in the transform function, based on the data that is piped into the vuetable. That's where I call normalizeFields()

jdriesen commented 7 years ago

@XjeaxaxX

Thanks for the update. As written in a previous post... I'm doing more or less the same :) Making evrt as generic as possible with super clear code... That's why I like Vue !!

(FYI: I'm an ex-Angular guy...they lost me after their switch to 2.rubbish)

Thanks again, Cheers and keep on coding.

Grtz, Johnny

jdriesen commented 7 years ago

@ratiw : This post is dated when I was using vuetable-2 version 1.6.3. Now I've been updating to 1.6.5. Is it possible that normalizeFields() doesn't work anymore when I want to update the column titles ?

Maybe I should clarify a bit WHY I'm using this... I have a multi-language application.

  1. Default language is English.
  2. Table data is loaded (column titles are shown in English)
  3. The user is still able to change the language of the APP

==> It would be great if the 'titles' can be 'refreshed' (i.e. reset with the translated texts) without a reload of the data ...

PS.: The translation itself is NOT a problem, it's just about being able to refresh the titles above the columns...

Any help is appreciated... Thanks in advance.

Grtz, Johnny

ratiw commented 7 years ago

normalizeFields should still work as I haven't modified it.

However, in the next release of Vuetable, the title option in fields definition can be a function. And this would make swapping title text to a different language a lot easier, like swapping out the lang object, without having to call normalizeFields.

jdriesen commented 7 years ago

Hi,

Yes, indeed... having a function available to define the title would be THE perfect solution. I can already 'see' the code in front of me ... A function

Super cool. :)

If I can ask (without willing to force anything...) when do you plan to have the next release available ?

Grtz, Johnny

ratiw commented 7 years ago

@jdriesen Just push it to the develop branch. You can see the examples here

jdriesen commented 7 years ago

@ratiw 👍 Works like a charm !!! Thank you !

Kind regards, Johnny (Belgium)

antonioribeiro commented 6 years ago

In version 1 there was no need to call normalizeFields(), or anything else, as far as I can tell, so this should be noted as another breaking change.

My use case is to let the user show/hide columns:

image

And this was all I had to do to make the whole thing work:

<div class="checkbox" v-for="field in fields">
    <label>
        <input type="checkbox" v-model="field.visible">
        @{{ field.title == '' ? field.name.replace('__', '') : field.title }}
    </label>
</div>

Which, of course, is not working after upgrading to v2.

nachodd commented 6 years ago

I managed to solve translations in title in this way. The problem I was facing was that if I use a function to declare the title, I can't pass an argument to this to get the translation of that specific title. And I don't want to declare a function per title to get the translation, becouse I have to many columns. But, if I declare the fields like this:

data () {
  return {
    fields: [
    {
      title: this.getTitle.bind(this,'translation_key'),
      name: 'id',
    },
    ....

And in methods:

methods: {
  getTitle (keyLang) {
    return this.$t(keyLang) // this.$t == i18n plugin
  },
  ...

This method works. But it feels a little bit dirty. And I dont have to refresh the table neither call normalizeFields(). So, what you guys think about this? Is there a "cleaner" way to achieve this? Many thanks!

ratiw commented 6 years ago

@nachodd I thought you would use it like this.

data () {
  return {
    fields: [
      {
        title: this.$t(keyLang),
        name: 'id',
      },
    ]
  }
}

Sorry, I don't fully understand your point as I do not use i18n myself. If you can clarify your point a little bit, maybe I can look into that.

nachodd commented 6 years ago

The point is, if I define the fields like you said:

fields: [
      {
        title: this.$t(keyLang),
        name: 'id',
      },
    ]

They are evaluated on mounted time, resulting this.$t(keyLang) a simple String. So if a change the language, it's not being re-evaluated, so the title it's not updated at all. My question was about if the approach was at least, fine.

BTW, many thanks for taking time to answer. You've done a really great work!

ratiw commented 6 years ago

@nachodd The following seems to work.

fields: [
  {
    title: () => this.$t(keyLang),
    name: 'id',
  }
]

I think it's the same as your solution, but with arrow function it looks a bit cleaner.