nil.to_sが"nil"になるような言語は(ry というのは置いといて、まだまだPythonをリハビリ中。
Rubyより関数志向での開発がしやすくて楽しいですよねえ。
リハビリを兼ねてweb.pyで個人的なツールを作ってます。web.pyはシンプルで軽いので、個人用途(非公開でツールとして使う)だったらレンタルサーバーでCGIとして動作させても問題なさそうです。(XREAでは簡単なものなら負荷率0ptでした。Railsとかならいれるだけでダメなんで、素晴らしい)
そこで、scriptaculousのAjax.InPlaceEditorを使っているわけですが、困ったことがひとつ。InPlaceEditorなわけで、値を当然入力します。でその値がサーバー側でバリデーションエラーな時どうしたもんかと。
理想的な動作としては
エラーをユーザーに通知する
サブミットする前の値のままtextareaを表示しておく
なんですが、コンストラクタの中のoptionsあたりをのぞいてもそれらしきオプションはなさげ。
ということでとりあえず場当たり的に書いてみたものが以下。
(function(){Ajax.RollbackableInPlaceEditor = Class.create();var dummy = function(){};dummy.prototype = Ajax.InPlaceEditor.prototype;Ajax.RollbackableInPlaceEditor.prototype = new dummy;Ajax.RollbackableInPlaceEditor.prototype.constructor = Ajax.RollbackableInPlaceEditor;})();Object.extend(Ajax.RollbackableInPlaceEditor.prototype, {initialize : function(element, url, options) {var self = this;options = Object.extend({callback: function(form) {self.oldValue = self.editField.value;return Form.serialize(form);},onFailure : Prototype.emptyFunction}, options || {});Ajax.InPlaceEditor.prototype.initialize.apply(this, [element, url, options]);},onclickCancel: function() {this.onComplete();this.element.innerHTML = this._oldInnerHTML;this.element.show();return false;},onComplete: function(transport) {this.leaveEditMode();if(transport && !Ajax.Base.prototype.responseIsSuccess.call({transport:transport})) {this.options.onFailure.bind(this)(transport, this.element);return this.enterEditMode();}else {this.oldValue = null;}this.options.onComplete.bind(this)(transport, this.element);},onFailure: function(transport) {return false;},getText : function() {if(this.oldValue != null && this.oldValue != undefined){var v = this.oldValue; this.oldValue = null; return v;}this._oldInnerHTML = this.element.innerHTML;return this.element.innerHTML;}});
サーバー側でエラーがあったときは適当に500とか406とかでレスポンスを返せばオッケーです。
なのでサーバー側ではたとえばweb.pyなら
# errors = ['データが長すぎます。'] などif len(errors) != 0:web.header("Content-Type", "text/javascript"),web.ctx["status"] = "406 Not Acceptable"print "".join(["alert('", "\n".join(errors), "');"])return
とすればエラーになって(エラーメッセージがアラートされる)、サブミットした内容のままで再度編集できます。
豆知識ですが、以上のようにサーバー側でtext/javascriptでレスポンスを返すとprototype.jsでは自動的にjavascriptとして評価してくれます。
うーむ、まさに場当たり的。いろいろまずそうだけど、まぁ動いてるっぽいし気にしないことにしとこう・・・・
No comments yet
trackback uriLeave a Comment