SugarCRMネタ。
SugarCRMの入力チェックはJavaScriptのcheck_form()
関数に実装されているが、
独自の入力チェックをしようとすると、このcheck_form()
を書き換えてやらないといけないわけで。。
この手法だとアップグレードセーフにならないし、カスタムソースとオリジナルソースがごっちゃになって管理面倒だしでデメリットしかない。長いことカスタム入力チェックをどう実装するかは自分の中で大きなテーマだったのだけれど、最近やっと落ち着いてきたので紹介しようと思う。
解決策その1: EditViewごとにバリデーションを実装する
一番単純でアップグレードセーフに対応するのが、これ。
editviewdefs.phpでJavaScriptが自由に読み込めるので、そこにバリデーションを書く。
メリット
- カスタマイズが単純
- SugarCRM初心者も分かりやすい
デメリット
- 保存ボタンのイベントをオーバーライドする必要がある(しかも複数)
- Edit系のビューはEditViewだけではない
- モジュールごとにたくさんJavaScriptを作らないといけない
- JavaScriptの読み込みコストがあがる
カスタム入力チェックを実装するモジュールが単体の場合はいいが、複数のモジュールに及ぶと管理が面倒だし、同じような処理を複数のファイルに渡って書く必要があるので、個人的に不採用。
解決策その2: バリデーションロジックをひとつの関数にまとめる
editviewdefs.phpでロードしていた処理を共通のロジックに移し一箇所で管理するのがこれ。check_form()
のカスタム版を作成し、どのモジュールからでも絶対に呼び出されるようにする手法。
メリット
- 一箇所で管理できるのでうれしい
- 処理を共通化できる
デメリット
- カスタムロジックを呼び出すために、保存イベントをオーバーライドする必要がある
今のところこれが一番実績がある。
しかし、イベントのオーバーライドが発生する点が頂けない。
解決策その3: check_formをラップする
underscore.jsのwrap
関数などを使用して、check_form()
をラップする。
既存の保存ボタンのイベントを全く触らなくて良いのが一番のメリット。
メリット
- 保存ボタンのイベントにノータッチ
- バリデーションルールだけ管理すれば OK
デメリット
- wrapは1回のみにしないと悲しいことになる
自分は、クライアントサイドにvalidationモジュールを作成して、シングルトンの仕組みとモジュールごとに別れたメソッドを呼び出すメソッド(エラー及びメッセージ管理あり)を用意して使っています。
このような感じで入力チェックには四苦八苦していたが、3つ目の手法でとりあえずは落ち着けるような気がしている。やはり管理とテストのしやすさ、オリジナルソースとの分離が大事。もっといい方法があれば教えて下さい。