【问题标题】:Validating dynamically added input fields in Laravel 5在 Laravel 5 中验证动态添加的输入字段
【发布时间】:2015-12-27 17:44:25
【问题描述】:

问题: 需要验证动态添加的输入字段。

这是用户界面的截图:

场景 1: 添加一个新的时间表,验证工作完美。

使用表单请求文件验证表单:

public function rules()
{
    $rules = [
        'name' => 'required|max:255',
        'due_at' => 'required|date_format:Y-m-d',
        'users' => 'required',
        'task_name' => 'required|max:255'
    ];
    if($this->request->get('task_name')){
        foreach($this->request->get('task_name') as $key => $val)
        {
            $rules['task_name.'.$key] = 'required|max:255';
            $rules['task_description.'.$key] = 'required|max:255';
        }
    }

    return $rules;
}

public function messages()
{
    $messages = [];
    foreach($this->request->get('task_name') as $key => $val) {
        $messages['task_name.'.$key.'.max'] = 'The field labeled task name must be less than :max characters.';
        $messages['task_name.'.$key.'.required'] = 'The field task name is required.';
        $messages['task_description.'.$key.'.max'] = 'The field task description must be less than :max characters.';
        $messages['task_description.'.$key.'.required'] = 'The field task description is required.';
    }
    return $messages;
}

场景 2:更新现有计划。这失败了,我收到以下错误消息:

helpers.php 第 454 行中的错误异常: htmlentities() 期望参数 1 是字符串,给定数组(查看:/Users/petestewart/Documents/Git Repos/.../resources/views/schedules/partials/_form.blade.php)(查看:/Users/. ../Documents/Git Repos/.../resources/views/schedules/partials/_form.blade.php)

这里是调度控制器更新函数:

/**
 * Update the specified resource in storage.
 *
 * @param  \App\Schedule $schedule
 * @return Response
 */
public function update(Schedule $schedule, ScheduleRequest $request)
{
    $schedule->name = $request->name;
    $schedule->apiary_id = $request->apiary_id;
    $schedule->due_at = $request->due_at;
    $schedule->update();

    // Attach users to the new schedule
    $schedule->users()->sync($request->get('users'));

    // Save the tasks
    if($request->get('task_name')){
        foreach($request->get('task_name') as $key => $task_name)
        {   
            //if(empty($task_name)) continue; // If a task is empty then skip to the next one   

            // Check if task exists and update task
            if(!empty($request->task[$key])){
                $task = Task::find($request->task[$key]);
                $task->name = $task_name;
                $task->description = $request->task_description[$key];
                $task->update();
            }else{
            // Add new task
                $task = new Task();
                $task->name = $task_name;
                $task->description = $request->task_description[$key];
                $task->schedule_id = $schedule->id;
                $task->save();
            }
        };
    };
    return Redirect::to('schedules')->with('success', trans('messages.update', ['name' => 'Schedule']));
}

这是 HTML 表单:

@if(isset($tasks))  
        @foreach($tasks as $task)
            <div class="task-item row form-group">
                {!! Form::hidden('task[]', $task->id) !!}
                <a href="{{ route('schedules.task.delete', $task) }}" class="btn btn-danger btn-sm task-delete-btn" data-method="delete" data-confirm="Are you sure you want to delete this task?"><span class="fa fa-trash"></span></a>
                <div class="col-sm-4 task-name">
                    {!! Form::label('task_name', 'Task Name', array('class'=>'control-label')) !!}
                    {!! Form::text('task_name[]', $task->name, array('class'=>'form-control')) !!}
                </div>
                <div class="col-sm-8">
                    {!! Form::label('task_description', 'Task Description', array('class'=>'control-label')) !!}
                    {!! Form::text('task_description[]', $task->description, array('class'=>'form-control')) !!}
                </div>
            </div>
        @endforeach        
    @else
        @if(Form::old('task_name'))
            @foreach(old('task_name') as $key => $val)
                <div class="task-item row form-group">
                    <a href="#" class="btn btn-default btn-sm remove-task"><span class="fa fa-minus"></span></a>
                    <div class="col-sm-4 task-name {!! $errors->first('task_name.'.$key, 'has-error') !!}">
                        {!! Form::label('task_name', 'Task Name', array('class'=>'control-label')) !!}
                        {!! Form::text('task_name['.$key.']', old('task_name.'.$key), array('class'=>'form-control')) !!}
                        {!! $errors->first('task_name.'.$key, '<p>:message</p>') !!}
                    </div>
                    <div class="col-sm-8 {!! $errors->first('task_description.'.$key, 'has-error') !!}">
                        {!! Form::label('task_description', 'Task Description', array('class'=>'control-label')) !!}
                        {!! Form::text('task_description['.$key.']', old('task_description.'.$key), array('class'=>'form-control')) !!}
                        {!! $errors->first('task_description.'.$key, '<p>:message</p>') !!}
                    </div>
                </div>
            @endforeach
        @else
            <div class="task-item row form-group">
                <a href="#" class="btn btn-default btn-sm remove-task"><span class="fa fa-minus"></span></a>
                <div class="col-sm-4 task-name">
                    {!! Form::label('task_name', 'Task Name', array('class'=>'control-label')) !!}
                    {!! Form::text('task_name[]', null, array('class'=>'form-control')) !!}
                    {!! $errors->first('task_name', '<p>:message</p>') !!}
                </div>
                <div class="col-sm-8">
                    {!! Form::label('task_description', 'Task Description', array('class'=>'control-label')) !!}
                    {!! Form::text('task_description[]', null, array('class'=>'form-control')) !!}
                </div>
            </div>
        @endif
    @endif
    <a href="#" class="btn btn-default btn-sm" id="add-task"><span class="fa fa-plus"></span></a>

最后是负责添加和删除任务的 Jquery:

var TaskList = {

    addTaskBtn: $('#add-task'),
    completeTaskBtn: $('.task-complete-btn'),
    deleteTaskBtn: $('.task-delete-btn'),
    taskTemplate: '<div class="task-item row form-group"> \
                        <a href="#" class="btn btn-default btn-sm remove-task"><span class="fa fa-minus"></span></a> \
                        <div class="col-sm-4 task-name"> \
                            <label for="task_name" class="control-label">Task Name</label> \
                            <input class="form-control" name="task_name[]" type="text"> \
                        </div> \
                        <div class="col-sm-8"> \
                            <label for="task_description" class="control-label">Task Description</label> \
                            <input class="form-control" name="task_description[]" type="text"> \
                        </div> \
                    </div>',

    init: function() { 
        this.bindUIActions();
    },
    bindUIActions: function() {
        // Add new task item
        this.addTaskBtn.click(function () {
            $('.task-item:last').after(TaskList.taskTemplate);
            var newTask = $('.task-item:last');
            newTask.find('input[type=text]:first').focus();             
            return false;
        }); 
        $(document).on('click', 'a.remove-task', function (e) {
            if($(this).parent().is(':first-child')){
                $(this).parent().find('input[type=text]').val('');
                return;
            };
            $(this).parent().remove();
            return false;
        }); 
        // Set task as complete via AJAX
        this.completeTaskBtn.change(function () {
            var h3 = $(this).parent().parent().parent().parent().find('h3');
            var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
            var url = '/schedules/update-task';
            $.ajax({
                type: 'POST',
                url: url,
                data: {   
                    id: $(this).attr('id'),
                    complete: $(this).is(':checked')? 1 : 0,
                    '_token': CSRF_TOKEN
                },
                dataType: 'JSON',
                success: function (data) {
                    h3.find('span').remove();
                    h3.append(data.status_label);
                }
            });
            return false;
        });
        // Delete Task via AJAX
        this.deleteTaskBtn.click(function () {
            var taskWrapper = $(this).parent();
            var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
            var url = $(this).attr('href');
            if (confirm('Are you sure you want to delete this task?')) {
                $.ajax({
                    type: 'DELETE',
                    url: url,
                    data: {   
                        '_token': CSRF_TOKEN
                    },
                    dataType: 'JSON',
                    success: function (data) {
                        taskWrapper.remove();
                    }
                });
            }
            return false;
        });
    },
};

在更新计划时验证这一点的任何帮助将不胜感激。非常感谢!

【问题讨论】:

  • 在渲染 _form.blade.php 时似乎会发生错误。我认为更新本身很好。
  • 您好,感谢您的回复。是的,我不确定如何处理在验证时呈现表单:a)从数据库中提取的当前任务(也可能由用户编辑)和 b)新的表单数据,即新的添加任务

标签: php jquery validation laravel-5


