vue-generators / vue-form-generator

:clipboard: A schema-based form generator component for Vue.js
MIT License
2.99k stars 532 forks source link

Customising a field's template #373

Open donalmurtagh opened 6 years ago

donalmurtagh commented 6 years ago

I found various issues that ask whether it is possible to customise a field's template, e.g. #232 #136. I also found this commit which attempts to make a field's template customisable, but it's unclear what the current status of this feature is?

As far as I can tell, there is currently no way to change the markup in a field's template (though obviously the style can be changed via CSS), is this correct?

Also, the documentation mentions

Bootstrap friendly templates

But the project does not appear to have a dependency on Bootstrap. Does "Bootstrap friendly" simply mean that the CSS classes used in the templates are the same as those used by Bootstrap, e.g. form-group and form-control?

andrelec1 commented 6 years ago

I think the most simple way is using a customField as a 'wrapper'

and yes for bootstrap answere ;) ( look the template : https://github.com/vue-generators/vue-form-generator/blob/master/src/formGenerator.vue )

donalmurtagh commented 6 years ago

I think the most simple way is using a customField as a 'wrapper'

@andrelec1 Could you show an example of how to do this, e.g. how would I customize the <input> field templates by adding the following at the top

<p>my custom text</p>
andrelec1 commented 6 years ago
import Vue from 'vue';
import Datepicker from 'vuejs-datepicker';
import VueFormGenerator from 'vue-form-generator';

Vue.component('fieldDatePicker', {
  template: '<datepicker :placeholder="schema.placeholder" v-model="datePicker_model"></datepicker>',
  components: {
    Datepicker,
  },
  data: function() {
    return {
      datePicker_model: '',
    };
  },
  mixins: [VueFormGenerator.abstractField],
  mounted() {
    this.datePicker_model = this.schema.default;
  },
  watch: {
    datePicker_model: function(newValue, OldValue) {
      if(this.format(newValue) !== this.format(OldValue)) {
        this.setModelValueByPath(this.schema.model, this.format(newValue));
      }
    },
  },
  computed: {
    value: {
      get: function() {
        return this.$moment(this.datePicker_model).format('DD-MM-YY')
      },
      set: function(newValue) {
        throw 'TODO : ' + newValue;
        // TODO converte and set value ! this.datePucker_model = newValue;
      },
    },
  },
});

this is my personal field for a datePicker ( WIP ) ( maybe need some improuvement but i think is a good start )

andrelec1 commented 6 years ago
import Vue from 'vue';
import Datepicker from 'vuejs-datepicker';
import VueFormGenerator from 'vue-form-generator';

Vue.component('fieldDatePicker', {
  template: '<datepicker :placeholder="schema.placeholder" v-model="datePicker_model"></datepicker>',
  components: {
    Datepicker,
  },
  data() {
    return {
      datePicker_model: '',
    };
  },
  mixins: [VueFormGenerator.abstractField],
  mounted() {
    this.datePicker_model = this.modelNameToProperty(this.schema.model);
  },
  methods: {
    modelNameToProperty(modelName) {
      return modelName
        .replace(/\[(\w+)\]/g, '.$1')
        .replace(/^\./, '')
        .split('.')
        .map(x => _.snakeCase(x))
        .reduce((a, b) => (a && a.hasOwnProperty(b) ? a[b] : null), this.model);
    },
    format(date) {
      return this.$moment(date).format('DD-MM-YY');
    },
  },
  watch: {
    datePicker_model(newValue, OldValue) {
      if (this.format(newValue) !== this.format(OldValue)) {
        this.setModelValueByPath(this.schema.model, this.format(newValue));
      }
    },
  },
  computed: {
    value: {
      get() {
        return this.format(this.datePicker_model);
      },
    },
  },
});