diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index db08ef0..03259bb 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -4,6 +4,7 @@ X-editable changelog
 
 Version 1.0.1 wip
 ----------------------------          
+[enh #1] params can be a function to calc it dynamically (vitalets)         
 [enh #6] do not preventDetault() in click when toggle='manual'. This allows to have clickable links (vitalets)         
 [bug #3] should not mark element with unsave css if url is user's function (vitalets)         
           
diff --git a/src/editable-form/editable-form.js b/src/editable-form/editable-form.js
index ea33cfe..76f03a2 100644
--- a/src/editable-form/editable-form.js
+++ b/src/editable-form/editable-form.js
@@ -186,15 +186,22 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
                 
             if (send) { //send to server
                 this.showLoading();
-                
-                //try parse json in single quotes
-                this.options.params = $.fn.editableform.utils.tryParseJson(this.options.params, true);                
-                
-                params = $.extend({}, this.options.params, {
+
+                //standart params
+                params = {
                     name: this.options.name || '',
                     value: value,
                     pk: pk 
-                });
+                };
+                
+                //additional params
+                if(typeof this.options.params === 'function') {
+                    $.extend(params, this.options.params.call(this, params));  
+                } else {
+                    //try parse json in single quotes (from data-params attribute)
+                    this.options.params = $.fn.editableform.utils.tryParseJson(this.options.params, true);   
+                    $.extend(params, this.options.params);
+                }
 
                 if(typeof this.options.url === 'function') { //user's function
                     return this.options.url.call(this, params);
@@ -289,10 +296,14 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
         **/        
         url:null,
         /**
-        Additional params for submit
+        Additional params for submit. Function can be used to calculate params dynamically
+        @example
+        params: function() {
+           return { a: 1 };
+        }
 
         @property params 
-        @type object
+        @type object|function
         @default null
         **/          
         params:null,
@@ -305,7 +316,8 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
         **/         
         name: null,
         /**
-        Primary key of editable object (e.g. record id in database). Use Object for composite keys.
+        Primary key of editable object (e.g. record id in database). For composite keys use object, e.g. <code>{id: 1, lang: 'en'}</code>.
+        Can be calculated dinamically via function.
 
         @property pk 
         @type string|object|function
diff --git a/test/unit/select.js b/test/unit/select.js
index d4c5e39..a4a1256 100644
--- a/test/unit/select.js
+++ b/test/unit/select.js
@@ -37,6 +37,7 @@ $(function () {
             $.fn.editable.defaults.name = 'name1';
             //clear cache
             $(document).removeData('groups.php-'+$.fn.editable.defaults.name);
+            $.support.transition = false;
         }
     });  
 
diff --git a/test/unit/text.js b/test/unit/text.js
index 3d5c9ca..d83bf44 100644
--- a/test/unit/text.js
+++ b/test/unit/text.js
@@ -4,6 +4,7 @@ $(function () {
        setup: function() {
            fx = $('#async-fixture');
            $.fn.editable.defaults.name = 'name1';
+           $.support.transition = false;
        }
    });
       
@@ -242,6 +243,38 @@ $(function () {
         
       });
       
+    asyncTest("params as function", function () {
+        var e = $('<a href="#" data-pk="1" data-url="post-resp.php">abc</a>').appendTo(fx).editable({
+             name: 'username',
+             params: function(params) {
+                 equal(params.pk, 1, 'params in func already have values (pk)');
+                 return { q: 2, pk: 3 };
+             },
+             success: function(resp) {   
+                 equal(resp.dataType, 'json', 'dataType ok');
+                 equal(resp.data.pk, 3, 'pk ok');
+                 equal(resp.data.name, 'username', 'name ok');
+                 equal(resp.data.value, newText, 'value ok');
+                 equal(resp.data.q, 2, 'additional params ok');
+             } 
+          }),  
+          newText = 'cd<e>;"'
+
+        e.click()
+        var p = tip(e);
+
+        ok(p.find('input[type=text]').length, 'input exists')
+        p.find('input').val(newText);
+        p.find('form').submit(); 
+        
+        setTimeout(function() {
+           e.remove();    
+           start();  
+        }, timeout);             
+        
+      });      
+      
+      
      asyncTest("submit to url defined as function", function () {
         expect(3);
         var newText = 'qwe',