Save multiple entries to database

pinixdes 12 May, 2011
I created a Chronoform using javascript that allows users to enter additional participants as needed. That seems to be working fine but I need to be able to save all the participants entered in the form to the database. Right now,only the last entry is saved in the database. So if I add 3 participants info - only the 3 participants info will be saved into the database.

Below is my code:

<?
$user =& JFactory::getUser();
?>

<script type="text/javascript">
var counter = 0;

function moreFields() {
   counter++;
   var newFields = document.getElementById('readroot').cloneNode(true);
   newFields.id = '';
   newFields.style.display = 'block';
   var newField = newFields.childNodes;
   for (var i=0;i<newField.length;i++) {
      var theName = newField[i].name
      if (theName)
         newField[i].name = theName + counter;
   }
   var insertHere = document.getElementById('writeroot');
   insertHere.parentNode.insertBefore(newFields,insertHere);
}

//window.onload = moreFields;

</script>

<!-- start hidden box -->
<div id="readroot" style="display: none">

<table>
  <tr>
    <td>Participant Names</td>
    <td><input maxlength="150" size="35" title="" id="participants_names" name="participants_names" type="text" /></td>
  </tr>
  <tr>
    <td>Session 1 Date</td>
    <td><input maxlength="150" size="35" title="" id="session1_date" name="session1_date" type="text" /></td>
  </tr>
  <tr>
    <td>Session 2 Date</td>
    <td><input maxlength="150" size="35" title="" id="session2_date" name="session2_date" type="text" /></td>
  </tr>
  <tr>
    <td>Session 3 Date</td>
    <td><input maxlength="150" size="35" title="" id="session3_date" name="session3_date" type="text" /></td>
  </tr>
  <tr>
    <td>Session 4 Date</td>
    <td><input maxlength="150" size="35" title="" id="session4_date" name="session4_date" type="text" /></td>
  </tr>
  <tr>
    <td>Session 5 Date</td>
    <td><input maxlength="150" size="35" title="" id="session5_date" name="session5_date" type="text" /></td>
  </tr>
  <tr>
    <td>Session 6 Date</td>
    <td><input maxlength="150" size="35" title="" id="session6_date" name="session6_date" type="text" /></td>
  </tr>
</table>

<input type="button" value="Remove Participant"
      onclick="this.parentNode.parentNode.removeChild(this.parentNode);" /><br /><br />
</div>

<!--end of hidden box -->
<!-- start form -->
<table width="100%" border="0" cellpadding="3">
  <tr>
    <td colspan="2" class="divider">LAC Cohort Attendance <br>
    Enter New LAC Cohort</td>
  </tr>
  <tr>
    <td colspan="2"><input type="hidden" name="name" value="<?php echo $user->name; ?>" /></td>
  </tr>
  <tr>
    <td colspan="2"><input type="hidden" name="email" value="<?php echo $user->email; ?>" /></td>
  </tr>
  <tr>
    <td>Group # or Description</td>
    <td><input maxlength="150" size="35" title="" id="group_description" name="group_description" type="text" /></td>
  </tr>
  <tr>
    <td>Location</td>
    <td><input maxlength="150" size="35" title="" id="location" name="location" type="text" /></td>
  </tr>
  <tr>
    <td># Participants (min 8 fields –  max 16)</td>
    <td><input maxlength="150" size="35" title="" id="participants" name="participants" type="text" /></td>
  </tr>
</table>

<p><span id="writeroot"></span>
  <input type="button"  value="Add Participant"  onclick="moreFields()" />
</p>

<p> *  Type verification image <br>{imageverification}
</p>
<p><span class="form_element cf_button">
  <input value="Submit Form" name="button_31" type="submit" />
</span> </p>



Can someone please help me? Thank you!!
GreyHead 12 May, 2011
Hi pinixdes,

The ChronoForms DB Connection can only handle saving one record per table so you'd need to code this by hand with a little PHP in one of the OnSubmit Boxes.

There's a document here with some code examples.

Bob
pinixdes 16 May, 2011
Thank you very much for your guidance. I got the form to save great but when it save it saves twice. Once with all the fields filled in and the other all fields are blank. Any ideas why? The code I'm using is

<?php
$data = array('participants_names', 'session1_date', 'session2_date', 'session3_date', 'session4_date', 'session5_date', 'session6_date');
$record =& JTable::getInstance("chronoforms_enter_data", "Table");
if ( !$record->save($data) ) {
JError::raiseWarning(100, $record->getError());
}

?>


Thanks again for your help.
GreyHead 18 May, 2011
Hi pinixdes,

It sounds as though you may have the DB Connection still enabled as well as your custom code and they are both writing records to the database.

Bob
GreyHead 09 Jun, 2011
Hi pinixdes,

The consent form is now working.

