coreui / coreui-vue

Bootstrap 5 based Vue 3 components and directives. CoreUI for Vue.js replaces and extends the Bootstrap 5 javascript. Components have been built from scratch as true Vue 3 components.
https://coreui.io/vue/docs/getting-started/introduction.html
MIT License
610 stars 128 forks source link

CDataTable tableFilter slots #96

Closed slav0nic closed 4 years ago

slav0nic commented 4 years ago

In current implementation here is no slots for blocks with tableFilter, paginator and it is not possible extend this block (that looks good for add some extra filters for example).

So, will be fine have move slots under table for this

https://github.com/coreui/coreui-vue/blob/2c6927e1dbc080a3f34b855235af773b1760056a/src/components/table/CDataTable.vue#L3-L43

slav0nic commented 4 years ago

ops, missed #over-table slot, not same what i need, but got authors point of view

woothu commented 4 years ago

Asking for development purposes: what was the needed feature, that made it necessary for customization?

slav0nic commented 4 years ago

sad that coreui still don't have some board/github discussion enabled or gitter room for this (https://gitter.im/coreui/community still empty) =)

I using default filter, mixing it with external filters and here is so much empty space in filter/pagination row that can't be used without rewriting component template =( for example https://ibb.co/gMGSKMf

also (not related to issue) will be nice add some docs how rewriting/extending/wrapping default components, for example, for now, for changing default column filter type from input to select i did some tricks for reusing coreui component methods/data in overriden slots (that required acces to columnFilterEvent and CDataTable.data):


<CDataTable
        ref="table"
...
      >
        <template #access-filter>
          <select
            class="form-control form-control-sm"
            @input="$refs.table.columnFilterEvent('access', $event.target.value, 'input')"
          >
            <option value selected="selected">Any</option>
            <option value="Public">Public</option>
            <option value="Private">Private</option>
          </select>
        </template>
        ...
</CDataTable>
woothu commented 4 years ago

sad that coreui still don't have some board/github discussion enabled or gitter room for this (https://gitter.im/coreui/community still empty) =)

Its worth consideration, but on the other hand having all discussion on issues makes it easier to research the history of changes

I using default filter, mixing it with external filters and here is so much empty space in filter/pagination row that can't be used without rewriting component template =( for example https://ibb.co/gMGSKMf

Although I agree with the point, our aim is to keep components as simple as possible. That's why we use slots for customizations.

also (not related to issue) will be nice add some docs how rewriting/extending/wrapping default components, for example, for now, for changing default column filter type from input to select i did some tricks for reusing coreui component methods/data in overriden slots (that required acces to columnFilterEvent and CDataTable.data):

Such hacking is not necessary since you have columnFilterValue prop and update:column-filter-value event

slav0nic commented 4 years ago

@woothu forget ask you about correct server side CForm elements validation, current implementation looks not good for this, i also checked coreui-vue-laravel version, that use some mixing templates.

Here is simple case when i want validate submitted form data on server (in some case will be fine use both: basic frontend validation and server-side) Now i using something like this:

<template>
  <CForm @submit.prevent="submit">
    <CAlert :color="alertColor" :show="alertShow" v-html="alertMessage" />
    <CInput
      label="Email"
      placeholder="Enter Email"
      name="email"
      type="email"
      v-model="form.email"
      :invalid-feedback="invalidFeedback('email')"
      :is-valid="isValidField('email')"
      required
    />
    <CInput
      label="Password"
      placeholder="Enter Password"
      name="password"
      type="password"
      v-model="form.password"
      :invalid-feedback="invalidFeedback('password')"
      :is-valid="isValidField('password')"
      required
    />
    <CButton color="success" size="sm" @click="submit">Submit</CButton>
  </CForm>
</template>

<script>
export default {
  name: "AddUser",

  data() {
    return {
      errors: [],
      form: {
        email: null,
        password: null
      }
    };
  },
  methods: {
    invalidFeedback(field) {
      if (this.errors.length > 0) {
        let error = this.errors.find(e => e.name === field);
        return error ? error.description : "";
      }
      return this.name;
    },
    isValidField(field) {
      if (this.errors.length > 0) {
        let error = this.errors.find(e => e.name === field);
        return error ? false : true;
      }
    },
    async submit() {
      try {
        const response = await AccountsService.add(this.form);
        this.errors = [];
        this.alertShow = false;
        this.notification("Account created", "success");
        //... success
      } catch (error) {
          // error example {"code":400,"errno":107,"error":"Invalid parameters","message":"password in body: Required","details":[{"location":"body","name":"password","description":"Required"}]}

          this.errors = error.data.details;
        }
      }
    }
  }
}
</script>

Maybe it make sense have something in core for this? Or can you show how coreui authors see the solution? At least documentation/admin-template need some improvements or this more related to non-free version?

woothu commented 4 years ago

Components are written in a way to be independent units which means that backend integration practices are totally up to the developer. Nevertheless, we have the backend integration section in docs https://coreui.io/vue/docs/introduction/template.html#backend-integration which will be probably extended in the future. As you noticed we also have laravel template which shows some backend integration examples, also PRO templates have more usage examples besides additional features.