An idiomatic way for checkbox checked in golang

huangapple go评论81阅读模式
英文:

An idiomatic way for checkbox checked in golang

问题

在你点击踩之前,请注意,这个问题并不像标题听起来那么荒谬。

假设我有物品和分类。一个物品可以属于多个分类。

我有一个基本的HTML表单,用户可以填写一些内容来创建一个物品,我还将所有分类列为复选框列表(见下面的代码),以便用户可以选择物品应该属于哪个分类(一个或多个)。

到目前为止一切都好。

然而,当用户编辑这个物品时,我当然希望显示分类复选框列表,并将物品所属的分类作为选中状态显示出来,这样你就可以轻松地看到物品当前属于哪些分类,并进行取消选择等操作。

听起来很简单。

所以,我们在控制器中会有类似以下的查询(假设我想编辑id为3的物品):

1)SELECT * FROM Item WHERE Id = 3(获取我们想要编辑的物品)
2)SELECT * FROM Categories WHERE 1(获取所有分类)
3)SELECT CategoryId FROM ItemCategories WHERE ItemId = 3(获取物品所属的分类的分类ID)

用于显示分类(所有分类)的HTML代码将类似于:

...
{{range .Categories}}
{{ .Title}}
{{end}}
...

所以,通常我想做的就是,对于范围内的每个分类,检查Id是否存在于ItemCategories结果中,如果存在,则在HTML代码中将其设置为选中状态。由于在这种情况下很难使用FuncMap,因为它不允许将带有选中分类的切片传递给方法,所以在表示层中如何完成这个任务变得有点具有挑战性,尽管你已经拥有所需的数据。

当然,我可以在控制器中以多种方式完成这个任务(从将第二个和第三个查询结果合并为一个结构体,到在那里构建HTML输出,通过上下文将其传递给HTML页面),但由于我还在学习如何使用golang编程,我只是想检查其他人是如何解决这种类型的情况的,因为它在本质上是相当通用的(也就是说,我肯定会再次遇到这种情况)。

谢谢。

英文:

Before you hit the downvote, the question isn't as ludicrous as it may sound from the title.

Say I have Items and Categories. An item can belong to multiple categories.

I have a basic HTML form where a user fills out stuff to create an item and I also list all categories as a list of checkboxes (see code below) so that a user can check which category (one or many) the item being created should belong to.

So far all is well.

However, when a user edits this item, I'd of course like to show the categories checkbox list with the categories the item belongs to populated as checked so that you can easily see which categories the item currently belongs to, and uncheck if you like etc.

Sounds easy enough.

So, we would have something like the following queries in the controller (say, I want to edit item with id = 3)

1) SELECT * FROM Item WHERE Id = 3  (gets us the item we want to edit)
2) SELECT * FROM Categories WHERE 1 (gets ALL categories)
3) SELECT CategoryId FROM ItemCategories WHERE ItemId = 3 (gets the categoryids for the categories the item belongs to)

The HTML for showing the categories (all categories) would look something like this

<form>
...
{{range .Categories}}
<input name="cat" type="checkbox" value="{{ .Id }}" /> {{ .Title}} <br />
{{end}}
...
</form>

So, what I'd typically would like to have done is just to be able to, per category in the range, check if the Id exists in the ItemCategories result, and if so set it to checked in the HTML code. Since it's difficult to use a FuncMap for this, since it won't allow you to pass along the slice with the checked categories to the method, it becomes a bit of a challenge to see how this can be done in the presentation layer, given that you have the data you need.

Of course, I can do this in several ways in the controller (anything from merging the two results in second and third query as a struct, to building the HTML output there, passing it via the context to the HTML page) but as I'm still learning how to code in golang, I just wanted to check how others are going about solving this type of situation as it is quite generic in its nature (i.e. I will certainly come across it again).

Thanks.

答案1

得分: 2

原文如下:

It turns out funcmap functions can take two parameters so we can actually put the comparison between the category and the categories of the item in the "view" i.e. in the HTML. The only trick is to avoid the "dot" context problem within the range.

So, the solution would look like so:

{{ $ic := .ItemCategories }}  //this is needed since range changes the context
{{range .Categories}}
    <input name="cat" type="checkbox" value="{{ .Id }}" {{ CategorySelected .Id $ic}}/> {{ .Title}} <br />
{{end}}

Note that the CategorySelected that compares the id to a slice of ids, need to be listed in the FuncMap definition in order to work (at least it didn't work without it for me).

翻译结果如下:

原来 funcmap 函数可以接受两个参数,因此我们实际上可以将类别与项目的类别比较放在“视图”中,即在 HTML 中。唯一的技巧是避免在 range 内部出现“点”上下文问题。

因此,解决方案如下所示:

{{ $ic := .ItemCategories }}  //这是必需的,因为 range 会改变上下文
{{range .Categories}}
    <input name="cat" type="checkbox" value="{{ .Id }}" {{ CategorySelected .Id $ic}}/> {{ .Title}} <br />
{{end}}

请注意,将 id 与 id 切片进行比较的 CategorySelected 函数需要在 FuncMap 定义中列出才能正常工作(至少对我来说,没有列出它时无法正常工作)。

英文:

It turns out funcmap functions can take two parameters so we can actually put the comparison between the category and the categories of the item in the "view" i.e. in the HTML. The only trick is to avoid the "dot" context problem within the range.

So, the solution would look like so:

{{ $ic := .ItemCategories }}  //this is needed since range changes the context
{{range .Categories}}
    &lt;input name=&quot;cat&quot; type=&quot;checkbox&quot; value=&quot;{{ .Id }}&quot; {{ CategorySelected .Id $ic}}/&gt; {{ .Title}} &lt;br /&gt;
{{end}}

Note that the CategorySelected that compares the id to a slice of ids, need to be listed in the FuncMap definition in order to work (at least it didn't work without it for me).

huangapple
  • 本文由 发表于 2014年10月4日 03:13:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/26185307.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定