diff --git a/extension/qfq/qfq/helper/KeyValueStringParser.php b/extension/qfq/qfq/helper/KeyValueStringParser.php
index 982ded8972cb52382d796294752920226141d7b8..e8527dd82a5972c9336eeb3ba1481ed63c42ec8a 100644
--- a/extension/qfq/qfq/helper/KeyValueStringParser.php
+++ b/extension/qfq/qfq/helper/KeyValueStringParser.php
@@ -14,6 +14,7 @@ use qfq;
 
 require_once(__DIR__ . '/../exceptions/UserFormException.php');
 require_once(__DIR__ . '/../../qfq/Constants.php');
+require_once(__DIR__ . '/../../qfq/helper/OnString.php');
 
 /**
  * Class KeyValueStringParser
@@ -102,6 +103,9 @@ class KeyValueStringParser {
         // Clean any "\r\n" to "\n"
         $keyValueString = str_replace("\r\n", "\n", $keyValueString);
 
+        // Allow {{ }} expressions to span several lines (replace \n inside these expressions)
+        $keyValueString = OnString::removeNewlinesInNestedExpression($keyValueString);
+
         // Check if there are 'escaped delimiter', If yes, use the more expensive explodeEscape().
         if (strpos($keyValueString, '\\' . $listDelimiter) !== false) {
             $keyValuePairs = self::explodeEscape($listDelimiter, $keyValueString, 2);
diff --git a/extension/qfq/qfq/helper/OnString.php b/extension/qfq/qfq/helper/OnString.php
index 2fa2461cdeaa9043dd633b6502849654380a40ee..3671b967368dde8e28b1130f2c0911d382f29398 100644
--- a/extension/qfq/qfq/helper/OnString.php
+++ b/extension/qfq/qfq/helper/OnString.php
@@ -30,7 +30,7 @@ class OnString {
             return '';
         }
 
-        return substr($haystack, strrpos($haystack, $needle) + 1);
+        return substr($haystack, strrpos($haystack, $needle) + strlen($needle));
     }
 
     /**
@@ -145,4 +145,61 @@ class OnString {
         return $urlParamNew;
     }
 
+    /**
+     * Removes new lines (\n) from expressions like {{var:SC0:alnumx}} and replaces them with spaces.
+     * Handles nested expressions like {{SELECT {{var::alnumx}}}}
+     * This function is useful to allow multiline expressions in form definitions such as:
+     *   sqlInsert = {{INSERT INTO test (grId)
+     *                 VALUES(123) }}
+     *
+     * @param $str - the string to be parsed
+     * @return string - the resulting string with new lines in expressions replaced
+     * @throws UserFormException - alerts the user if the delimiters are not balanced
+     */
+    public static function removeNewlinesInNestedExpression($str) {
+        $delimStart = '{{';
+        $delimEnd = '}}';
+        $lastDelimPos = -strlen($delimStart);
+        $exprDepth = 0; // keeps count of the level of expression depth
+        $nestingStart = 0;
+
+        // Process the string one start/end delimiter at a time
+        while(true) {
+            // find the next start/end delimiter
+            $nextDelimStartPos = strpos($str, $delimStart, $lastDelimPos + strlen($delimStart));
+            $nextDelimEndPos = strpos($str, $delimEnd, $lastDelimPos + strlen($delimEnd));
+            if ($nextDelimStartPos === false && $nextDelimEndPos === false) break;
+            $nextDelimPos = min($nextDelimStartPos, $nextDelimEndPos);
+            if ($nextDelimStartPos === false) $nextDelimPos = $nextDelimEndPos;
+            if ($nextDelimEndPos === false) $nextDelimPos = $nextDelimStartPos;
+
+            if ($nextDelimPos == $nextDelimStartPos) { // opening delimiter
+                if ($exprDepth == 0) $nestingStart = $nextDelimPos;
+                $exprDepth++;
+            } else { // closing delimiter
+                $exprDepth--;
+                if ($exprDepth < 0) {
+                    throw new UserFormException("Too many closing delimiters '$delimEnd' in '" . $str . "'", ERROR_MISSING_OPEN_DELIMITER);
+                    break;
+                } elseif ($exprDepth == 0) {
+                    // end of nesting -> replace \n inside nested expression with space
+                    $pre = substr($str, 0, $nestingStart);
+                    $nest = substr($str, $nestingStart, $nextDelimPos - $nestingStart);
+                    $nestNew = str_replace('\n', ' ', $nest);
+                    $post = substr($str, $nextDelimPos);
+                    $str = substr($str, 0, $nestingStart) .
+                        str_replace("\n", " ", substr($str, $nestingStart, $nextDelimPos - $nestingStart)) .
+                        substr($str, $nextDelimPos);
+                }
+            }
+
+            $lastDelimPos = $nextDelimPos;
+        }
+        if ($exprDepth > 0 ) {
+            throw new UserFormException("Missing close delimiter '$delimEnd' in '" . $str . "'", ERROR_MISSING_CLOSE_DELIMITER);
+        }
+
+        return $str;
+    }
+
 }
