I have a triple select option menu, that works fine now, but when I post/echo it in PHP both the option name and value are the same, so if I want a category that the name is Books, and that could be id=2 example.
I don't know how to put another value in the option, separate the name and value, can someone show me how???
Everything works fine, except I want to have another value than the same name I use to show option name. I hope you understand. :)
My code:
<script type="text/javascript">
var categories = [];
categories["startList"] = ["Wearing Apparel","Books"];
categories["Wearing Apparel"] = ["Men","Women","Children"];
categories["Books"] = ["Biography","Fiction","Nonfiction"];
categories["Men"] = ["Shirts","Ties","Belts","Hats"];
categories["Women"] = ["Blouses","Skirts","Scarves", "Hats"];
categories["Children"] = ["Shorts", "Socks", "Coats", "Nightwear"];
categories["Biography"] = ["Contemporay","Historical","Other"];
categories["Fiction"] = ["Science Fiction","Romance", "Thrillers", "Crime"];
categories["Nonfiction"] = ["How-To","Travel","Cookbooks", "Old Churches"];
var nLists = 3; // number of select lists in the set
function fillSelect(currCat,currList){
var step = Number(currList.name.replace(/\D/g,""));
for (i=step; i<nLists+1; i++) {
document.forms['tripleplay']['List'+i].length = 0;
document.forms['tripleplay']['List'+i].selectedIndex = 0;
}
var nCat = categories[currCat];
for (each in nCat) {
var nOption = document.createElement('option');
var nData = document.createTextNode(nCat[each]);
nOption.setAttribute('value',nCat[each]);
nOption.appendChild(nData);
currList.appendChild(nOption);
}
}
function init() {
fillSelect('startList',document.forms['tripleplay']['List1'])
}
navigator.appName == "Microsoft Internet Explorer" ? attachEvent('onload', init, false) : addEventListener('load', init, false);
</script>
<form name="tripleplay" action="" method="post">
<select name='List1' onchange="fillSelect(this.value,this.form['List2'])" size="5">
</select>
<select name='List2' onchange="fillSelect(this.value,this.form['List3'])" size="5">
</select>
<select name='List3' onchange="getValue(this.value, this.form['List2'].value, this.form['List1'].value)" size="5">
</select>
<br><br>
<input type="submit" value="Submit" name="next" />
</form>
<?php
if($_POST['next'])
{
echo $_POST['List1'].'<br>'.$_POST['List2'].'<br>'.$_POST['List3'].'<br>';
}
?>
I am not sure that I understand your intention, but when a form is submitted, the value(s) of select boxes are delivered to the server.
The label property is being displayed in the UI (no need to append a text node).
If you set the value and label properties appropriately, you will be able to submit the form with any value that you want.
For example, the option construction code could be:
var nOption = document.createElement('option');
nOption.setAttribute('value',each);
nOption.setAttribute('label',nCat[each]);
currList.appendChild(nOption);
And you could get the label by using this.selectedOptions[0].label.
Notes:
The coding style that you are using is not very good.
You use inline event handling and do not separate business logic from UI, to name the main issues.
I suggest that you try some kind of JavaScript framework, such as jQuery, which will prevent you from reinventing the wheel and ease you development considerably, leaving you time to do actual work (you may consider a server-side PHP framework as well).
Here is a jsFiddle demo that shows what I believe to be your desired effect.
Edit:
Since you asked about a better approach, I will describe one possibility that slightly abstracts the logic and separates it from the UI.
This is not extremely useful in this type of situations, but it can help in more complex cases.
represent the data hierarchically.
[{
"id": 131,
"label": "Wearing Apparel",
"children": [{
"id": 131,
"label": "Men",
"children": [{
"id": 65,
"label": "Shirts"
}, ...
]
}, {
"id": 143,
"label": "Women",
"children": [{
"id": 133,
"label": "Blouses"
},
...
]
}]
]
this way, you can encode a tree representation of PHP objects into JSON.
Create a jQuery objects that represents the list and generates the markup, since there is little use for it without JavaScript anyway.
Try to make your utility classes such that they could handle more general cases, so that in the future or as your current requirements change, you can still use it with minimal changes to your code.
Try to avoid inline handlers whenever possible (i.e, always).
I have created a jsFiddle example that does not go all the way, but still demonstrates some of those principles: it generates most of the markup on its own, handles the events itself, able to handle data with arbitrary and varying depth.
If I understand your problem is
<option value="Wearing Apparel">Wearing Apparel</option>
that the value and the text(Wearing Apparel) is the same
First of all use another array sructure ( but json would be better )
categories["Books"] = [
["Biography"],
["Fiction"],
["Nonfiction"]
];
An your loop
for (i=0; i<nCat.length; i++) {
var nOption = document.createElement('option');
var nData = document.createTextNode(nCat[i]); // <------- use the "text"
nOption.setAttribute('value',i); // <------- use the index of the step
nOption.appendChild(nData);
currList.appendChild(nOption);
}
In this case
<option value="0">Wearing Apparel</option>
And your POST array will look like
Array ( [List1] => 0
[next] => Submit
)
Where 0 is the ID of the "Wearing Apparel" element
... and 1 is ID of the "Books"
Related
I'm trying to create an update form where the user selects an ID and the rest of the form gets automatically filled with the corresponding data to that ID which would make updating really simple, obviously i'd have to use AJAX but do i really have to write a whole form code inside the PHP and return it in a single statement and then assigning it in a single innerHTML?
Is it possible to run whatever returns from the php file as a javascript, such that i would be able to write a mini scripts to set the innerHTML of each element by itself and without having to reload the whole form's HTML code, just the values inside form elements?
<?php
$myname = "test";
$myage = 22;
echo
'<script>
document.getElementById("name").innerHTML = "$myname";
document.getElementById("age").innerHTML = "$myage";
</script>';
?>
PS i have no experience of AJAX and i can only find the xmlhttp.responseText for returning the output of a PHP script.
It would be better if you return the data structured in some form (e.g.: JSON), then process it with JavaScript.
For example, instead of what you are returning, do something like this:
<?php
$to_return = array(
"name" => "test",
"age" => 22
);
echo json_enconde($to_return);
Then on your page, parse your response, and process it:
data = JSON.parse(response);
document.getElementById("name") = data.name;
document.getElementById("age") = data.age;
If you want to standardize it a little bit more, you could return something like this:
[
{
"target": "name",
"value": "test"
},
{
"target": "age",
"value": 22
}
]
and create a function like this:
function populateForm(data) {
for (var x = 0; x < data.length; x++) {
document.getElementById(data[x].target).innerHTML = data[x].value;
}
}
Then call that function with the JSON response from your PHP.
I would recommand to return an Array in the server side (the php that handles the ajax request). and in the browser side after you get the the respone from the server then you set
document.getElementById("name").innerHTML = $myname;
document.getElementById("age").innerHTML = $myage;
Okay, that's a presumptuous title - it's complex to me.
Overview: (See screenshots and UPDATE at bottom.)
a. On $(document).ready, jQuery/AJAX builds table with one contact per row
b. Each table row, 3rd cell, is: <a id="edit_83">edit</a> tag -- "83" is example and represents the contact_id from db, so each a tag will have a unique id number that is used in step (d)
c. As table being built, construct jqueryui dialog (autoOpen=false) for each contact in AJAX callback
d. when any edit anchor is clicked, jquery splits off the contact_id and uses that to display the appropriate jQueryUI dialog.
Objective: Clicking on edit link in any table row opens a jqueryui dialog with edit form for that contact.
Problem: The form opens, but there are no form fields inside. In fact, in the DOM the injected form/div is missing for each table row. ???
HTML:
<div id="contact_table"></div>
Javascript/jQuery - AJAX call:
$(document).ready(function() {
$.ajax({
type: "POST",
url: "ax_all_ajax_fns.php",
data: 'request=index_list_contacts_for_client&user_id=' + user_id,
success: function(data) {
$('#contact_table').html(data);
var tbl = $('#injected_table_of_contacts');
tbl.find("div").each(function() {
$(this).dialog({
autoOpen: false,
height: 400,
width: 600,
modal: true,
buttons:
{
Okay: function() {
$( this ).dialog( "close" );
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
})
});
}
});
});
AJAX/PHP 1 - ax_all_ajax_fns.php:
}else if ($_POST['request'] == 'index_list_contacts_for_client') {
$user_id = $_POST['user_id'];
$r = build_contact_table_for_client($user_id);
echo $r;
}
AJAX/PHP 2: - functions.php
function build_contact_table_for_client($user_id) {
$aContact_info = get_contact_data_ARRAY_user_id($user_id, 'first_name','last_name','email1','cell_phone', 'contact_id');
$r = '<table id="injected_table_of_contacts">
<tr>
<th width="120">Name</th>
<th width="200">Email Address</th>
<th width="100">Cell Phone</th>
<th>Action</th>
</tr>
';
while ($rrow = mysql_fetch_array($aContact_info)) {
$r .= '
<tr>
<td>'.$rrow['first_name'].' '.$rrow['last_name'].'</td>
<td>'.$rrow['email1'].'</td>
<td>'.$rrow['cell_phone'].'</td>
<td>
<a class="editcontact" id="edit_'.$rrow['contact_id'].'" href="#">edit</a>
/
<a class="delcontact" id="del_'.$rrow['contact_id'].'" href="#">del</a>
<div id="editThisContact_'.$rrow['contact_id'].'" style="display:none">
<form name="editForm" onsubmit="return false;">
<p class="instructions">Edit contact information:</p>
First Name:<span style="padding:0 20px;">Last Name:</span><br />
<input type="hidden" id="fn_'.$rrow['contact_id'].'" value="'.$rrow['first_name'].'">
<input type="hidden" id="ln_'.$rrow['contact_id'].'" value="'.$rrow['last_name'].'">
Email:<span style="padding:0 20px;">Cell Phone:</span><br />
<input type="hidden" id="em_'.$rrow['contact_id'].'" value="'.$rrow['email1'].'">
<input type="hidden" id="cp_'.$rrow['contact_id'].'" value="'.$rrow['cell_phone'].'">
</form>
</div>
</td>
</tr>
';
}
$r .= '</table>';
return $r;
}
jQuery - document.click event - if injected code missing, how is it able to find the selector??
$(document).on('click', '.editcontact', function(event) {
var contact_id = this.id.split( 'edit_' )[1];
var etc = $( '#editThisContact_' + contact_id );
etc.dialog("open");
});
UPDATE - PARTIAL SOLUTION:
The dialog is now appearing - the cancel button was out of place, per this post. However, the injected code has vanished. Nothing else changed - just got the dialog code working by fixing syntax error in placement of cancel button.
In response to the question on my comment on the original post:
You really already know JSON, it stands for JavaScript Object Notation. This is a JSON object:
{"a":1,"b":2,"c":3}
look familiar? JSON is just a fancy name for something we've been using a long time (that may not be 100% true, but it's how I see it.)
The idea is to have the server pass back JSON objects and have your JavaScript create/update HTML based on them. In your scenario, you were having your PHP build multiple HTML dialogs. Instead, you would have your PHP pass back an array of objects each one representing a single row from your table, like so:
{
"records":
[
{
"field a":"value a",
"field b":"value b"
},
// record 2
{
"field a":"value a",
"field b":"value b"
}
]
}
If you were to request that from the server using .getJSON(), jQuery would automatically read that and give you a an object with a .records property that is an array of objects! Now you can use JavaScript to update a single dialog/form on the screen when they click one of the corresponding records.
Note: You could have PHP just pass back an array of objects, but it is best practice to wrap it in an object above. Many times you'll want other info too, for example, when you are doing paginated search results you're going to need to know the total number of records and what page you're on and maybe other data points.
An added benefit of this is that the server is done much faster. You push all of the display logic onto the client's computer, and hence, can server more pages from the same server.
That's a real brief explanation. There are tutorials and examples ALL OVER the web. Any good Ajax app you use online (GMail for example) uses JSON objects instead of passing huge blocks of HTML around. Here are a few links, Google has quite a few more:
http://php.net/manual/en/function.json-encode.php (turn any variable into a JSON string.)
http://www.json.org/example.html
http://www.w3schools.com/json/default.asp
http://www.jsonexample.com/
PHP Example: http://www.electrictoolbox.com/json-data-jquery-php-mysql/
Another PHP Example: http://www.jquery4u.com/json/ajaxjquery-getjson-simple/ (the alternative method for json-data.php in this link is the way to go, the other way is just silly!)
There are also some really good frameworks out there to help out with this process. I'm a huge fan of both backbone.js and spine.js. Both use jQuery, both help you use best practices when building apps (like MVC.)
It's nice when you solve your own question. Not so nice when the answer is a ID-ten-T error.
In the injected HTML, note the type of the input fields (screenshot 1). Change type to type="text", and all works as desired.
When concepts are new, Occam's Razor moves almost beyond reach.
I still don't understand why I can't see the injected markup, though..!
I'm coding a new website to learn PHP, and coding, and am making an autosuggest that is populated by two mysql tables.
Heres my code (Yes, I'm using mysql, but I'll rewrite this in mysqli once I find a solution!):
suggest.php:
require("./config.php");
$q = $_GET['q'];
$names = '';
$result = mysql_query("SELECT name FROM company WHERE name LIKE '$q%' UNION SELECT cat FROM cat WHERE cat LIKE '$q%' UNION SELECT subcat FROM subcat WHERE subcat LIKE '$q%' LIMIT 10"");
while ($row = mysql_fetch_array($result)) { $names .= $row[name]."\n"; }
echo $names;
?>
index.php ( where the searchbox is)
<form class="form-search span8 offset6">
<input type="text" id='search' name='q' class="input-medium search-query">
<button type="submit" class="btn btn-warning">GO!</button>
</form>
later in index.php (I call jquery.js before):
<script src="public/js/jquery-ui-1.8.22.custom.min.js" type="text/javascript"
charset="utf-8"></script>
<script>
$(function () {
$(document).ready(function () {
$("#search").autocomplete("./suggest.php");
});
});
</script>
The rows I'm trying to populate my autosuggest are the subcat row from the subcat table, the name table from company table, and cat from cat table.
The autosuggest isn't showing up? What's wrong?
Thanks for all help!
Try sending JSON formatted data from php, like:
$names = array();
while ($row = mysql_fetch_array($result)) {
$names[] = $row['name'];
}
echo json_encode($names);//format the array into json data
http://jqueryui.com/demos/autocomplete/
Expected data format The data from local data, a url or a callback can
come in two variants:
An Array of Strings:
[ "Choice1", "Choice2" ]
An Array of Objects with label and value properties:
[ { label: "Choice1", value: "value1" }, ... ]
you are just returning the names selected separated by line breaks
read the documentation of jquery ui autocomplete
Expected data format
The data from local data, a url or a callback can come in two variants:
An Array of Strings:
[ "Choice1", "Choice2" ]
An Array of Objects with label and value properties:
[ { label: "Choice1", value: "value1" }, ... ]
The label property is displayed in the suggestion menu. The
value will be inserted into the input element after the user selected
something from the menu. If just one property is specified, it will be
used for both, eg. if you provide only value-properties, the value
will also be used as the label.
from the documentations of jquery autocomplete
http://jqueryui.com/demos/autocomplete/
The data from local data, a url or a callback can come in two variants:
An Array of Strings:
[ "Choice1", "Choice2" ]
An Array of Objects with label and value properties:
[ { label: "Choice1", value: "value1" }, ... ]
try to pass your data accordingly.
I'm trying to store HTML in a Javascript Variable so that it's easy to read and edit in the future.
I've done this:
var form = [
"<fieldset>",
" <label></label>",
"</fieldset>" ].join("\n");
Only thing is I want it to be easier than that to edit in the future, possibly store it in a variable in PHP (if that's any easier) and then encode it or something.
There is going to be a whole lot more HTML then that
In PHP variable:
$form =<<<FORM
<fieldset>
<label></label>
</fieldset>
FORM;
http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
If the PHP option you mentioned is the way you want to go, one option (that's very readable and easily editable) would be something like:
$out = '<div>';
$out .= '<p>Hello, World</p>';
$out .= '</div>;
The largest advantage (I think) is that this allows you to indent freely for readability. Obviously a very simple example, but hopefully the point gets across.
You can write multi-line strings by adding backslashes to each line:
Creating multiline strings in JavaScript
I would use jQuery templates.
http://blog.reybango.com/2010/07/09/not-using-jquery-javascript-templates-youre-really-missing-out/
Your example:
<script id="myTemplate" type="text/html">
<fieldset><label></label></fieldset>
</script>
Additionally, the templates allow you to add in variables, for example:
<script id="myTemplate" type="text/html">
<fieldset><label class="${labelclass}">${label}</label></fieldset>
</script>
You pass in the information as an array
var templateData = [
{ labelclass: "fruit", label: "orange" },
{ labelclass: "vegetable", label: "cucumber" },
{ labelclass: "animal", label: "dog" }
];
Then you can append to where you want
$("#myTemplate").tmpl(templateData ).appendTo( "form" );
You don't have to use the variables, but it's much cleaner than trying to construct it manually.
I'm implementing a system these days, i want to implement a combo box selection process but i don't know how to implement it, so asking you guys favor?
my scenario is this, let's say we have two combo box selection lists, left one and right one, left one is the main one and the right one is the child of the left one.
when i select a item from the left combo box the right combo box's content should be changed according to the selection of the left one,
Ex: let's think about mobile phones, if i select the brand
Nokia
from the left combo box right combo box's content should be changed to
C6-01
E7-00
5232
X3-02
C1-01
C7-00
5228
C5-03
5250
6120ci
E5-00
E73
like wise. please help me to implement a this kind of scenario!
any tutorial links, sample codes to understand the scenario is better!
regards,
Rangana
The trick is do subscribe to the change event and reset the contents of the second box accordingly.
HTML:
<select id="brand">
<option value="">- select -</option>
<option value="nokia">Nokia</option>
<option value="apple">Apple</option>
</select>
<select id="type"></select>
JavaScript (on ready):
var selectBrand = $("#brand");
var selectType = $("#type");
var optionsList = {
nokia: [
"C6-01",
"E7-00"
],
apple: [
"iPhone 3",
"iPhone 3G",
"iPhone 4"
]
};
selectBrand.change(function() {
var brand = selectBrand.val();
var options = optionsList[brand];
var html;
if (options) {
html = '<option value="">- select -</option>';
$.each(options, function(index, value) {
html += '<option value="' + value + '">' + value + '</option>';
});
} else {
html = '<option value="">Select a brand</option>';
}
selectType.html(html);
}).change();
Full example at See http://www.jsfiddle.net/TJJ8f/
This works by having two things. Firstly, a server that will return JSON for the category you need and, secondly, the code for the front end.
<?php
// Do what you need to
$modelsArray = getModelsForBrand($_REQUEST['brand']);
echo json_encode($modelsArray);
?>
This uses the json_encode function to get the JSON on the array returned by whatever you use to get the models. I haven't used this function myself but it looks pretty simple.
Then your jQuery would look like this:
$("#brandCombo").change(function(){
var chosenBrand = $(this).val(); // Get the value
$.getJSON('/your-php-file.php', { "brand" : chosenBrand }, function(request){
// Successful return from your PHP file
$("#modelCombo").empty();
// For each item returned, add it to your models combo box
$.each(request, function(i,item){
$("#modelCombo").append("<option value='" + item.value + "'>"+ item.name + "</option>");
});
});
});
In this example, brandCombo is the ID of the list with the brands and modelCombo is the ID of the list the models should appear. When the value of brandCombo is changed, it makes the request to your PHP file to get the array of models in JSON. Then it goes through each one and adds a new option to your modelCombo list.
A similar question I answered is here, where I mentioned how to do it with all the data already on the page and in listboxes (hiding/showing them) or by AJAX requests (as the example above).
The other option, as shown in dyve's answer is to have all the information you need on the page already, in the form of a JavaScript object. If you wanted to do this, then then PHP json_encode function could still be of use (although you just call it once with all your data and plop it onto the page).
A number of previous SO posts cover this topic, have a look at this for example: Using javascript and jquery, to populate related select boxes with array structure