Creating a JSON object from multiple form fields using jQuery - php

I am trying to create a JSON object from a bunch of grouped HTML elements, this is my markup,
HTML:
<div id="locations_wrapper">
<div id="location_0" class="locations">
<div class="container">
<label for="locations_province">Province: </label>
<div>
<select id="locations_province" name="locations_province" onchange="get_cities(this);">
<option value="">Select one</option>
<option>Eastern Cape</option>
<option>Freestate</option>
<option>Gauteng</option>
<option>KZN</option>
<option>Limpopo</option>
<option>Mpumalanga</option>
<option>North West</option>
<option>Northern Cape</option>
<option>Western Cape</option>
</select>
</div>
</div>
<!-- City -->
<div class="container">
<label for="locations_city">City: </label>
<div>
<select id="locations_city" name="locations_city">
<option value="">Select one</option>
</select>
</div>
</div>
<!-- Towns -->
<div class="container">
<label for="locations_towns">Towns: </label>
<div>
<input type="text" name="locations_towns" id="locations_towns" />
</div>
</div>
</div>
</div>
At the moment I am cloning these 3 fields and appending them to the parent div locations_wrapper, I also increment the id attribute of each field, the problem now is that I need to get all of the cloned elements and somehow, using jQuery/ajax, capture all of the data of each location into a database.
How could I go about getting that information?
here is some jQuery I wrote that basically does the same thing, but with one fied instead of 3:
var sections = $('#systems_wrapper').find('.dropDowns');
var newArray = new Array();
sections.each(function(){
var id = $(this).attr('id');
var val = $(this).val();
var o = { 'id': id, 'value': val };
newArray.push(o);
});
$.ajax({
type: 'POST',
url: 'qwer.php',
dataType: 'json',
data: { json: JSON.stringify(newArray) }
});
Maybe I could try creating a JSON object with 3 fields province, city and town? I am a little unsure.
Thanx in advance!

The easiest way to serialize a form as JSON is to use jQuery's serializeArray():
JSON.stringify($("#myForm").serializeArray());
You will need to wrap a form around your HTML for this to work though. It won't change the behavior.
http://api.jquery.com/serializeArray/

It's not very clear, from your question, what you're trying to accomplish. But I'm guessing, from your markup, that you're building something that will allow the user to add multiple "locations" within the "locations_wrapper" object. This sort of thing usually starts with markup like you've shown, providing a single blank "location" form for the user to fill in (3-fields, in this case); and a button that they can click to add additional "location" blocks as needed.
Assuming that this is what you're doing, my first suggestion would be that, instead of cloning the three form fields individually, you should be cloning only their parent container, "location_0". Something like this should do the trick:
$('#location_0').clone().appendTo('#locations_wrapper');
That will copy the entire block -- and you don't really need to worry about changing the ids of things, jQuery and/or the browser will take care of ensuring that everything has a unique id behind-the-scenes.
Now, assuming that your markup is located within a form, the easiest way to get the information back up to the server is just to submit the form. The form post will contain multiple fields with the same name -- which is completely valid, and most server-side languages have a simple way of dealing with it.
In php, multi-value request parameters come in as an array. So in php, you could do something like this:
<?php
$field_names = ['locations_province', 'locations_city', 'locations_town'];
$locations = array();
foreach( $field_names as $fieldname ) {
$temp = (array)$_REQUEST[$fieldname];
for( $i=0; $i<count($temp); ++$i ) {
if( !isset($locations[$i]) ) $locations[$i] = array();
$locations[$i][$fieldname] = $temp[$i];
}
}
If you'd rather aggregate it all in javascript, you can access your field groups like this:
var allLocations = [];
$(".locations").each( function(i, location) {
// for each location block
location = $(location);
var loc = {
'locations_province' : $("select[name='locations_province']", location).val(),
'locations_city' : $("select[name='locations_city']", location).val(),
'locations_towns' : $("input[name='locations_towns']", location).val()
};
allLocations.push( loc );
});
// allLocations will contain a list of objects with properties representing
// your locations. at this point, you can do whatever you want with 'em
// send them up via Ajax, or whatever.
good luck!

My thought, if you've got control over what the server can accept, would be to pass a bag instead of an array e.g.
{"province" : "", "city" : "", "town" : ""}
I'd then create a payload object:
var province, city, town, payload;
province = $("#locations_province").val();
city= $("#locations_city").val();
town= $("#locations_town").val();
payload = {"province" : province, "city" : city, "town" : town};
...and give the payload to $.ajax:
$.ajax({
type: 'POST',
url: 'qwer.php',
dataType: 'json',
data: payload
});
jQuery will URI encode the payload for you.
You can streamline the payload creation even further if you use Mustache.

Related

PHP/JSON Array display values based on dropdown selection

Having a difficult time trying to suss this out. I've searched through, but I'm not sure if the phrase I'm using to search is correct or not.
I have a JSON file that I'm using to bring in an array of data from an outside source. Using PHP, I decode the contents. I've created a dropdown box that will display the keys, but what I'm looking to do now is dynamically populate a printout with the different values that the keys are attached to based on what the select box has selected.
<?php
// JSON string
$json = file_get_contents("showrace.json");
$races = json_decode($json, true);
?>
<select id="raceSelect">
<option value="select one" selected>Select One</option>
<?php foreach($races as $key => $value) { ?>
<option value="<?php echo $key ?>"><?php echo $value['race'] ?></option>
<?php } ?>
</select>
<div id="template">
Str Plus: # Dex Plus: # Wis Plus: # Int Plus: #<br>
</div>
And here is a sample of what the JSON file looks like:
{
"Ithorian":{"price":0,"wis":3,"str":2,"lck":0,"int":2,"frc":0,"dex":-2,"con":2,"cha":-3,"app":"No","hp":1200,"ac":0,"race":"Ithorian","lang":"ithorian"},
"Weequay":{"price":1000,"wis":-2,"str":3,"lck":0,"int":-2,"frc":0,"dex":0,"con":2,"cha":-3,"app":"No","hp":1350,"ac":0,"race":"Weequay","lang":"weequay"}
}
In the first snippet, the #'s in the template div will be outputs for the JSON values such as "str" and "dex" and such. While I was able to find out how to set the select to draw in the keys from the JSON, I am baffled at how to populate the template portion with the corresponding values, based off of the selected item.
Thanks in advance!
This may help you get started, as it is not fully fleshed out for everything. But it covers some basics you could use.
First off you would want an onchange handler in your jquery. This will fire off everytime someone changes their choice with the :
$("#raceSelect").change(function(e){
// magic will go here (see further below)
});
// or
$("form").on("change","#raceSelect",function(e){
// magic will go here (see further below)
});
Next up you would want to have access to all that json data in your jquery area to use for displaying those values based on what they chose:
<script>
// define this in your php page output near the top
// or within your jquery .ready block
var jsonData = <?PHP echo $json;?>;
</script>
Now you are ready to do some of the magic with the onchange. Accessing the right array in the jsonData, with the id chosen, you can swap out spans and divs to your hearts content. A combined example is as follows:
<?PHP
// your php script
$json = file_get_contents("showrace.json");
$races = json_decode($json, true);
?>
<!-- your form here as you have it in your example -->
<div id="template">
Str Plus: <span id="dat_str">#</span> Dex Plus: # Wis Plus: # Int Plus: #<br>
</div>
<script>
$( document ).ready(function() {
// this is your jquery .ready block
var jsonData = <?PHP echo $json;?>;
$("form").on("change","#raceSelect",function(e){
var race = $(this).val();
$("#dat_str").html( jsonData[race].str );
// you can set the dex, and wiz, etc as well
// following the same format to assign
});
});
</script>
Disclaimer: I hand typed this out, and didn't vett or test it. Its purely an example of pieces that should hopefully help you out.
you can do it using JS
var raceSelect = $('#raceSelect').find(":selected").text();
and check out this link on how te select from json
then print what you want
select from json

Populate form based on selected item php

