variantjs / vue

Vue Variantjs
https://variantjs.netlify.app
182 stars 13 forks source link

How to set the label of a RichText component with fetchOptions? #28

Open jaulz opened 3 years ago

jaulz commented 3 years ago

As far as I can see the component needs the options itself to resolve the label. Is there any way to set the label in another way?

alfonsobries commented 3 years ago

@jaulz what do you mean by label? The option label?

jaulz commented 3 years ago

@alfonsobries yep, when you use fetchOptions the options are retrieved on the fly and the selected option label is derived by searching for the key within the options result. However, initially there are no options and thus the value (which is the key) cannot determine the option label so it looks empty.

alfonsobries commented 3 years ago

@jaulz ok made some tests and I will need to adjust the select field

In those cases you usually have two options:

  1. Add an initial set of options that include the option that you want to pre-select in your rich select (otherwise there is no way to know what are the value)

^ hardcoded some values and that is not working currently

  1. Use the prefetchOptions prop that when set it will call the fetchOptions once the component is mounted

^ found two issues here: a) the fetchOptions sometimes require a search query (or a minimum search input length) so I will need to add some kind of prefetchOptionsQuery prop to be used within the prefetchOptions so it loads the results properly b) even if you don't need to use a search query (you can, for example, modify your fetchOptions to ensure it loads the option you need) the option once loaded is not being selected

So in summary ill create a new task to fix both issues, meanwhile think will not be possible

jaulz commented 3 years ago

Thanke for having a look! Another idea would be to pass a function to prefetchOptions which is of the same type as the fetchOptions prop and which defines how to fetch the initial options. Usually, the latter filters the label of the option but for the initial load we would like to search by the key of the option. What do you think?

alfonsobries commented 3 years ago

@jaulz good idea!, definitely will try that

alfonsobries commented 3 years ago

@jaulz follow up on this, I'm working on the feature that allows u to add a function on the prefetchOptions prop but one correction with my previous comment, you can actually add an initial set of options if you want that a value is preselectedd

You just need to ensure that the options match the format returned from the ajax call (if you are using a custom value-attribute or a custom text-attribute)

See this working example:

<template>
  <t-rich-select
    v-model="preselectedOption"
    :options="initialSet"
    :fetch-options="fetchOptions"
    :minimum-input-length="3"
    value-attribute="imdbID"
    text-attribute="Title"
  />
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import TRichSelect from '../components/TRichSelect.vue';

const fetchOptions = (query?: string, nextPage?: number) => {
  const url = `https://www.omdbapi.com/?apikey=e1b3617e&s=${query}&page=${nextPage || 1}`;

  return fetch(url)
    .then((response) => response.json())
    .then((data) => ({
      results: data.Search as Record<string, any>[],
      hasMorePages: data.Search && data.totalResults > (data.Search.length * (nextPage || 1)) * 10,
    }));
};

export default defineComponent({
  name: 'RichSelect',
  components: {
    TRichSelect,
  },
  data() {
    return {
      fetchOptions,
      initialSet: [
        {
          Title: 'The Matrix',
          Year: '1999',
          imdbID: 'tt0133093',
          Type: 'movie',
          Poster: 'https://m.media-amazon.com/images/M/MV5BNzQzOTk3OTAtNDQ0Zi00ZTVkLWI0MTEtMDllZjNkYzNjNTc4L2ltYWdlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_SX300.jpg',
        },
      ],
      preselectedOption: 'tt0133093',
    };
  },
});
</script>

If you see the initialSet attribute it contains the option in the exact same format that the ajax call return so the value can be preselected

of course that only will work in the cases you are able to build that first set, if you need to make an ajax call that's another history, adding a prefetchOptions should work but that's a WIP feature

jaulz commented 3 years ago

@alfonsobries thanks a lot for your feedback! Unfortunately, I had no chance to have a look at this this week but I will do so next week and maybe raise a PR for the prefetchOptions if it makes sense 😊

alfonsobries commented 3 years ago

@jaulz added the possibility of using prefetchOptions as a function see example on PR https://github.com/variantjs/vue/pull/45 (^ 0.0.17)