From 07bd09a82ed6d63b764f7e9ae67e3a1103d78c06 Mon Sep 17 00:00:00 2001 From: Alessandro Costa de Oliveira Date: Fri, 10 Apr 2026 14:05:24 -0300 Subject: [PATCH] =?UTF-8?q?Campo=20extra=20do=20tipo=20texto=20com=20limit?= =?UTF-8?q?a=C3=A7=C3=A3o=20opcional=20de=20quantidade=20de=20caracteres?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/ChamadoController.php | 4 ++ app/Http/Controllers/FilaController.php | 9 +++++ app/Models/Fila.php | 2 +- app/Utils/JSONForms.php | 40 +++++++++++++++++++ public/js/functions.js | 19 +++++++++ .../template-btn-novocampo-modal.blade.php | 11 ++++- resources/views/filas/template.blade.php | 17 ++++++-- tests/Unit/JSONFormsTest.php | 20 ++++++++++ 8 files changed, 117 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/ChamadoController.php b/app/Http/Controllers/ChamadoController.php index 37dd29dc..d0427477 100644 --- a/app/Http/Controllers/ChamadoController.php +++ b/app/Http/Controllers/ChamadoController.php @@ -127,6 +127,8 @@ public function store(ChamadoRequest $request, Fila $fila) { $this->authorize('chamados.create', $fila); + $request->validate(JSONForms::buildTextMaxLengthRules($request->extras, $fila)); + # na criação não precisa #$request->validate(JSONForms::buildRules($request, $fila)); @@ -303,6 +305,8 @@ public function update(Request $request, Chamado $chamado) { $this->authorize('chamados.update', $chamado); + $request->validate(JSONForms::buildTextMaxLengthRules($request->extras, $chamado->fila)); + # inicialmente atende a atualização do campo anotacoes via ajax if ($request->ajax()) { $chamado->fill($request->all()); diff --git a/app/Http/Controllers/FilaController.php b/app/Http/Controllers/FilaController.php index 7b981b63..6090a987 100644 --- a/app/Http/Controllers/FilaController.php +++ b/app/Http/Controllers/FilaController.php @@ -236,11 +236,13 @@ public function storeTemplate(Request $request, Fila $fila) $request->validate([ 'template.*.label' => 'required', 'template.*.type' => 'required', + 'template.*.maxlength' => 'nullable|integer|min:1', ]); if (isset($request->campo)) { $request->validate([ 'new.label' => 'required', 'new.type' => 'required', + 'new.maxlength' => 'nullable|integer|min:1', ]); } $template = []; @@ -255,9 +257,16 @@ public function storeTemplate(Request $request, Fila $fila) if ($atributo['type'] == 'select') { $template[$campo]['value'] = json_decode($atributo['value'], true); } + + if (($atributo['type'] ?? '') != 'text') { + unset($template[$campo]['maxlength']); + } } # adiciona o campo novo $new = array_filter($request->new, 'strlen'); + if (($new['type'] ?? '') != 'text') { + unset($new['maxlength']); + } if (isset($request->campo)) { $template[$request->campo] = $new; } diff --git a/app/Models/Fila.php b/app/Models/Fila.php index ba842ab8..8e01323d 100644 --- a/app/Models/Fila.php +++ b/app/Models/Fila.php @@ -143,7 +143,7 @@ public static function getFields() */ public static function getTemplateFields() { - return ['label', 'type', 'can', 'help', 'value', 'validate']; + return ['label', 'type', 'can', 'help', 'value', 'validate', 'maxlength']; } /** diff --git a/app/Utils/JSONForms.php b/app/Utils/JSONForms.php index dc329edb..cd94a2f4 100644 --- a/app/Utils/JSONForms.php +++ b/app/Utils/JSONForms.php @@ -30,6 +30,39 @@ public static function buildRules($request, $fila) return $validate; } + /** + * Monta regras de limite de caracteres para campos extras do tipo texto. + */ + public static function buildTextMaxLengthRules($extras, $fila) + { + $template = json_decode($fila->template); + $validate = []; + + if (!$template || !is_array($extras)) { + return $validate; + } + + foreach ($template as $key => $json) { + if (($json->type ?? null) != 'text' || !isset($json->maxlength)) { + continue; + } + + if (!array_key_exists($key, $extras)) { + continue; + } + + $maxlength = filter_var($json->maxlength, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]); + if ($maxlength === false) { + continue; + } + + $field = 'extras.' . $key; + $validate[$field] = 'nullable|string|max:' . $maxlength; + } + + return $validate; + } + /** * Renderiza o formulário como array contendo html */ @@ -65,6 +98,13 @@ protected static function JSON2Form($template, $data, $perfil) default: $fieldInput = html()->textarea("extras[$key]", $value)->class('form-control')->rows(3); + if ($type == 'text' && isset($json->maxlength)) { + $maxlength = filter_var($json->maxlength, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]); + if ($maxlength !== false) { + $fieldInput = $fieldInput->attribute('maxlength', strval($maxlength)); + } + } + if (isset($json->validate) && strpos($json->validate, 'required') !== false) { $fieldInput = $fieldInput ->required(); } diff --git a/public/js/functions.js b/public/js/functions.js index 4bb5dc3f..f476e749 100644 --- a/public/js/functions.js +++ b/public/js/functions.js @@ -62,3 +62,22 @@ function mudarCampoInputTextarea(campo) { }); } } + +/* @autor uspdev/alecosta 10/04/2026 +* Habilita o campo de limite de caracteres apenas quando tipo é texto +*/ +function toggleCampoMaxlength(campo) { + var fieldTypeSelect = $('select[name="' + campo + '"]').find(':selected').val(); + var maxlengthField = $('input[name="' + campo.replace('][type]', '][maxlength]') + '"]'); + + maxlengthField.each(function () { + if (fieldTypeSelect == 'text') { + $(this).prop('disabled', false); + $(this).attr('placeholder', 'Opcional'); + } else { + $(this).val(''); + $(this).prop('disabled', true); + $(this).attr('placeholder', 'Apenas para Texto'); + } + }); +} diff --git a/resources/views/filas/partials/template-btn-novocampo-modal.blade.php b/resources/views/filas/partials/template-btn-novocampo-modal.blade.php index f2c2aa9f..abc71b16 100644 --- a/resources/views/filas/partials/template-btn-novocampo-modal.blade.php +++ b/resources/views/filas/partials/template-btn-novocampo-modal.blade.php @@ -47,7 +47,10 @@ @break @default - + @endswitch @endforeach @@ -70,6 +73,12 @@ json_modal_form = function() { jsonForm.modal(); } + + toggleCampoMaxlength('new[type]'); + + $('select[name="new[type]"]').on('change', function() { + toggleCampoMaxlength(this.name); + }); }); diff --git a/resources/views/filas/template.blade.php b/resources/views/filas/template.blade.php index 4b808ba6..bc56f421 100644 --- a/resources/views/filas/template.blade.php +++ b/resources/views/filas/template.blade.php @@ -36,7 +36,7 @@ @isset($tvalue[$field]) @switch($field) @case('type') - @@ -57,7 +57,14 @@ @break @default - + @php + $maxLengthDisabled = $field === 'maxlength' && (($tvalue['type'] ?? '') !== 'text'); + @endphp + @endswitch @endisset @empty($tvalue[$field]) @@ -76,7 +83,10 @@ @break @default - + @endswitch @endempty @@ -146,6 +156,7 @@ function move(r, up) { var nameField = $(this).prop('name'); // muda o campo de input para caixa de texto $(mudarCampoInputTextarea(nameField)); + $(toggleCampoMaxlength(nameField)); }); }); diff --git a/tests/Unit/JSONFormsTest.php b/tests/Unit/JSONFormsTest.php index 779b8053..40a5ba58 100644 --- a/tests/Unit/JSONFormsTest.php +++ b/tests/Unit/JSONFormsTest.php @@ -139,6 +139,16 @@ public function testGenerateFormHelp() $this->assertStringContainsString("Local de atendimento", $form[0][2]->toHtml()); } + public function testGenerateFormTextMaxlength() + { + $tmp = $this->template; + $tmp["predio"]["maxlength"] = 10; + $template = json_encode($tmp); + $fila = Fila::factory()->make(['template' => $template]); + $form = JSONForms::generateForm($fila); + $this->assertStringContainsString('maxlength="10"', $form[0][1]->toHtml()); + } + public function testBuildRules() { $tmp = $this->template; @@ -149,4 +159,14 @@ public function testBuildRules() $validate = JSONForms::buildRules($request, $fila); $this->assertEquals($validate, ["extras.predio" => "required"]); } + + public function testBuildTextMaxLengthRules() + { + $tmp = $this->template; + $tmp["predio"]["maxlength"] = 10; + $template = json_encode($tmp); + $fila = Fila::factory()->make(['template' => $template]); + $validate = JSONForms::buildTextMaxLengthRules(["predio" => "Administracao"], $fila); + $this->assertEquals($validate, ["extras.predio" => "nullable|string|max:10"]); + } }