Jump to content

Creating array to POST with jQuery


Adamhumbug
Go to solution Solved by Barand,

Recommended Posts

Hi All,

I have a form that allows the user to provide data in input boxes)

I have a button that allows the user to add more rows (the same as row 1 repeated)

I am using Ajax to post this form but my question is, how do i build the array in jquery of all of the inputs that will then be posted to PHP to insert into the database.

The form looks like this:

<div class="row mb-3 zone-row">
  <div class="col">
    <label for="zoneType" class="form-label">Zone Type</label>
    <select id="zoneType" class="form-select zoneType">
      <option value="1">Normal Zone</option><option value="2">Special Zone</option>							
    </select>
  </div>
  <div class="col">
    <label for="zoneName" class="form-label">Zone Name</label>
    <input type="text" class="form-control simple-string zoneName" id="zoneName">
  </div>
  <div class="col">
    <label for="printValue" class="form-label">Print Value</label>
    <input type="text" class="form-control simple-string printValue" id="printValue">
  </div>
</div>

when clicking the button to add another row - it adds:

<div class="row mb-3 extra-row">
  <div class="col">
    <select id="" class="form-select zoneType"> 
      <option value="1">Normal Zone</option>
      <option value="2">Special Zone</option> 
    </select>
  </div>
  <div class="col">
    <input type="text" class="form-control simple-string zoneName" id="">
  </div>
  <div class="col">
    <input type="text" class="form-control simple-string printValue" id="">
  </div>
</div>

i expect that this will need to be some sort of each function?

Link to comment
Share on other sites

I seem to be collecting the data with the following

$('#addZonesButton').on('click', function() {
			$zTypes = $('.zoneType').each(function() {
				$zType = $(this).val()
				console.log($zType);
			})
		})

but how would i then create the array needed in order to post it

Link to comment
Share on other sites

I am not sure if this is getting me closer or further away.

$('#addZonesButton').on('click', function() {
  $zNameArr = []
  $zPrintArr = []
  $('.zoneType').each(function() {
    $zType = $(this).val()

  })
  $('.zoneName').each(function() {
    $zName = $(this).val()
    $zNameArr.push($zName)
  })
  $('.printValue').each(function() {
    $pVal = $(this).val()
    $zPrintArr.push($pVal)
  })
		})

 

Link to comment
Share on other sites

Landed here:

Seems to be working but i dont know if there is a more optimal way of doing this.  Feels a bit like a hack.

$('#addZonesButton').on('click', function() {
			$zNameArr = []
			$zPrintArr = []
			$zTypeArr = []
			$data = [];
			$('.zoneType').each(function() {
				$zType = $(this).val()
				$zTypeArr.push($zType)

			})
			$('.zoneName').each(function() {
				$zName = $(this).val()
				$zNameArr.push($zName)
			})
			$('.printValue').each(function() {
				$pVal = $(this).val()
				$zPrintArr.push($pVal)
			})

			for (i = 0; i < $zNameArr.length; i++) {

				$data[i] = Array($zTypeArr[i], $zNameArr[i], $zPrintArr[i]);
			}
	
			$filteredData = $data.filter(function(x) {
				/* here, x is an array, not an object */
				return !(x.some(element => element === (undefined || null || '')))
			});
			
		})

The data is output as:

 

[
  [
    "1",
    "1",
    "p1"
  ],
  [
    "1",
    "3",
    "p3"
  ],
  [
    "1",
    "2",
    "p2"
  ]
]

Would have preferred this to have keys also.

Now i need to send it to php with ajax and insert it.

Edited by Adamhumbug
Link to comment
Share on other sites

if you put the form fields inside a form, and give them array names, you can use the jquery .serialize() method to get the form data using a single line of code - https://api.jquery.com/serialize/ you would use this in the data value in the .ajax call, e.g. data: $(this).serialize(),

next, if you put the dynamically to-be added markup inside a <template></template> tag, it is simple to dynamically add it - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template

if you put the closing </label> tag after the form field it corresponds to, you can leave out the for='...' attributes and the corresponding id='...' attributes, and make the labels work for the dynamically added fields.

Link to comment
Share on other sites

Here's a sample script

<?php