【解决方案1】:

通过以下方式解决了这个问题,不确定这是否是最佳选择,但现在可以使用。在更新时,我会删除所有当前任务并根据表单数据添加它们...

将表格更改为:

@if(Form::old('task_name'))
        @foreach(old('task_name') as $key => $val)
            <div class="task-item row form-group">
                <a href="#" class="btn btn-default btn-sm remove-task"><span class="fa fa-minus"></span></a>
                <div class="col-sm-4 task-name {!! $errors->first('task_name.'.$key, 'has-error') !!}">
                    {!! Form::label('task_name', 'Task Name', array('class'=>'control-label')) !!}
                    {!! Form::text('task_name['.$key.']', old('task_name.'.$key), array('class'=>'form-control')) !!}
                    {!! $errors->first('task_name.'.$key, '<p>:message</p>') !!}
                </div>
                <div class="col-sm-8 {!! $errors->first('task_description.'.$key, 'has-error') !!}">
                    {!! Form::label('task_description', 'Task Description', array('class'=>'control-label')) !!}
                    {!! Form::text('task_description['.$key.']', old('task_description.'.$key), array('class'=>'form-control')) !!}
                    {!! $errors->first('task_description.'.$key, '<p>:message</p>') !!}
                </div>
            </div>
        @endforeach
    @elseif(isset($tasks))  
        @foreach($tasks as $task)
            <div class="task-item row form-group">
                {!! Form::hidden('task[]', $task->id) !!}
                <a href="{{ route('schedules.task.delete', $task) }}" class="btn btn-danger btn-sm task-delete-btn" data-method="delete" data-confirm="Are you sure you want to delete this task?"><span class="fa fa-trash"></span></a>
                <div class="col-sm-4 task-name">
                    {!! Form::label('task_name', 'Task Name', array('class'=>'control-label')) !!}
                    {!! Form::text('task_name[]', $task->name, array('class'=>'form-control')) !!}
                </div>
                <div class="col-sm-8">
                    {!! Form::label('task_description', 'Task Description', array('class'=>'control-label')) !!}
                    {!! Form::text('task_description[]', $task->description, array('class'=>'form-control')) !!}
                </div>
            </div>
        @endforeach      
    @else
        <div class="task-item row form-group">
            <a href="#" class="btn btn-default btn-sm remove-task"><span class="fa fa-minus"></span></a>
            <div class="col-sm-4 task-name">
                {!! Form::label('task_name', 'Task Name', array('class'=>'control-label')) !!}
                {!! Form::text('task_name[]', null, array('class'=>'form-control')) !!}
                {!! $errors->first('task_name', '<p>:message</p>') !!}
            </div>
            <div class="col-sm-8">
                {!! Form::label('task_description', 'Task Description', array('class'=>'control-label')) !!}
                {!! Form::text('task_description[]', null, array('class'=>'form-control')) !!}
            </div>
        </div>
    @endif

以及控制器中的更新功能:

public function update(Schedule $schedule, ScheduleRequest $request)
{
    $schedule->name = $request->name;
    $schedule->apiary_id = $request->apiary_id;
    $schedule->due_at = $request->due_at;
    $schedule->update();

    // Sync users to the schedule
    $schedule->users()->sync($request->get('users'));

    // Remove all tasks and add as new
    $schedule->tasks()->delete();
    // Save the tasks
    if($request->get('task_name')){
        foreach($request->get('task_name') as $key => $task_name)
        {   
            //if(empty($task_name)) continue; // If a task is empty then skip to the next one   

            // // Check if task exists and update task
            // if(isset($request->task[$key])){
            //  $task = Task::find($request->task[$key]);
            //  $task->name = $task_name;
            //  $task->description = $request->task_description[$key];
            //  $task->update();
            // }else{
            // Add new task
                $task = new Task();
                $task->name = $task_name;
                $task->description = $request->task_description[$key];
                $task->schedule_id = $schedule->id;
                $task->save();
            //}
        };
    };
    return Redirect::to('schedules')->with('success', trans('messages.update', ['name' => 'Schedule']));
}

【讨论】:

    猜你喜欢
    • 2012-07-17
    • 2021-08-13
    • 2021-05-21
    • 2014-12-19
    • 2020-06-05
    • 1970-01-01
    • 2013-06-27
    相关资源
    最近更新 更多