diff --git a/extension/qfq/tests/phpunit/OnStringTest.php b/extension/qfq/tests/phpunit/OnStringTest.php
index e6cf0ac870f3c8defa6b47d407f688fbffe5d588..6868508e0d68fd44ef8720fe72f88a5680ce0a29 100644
--- a/extension/qfq/tests/phpunit/OnStringTest.php
+++ b/extension/qfq/tests/phpunit/OnStringTest.php
@@ -9,6 +9,7 @@
 namespace qfq;
 
 require_once(__DIR__ . '/../../qfq/helper/OnString.php');
+require_once(__DIR__ . '/../../qfq/exceptions/UserFormException.php');
 
 use qfq;
 
@@ -69,4 +70,69 @@ class OnStringTest extends TestCase {
         $this->assertEquals(' te\'st ', OnString::trimQuote("' te'st '"));
 
     }
+
+    /**
+     *
+     */
+    public function testRemoveNewlinesInNestedExpression() {
+        $this->assertEquals("", OnString::removeNewlinesInNestedExpression(""));
+        $this->assertEquals("test", OnString::removeNewlinesInNestedExpression("test"));
+        $this->assertEquals("{{test}}", OnString::removeNewlinesInNestedExpression("{{test}}"));
+        $this->assertEquals("{{test }}", OnString::removeNewlinesInNestedExpression("{{test\n}}"));
+        $this->assertEquals("{{test two}}", OnString::removeNewlinesInNestedExpression("{{test\ntwo}}"));
+        $this->assertEquals("Pre{{test two}}Post", OnString::removeNewlinesInNestedExpression("Pre{{test\ntwo}}Post"));
+        $this->assertEquals("{{test{{two}}}}", OnString::removeNewlinesInNestedExpression("{{test{{two}}}}"));
+        $this->assertEquals("{{a {{b }}}}",
+            OnString::removeNewlinesInNestedExpression("{{a\n{{b\n}}}}"));
+        $this->assertEquals("{{a b{{c d}}{{e f}} h}}",
+            OnString::removeNewlinesInNestedExpression("{{a\nb{{c\nd}}{{e\nf}}\nh}}"));
+        $this->assertEquals("param1=abc\nsqlInsert = {{SELECT * FROM test WHERE '{{var}}'='true'}}",
+            OnString::removeNewlinesInNestedExpression("param1=abc\nsqlInsert = {{SELECT *\nFROM test\nWHERE '{{var}}'='true'}}"));
+        $this->assertEquals("sqlInsert = {{SELECT * FROM test WHERE '{{var}}'='true'}}\nparam1=abc",
+            OnString::removeNewlinesInNestedExpression("sqlInsert = {{SELECT *\nFROM test\nWHERE '{{var}}'='true'}}\nparam1=abc"));
+    }
+
+    /**
+     * @expectedException \qfq\UserFormException
+     *
+     */
+    public function testRemoveNewlinesInNestedExpression_missingClosing_1() {
+        $str = OnString::removeNewlinesInNestedExpression("Hi! {{Test ");
+    }
+    /**
+     * @expectedException \qfq\UserFormException
+     *
+     */
+    public function testRemoveNewlinesInNestedExpression_missingClosing_2() {
+        $str = OnString::removeNewlinesInNestedExpression("Hi! {{Test}");
+    }
+    /**
+     * @expectedException \qfq\UserFormException
+     *
+     */
+    public function testRemoveNewlinesInNestedExpression_missingClosing_3() {
+        $str = OnString::removeNewlinesInNestedExpression("Hi! {{Test {{var }}");
+    }
+
+    /**
+     * @expectedException \qfq\UserFormException
+     *
+     */
+    public function testRemoveNewlinesInNestedExpression_missingOpening_1() {
+        $str = OnString::removeNewlinesInNestedExpression("}}");
+    }
+    /**
+     * @expectedException \qfq\UserFormException
+     *
+     */
+    public function testRemoveNewlinesInNestedExpression_missingOpening_2() {
+        $str = OnString::removeNewlinesInNestedExpression("{}}");
+    }
+    /**
+     * @expectedException \qfq\UserFormException
+     *
+     */
+    public function testRemoveNewlinesInNestedExpression_missingOpening_3() {
+        $str = OnString::removeNewlinesInNestedExpression("{{Test}}}}");
+    }
 }
\ No newline at end of file