【问题标题】:change form action based on radio button is not working properly基于单选按钮更改表单操作无法正常工作
【发布时间】:2026-02-10 09:45:01
【问题描述】:

我有一个表单,允许用户编辑帖子的管理员,还可以为帖子创建新的管理员。

这个表单有一些单选按钮。每个单选按钮对应于帖子的管理员。单击某个单选按钮(管理员)时,管理员的详细信息将填充到表单字段中。单击“更新”按钮时,管理员的详细信息将被更新。

这部分工作正常。

怀疑:

但是有一个静态单选按钮“创建新管理员”,允许创建新管理员。选择此单选按钮后,表单字段将被重置,因此用户可以在单击“存储”按钮时插入值以创建新管理员。

我有下面的 jQuery 来更改基于单选按钮选择的表单操作。

使用这个 js 部分来更改基于所选单选按钮的表单操作代码无法正常工作,有 3 个问题:

  • When an administrator (radio button) is selected the form fields are not populated with that administrator details (this was working fine before insert the js part to change the form action based on radio button selection)
  • Also when the "Create new admin" radio button is selected the form fields are not reseted.
  • 单击“存储”按钮时也会出现错误:“从空值创建默认对象”。

表格:

<form method="post" class="clearfix" action="{{route('admins.update', ['id' => $post->id])}}" enctype="multipart/form-data">
    {{csrf_field()}}
    @foreach($administrators $admin)
          <div class="form-check">
            <input class="form-check-input" type="radio" name="radiobutton" id="{{$admin->id}}" value="">
            <label class="form-check-label" for="">
              {{$admin->name}}
            </label>
          </div>
    @endforeach
    <div class="form-check">
      <input class="form-check-input" type="radio" name="radiobutton" id="create_administrator"
             value="option2">
      <label class="form-check-label" for="exampleRadios2">
          Create new administrator
      </label>
  </div>
  <div class="form-group">
    <label for="name">Name</label>
    <input type="text" required class="form-control" value="{{ $admin->name }}" name="name">
  </div>

  <!-- below I have more form fields like administrator name, email, etc -->

  <input type="submit" id="adminStoreButton" class="btn btn-primary" value="Create"/>
  <input type="submit" id="adminUpdateButton" class="btn btn-primary" value="Update"/>
  </form>

jQuery:根据单选按钮选择显示管理员的详细信息,隐藏和显示存储/更新按钮以及根据单选按钮选择更改表单操作

   var admins = {!!  $administrators !!}

    $("input[name='radiobutton']").click(function() {

    if($(this).attr("id") == "create_administrator"){
        $("#adminUpdateButton").hide();
        $("#adminStoreButton").show();
        form.attr('action', '{{route('admins.store', ['post_id' => $post->id])}}');
    }
    else{
        $("#adminUpdateButton").show();
        $("#adminStoreButton").hide();
        form.attr('action', '{{route('admins.update', ['post_id' => $post->id])}}');
    }

    let id = $(this).attr("id");

    let data = administrators.find(e => e.id == id) || {
        name: "",
       email: "",
       ...: ""
    };
   $("input[name='name']").val(data.name);
    ...
    });

//更新管理员路由

Route::get('post/edit/{id}/admins',    [ 'uses' => 'AdminController@edit', 'as'=>'admins.edit']);
Route::post('post/update/{id}/admins', [ 'uses' => 'AdminController@update', 'as'=>'admins.update']);
Route::post('post/store/{id}/admins', [ 'uses' => 'AdminController@store', 'as'=>'admins.store']);

管理员控制器更新方法:

    public function update(Request $request, $id){


        $this->validate($request, [
            'name' => 'required|string',
          ...
        ]);


        $adminToUpdate = Administrator::find($request->radiobutton);

        $adminToUpdate->name = $request->name;
        ...

        $adminToUpdate->save();

        return redirect()->back();
    }

}

管理员控制器编辑方法:

public function edit($id)
    {
        $post = Post::find($id);
        $administrators = Administrator::where('post_id', $id)->get();

        return view('administrators.edit')
            ->with('post', $post)
            ->with('administrators', $administrators));
    }

管理员控制器存储方法:

public function store(Request $request, $id){
    $this->validate($request, [
        'name' => 'required|string',
    ]);

    $post = Post::find($id);

    Administrator::create([
        'nome' => $request->name,
        'post_id' => $post->id
    ]);

    return redirect()->back();

}

【问题讨论】:

  • 像这样改变你的jQuery点击功能$(document).on('click', input[name^=radiobutton]", function () {}
  • 表单在提交时有 admin.update 路由,用于编辑管理员的数据,但 admin.store 路由在哪里存储新管理员的信息?
  • 谢谢我用“admins.store”而不是“admins.update”来更新路由,这是一个错字。使用 $(document).on('click'...) 它也无法正常工作,我遇到了同样的问题。
  • 更新 jQuery 部分后隐藏和显示是否正常工作?什么工作不正常?
  • 当某些单选按钮被选中时,不会出现该单选按钮的详细信息(管理员)。此外,当单击“创建新管理员”时,表单字段不会重置,按钮也不会从“更新”更改为“存储”。

标签: javascript jquery laravel


【解决方案1】:

这是一个答案,是我和 Jon 之间的合作努力。

将问题分成不同的部分。

1) 当您处理多个具有相同名称的复选框/单选按钮时,您应该使用插入符号而不是仅名称。

修复 1:

Replace $("input[name='radiobutton']").click(function() {} with 

$(document).on('click', input[name^=radiobutton]", function () {}

2) Laravel 预装了 Lodash。随时随地使用它。

修复 2:

var admins = {!!  $administrators !!}
let id = $(this).attr("id");

let data = administrators.find(e => e.id == id) || {
        name: "",
       email: "",
       ...: ""
};

replace this logic with _.find method of lodash.

var admins = {!!  $administrators !!}
var admin_data = _.find(admin, function(o) { return o.id < SOME_ID_VALUE; });

3) 表单没有 ID 属性。分配 ID,以便用于设置表单的操作属性。

修复 3:

<form id="admin-form">

Change your code
//Remove this entirely
form.attr('action', '{{route('admins.store', ['post_id' => $post->id])}}');

//Replace with following lines of code.
//Route is upto you. Whichever route you want to pass.
var url = "{{route('admins.update', ['post_id' => $post->id])}}"; form.attr('action', url);

建议 当您在同一个表单中进行编辑和创建时,请尽量避免使用多条路线。

这里的路由可以这样处理。 Route::post('post/update/{id}/admins/{adminID?}', [ 'uses' =&gt; 'AdminController@update', 'as'=&gt;'admins.update']);

$admingID 是可选的,如果不通过则为 null,因此您应该创建新的管理员记录,否则更新现有管理员的记录。

【讨论】: