2

I have a section where users can enter their educational history. each time the "Add education" anchor tag is clicked and set of three inputs is created. the education_institution, education_outcome and education_date. So each user can have one or one hundred.

This is then saved in MYSQL as JSON data. My question is how can I then get it from the database and loop through (either with PHP or javascript) the JSON and display each set in 3 inputs row as seen below in the HTML?

Any help is most appreciated.

HTML:

<p class="mt-3 text-left"> Education </p>

<div class="row block">

    <div class="col-md-3">
        <input type="text" name="education_institution[]" placeholder="Institution" value="<?php echo($decoded_data->education->education_institution); ?>">
    </div>

    <div class="col-md-3">
        <input type="text" name="education_outcome[]" placeholder="Outcome" value="<?php echo($decoded_data->education->education_outcome); ?>">
    </div>

    <div class="col-md-3">
        <input type="Date" name="education_date[]" placeholder="Date of completion" value="<?php echo($decoded_data->education->education_date); ?>">

    </div>
    <div class="col-md-3 text-center">
        <button href="#" class="able_btn m-0 w-100"> remove </button>
    </div>

</div>  

    <div class="text-center mt-3">
        <a class="add_education" href=""> Add education </a>    
    </div>

JQUERY:

$('.add_education').click(function(evt) {
 evt.preventDefault();

    $('.block:last').after('<div class="row block"><div class="col-md-3"><input type="text" name="education_institution[]" placeholder="Institution"></div><div class="col-md-3"><input type="text" name="education_outcome[]" placeholder="Outcome"></div><div class="col-md-3"><input type="Date" name="education_date[]" placeholder="Date of completion"></div><div class="col-md-3 text-center"><button class="able_btn m-0 w-100 remove"> remove </button></div></div>');
});

PHP:

$json_data = array(
        'profession' => $profession,
        'personal_statement' => $personal_statement,

    'education' => [
        'education_institution' => $education_institution,
        'education_outcome' => $education_outcome,
        'education_date' => $education_date],
    'employment' => [
        'job_title' => $job_title,
        'job_location' => $job_location,
        'job_duration' => $job_duration]);


$data = json_encode($json_data);

JSON:

{
    "profession": "",
    "personal_statement": "",
    "education": {
        "education_institution": [
            "school one",
            "school two"
        ],
        "education_outcome": [
            "out one",
            "out two"
        ],
        "education_date": [
            "2017-11-01",
            "2017-11-04"
        ]
    },
    "employment": {
        "job_title": [
            ""
        ],
        "job_location": [
            ""
        ],
        "job_duration": [
            ""
        ]
    }
}
5
  • 1. get data from database 2. json_decode($data) 3. use for each() loop Commented Nov 28, 2017 at 6:13
  • 1
    It's not clear whether you want to loop through the JSON with PHP or JavaScript. Either way, look at for each loops. foreach ($data as $row) and JSON.parse(json).forEach(...) Commented Nov 28, 2017 at 6:14
  • @fubar I updated the question, really either one. I just need to get it displaying. Commented Nov 28, 2017 at 6:15
  • 1
    The JSON structure isn't clear. Can you post a more complete example, without variables in it. Commented Nov 28, 2017 at 6:28
  • @fubar I've updated the question. Commented Nov 28, 2017 at 6:40

2 Answers 2

1

Because you're not storing the three field values together in a single JSON object, it's actually not going to be possible to use a foreach loop. I've therefore used a for loop instead.

You might find it much easier to work with the data if you did maintain the same structure between the UI and database. This can be done using specific indexes. I've included an example at the end.

<?php

// Decode database to PHP array
$data = json_decode($json, true);

// Assumes `education`, `education_institution`, `education_outcome` and `education_date` indexes will always exist
// Count number of items in `education_institution` and assume `education_outcome` and `education_date` will have same count
$count = count($data['education']['education_institution']);

?>

<p class="mt-3 text-left"> Education </p>

<?php for ($i = 0; $i < $count; $i++): ?>
    <div class="row block">

        <div class="col-md-3">
            <input type="text" name="education_institution[]" placeholder="Institution" value="<?= $data->education->education_institution[$i] ?>">
        </div>

        <div class="col-md-3">
            <input type="text" name="education_outcome[]" placeholder="Outcome" value="<?= $data->education->education_outcome[$i] ?>">
        </div>

        <div class="col-md-3">
            <input type="Date" name="education_date[]" placeholder="Date of completion" value="<?= $data->education->education_date[$i] ?>">
        </div>

        <div class="col-md-3 text-center">
            <button href="#" class="able_btn m-0 w-100"> remove </button>
        </div>

    </div>  
<?php endfor ?>

<div class="text-center mt-3">
    <a class="add_education" href=""> Add education </a>    
</div>

Example using indexes to maintain data structure:

<div class="row block">

    <div class="col-md-3">
        <input type="text" name="education[0]['institution']" placeholder="Institution" value="<?= $data['education_institution'][$i] ?>">
    </div>

    <div class="col-md-3">
        <input type="text" name="education[0]['outcome']" placeholder="Outcome" value="<?= $data['education_outcome'][$i] ?>">
    </div>

    <div class="col-md-3">
        <input type="Date" name="education[0]['date']" placeholder="Date of completion" value="<?= $data['education_date'][$i] ?>">
    </div>

    <div class="col-md-3 text-center">
        <button href="#" class="able_btn m-0 w-100"> remove </button>
    </div>

</div>

<div class="row block">

    <div class="col-md-3">
        <input type="text" name="education[1]['institution']" placeholder="Institution" value="<?= $data['education_institution'][$i] ?>">
    </div>

    <div class="col-md-3">
        <input type="text" name="education[1]['outcome']" placeholder="Outcome" value="<?= $data['education_outcome'][$i] ?>">
    </div>

    <div class="col-md-3">
        <input type="Date" name="education[1]['date']" placeholder="Date of completion" value="<?= $data['education_date'][$i] ?>">
    </div>

    <div class="col-md-3 text-center">
        <button href="#" class="able_btn m-0 w-100"> remove </button>
    </div>

</div>

// ...

And here's an example using the revised indexing structure.

<?php foreach ($data['education'] as $i => $row): ?>

    <div class="row block">

        <div class="col-md-3">
            <input type="text" name="education[<?= $i ?>]['institution']" placeholder="Institution" value="<?= $row['education_institution'] ?>">
        </div>

        <div class="col-md-3">
            <input type="text" name="education[<?= $i ?>]['outcome']" placeholder="Outcome" value="<?= $row['education_outcome'] ?>">
        </div>

        <div class="col-md-3">
            <input type="Date" name="education[<?= $i ?>]['date']" placeholder="Date of completion" value="<?= $row['education_date'] ?>">
        </div>

        <div class="col-md-3 text-center">
            <button href="#" class="able_btn m-0 w-100"> remove </button>
        </div>

    </div>

<?php endforeach ?>
Sign up to request clarification or add additional context in comments.

8 Comments

The first example isn't displaying the values in the inputs.
I'll take your advice and use indexes. however, how would I then achieve the looping?
@bob I've fixed the first example. I missed the education index.
ok, got that working. changed the value= "$data->education->education_date[$i] "
Then yes you will. Just replace the value of the education index in the JSON with the value from $_POST[education]
|
1

NOTE:

fubar example is more fast and recommended, because its using PHP instead javascript

i just add example if you want using js instead php

$(function(){
	var limit = 20; //please use limit to prevent spamming

	$('.add_education').click(function(evt) {
		evt.preventDefault();
		if($('.row').length < limit )addData();
		else alert('you input too much');
	});
	
	function addData(a='', b='', c=''){
		$('.container').append('<div class="row block"><div class="col-md-3"><input type="text" name="education_institution[]" placeholder="Institution" value="'+a+'"></div><div class="col-md-3"><input type="text" name="education_outcome[]" placeholder="Outcome" value="'+b+'"></div><div class="col-md-3"><input type="Date" name="education_date[]" placeholder="Date of completion" value="'+c+'"></div><div class="col-md-3 text-center"><button class="able_btn m-0 w-100 remove"> remove </button></div></div>');
	}
	
	$('.container').on('click','.remove', function(){
		$(this).closest('.row').remove();
	})
	
	function loadData(){
		//$.ajax() run here.
		//im not using ajax, i just direct to get the return. so take care of the php by your self
		var data = {
			"profession": "",
			"personal_statement": "",
			"education": {
				"education_institution": [
					"school one",
					"school two"
				],
				"education_outcome": [
					"out one",
					"out two"
				],
				"education_date": [
					"2017-11-01",
					"2017-11-04"
				]
			},
			"employment": {
				"job_title": [
					""
				],
				"job_location": [
					""
				],
				"job_duration": [
					""
				]
			}
		};
		var edu = data.education;
		for(a=0; a < edu.education_institution.length; a++){
			addData(edu.education_institution[a], edu.education_outcome[a], edu.education_date[a]);
		}
	}
	
	loadData();
});
<p class="mt-3 text-left"> Education </p>

<!--provide parent element if you want insert new dom, because this makes easy to handle your new dom-->
<div class="container"></div>  

<div class="text-center mt-3">
	<a class="add_education" href=""> Add education </a>    
</div>

<script src="https://code.jquery.com/jquery-1.11.3.js"></script>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.