##
##  HANDLE AJAX REQUEST
##
    if (isset($_POST['ajax']))   {
        if ($_POST['ajax']=='testdata') {
            exit('<pre>' . print_r($_POST, 1) . '</pre>');      // JUST RETURNS THE ARRAY OF POSTED DATA FOR DISPLAY
        }
        exit();
    }
    
?>
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <title>Example</title>
   <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
   
   <script type='text/javascript'>
       $(function() {
           $("#form1").submit(function(ev) {
               ev.preventDefault()
               let fdata = $(this).serialize()
               console.log(fdata)
               $.post(
                   "",
                   fdata,
                   function(resp) {
                       $("#test-output").html(resp)
                   },
                   'TEXT'
               )
           })
       })
   </script> 
</head>
<body>
    <form id='form1'>
    <input type='hidden' name='ajax' value='testdata'>
      <div class="col">
        <label for="zoneType" class="form-label">Zone Type</label>
        <select name="zoneType[]" class="form-select zoneType">
          <option value="1">Normal Zone</option><option value="2">Special Zone</option>                            
        </select>
      </div>
      <div class="col">
        <label for="zoneName" class="form-label">Zone Name</label>
        <input type="text" class="form-control simple-string zoneName" name="zoneName[]">
      </div>
      <div class="col">
        <label for="printValue" class="form-label">Print Value</label>
        <input type="text" class="form-control simple-string printValue" name="printValue[]">
      </div>
      <br>
      
      <div class="col">
        <label for="zoneType" class="form-label">Zone Type</label>
        <select name="zoneType[]" class="form-select zoneType">
          <option value="1">Normal Zone</option><option value="2">Special Zone</option>                            
        </select>
      </div>
      <div class="col">
        <label for="zoneName" class="form-label">Zone Name</label>
        <input type="text" class="form-control simple-string zoneName" name="zoneName[]">
      </div>
      <div class="col">
        <label for="printValue" class="form-label">Print Value</label>
        <input type="text" class="form-control simple-string printValue" name="printValue[]">
      </div>
      <br>
      
      <div class="col">
        <label for="zoneType" class="form-label">Zone Type</label>
        <select name="zoneType[]" class="form-select zoneType">
          <option value="1">Normal Zone</option><option value="2">Special Zone</option>                            
        </select>
      </div>
      <div class="col">
        <label for="zoneName" class="form-label">Zone Name</label>
        <input type="text" class="form-control simple-string zoneName" name="zoneName[]">
      </div>
      <div class="col">
        <label for="printValue" class="form-label">Print Value</label>
        <input type="text" class="form-control simple-string printValue" name="printValue[]">
      </div>
      <br>
    <input type='submit'>
    </form>
    <div id='test-output'>
    </div>
</body>
</html>

[edit]...

NOTE - your form's input fields need name attributes

Link to comment
Share on other sites

46 minutes ago, Barand said:

Here's a sample script

<?php

##
##  HANDLE AJAX REQUEST
##
    if (isset($_POST['ajax']))   {
        if ($_POST['ajax']=='testdata') {
            exit('<pre>' . print_r($_POST, 1) . '</pre>');      // JUST RETURNS THE ARRAY OF POSTED DATA FOR DISPLAY
        }
        exit();
    }
    
?>
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <title>Example</title>
   <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
   
   <script type='text/javascript'>
       $(function() {
           $("#form1").submit(function(ev) {
               ev.preventDefault()
               let fdata = $(this).serialize()
               console.log(fdata)
               $.post(
                   "",
                   fdata,
                   function(resp) {
                       $("#test-output").html(resp)
                   },
                   'TEXT'
               )
           })
       })
   </script> 
