22176


play framework（2.4）のScalaテンプレートとして、  
カスタムinputヘルパを作成したいと考えています。

カスタムinputヘルパでは、固定のattribute（styleやclass）を付けたいのですが、  
カスタムinputヘルパを呼び出す側でもattributeを付けたい場合があります。

そこで、カスタムinputヘルパに渡される(Symbol, Any)* と  
カスタムinputヘルパ内で設定したい (Symbol, Any)* をマージできれば良いのではないかと考えました。

ふたつの同じSymbolがあればvalueを文字列として結合するイメージです。

[code]

    @(field: play.api.data.Field, args: (Symbol,Any)*)(implicit handler: helper.FieldConstructor)
    
    @{ ここでargsと 'style -> "aaa", 'class -> "bbb" をマージするイメージ }@
    
    @helper.input(field, args:_*) { (id, name, value, htmlArgs) =>
        <input type="text" id="@id" name="@id" value="@value" @toHtmlArgs(htmlArgs) />
    }
    
[/code]

どのような方法で実現できるでしょうか。  
（template functionとして切り出したいと考えています）.


CC BY-SA 3.0
2016-02-16T02:02:23.017
22138
2016-04-16T18:04:05.173
2016-02-16T12:43:21.793
8647
8647
question
scala playframework
(Symbol, Any)* と (Symbol, Any)* のマージ


## 解決方法

別途、マージ処理用のScalaソースコードを用意する。（ViewUtility.scala）

[code]

    package hoge.piyo.scala
    
    object ViewUtility {
        def merge(xs: Seq[(Symbol, Any)], ys: Seq[(Symbol, Any)]): Seq[(Symbol, Any)] = {
          (xs ++ ys).groupBy(_._1)
            .mapValues {
              case (_, x) +: Nil         => x
              case (_, x) +: (_, y) +: _ => s"$x$y"
            }
            .toSeq
        }
    }
    
[/code]

テンプレート側で呼び出す。

[code]

    @(field: play.api.data.Field, args: (Symbol, String)*)(implicit handler: helper.FieldConstructor)
    
    @import hoge.piyo.scala._
    
    @defining(ViewUtility.merge(args, Seq('readonly -> "true", 'tabindex -> "-1", 'style -> "border: none;background-color: transparent;"))) { list =>
      @helper.input(field, list:_*) { (id, name, value, htmlArgs) =>
        <input type="text" id="@id" name="@id" value="@value" @toHtmlArgs(htmlArgs) />
      }
    }
    
[/code]

htmlArgsにはマージ後（同一Symbolがあったら文字列連結される）の値がセットされる。

※解決にはScala.jpの有志の方の力を全面的にお借りしました


CC BY-SA 3.0
2016-02-16T12:44:26.973
22176
2016-02-16T12:44:26.973
8647
22138
answer