I have a page with a select list (gets successfully populated from mysql) and a text box. The text box has to be populated with a value from mysql based on the item selected in the list. But the ajax call to php is not working and i can not figure out what the issue is. I am just learning ajax and php, so a novice.. Please help. i am stuck with this for a long time.
<script>
$(document).ready(function() {
$('.selectpicker').on("change", function(){
var selected_data = $(this).find("option:selected").val();
alert(selected_data);
$.ajax ({
type: "POST",
data: { selected_data: selected_data },
url: "getoldcharity.php",
dataType: "json",
success: function(res) {
$('#charity_new').val(data.charity_new);
}
});
});
});
</script>
<form id="assign-fundraiser_form" class="form-horizontal" action="" method="post">
<div class="form-group">
<div class="col-md-3">
<select class="selectpicker form-control" id="fundraiser" name="fundraiser" required>
<option value="" selected disabled>Select a Fundraiser</option>
<?php
include('session.php');
$result1 = mysqli_query($db,"select concat(f_firstname,' ',f_lastname) fundraiser from fundraiser where f_company in (select contractor_name from contractor where company_name = '$_SESSION[login_user]') and f_status = 'Active' order by concat(f_firstname,' ',f_lastname)");
while ($rows = mysqli_fetch_array($result1))
{
echo "<option>" .$rows[fundraiser]. "</option>";
}
?>
</select>
</div>
</div>
<input type="text" name="charity" id="charity_new" />
</form>
<?php
include "session.php";
if (ISSET($_POST['.selectpicker'])) {
$ref = $_POST['.selectpicker'];
$query = $db->query("select f_charity charity_new from fundraiser limit 1");
$row = $query->fetch_assoc();
$charity_new = $row['charity_new'];
$json = array('charity_new' => $charity_new);
echo json_encode($json);
}
$db->close();
?>
There are a few problems that I've spotted from quick glance, so I've separated them below.
PHP
In your AJAX request, you are using data: { selected_data: selected_data } which means the PHP code will be expecting a POSTed key named selected_data but you're looking for .selectpicker. You seem to have mixed up a couple of things, so instead of:
$_POST['.selectpicker']
it should be:
$_POST['selected_data']
JavaScript
As Ravi pointed out in his answer, you also need to change your success function. The parameter passed through to this function is res not data, so instead of:
$('#charity_new').val(data.charity_new);
it should be:
$('#charity_new').val(res.charity_new);
MySQL
It also appears as though your query itself is invalid - you seem to be missing a comma in the column selection.
select f_charity charity_new from fundraiser limit 1
should be:
select f_charity, charity_new from fundraiser limit 1
or, seeing as you're not using the f_charity column in the results anyway:
select charity_new from fundraiser limit 1
You aren't using the value that is being POSTed either, meaning that whatever option is selected in the dropdown makes no difference to the query itself - it will always return the first record in the database.
Other
One other thing to be aware of is you're using a class selector on your change function. This means if you have multiple dropdowns with the same class name in your HTML, they will all be calling the same AJAX function and updating the textbox. I don't know if this is what you're aiming for, but from your code posted, you only have one dropdown in the form. If you only want that one dropdown to be calling the AJAX function, you should use an ID selector instead:
$('#fundraiser').on("change", function() {
// ...
}
I think, it should be
$('#charity_new').val(res.charity_new);
instead of
$('#charity_new').val(data.charity_new);

Dynamically added form elements are posted to PHP but cannot access them

I'm posting dynamically added form elements to PHP via AJAX.
I can see that the serialised form data is posted to the php, but when I try to access the data within it, some of the fields come up NULL i.e. var_dump in the PHP below shows NULL.
this is the Jquery that adds the dynamic elements:
$(function(){
var count=0;
$('#more_edu').click(function(){
count ++;
$('#education_add').append('<br><br><label>University/Institution: </label><input type="text" class="searchbox" id="edu_inst'+count+'" name="edu_inst[]" maxlength="200" value="">);
event.preventDefault();
});
});
and the Jquery posting to php:
function profileSub(){
var myform;
event.preventDefault();
myform = $('form').serialize();
$.ajax({
type: 'POST',
url: 'tutorprofileinput.php',
data: {"form": myform},
success:function(data, response, xhr){
console.log(response);
console.log(data);
console.log(xhr);
},
error:function(){
// failed request; give feedback to user
$('#ajax-panel').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
}
This is the original form:
<form id="tutor_profile_input" onsubmit="return false;">
<label>University/Institution: </label>
<input type="text" class="searchbox" id="edu_inst" name="edu_inst[]" maxlength="200" value=""> </br></br>
<label>Subject:</label>
<input type="text" class="searchbox" id="edu_subj" name="edu_subject[]" maxlength="200" value=""></br></br>
<label> Level </label>
<select id="edu_level" name="edu_level[]">
and the PHP itself:
<?php
if (isset($_POST['form'])){
$form = $_POST['form'];
var_dump($_POST["edu_inst"]);?>
This is the var dump of the whole $_POST:
location=&price=&tutorname=&edu_inst%5B%5D=Uni1&edu_subject%5B%5D=subje1&edu_level%5B%5D=BA&edu_inst%5B%5D=uni2&edu_subject%5B%5D=subj2&edu_level%5B%5D=BA&bio=%09&exper
The form you've posted has an ID of #tutor_profile_input, where as the one you're appending to in the jQuery function is #education_add - Unless I've misunderstood?
Otherwise I'd look at specifying a more specific target in the AJAX request - You're just targetting $('form') at the moment which could be any form on the page..
Have discovered the answer so thought I would share - The Jquery serialize() function encodes the data into a string, which is then posted to PHP as an array with the key of "form".
In order to deal with this in php I had to first use the urldecode function in PHP to convert the string encoded elements (%5B%5D) from the name attributes. This was because there might be multiple values in these so they were declared in the form as an array ("name="edu_insts[]"). Then use parse_str to split the string into an array.
<?php
$querystring = $_POST['form'];
$querystring = urldecode($querystring);
parse_str($querystring, $params);
$insts = $params['edu_inst'];
echo $insts[0]."<br>";
echo $insts[1]."<br>";
?>
This will create an array named $params with keys corresponding to the form name attributes.
Note that if you have multiple values within the same name, then each one will be placed within an array itself, so with the above text you will have $insts[0] = University 1
and $insts[1] = University 2 etc.
Hope this helps anyone with the same problem.

Send data in Ajax response

hey I am trying to populate one select dropdown on the basis of another one using ajax. I have one select populated with portfolios and the 2nd one is empty. when I select an option from the 1st select box. I call an ajax function in which I send the selected portfolio id, In the ajax method I find the groups for the selected id, how can I populate the 2nd select with the groups I found. My code is
The form which contains two selects
<form name="portfolios" action="{{ path('v2_pm_portfolio_switch') }}" method="post" >
<select id="portfolios" name="portfolio" style="width: 200px; height:25px;">
<option selected="selected" value="default">Select Portfolio</option>
{% for portfolio in portfolios %}
<option get-groups="{{ path('v2_pm_patents_getgroups') }}" value={{ portfolio.id }}>{{ portfolio.portfolioName }}</option>
{% endfor %}
</select><br/><br/>
<select id="portfolio-groups" name="portfolio-groups" style="width: 200px; height:25px;">
<option selected="selected" value="default">Select Portfolio Group</option>
</select><br/>
</form>
The JS
<script>
$(document).ready(function(){
$('#portfolios').change(function() {
var id = $("#portfolios").val();
var url = $('option:selected', this).attr("get-groups");
var data = {PID:id};
$.ajax({
type: "POST",
data: data,
url:url,
cache: false,
success: function(data) {
//want to populate the 2nd select box here
}
});
});
});
</script>
Controller method where I find the groups for the selected portfolio
public function getgroupsAction(Request $request){
if ($request->isXmlHttpRequest()) {
$id = $request->get("PID");
$em = $this->getDoctrine()->getEntityManager();
$portfolio_groups = $em->getRepository('MunichInnovationGroupPatentBundle:PmPatentgroups')
->getpatentgroups($id);
return $portfolio_groups;
}
}
Any idea how can i send the portfolio groups and populate the 2nd select
thanks in advance
Use getJson instead of ajax();
Json (JavaScript Object Notation) , is the most easiest way to send structured data between php and javascript.
I Assuming here that the controller respond directly to the ajax query and that $portfolio_groups is an associative array with "id" and "name" as keys or an object with this same properties.
In your PHP controller send json data:
public function getgroupsAction(Request $request){
if ($request->isXmlHttpRequest()) {
$id = $request->get("PID");
$em = $this->getDoctrine()->getEntityManager();
$portfolio_groups = $em->getRepository('MunichInnovationGroupPatentBundle:PmPatentgroups')
->getpatentgroups($id);
echo json_encode($portfolio_groups);
}
}
Then use getJson to retrieve data and iterate over it :
$.getJSON(url, data, function(result) {
var options = $("#portfolio-groups");
$.each(result, function(item) {
options.append($("<option />").val(item.id).text(item.name));
});
});
Have a look to the getjson documentation for more detail about it
Check out this XML tutorial (someone out there is going to flame me for linking to w3schools) it's a good start.
AJAX requests are, in VERY broad terms, calls which make a browser open a window that only it can see (not the user). A request is made to the server, the server returns a page, the script that made the request can view that page. This means that anything which can be expressed in text can be transmitted via AJAX, including XML (for which the X in AJAX stands for).
How is this helpful? Consider, if you are trying to populate a drop down list, you need to return a list of items to populate it with. You COULD make an ajax call to a page http://www.mysite.com/mypage.php?d=select1 (if you are unfamiliar with GET and POST requests, or are a little in the dark regarding the more utilitarian aspects of AJAX, another full tutorial is available here) and have it return a list of items as follows:
item1
item2
item3
...
And scan the text for line breaks. While this certainly would work for most cases, it's not ideal, and certainly won't be useful in all other cases where AJAX may be used. Instead consider formatting the return in your PHP (.NET, ASP, whatever) in XML:
<drop>
<item>item1</item>
<item>item2</item>
<item>item3</item>
</drop>
And use Javascripts built in parser (outlined here) to grab the data.
What I would do is to use the $.load() function.
To do this, your getgroupsAction should return the options html.
The JS:
<script>
$(document).ready(function(){
$('#portfolios').change(function() {
var id = $("#portfolios").val();
var url = $('option:selected', this).attr("get-groups");
var data = {PID:id};
// Perhaps you want your select to show "Loading" while loading the data?
$('#portfolio-groups').html('<option selected="selected" value="default">Loading...</option>');
$('#portfolio-groups').load(url, data);
});
});
</script>
I don't know how $portfolio_groups stores the data, but let's say you'd do something like this in your response:
<?php foreach($portfolio_groups as $p) : ?>
<option value="<?php echo $p->value ?>"><?php echo $p->name ?></option>
<?php endforeach ?>
This way, the select will be filled with the options outputted by getgroupsAction.
The easiest way would be to return json string from your controller and then process it in the 'success' call of the $.ajax.
Lets assume, that your $portfolio_groups variable is an array:
$portfolio_groups = array('1'=>'Portfolio 1', '2' => 'Portfolio 2');
then you can return it from controller as json string like this:
echo json_encode($portfolio_groups);
Then in your jQuery ajax call you can catch this string in the response (the 'success' setting of the $.ajax). Don't forget to add setting dataType: 'json'
Roughly, your $.ajax call will look like this:
$.ajax({
type: "POST",
data: data,
url:url,
cache: false,
dataType: 'json', // don't forget to add this setting
success: function(data) {
$.each(data, function(id, title){
var node = $('<option>').attr('value', id).html(title);
// this will simply add options to the existing list of options
// you might need to clear this list before adding new options
$('#portfolio-groups').append(node);
});
}
});
Of course, you will also need to add the checks if the data is not empty, etc.
Supposing that the function getgroupsAction stays in a flat php controller ( not inside a class ) you should tell the server to execute the function
so at the end of file being called by ajax you should barely call the function first ( probably you did it! )
For your patents group result set, you can generate the select by php or by javascript
In first case you should do this:
//php
$options = getgroupsAction($_REQUEST);
$return = "<select name =\"name\" id=\"id\"><option value=\"\"></option>";
foreach( $options as $option){
$return.= "<option value=\"$option\">$option</option>";
}
$return .= "</select>";
echo $return;
Then in Javascript:
// javascript
var data = {PID:id};
$.ajax({
type: "POST",
data: data,
url:url,
cache: false,
success: function(data) {
//inside data you have the select html code so just:
$('#divWhereToappend').append(data);
},
error: function(data) {
//ALWAYS print the error string when it returns error for a more easily debug
alert(data.responseText);
}
});

PHP overriding AJAX post request

On my Code I have this callback
$('#tagList').tagit({
//Every new dag will be pushed in the list array
tagsChanged: function(tagValue,action,element){
list.push(tagValue);
$.ajax({
url: "dostuff.php",
type: "POST",
data:{ items:list.join("::")},
success: function(data){
$('#wrap').append(data);
}
});
}
});
What it does it that each time I add a tag the newly added tag will be pushed in the array and after that it will make an AJAX post request.
And Then i have these field here
<form method = "POST" action = "demo3.php">
News Title <input id = "news_title" type = "text" name = "news_title" /><br>
<label>Insert Some tags </label>
<ul id="tagList" data-name="demo2">
</ul>
<input type = "submit" name = "submit" id = "submit" value = "Post News" />
</div>
</form>
and when I click the submit(it basically reloads the page) the $_POST['items'](This was created on AJAX request everytime a new tag is added) is being erased or removed in the POST global array. and therefore leaving my $_POST global array empty.
Is there anyway I can merge these two? or anyway not to let PHP override or remove the $_POST['items'] ?since I would be needing items for my query
Also I am using a plugin called tagit
If you guys are interested here's my whole code
<!doctype html>
<html>
<head>
<script src="demo/js/jquery.1.7.2.min.js"></script>
<script src="demo/js/jquery-ui.1.8.20.min.js"></script>
<script src="js/tagit.js"></script>
<link rel="stylesheet" type="text/css" href="css/tagit-stylish-yellow.css">
<script>
$(document).ready(function () {
var list = new Array();
$('#tagList').tagit({
//Every new dag will be pushed in the list array
tagsChanged: function(tagValue,action,element){
list.push(tagValue);
$.ajax({
url: "dostuff.php",
type: "POST",
data:{ items:list.join("::")},
success: function(data){
$('#wrap').append(data);
}
});
}
});
});
</script>
</head>
<body>
<div id="wrap">
<div class="box">
<button class = "viewTags">View Tags</button>
<form method = "POST" action = "demo3.php">
News Title <input id = "news_title" type = "text" name = "news_title" /><br>
<label>Insert Some tags </label>
<ul id="tagList" data-name="demo2">
</ul>
<input type = "submit" name = "submit" id = "submit" value = "Post News" />
</div>
</form>
</div>
</body>
</html>
and here's dostuff. php
<?php
$lis = $_POST['items'];
$liarray = explode("::", $lis);
print_r($liarray);
print_r($_POST);
?>
The way PHP handles requests are that every request is completely separated from every other one, this sometimes referred as the share nothing architecture. This is the reason of that the request generated from the <form> to demo3.php doesn't know about the other requests sent by ajax to dostuff.php is this separation. This is not necessarily php specific, it's because the underlying HTTP protocol is stateless.
If you want to include tags into the request generated when your <form> is submitted you need to add those values to the form. For this, the tagit library has a built in way controlled by two config option:
itemName controls what the parameter named (defaults to item)
fieldName controls what the field in the itemName gets called (defaults to tags)
If you initialize your plugin like this (demo without styles):
$('#tagList').tagit({
itemName: 'article',
fieldName: 'tags'
});
Then on submit, the parametes sent down to php should be in $_POST['article']['tags'], the parameter names generated will look like article[tags][]. See the demos of the plugin. (the page source has nicely formatted javasript examples). By default simply calling $('#tagList').tagit(); without all the extra callbacks or configuration should work.
This is how it should show up in the net panel of firebug (never mind the demo4.php not beeing there)
If you want to do it manually you can hook into the submit event of <form> like this:
$('form').on('submit', function(){
var $form = $(this),
tags = $('#tagList').tagit('assignedTags'); // see the docs https://github.com/aehlke/tag-it/blob/master/README.markdown#assignedtags
$.each(tags, function(i, tag){
$('<input type="hidden" name="tags[]">').attr('value', tag).appendTo($form); // using jquery to create new elements
});
});
By using the assignedTags method (with jquery ui calling schema) of the tagit plugin, you can get the tag names, and simply add a new hidden input just before submitting the <form>. Joining them together like this might be a bad idea if your can include any string imaginable even ::.
In the example, i've used separate input for each tag so in your demo3.php they will arrive as an array (ending the name with [] makes php do that).

Categories