We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 32380
    • 137 Posts
    Hi Guys,

    Hope someone can help, i have a large form that needs splitting over 4-5 steeps, i have tried to use eform which works but it doesn’t like TV’s.
    So i am wondering if any one knows of a simple snippet I can uses to over come this?
    I have crawled the web and cant see any tutorials or code but there are lots of sites that used this method of dealing with large forms?
      • 29774
      • 386 Posts
      Splitting a form over multiple pages is not trivial as I’m sure you know. I think from your previous posts that you have tried the ’single page’ method with eform, however, it is also possible to split your form by using multiple pages and multiple forms.

      The problem then is how you persist the data from page to page, and, if needs be, re-populate the form with previously entered data. The solution I developed for a recent project was to serialise the form data and store it in a database table. In my case I needed the data to end up in the db anyway, but for your purposes you could just delete it on the last form step right after unserializing it.

      An simplified example might look like this, and assumes your user is logged in (otherwise use a snippet to call session_start() somewhere at the top of your template). You would have a table with columns
      id (auto-increment primary key), token (string), my_data_1 (mediumtext), my_data_2, my_data_3 (etc)
      <?php
      // called on eFormOnBeforeFormParse
      function step1_populate(&$fields,&$templates){
      	
      	global $modx;
      	
      	# populate form with existing data
      	$evt =&$modx->event; // The Snippet call event (not eFormOnBeforeFormParse event)
      	$validFormId = ($evt->params['formid'] == $_POST['formid']);
      	$isPostBack = ($validFormId && count($_POST) > 0); // (bool)true if the form is being updated
      
      	if (!$isPostBack && isset($_SESSION['token']) && isset($_SESSION['row_id']) ) {
      		
      		$token = $modx->db->escape($_SESSION['token']);
      		$row_id = $modx->db->escape($_SESSION['row_id']);
      		
      		// do query to get data from the db
      		$sql="SELECT my_data_1 FROM my_table WHERE token= '{$token}' AND id='{$id}'";
      	
      		$result = $modx->db->query($sql);
      		$row = $modx->db->getRow($result);
      		# re-populate
      		if (!empty($row)) {
      			$fields = unserialize($row);
      		}
      		
      		// add token to form to prevent CSRF
      		$fields['token'] = $token;
      	}
      }
      
      // called eFormOnBeforeMailSent - also set noemail=`1` in the eform snippet call
      function step1_save(&$fields){
      	
      	global $modx;
      	
      	// only need to do this on step 1
      	if (!isset($_SESSION['token'])) {
      		// create a token, say from the user's firstname and lastname assuming they're on form 1
      		$token .= strtoupper(substr($fields['firstname'],0,1)).strtoupper(substr($fields['lastname'],0,1));
      		$token .= date('ymdHi');
      		$token = md5($token);
      		// store in session
      		$_SESSION['token'] = $token;
      	} else {
      		if ($_SESSION['token'] !== $fields['token']) {
      			exit;
      		}
      	}
      	
      	// insert data
      	$token = $modx->db->escape($token);
      	$data = $modx->db->escape(serialize($fields));
      
      	$sql="INSERT INTO my_table SET my_data_1='{$data}', token='{$token}'";
      
      	if ($result = $modx->db->query($sql)) {		
      		$row_id = mysql_insert_id();
      		//store insert id in the session for subsequent steps
      		$_SESSION['row_id'] = $row_id;
      		$modx->sendRedirect('/step-2/');
      	}	
      	return true;		
      }
      
      // step 2 poplutate is similar to step 1
      
      // step 2 save - following step saves will be similar to this
      function step2_save(&$fields){
      	
      	global $modx;
      	
      	if ( isset($_SESSION['token']) && isset($_SESSION['row_id']) ) {
      		
      		if ($_SESSION['token'] !== $fields['token']) {
      			exit;
      		}
      		
      		$token = $modx->db->escape($_SESSION['token']);
      		$row_id = $modx->db->escape($_SESSION['row_id']);
      
      		$data = $modx->db->escape(serialize($fields));
      	
      		$sql="UPDATE my_table SET my_data_2='{$data}' WHERE token='{$token}' AND id='{$id}'";
      	
      		if ($result = $modx->db->query($sql)) {		
      			$row_id = mysql_insert_id();
      			//store this in session for subsequent steps
      			$_SESSION['row_id'] = $row_id;
      			$modx->sendRedirect('/step-X/');
      		}
      	}
      	session_write_close();
      	
      	return true;		
      	
      }
      
      //steps 3,4 etc
      
      function step6_save(&$fields){{
      	
      	global $modx;
      	
      	if (isset($_SESSION['token']) && isset($_SESSION['row_id']) ) {
      		
      		if ($_SESSION['token'] !== $fields['token']) {
      			exit;
      		}
      		
      		$token = $modx->db->escape($_SESSION['token']);
      		$row_id = $modx->db->escape($_SESSION['row_id']);
      		
      		$sql="SELECT * FROM my_table WHERE token='{$token}' AND id='{$id}'";
      	
      		$result = $modx->db->query($sql);
      	
      		if ($result && mysql_num_rows($result)>0) {	
      			$row = $modx->db->getRow($result);
      			$fields = array_merge( $row['my_data_1'], $row['my_data_2'], $row['my_data_3'], $row['my_data_4'], $fields);
      			
      			 // now cleanup
      			$sql2="DELETE * FROM my_table WHERE token='{$token}' AND id='{$id}'";
      			$result2 = $modx->db->query($sql2);
      		}
      	}
      	
      	// now allow eform to send mail - make sure all form field placeholders are in the last report template
      	return true;		
      }
      
      

        Snippets: GoogleMap | FileDetails | Related Plugin: SSL
        • 32380
        • 137 Posts
        Thanks @therebechips Thanks for your detailed reply.

        I have been trying out the single page form with TV’s as all of the products have the same form and i can select what options are shown via TV’s, but for some reason the TV’s fail to validate using this method which is a real bummer as im soo nearly there, they show up correctly on the form but will not process sad.
        I think if i go for a multi page option i will loose the ability to control the TV’s for each product, this is how i am trying to get it to work at the moment example:

        I add a page with the eForm call, that page contains the TV’s with the options to select, the options are called into the form chunks, this all works as i would expect but the form fails to validate, saying incorrect value?

        Would I loose the this flexibility by using multi page form as I cant see how to implement the TV’s?

        Regards,
        David.




          • 29774
          • 386 Posts
          Quote from: wiggy at Sep 25, 2009, 08:09 AM

          Thanks @therebechips Thanks for your detailed reply.

          I have been trying out the single page form with TV’s as all of the products have the same form and i can select what options are shown via TV’s, but for some reason the TV’s fail to validate using this method which is a real bummer as im soo nearly there, they show up correctly on the form but will not process sad.

          It sounds like eform thinks you are modifying the form template between the time it is first rendered and then validated on submit; eform will detect the changed options and throw an error (this is actually an important security feature).

          Are you using this method? (it works for me)
          http://modxcms.com/forums/index.php/topic,22072.msg136074.html#msg136074


            Snippets: GoogleMap | FileDetails | Related Plugin: SSL
            • 32380
            • 137 Posts
            Ooo havnt seen this, do you think this will work with this http://modxcms.com/forums/index.php/topic,8572.0.html this is where i got the info to split eForm?
              • 32380
              • 137 Posts
              Its a crying shame eForm isn’t directly compatible with TV’s out of the box, would make many peoples life’s (including mine) a lot easier as I use TV’s for almost every site I build on Modx, its one of the reasons Modx is so flexible, hopefully one of the eForm updates will address this issue? Fingers crossed!!
                • 29774
                • 386 Posts
                Looks like it should work - just add the relevant code to the beforeParseFunction function in the multi page form example.

                  Snippets: GoogleMap | FileDetails | Related Plugin: SSL
                  • 4971
                  • 964 Posts
                    Website: www.mercologia.com
                    MODX Revo Tutorials:  www.modxperience.com

                    MODX Professional Partner
                    • 32380
                    • 137 Posts
                    This might be a silly question but can you have more than one beforeParseFunction in an eForm call?
                    Because im using the eForm multi part form snippet, this has its own beforeParseFunction.