-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dc3e4 new matrix field #484
Changes from 30 commits
a4ac0d1
9345436
c4e069f
ad07808
ce99260
840e9c1
d443551
267e631
34ff509
8697ede
9bf816c
bdc64bc
4a5b72c
49a8a04
7079bd4
a9c5371
d633500
88c3a67
0c37a89
a853c82
a307379
4e87cf8
ca723b6
046038b
82fe4b0
a1dbd4a
c1cfcac
c7f7e5d
e19c461
54b7a7b
104eabe
4d4b747
1b6ec44
88ec9a3
8afbdb1
24ac419
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
namespace App\Rules; | ||
|
||
use Closure; | ||
use Illuminate\Contracts\Validation\ValidationRule; | ||
|
||
class MatrixValidationRule implements ValidationRule | ||
{ | ||
/** | ||
* Run the validation rule. | ||
* | ||
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail | ||
*/ | ||
public function validate(string $attribute, mixed $value, Closure $fail): void | ||
{ | ||
if (!is_array($value)) { | ||
$fail('The Matrix field must be an array.'); | ||
return; | ||
} | ||
$nullValues = array_filter($value, function ($val) { | ||
return $val === null; | ||
}); | ||
if (sizeof($nullValues)) { | ||
$fail('The Matrix field is required.'); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,6 +81,17 @@ public function useSignedUrlForFiles() | |
return $this; | ||
} | ||
|
||
public function getMatrixString(array $val): string | ||
{ | ||
$parts = []; | ||
foreach ($val as $key => $value) { | ||
if ($key !== null && $value !== null) { | ||
$parts[] = "$key: $value"; | ||
} | ||
} | ||
return implode(' | ', $parts); | ||
} | ||
|
||
/** | ||
* Return a nice "FieldName": "Field Response" array | ||
* - If createLink enabled, returns html link for emails and links | ||
|
@@ -145,6 +156,8 @@ public function getCleanKeyValue() | |
} else { | ||
$returnArray[$field['name']] = $val; | ||
} | ||
} elseif ($field['type'] == 'matrix') { | ||
$returnArray[$field['name']] = $this->getMatrixString($data[$field['id']]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate matrix data type. Ensure that the matrix data is always an array before passing it to } elseif ($field['type'] == 'matrix' && is_array($data[$field['id']])) {
$returnArray[$field['name']] = $this->getMatrixString($data[$field['id']]);
} |
||
} elseif ($field['type'] == 'files') { | ||
if ($this->outputStringsOnly) { | ||
$formId = $this->form->id; | ||
|
@@ -219,6 +232,8 @@ public function getFieldsWithValue() | |
} else { | ||
$field['value'] = $val; | ||
} | ||
} elseif ($field['type'] == 'matrix') { | ||
$field['value'] = str_replace(' | ', "\n", $this->getMatrixString($data[$field['id']])); | ||
} elseif ($field['type'] == 'files') { | ||
if ($this->outputStringsOnly) { | ||
$formId = $this->form->id; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
<template> | ||
<input-wrapper v-bind="inputWrapperProps"> | ||
<template #label> | ||
<slot name="label"/> | ||
</template> | ||
<div class='border' :class="[ | ||
theme.default.borderRadius, | ||
{ | ||
'!ring-red-500 !ring-2 !border-transparent': hasError, | ||
'!cursor-not-allowed !bg-gray-200': disabled, | ||
}, | ||
]"> | ||
<table | ||
class="w-full table-fixed overflow-hidden border border-collapse border-transparent" | ||
:class="[ | ||
theme.default.borderRadius]" | ||
> | ||
<thead class=""> | ||
<tr class="bg-gray-200/60"> | ||
<th @click="test" class="border border-gray-300"> | ||
|
||
</th> | ||
<td v-for="column in columns" :key="column" class="border border-gray-300"> | ||
<div class="p-2 w-full flex items-center justify-center capitalize text-sm truncate"> | ||
{{ column }} | ||
</div> | ||
</td> | ||
</tr> | ||
</thead> | ||
|
||
<tbody> | ||
<tr v-for="row, rowIndex in rows" :key="rowIndex" class=""> | ||
<td class="border border-gray-300"> | ||
<div class="w-full flex-grow p-2 text-sm truncate"> | ||
{{ row }} | ||
</div> | ||
</td> | ||
<td v-for="column in columns" :key="row + column" class="border border-gray-300"> | ||
<div | ||
class="w-full flex items-center justify-center hover:bg-gray-200/40" | ||
v-if="compVal" | ||
role="radio" | ||
:aria-checked="compVal[row] === column" | ||
:class="[ | ||
theme.FlatSelectInput.spacing.vertical, | ||
theme.FlatSelectInput.fontSize, | ||
theme.FlatSelectInput.option, | ||
]" | ||
@click="onSelect(row, column)" | ||
> | ||
<Icon | ||
v-if="compVal[row] === column" | ||
:key="row+column" | ||
name="material-symbols:radio-button-checked-outline" | ||
class="text-inherit" | ||
:color="color" | ||
:class="[theme.FlatSelectInput.icon]" | ||
/> | ||
<Icon | ||
v-else | ||
:key="row+column" | ||
name="material-symbols:radio-button-unchecked" | ||
:class="[theme.FlatSelectInput.icon,theme.FlatSelectInput.unselectedIcon]" | ||
/> | ||
</div> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
<template #help> | ||
<slot name="help"/> | ||
</template> | ||
<template #error> | ||
<slot name="error"/> | ||
</template> | ||
</input-wrapper> | ||
</template> | ||
<script> | ||
import {inputProps, useFormInput} from "./useFormInput.js" | ||
import InputWrapper from "./components/InputWrapper.vue" | ||
|
||
export default { | ||
name: "MatrixInput", | ||
components: {InputWrapper}, | ||
|
||
props: { | ||
...inputProps, | ||
rows: {type: Array, required: true}, | ||
columns: {type: Array, required: true}, | ||
}, | ||
data() { | ||
return { | ||
} | ||
}, | ||
setup(props, context) { | ||
return { | ||
...useFormInput(props, context), | ||
} | ||
}, | ||
computed: {}, | ||
methods: { | ||
test(){ | ||
console.log(this.compVal) | ||
this.compVal = {} | ||
}, | ||
onSelect(row, column) { | ||
if (this.compVal[row] === column) { | ||
this.compVal[row] = null | ||
} else { | ||
this.compVal[row] = column | ||
} | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optimize event handling. The Consider removing the |
||
}, | ||
beforeMount() { | ||
if (!this.compVal || typeof this.compVal !== 'object') { | ||
this.compVal = {} | ||
} | ||
}, | ||
} | ||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<template> | ||
<div | ||
role="radio" | ||
:aria-checked="selected" | ||
:class="[ | ||
theme.FlatSelectInput.spacing.vertical, | ||
theme.FlatSelectInput.fontSize, | ||
theme.FlatSelectInput.option, | ||
]" | ||
@click="onSelect" | ||
> | ||
<Icon | ||
v-if="selected" | ||
name="material-symbols:radio-button-checked-outline" | ||
class="text-inherit" | ||
:color="color" | ||
:class="[theme.FlatSelectInput.icon]" | ||
/> | ||
<Icon | ||
v-else | ||
name="material-symbols:radio-button-unchecked" | ||
:class="[theme.FlatSelectInput.icon,theme.FlatSelectInput.unselectedIcon]" | ||
/> | ||
</div> | ||
</template> | ||
<script> | ||
export default { | ||
emits: ['toggle-select'], | ||
props: { | ||
theme: { type: Object }, | ||
color: {type: String, default: "#3B82F6"}, | ||
selected: { type: Boolean, default: false } | ||
}, | ||
methods: { | ||
onSelect(){ | ||
this.$emit("toggle-select") | ||
} | ||
} | ||
|
||
} | ||
|
||
</script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor for efficiency in
checkMatrixContains
.The current implementation checks for key existence twice. This can be streamlined by checking once and then comparing values.
Committable suggestion