</head>
<body>
    <form id='form1'>
    <input type='hidden' name='ajax' value='testdata'>
      <div class="col">
        <label for="zoneType" class="form-label">Zone Type</label>
        <select name="zoneType[]" class="form-select zoneType">
          <option value="1">Normal Zone</option><option value="2">Special Zone</option>                            
        </select>
      </div>
      <div class="col">
        <label for="zoneName" class="form-label">Zone Name</label>
        <input type="text" class="form-control simple-string zoneName" name="zoneName[]">
      </div>
      <div class="col">
        <label for="printValue" class="form-label">Print Value</label>
        <input type="text" class="form-control simple-string printValue" name="printValue[]">
      </div>
      <br>
      
      <div class="col">
        <label for="zoneType" class="form-label">Zone Type</label>
        <select name="zoneType[]" class="form-select zoneType">
          <option value="1">Normal Zone</option><option value="2">Special Zone</option>                            
        </select>
      </div>
      <div class="col">
        <label for="zoneName" class="form-label">Zone Name</label>
        <input type="text" class="form-control simple-string zoneName" name="zoneName[]">
      </div>
      <div class="col">
        <label for="printValue" class="form-label">Print Value</label>
        <input type="text" class="form-control simple-string printValue" name="printValue[]">
      </div>
      <br>
      
      <div class="col">
        <label for="zoneType" class="form-label">Zone Type</label>
        <select name="zoneType[]" class="form-select zoneType">
          <option value="1">Normal Zone</option><option value="2">Special Zone</option>                            
        </select>
      </div>
      <div class="col">
        <label for="zoneName" class="form-label">Zone Name</label>
        <input type="text" class="form-control simple-string zoneName" name="zoneName[]">
      </div>
      <div class="col">
        <label for="printValue" class="form-label">Print Value</label>
        <input type="text" class="form-control simple-string printValue" name="printValue[]">
      </div>
      <br>
    <input type='submit'>
    </form>
    <div id='test-output'>
    </div>
</body>
</html>

[edit]...

NOTE - your form's input fields need name attributes

Amazing, i have modified your code a little so that it fits with how i have done everything else (and i can understand it in the future)

		$("#newZones").submit(function(ev) {
			ev.preventDefault()
			let fdata = $(this).serialize()
			console.log(fdata)
			$.ajax({
				type: 'post',
				data: {
					'ajax': 'addNewZones',
					'data': fdata,

				},
				success: function(resp) {
					$('.alert-container').html(resp).show()
				}
			})
		})

and

if (isset($_POST['ajax'])) {
	switch ($_POST['ajax']) {
		case 'addNewZones':
			exit(addNewZones($pdo, $_POST['data']));
			break;
	}
}

Once the data has been sent into PHP function. Do i need to unserialise it to insert it?

Also, if the zone name field is blank the whole row of 3 fields need to be removed from the array that is sent.  Would this be a filter?

 

Edited by Adamhumbug
Link to comment
Share on other sites

58 minutes ago, mac_gyver said:

if you put the form fields inside a form, and give them array names, you can use the jquery .serialize() method to get the form data using a single line of code - https://api.jquery.com/serialize/ you would use this in the data value in the .ajax call, e.g. data: $(this).serialize(),

next, if you put the dynamically to-be added markup inside a <template></template> tag, it is simple to dynamically add it - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template

if you put the closing </label> tag after the form field it corresponds to, you can leave out the for='...' attributes and the corresponding id='...' attributes, and make the labels work for the dynamically added fields.

Thanks for this.  I will certainly have a look at <template> and great tip on the lables.

Link to comment
Share on other sites

This seems to suggest that i have got it how i need it - i think

 

function addNewZones($pdo, $zoneArr)
{
	$params = array();
	parse_str($zoneArr, $params);
	echo ("<pre>");
	var_dump($params);
	echo "</pre>";
}
array(3) {
  ["zoneType"]=>
  array(3) {
    [0]=>
    string(1) "1"
    [1]=>
    string(1) "1"
    [2]=>
    string(1) "1"
  }
  ["zoneName"]=>
  array(3) {
    [0]=>
    string(1) "1"
    [1]=>
    string(1) "3"
    [2]=>
    string(1) "5"
  }
  ["printValue"]=>
  array(3) {
    [0]=>
    string(1) "2"
    [1]=>
    string(1) "4"
    [2]=>
    string(1) "6"
  }
}

 

Edited by Adamhumbug
Link to comment
Share on other sites

Your POST array looks like this, as you separate the "ajax" value from the serialized data in your JSON string...

Array
(
    [ajax] => testdata
    [data] => zoneType%5B%5D=1&zoneName%5B%5D=aa&printValue%5B%5D=1&zoneType%5B%5D=1&zoneName%5B%5D=bb&printValue%5B%5D=2&zoneType%5B%5D=1&zoneName%5B%5D=cc&printValue%5B%5D=3
)

 