You did have the DB Connection turned on at the same time as your custom code. I also re-wrote the custom code to include all of the data in the table.

Bob
pinixdes 14 Jun, 2011
Bob - Thanks for all your help. Now I have another problem. My other form that I am using the same method does not save to the database. Some field types are TEXT instead of VARCHAR(255). Any ideas?

Hi pinixdes,

The consent form is now working.

You did have the DB Connection turned on at the same time as your custom code. I also re-wrote the custom code to include all of the data in the table.

Bob

GreyHead 14 Jun, 2011
Hi pinixdes ,

I've no idea. Cross-check with the code in the working form.

Using TEXT vs VARCHAR will not stop the results saving; and the code to save is the same.

Bob
quantum_leap 20 Jul, 2012
I am trying to do a similar thing. I am using a javascript script to dynamically add the fields that I want. I also have a counter to track the number of participants added dynamically by the user. The fields that are dynamically added is name and email. My script can either generate identical name values for the fields or append a _1 next to them.

I have trouble rewritting the script you mention on the book to be able to enter all records added by the user since I don't know exactly how many records the user might add. In addition, I would like to be able to send emails to the added users instead of just one once the form is submitted.
quantum_leap 20 Jul, 2012
I tried to execute the code exactly as I found it on the book. It didn't work in my example.

