Feature: Disabled fields (#98)

* Feature: Disabled fields

* disable field for rating

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
Chirag Chhatrala 2023-03-22 20:19:52 +05:30 committed by GitHub
parent db43b2825c
commit 9b3f5ddbdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 60 additions and 17 deletions

View File

@ -9,7 +9,7 @@
<prism-editor :id="id?id:name" v-model="compVal" :disabled="disabled" <prism-editor :id="id?id:name" v-model="compVal" :disabled="disabled"
class="code-editor" class="code-editor"
:class="[theme.CodeInput.input,{ 'ring-red-500 ring-2': hasValidation && form.errors.has(name), 'cursor-not-allowed bg-gray-200':disabled }]" :class="[theme.CodeInput.input,{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }]"
:style="inputStyle" :name="name" :style="inputStyle" :name="name"
:placeholder="placeholder" :placeholder="placeholder"
:highlight="highlighter" @change="onChange" :highlight="highlighter" @change="onChange"

View File

@ -58,8 +58,10 @@ export default {
computed: { computed: {
inputClasses (){ inputClasses (){
const str = 'border border-gray-300 dark:bg-notion-dark-light dark:border-gray-600 dark:placeholder-gray-500 dark:text-gray-300 flex-1 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-opacity-100 placeholder-gray-400 px-4 py-2 rounded-lg shadow-sm text-base text-black text-gray-700' let str = 'border border-gray-300 dark:bg-notion-dark-light dark:border-gray-600 dark:placeholder-gray-500 dark:text-gray-300 flex-1 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-opacity-100 placeholder-gray-400 px-4 py-2 rounded-lg shadow-sm text-base text-black text-gray-700'
return this.dateRange ? str + ' w-50' : str + ' w-full' str += this.dateRange ? ' w-50' : ' w-full'
str += this.disabled ? ' !cursor-not-allowed !bg-gray-200' : ''
return str
}, },
useTime() { useTime() {
return this.withTime && !this.dateRange return this.withTime && !this.dateRange

View File

@ -9,7 +9,7 @@
<span class="inline-block w-full rounded-md shadow-sm"> <span class="inline-block w-full rounded-md shadow-sm">
<button type="button" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label" role="button" <button type="button" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label" role="button"
class="cursor-pointer relative flex" class="cursor-pointer relative flex"
:class="[theme.default.input,{'ring-red-500 ring-2': hasValidation && form.errors.has(name)}]" :class="[theme.default.input,{'!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled}]"
:style="inputStyle" @click.self="showUploadModal=true" :style="inputStyle" @click.self="showUploadModal=true"
> >
<div v-if="currentUrl==null" class="h-6 text-gray-600 dark:text-gray-400 flex-grow truncate" <div v-if="currentUrl==null" class="h-6 text-gray-600 dark:text-gray-400 flex-grow truncate"
@ -190,6 +190,13 @@ export default {
}, },
watch: { watch: {
showUploadModal: {
handler (val) {
if(this.disabled){
this.showUploadModal = false
}
}
},
files: { files: {
deep: true, deep: true,
handler (files) { handler (files) {

View File

@ -12,7 +12,7 @@
<loader v-if="loading" key="loader" class="h-6 w-6 text-nt-blue mx-auto" /> <loader v-if="loading" key="loader" class="h-6 w-6 text-nt-blue mx-auto" />
<div v-for="(option, index) in options" v-else :key="option[optionKey]" role="button" <div v-for="(option, index) in options" v-else :key="option[optionKey]" role="button"
:class="[theme.default.input,'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 flex',{ 'mb-2': index !== options.length,'ring-red-500 ring-2': hasValidation && form.errors.has(name), 'cursor-not-allowed bg-gray-200':disabled }]" :class="[theme.default.input,'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 flex',{ 'mb-2': index !== options.length,'!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }]"
@click="onSelect(option[optionKey])" @click="onSelect(option[optionKey])"
> >
<p class="flex-grow"> <p class="flex-grow">
@ -53,6 +53,10 @@ export default {
computed: {}, computed: {},
methods: { methods: {
onSelect (value) { onSelect (value) {
if(this.disabled){
return
}
if (this.multiple) { if (this.multiple) {
const emitValue = Array.isArray(this.compVal) ? [...this.compVal] : [] const emitValue = Array.isArray(this.compVal) ? [...this.compVal] : []

View File

@ -10,9 +10,9 @@
<div class="stars-outer"> <div class="stars-outer">
<div v-for="i in numberOfStars" :key="i" <div v-for="i in numberOfStars" :key="i"
class="cursor-pointer inline-block" class="cursor-pointer inline-block"
:class="{'text-yellow-400':i<=compVal, 'text-yellow-100 dark:text-yellow-900':i>compVal && i<=hoverRating ,'text-gray-200 dark:text-gray-800':i>compVal && i>hoverRating}" :class="{'text-yellow-400':i<=compVal, 'text-yellow-100 dark:text-yellow-900':i>compVal && i<=hoverRating ,'text-gray-200 dark:text-gray-800':i>compVal && i>hoverRating, '!cursor-not-allowed':disabled}"
role="button" @click="setRating(i)" role="button" @click="setRating(i)"
@mouseover="hoverRating = i" @mouseover="hoverRating = (disabled) ? null : i"
@mouseleave="hoverRating = null" @mouseleave="hoverRating = null"
> >
<svg class="w-8 h-8" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <svg class="w-8 h-8" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
@ -56,6 +56,9 @@ export default {
methods: { methods: {
setRating (val) { setRating (val) {
if(this.disabled){
return
}
if (this.compVal === val) { if (this.compVal === val) {
this.compVal = 0 this.compVal = 0
} else { } else {

View File

@ -7,7 +7,7 @@
<span v-if="required" class="text-red-500 required-dot">*</span> <span v-if="required" class="text-red-500 required-dot">*</span>
</label> </label>
<vue-editor :id="id?id:name" ref="editor" v-model="compVal" :disabled="disabled" <vue-editor :id="id?id:name" ref="editor" v-model="compVal" :disabled="disabled"
:placeholder="placeholder" :class="[{ 'ring-red-500 ring-2': hasValidation && form.errors.has(name) }, theme.RichTextAreaInput.input]" :placeholder="placeholder" :class="[{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }, theme.RichTextAreaInput.input]"
:editor-toolbar="editorToolbar" class="rich-editor resize-y" :editor-toolbar="editorToolbar" class="rich-editor resize-y"
:style="inputStyle" :style="inputStyle"
/> />

View File

@ -16,6 +16,7 @@
:theme="theme" :theme="theme"
:has-error="hasValidation && form.errors.has(name)" :has-error="hasValidation && form.errors.has(name)"
:allowCreation="allowCreation" :allowCreation="allowCreation"
:disabled="disabled"
@update-options="updateOptions" @update-options="updateOptions"
> >

View File

@ -8,7 +8,7 @@
</label> </label>
<VueSignaturePad ref="signaturePad" <VueSignaturePad ref="signaturePad"
:class="[theme.default.input,{ 'ring-red-500 ring-2': hasValidation && form.errors.has(name), 'cursor-not-allowed bg-gray-200':disabled }]" height="150px" :class="[theme.default.input,{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }]" height="150px"
:name="name" :name="name"
:options="{ onEnd }" :options="{ onEnd }"
/> />
@ -45,9 +45,13 @@ export default {
this.onEnd() this.onEnd()
}, },
onEnd () { onEnd () {
if(this.disabled){
this.$refs.signaturePad.clearSignature()
}else{
const { isEmpty, data } = this.$refs.signaturePad.saveSignature() const { isEmpty, data } = this.$refs.signaturePad.saveSignature()
this.$set(this.form, this.name, (!isEmpty && data) ? data : null) this.$set(this.form, this.name, (!isEmpty && data) ? data : null)
} }
} }
} }
}
</script> </script>

View File

@ -7,7 +7,7 @@
<span v-if="required" class="text-red-500 required-dot">*</span> <span v-if="required" class="text-red-500 required-dot">*</span>
</label> </label>
<textarea :id="id?id:name" v-model="compVal" :disabled="disabled" <textarea :id="id?id:name" v-model="compVal" :disabled="disabled"
:class="[theme.default.input,{ 'ring-red-500 ring-2': hasValidation && form.errors.has(name) }]" :class="[theme.default.input,{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }]"
class="resize-y" class="resize-y"
:name="name" :style="inputStyle" :name="name" :style="inputStyle"
:placeholder="placeholder" :placeholder="placeholder"

View File

@ -11,7 +11,7 @@
<input :id="id?id:name" v-model="compVal" :disabled="disabled" <input :id="id?id:name" v-model="compVal" :disabled="disabled"
:type="nativeType" :type="nativeType"
:style="inputStyle" :style="inputStyle"
:class="[theme.default.input,{ 'ring-red-500 ring-2': hasValidation && form.errors.has(name), 'cursor-not-allowed bg-gray-200':disabled }]" :class="[theme.default.input,{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }]"
:name="name" :accept="accept" :name="name" :accept="accept"
:placeholder="placeholder" :min="min" :max="max" :maxlength="maxCharLimit" :placeholder="placeholder" :min="min" :max="max" :maxlength="maxCharLimit"
@change="onChange" @keydown.enter.prevent="onEnterPress" @change="onChange" @keydown.enter.prevent="onEnterPress"

View File

@ -10,7 +10,7 @@
:disabled="disabled" :disabled="disabled"
@click="handleClick" @click="handleClick"
> >
<label :for="id || name" class="text-gray-700 dark:text-gray-300 ml-2" :class="{'cursor-not-allowed':disabled}"> <label :for="id || name" class="text-gray-700 dark:text-gray-300 ml-2" :class="{'!cursor-not-allowed':disabled}">
<slot /> <slot />
</label> </label>
</div> </div>

View File

@ -13,7 +13,7 @@
<span class="inline-block w-full rounded-md"> <span class="inline-block w-full rounded-md">
<button type="button" :dusk="dusk" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label" <button type="button" :dusk="dusk" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label"
class="cursor-pointer" class="cursor-pointer"
:style="inputStyle" :class="[theme.SelectInput.input,{'py-2':!multiple || loading,'py-1': multiple, 'ring-red-500 ring-2': hasError}]" :style="inputStyle" :class="[theme.SelectInput.input,{'py-2':!multiple || loading,'py-1': multiple, '!ring-red-500 !ring-2': hasError, '!cursor-not-allowed !bg-gray-200':disabled}]"
@click="openDropdown" @click="openDropdown"
> >
<div :class="{'h-6':!multiple, 'min-h-8':multiple && !loading}"> <div :class="{'h-6':!multiple, 'min-h-8':multiple && !loading}">
@ -108,6 +108,7 @@ export default {
uppercaseLabels: { type: Boolean, default: true }, uppercaseLabels: { type: Boolean, default: true },
theme: { type: Object, default: () => themes.default }, theme: { type: Object, default: () => themes.default },
allowCreation: { type: Boolean, default: false }, allowCreation: { type: Boolean, default: false },
disabled: { type: Boolean, default: false }
}, },
data () { data () {
return { return {
@ -172,7 +173,7 @@ export default {
this.searchTerm = '' this.searchTerm = ''
}, },
openDropdown () { openDropdown () {
this.isOpen = !this.isOpen this.isOpen = this.disabled ? false : !this.isOpen
}, },
select (value) { select (value) {
if (!this.multiple) { if (!this.multiple) {

View File

@ -12,6 +12,7 @@
<component :is="getFieldComponents(field)" v-if="getFieldComponents(field)" <component :is="getFieldComponents(field)" v-if="getFieldComponents(field)"
:key="field.id + formVersionId" :class="getFieldClasses(field)" :key="field.id + formVersionId" :class="getFieldClasses(field)"
v-bind="inputProperties(field)" :required="isFieldRequired[field.id]" v-bind="inputProperties(field)" :required="isFieldRequired[field.id]"
:disabled="isFieldDisabled[field.id]"
/> />
<template v-else> <template v-else>
<div v-if="field.type === 'nf-text' && field.content" :id="field.id" :key="field.id" <div v-if="field.type === 'nf-text' && field.content" :id="field.id" :key="field.id"
@ -215,7 +216,14 @@ export default {
fieldsRequired[field.id] = (new FormLogicPropertyResolver(field, this.dataFormValue)).isRequired() fieldsRequired[field.id] = (new FormLogicPropertyResolver(field, this.dataFormValue)).isRequired()
}) })
return fieldsRequired return fieldsRequired
} },
isFieldDisabled () {
const fieldsDisabled = {}
this.fields.forEach((field) => {
fieldsDisabled[field.id] = (field.disabled === true)
})
return fieldsDisabled
},
}, },
watch: { watch: {

View File

@ -53,6 +53,12 @@
> >
Required Required
</v-checkbox> </v-checkbox>
<v-checkbox v-model="field.disabled" class="mb-3"
:name="field.id+'_disabled'"
@input="onFieldDisabledChange"
>
Disabled
</v-checkbox>
</div> </div>
<!-- Checkbox --> <!-- Checkbox -->
@ -440,6 +446,12 @@ export default {
this.close() this.close()
this.$emit('duplicate-block', this.field) this.$emit('duplicate-block', this.field)
}, },
onFieldDisabledChange (val) {
this.$set(this.field, 'disabled', val)
if (this.field.disabled) {
this.$set(this.field, 'hidden', false)
}
},
onFieldRequiredChange(val) { onFieldRequiredChange(val) {
this.$set(this.field, 'required', val) this.$set(this.field, 'required', val)
if (this.field.required) { if (this.field.required) {
@ -450,6 +462,7 @@ export default {
this.$set(this.field, 'hidden', val) this.$set(this.field, 'hidden', val)
if (this.field.hidden) { if (this.field.hidden) {
this.$set(this.field, 'required', false) this.$set(this.field, 'required', false)
this.$set(this.field, 'disabled', false)
} else { } else {
this.$set(this.field, 'generates_uuid', false) this.$set(this.field, 'generates_uuid', false)
this.$set(this.field, 'generates_auto_increment_id', false) this.$set(this.field, 'generates_auto_increment_id', false)