With my code, where only the serialized form data is sent (which includes the "ajax" value from a hidden form field) it looks like this...

Array
(
    [ajax] => testdata
    [zoneType] => Array
        (
            [0] => 1
            [1] => 1
            [2] => 1
        )

    [zoneName] => Array
        (
            [0] => aa
            [1] => bb
            [2] => cc
        )

    [printValue] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)

 

Link to comment
Share on other sites

1 hour ago, Barand said:

Your POST array looks like this, as you separate the "ajax" value from the serialized data in your JSON string...

Array
(
    [ajax] => testdata
    [data] => zoneType%5B%5D=1&zoneName%5B%5D=aa&printValue%5B%5D=1&zoneType%5B%5D=1&zoneName%5B%5D=bb&printValue%5B%5D=2&zoneType%5B%5D=1&zoneName%5B%5D=cc&printValue%5B%5D=3
)

 

With my code, where only the serialized form data is sent (which includes the "ajax" value from a hidden form field) it looks like this...

Array
(
    [ajax] => testdata
    [zoneType] => Array
        (
            [0] => 1
            [1] => 1
            [2] => 1
        )

    [zoneName] => Array
        (
            [0] => aa
            [1] => bb
            [2] => cc
        )

    [printValue] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)

 

is that becuase my code is "wrong" - should i be switching to your way that works or is there another way around.

Link to comment
Share on other sites

$("#newZones").submit(function(ev) {
			ev.preventDefault()
			let fdata = $(this).serialize() + "&ajax=addNewZones";



			$.ajax({
				type: 'post',
				data: fdata,
				success: function(resp) {
					console.log(resp);
					$('.alert-container').html(resp).show()
					// if (resp == "User Created") {
					// 	$(':input', '#createNewUser')
					// 		.not(':button, :submit, :reset, :hidden')
					// 		.val('')
					// 		.prop('checked', false)
					// 		.prop('selected', false);
					// }
				}
			})
		})

 

function addNewZones($pdo)
{
	$sql = "INSERT INTO zones (name, print_value, event_site_attachment_id, zone_type_attachment_id) values (:name, :printVal, :siteId, :zTypeId)";
	$stmt = $pdo->prepare($sql);
	echo "<pre>";
	var_dump($_POST);
	echo "</pre>";
}

This is now showing what looks like the right output

array(4) {
  ["zoneType"]=>
  array(2) {
    [0]=>
    string(1) "1"
    [1]=>
    string(1) "1"
  }
  ["zoneName"]=>
  array(2) {
    [0]=>
    string(1) "1"
    [1]=>
    string(1) "3"
  }
  ["printValue"]=>
  array(2) {
    [0]=>
    string(1) "2"
    [1]=>
    string(1) "4"
  }
  ["ajax"]=>
  string(11) "addNewZones"
}

How does one go about looping through this array to insert it into the DB but only when a zone name is present.

Link to comment
Share on other sites

  • Solution
6 minutes ago, Adamhumbug said:
		let fdata = $(this).serialize() + "&ajax=addNewZones";

Yes.

That is what I was going to suggest if you didn't want to use the hidden field approach. That way you send just a single querystring which will be handled automatically to create the $_POST array

12 minutes ago, Adamhumbug said:

How does one go about looping through this array to insert it into the DB but only when a zone name is present.

Perhaps

    $stmt = $pdo->prepare("INSERT INTO mytable (zoneType, zoneName, printValue) VALUES (?,?,?)");
    foreach ($_POST['zoneName'] as $k => $zn)  {
        if ($zn) {
            $stmt->execute([ $_POST['zoneType'][$k], $zn, $_POST['printValue'][$k] ]);
        }
    }

 

  • Great Answer 1
Link to comment
Share on other sites

4 minutes ago, Barand said:

Yes.

That is what I was going to suggest if you didn't want to use the hidden field approach. That way you send just a single querystring which will be handled automatically to create the $_POST array

Perhaps

    $stmt = $pdo->prepare("INSERT INTO mytable (zoneType, zoneName, printValue) VALUES (?,?,?)");
    foreach ($_POST['zoneName'] as $k => $zn)  {
        if ($zn) {
            $stmt->execute([ $_POST['zoneType'][$k], $zn, $_POST['printValue'][$k] ]);
        }
    }

 

You are a wonderful human.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.