My database table name is jos_training_courses_trainees. Amongst my fields are id and full_name. I tried to modify the name full_name field in the record with id 352. I disabled database data storage. I used this code on the On Submit code - after sending email box:
<?php
$data = array();
$data['id'] = 352;
$data['full_name'] = 'New name';
$record =& JTable::getInstance("training_courses_trainees", "Table");
if ( !$record->save($data) ) {
  JError::raiseWarning(100, $record->getError());
}
if ( !class_exists('Tabletraining_courses_trainees') ) {
  class Tabletraining_courses_trainees extends JTable {
  {
    var $id = null;
    var $course_id = null;
    var $full_name = null;
    var $company = null;
    var $position = null;
    var $phone = null;
    var $email = null;
    var $sales_account_manager = null;
    var $partner_status = null;
    var $payment_method = null;
    function __construct( &$database ) {
      parent::__construct( '#__training_courses_trainees', 'id', $database );
    }
  }
}
?>

After I submitted the form the record was not altered. It doesn't even display the other info I've entered in the On Submit code - after sending email box before the php code. Is the code correct?
GreyHead 21 Jul, 2012
Hi quantum_leap,

The code looks good to me. I suggest that you add some debug lines to see exactly what is happening.

Bob
quantum_leap 21 Jul, 2012
Ok, I realised there was an extra { somewhere in the code. But that didn't make any difference. I have debug mode on and the code works when I have enabled database data storage but the info from the actual form are also being recorded.

The code being used is this:
<?php
$data = array();
$data['id'] = 375;
$data['full_name'] = 'John Smith';
$record =& JTable::getInstance("training_courses_trainees", "Table");
if ( !$record->save($data) ) {
JError::raiseWarning(100, $record->getError());
}
if (!class_exists('Tabletraining_courses_trainees')) {
class Tabletraining_courses_trainees extends JTable
{
var $id = null;
var $course_id = null;
var $full_name = null;
var $company = null;
var $position = null;
var $phone = null;
var $email = null;
var $sales_account_manager = null;
var $partner_status = null;
var $payment_method = null;
function __construct( &$database ) {
parent::__construct( '#__training_courses_trainees', 'id', $database );
}
}
}
?>


When I have database storage enabled, I get the confirmation message in my On Submit code - after sending email box like this:
Save multiple entries to database image 1


But when I disable data storage, I get the confirmation message but with the css missing and the variable {count_field} not being translated properly from the POST array. I also don't get any debugging code either. Like this:
Save multiple entries to database image 2
quantum_leap 21 Jul, 2012
It seems that it worked now once I changed the order of some code blocks. The code now is:

<?php
if (!class_exists('Tabletraining_courses_trainees')) {
class Tabletraining_courses_trainees extends JTable
{
var $id = null;
var $course_id = null;
var $full_name = null;
var $company = null;
var $position = null;
var $phone = null;
var $email = null;
var $sales_account_manager = null;
var $partner_status = null;
var $payment_method = null;
function __construct( &$database ) {
parent::__construct( '#__training_courses_trainees', 'id', $database );
}
}
}
$data = array();
$data['id'] = 375;
$data['full_name'] = 'John Smith';
$record =& JTable::getInstance("training_courses_trainees", "Table");
if ( !$record->save($data) ) {
JError::raiseWarning(100, $record->getError());
}
?>


It's doing the update as expected even thought when the value of id is a number one value higher than the current highest id number it doesn't create a new record unfortunately. How could I modify the code so that I can enter multiple entries according to the dynamic fields being added by the user as per previous post?

I am trying to do a similar thing. I am using a javascript script to dynamically add the fields that I want. I also have a counter to track the number of participants added dynamically by the user. The fields that are dynamically added is name and email. My script can either generate identical name values for the fields or append a _1 next to them.

I have trouble rewritting the script you mention on the book to be able to enter all records added by the user since I don't know exactly how many records the user might add. In addition, I would like to be able to send emails to the added users instead of just one once the form is submitted.

GreyHead 21 Jul, 2012
Hi quantum_leap,

Which box do you have this code in? If it is in the On Submit Before Email box then it will only run if Send Emails is set to Yes on the General tab.

Bob
quantum_leap 21 Jul, 2012
Yes, I know, I have emails temporarily set to OFF but the code is in the After box! Basically, it's working and if I don't declare an id it inserts a new record. I would just like to know how to enter multiple records defined by the user...
GreyHead 22 Jul, 2012
Hi quantum_leap,

Sorry, I was replying to your earlier post. To create a new record leave the id out of the data array. I assume that your table has an autoincrementing primary key?

The code works like this: if there is an id value set try to update that record; if there is no id create a new record.

Bob
quantum_leap 26 Jul, 2012
I made progress. I added [] after the name fields that are added dynamically by the user thus converting them to arrays. So for instance name became name[], email became email[], etc. I then used a for loop to enter multiple entries in the On Submit code - after sending email box. Here is the code:
<?php
if (!class_exists('Tabletraining_courses_trainees')) {
class Tabletraining_courses_trainees extends JTable
{
var $id = null;
var $course_id = null;
var $full_name = null;
var $company = null;
var $position = null;
var $phone = null;
var $email = null;
var $sales_account_manager = null;
var $partner_status = null;
var $payment_method = null;
function __construct( &$database ) {
parent::__construct( '#__training_courses_trainees', 'id', $database );
}
}
}
$count = $_POST['count_field'];
for ($i = 1; $i <= $count; $i++) {
$data = array();
$data['course_id'] = $_POST['course_id'];
$full_name = explode(", ", $_POST['full_name']);
$data['full_name'] = $full_name[$i-1];
$data['company'] = $_POST['company'];
$position = explode(", ", $_POST['position']);
$data['position'] = $position[$i-1];
$data['phone'] = $_POST['phone'];
$email = explode(", ", $_POST['email']);
$data['email'] = $email[$i-1];
$data['sales_account_manager'] = $_POST['sales_account_manager'];
$data['partner_status'] = $_POST['partner_status'];
$data['payment_method'] = $_POST['payment_method'];
$record =& JTable::getInstance("training_courses_trainees", "Table");
if ( !$record->save($data) ) {
JError::raiseWarning(100, $record->getError());
}
}
?>


Now I would like to send confirmation emails to the emails that are being added dynamically by the user. But I would also like these emails to be different according to which email they are being sent to. Is that even possible?
quantum_leap 26 Jul, 2012
My requirements changed and I no longer want to send different emails to all the different addresses. I just want to send the same email to all the different email addresses. So I create a DynamicTo email field and I name it email(that's the name of my email fields). While I am debugging the form, I can see that the To field is being populated with the email addresses entered by the user in the form of
To: user1@email.com, user2@email.com
but the users don't receive any emails. The funny thing is that when I create a static To field and name it [email]user1@email.com[/email], [email]user2@email.com[/email] then save the form, the emails are being sent normally!

It's the last piece of the puzzle, I would appreciate a final helping hand!
GreyHead 27 Jul, 2012
Hi quantum_leap,

I'm afraid that I don't remember if the Dynamic To in CFv3.2 supports comma separated strings in variable (the Cfv4 one doesn't).

Looking at the code I think it will work if you set up the Dynamic To entry as email_1,email_2 using separate entries for each ermail.

Bob
quantum_leap 04 Aug, 2012
I am afraid I am going to have to keep the field as an array since I have an email field in my database and I don't waht to have to create name_1, name_2, name_n, etc variables since they might be lots of emails entered by the user. What I don't understand is that why does it work when I enter [email]emai1l@email.com[/email], [email]email2@email.com[/email] in the Dynamic To field and not when I set the email variable that contains the comma separated strings. It's the same thing, isn't it? Or would I need to extract the emails from the array, put the in separate variables then enter those variables separated by comma in the Dynamic To field? And how would I do that?
GreyHead 05 Aug, 2012
Hi quantum leap,

It's the same thing, isn't it?

No.

Or would I need to extract the emails from the array, put the in separate variables then enter those variables separated by comma in the Dynamic To field?

Yes, but you may have a problem if the number of emails is variable. You'd need to try the code and see; if it doesn't work then a hand-coded email send may be the simplest answer.

Bob
This topic is locked and no more replies can be posted.