PHP: Easiest and cleanest way to modify multidimensional array? - php

I have a dynamic multi-dimensional array that can be of any dimension here is a sample:
$array_serial = 'a:2:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:27:"products.php?la=electronics";s:6:"otitle";s:11:"Electronics";s:6:"utitle";s:11:"Electronics";s:4:"ttip";s:11:"Electronics";}s:8:"children";a:2:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:51:"products.php?la=electronics&lb=Computer-Peripherals";s:6:"otitle";s:20:"Computer Peripherals";s:6:"utitle";s:20:"Computer Peripherals";s:4:"ttip";s:34:"Electronics : Computer Peripherals";}s:8:"children";a:1:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:63:"products.php?la=electronics&lb=Computer-Peripherals&lc=Printers";s:6:"otitle";s:8:"Printers";s:6:"utitle";s:8:"Printers";s:4:"ttip";s:45:"Electronics : Computer Peripherals : Printers";}s:8:"children";a:1:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:90:"products.php?la=electronics&lb=Computer-Peripherals&lc=Printers&ld=Single-Function-Printer";s:6:"otitle";s:23:"Single Function Printer";s:6:"utitle";s:23:"Single Function Printer";s:4:"ttip";s:71:"Electronics : Computer Peripherals : Printers : Single Function Printer";}}}}}}i:1;a:1:{s:2:"id";a:4:{s:3:"url";s:38:"products.php?la=electronics&lb=Mobiles";s:6:"otitle";s:7:"Mobiles";s:6:"utitle";s:7:"Mobiles";s:4:"ttip";s:21:"Electronics : Mobiles";}}}}i:1;a:2:{s:2:"id";a:4:{s:3:"url";s:31:"products.php?la=homenfurnitures";s:6:"otitle";s:19:"Home And Furnitures";s:6:"utitle";s:19:"Home And Furnitures";s:4:"ttip";s:19:"Home And Furnitures";}s:8:"children";a:2:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:9:"about.php";s:6:"otitle";s:8:"About Us";s:6:"utitle";s:8:"About Us";s:4:"ttip";s:8:"About US";}}i:1;a:2:{s:2:"id";a:4:{s:3:"url";s:40:"products.php?la=homenfurnitures&lb=Other";s:6:"otitle";s:5:"Other";s:6:"utitle";s:5:"Other";s:4:"ttip";s:27:"Home And Furnitures : Other";}s:8:"children";a:1:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:51:"products.php?la=homenfurnitures&lb=Lights-AnD-Lamps";s:6:"otitle";s:14:"Lights & Lamps";s:6:"utitle";s:14:"Lights & Lamps";s:4:"ttip";s:36:"Home And Furnitures : Lights & Lamps";}s:8:"children";a:2:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:12:"contacts.php";s:6:"otitle";s:10:"Contact Us";s:6:"utitle";s:10:"Contact Us";s:4:"ttip";s:10:"Contact US";}}i:1;a:2:{s:2:"id";a:4:{s:3:"url";s:58:"products.php?la=homenfurnitures&lb=Dinnerware-AnD-Crockery";s:6:"otitle";s:21:"Dinnerware & Crockery";s:6:"utitle";s:21:"Dinnerware & Crockery";s:4:"ttip";s:43:"Home And Furnitures : Dinnerware & Crockery";}s:8:"children";a:1:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:78:"products.php?la=homenfurnitures&lb=Dinnerware-AnD-Crockery&lc=Cups-AnD-Saucers";s:6:"otitle";s:14:"Cups & Saucers";s:6:"utitle";s:14:"Cups & Saucers";s:4:"ttip";s:60:"Home And Furnitures : Dinnerware & Crockery : Cups & Saucers";}}}}}}}}}}}';
All index "otitle" of this array will be displayed in form in an input type text, and the user can modify this Title according to their desire. How can I achieve this in a clean way?
And this is just part of the array, the actual array can be much bigger.
Here is my code to view "otitle" in a input type
function get_menu_list($selected_menus)
{
if($selected_menus != null){
foreach($selected_menus as $menu_level_1)
{
$title = implode("///",$menu_level_1['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="text" name="otitle[]" value="'.$menu_level_1['id']['otitle'].'" />
</div>
';
if(isset($menu_level_1['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_1['children'] as $menu_level_2)
{
$title_level_2 = implode("///",$menu_level_2['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="text" name="otitle[]" value="'.$menu_level_2['id']['otitle'].'" />
</div>
';
if(isset($menu_level_2['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_2['children'] as $menu_level_3)
{
$title_level_3 = implode("///",$menu_level_3['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="text" name="otitle[]" value="'.$menu_level_3['id']['otitle'].'" />
</div>
';
if(isset($menu_level_3['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_3['children'] as $menu_level_4)
{
$title_level_4 = implode("///",$menu_level_4['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="text" name="otitle[]" value="'.$menu_level_4['id']['otitle'].'" />
</div>
';
if(isset($menu_level_4['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_4['children'] as $menu_level_5)
{
$title_level_5 = implode("///",$menu_level_5['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="text" name="otitle[]" value="'.$menu_level_5['id']['otitle'].'" />
</div>
</li>
';
}
echo "</ol>";
}
echo '</li>';
}
echo "</ol>";
}
echo '</li>';
}
echo "</ol>";
}
echo '</li>';
}
echo '</ol>';
}
echo '</li>';
}
}//end if
else
return null;
}
$array_unserial = unserialize($array_serial);
echo get_menu_list($array_unserial);

I did not used the Recursion method but since I have already written the function with using foreach loop. And here is the code of how I accomplished this task using this same function.
if (isset($_REQUEST['u_arr'])) {
$array_serial = serialize($_REQUEST['u_arr']);
}
else {
//Here is my code to view "utitle" in a input type
$array_serial = $array_serial; /*You can get $array_serial from the question of this post*/
}
function get_menu_list($selected_menus)
{
if($selected_menus != null){
foreach($selected_menus as $id1=>$menu_level_1)
{
$title = implode("///",$menu_level_1['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="hidden" name="u_arr['.$id1.'][id][url]" value="'.$menu_level_1['id']['url'].'" />
<input type="hidden" name="u_arr['.$id1.'][id][otitle]" value="'.$menu_level_1['id']['otitle'].'" />
<input type="text" name="u_arr['.$id1.'][id][utitle]" value="'.$menu_level_1['id']['utitle'].'" />
<input type="hidden" name="u_arr['.$id1.'][id][ttip]" value="'.$menu_level_1['id']['ttip'].'" />
</div>
';
if(isset($menu_level_1['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_1['children'] as $id2=>$menu_level_2)
{
$title_level_2 = implode("///",$menu_level_2['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][id][url]" value="'.$menu_level_2['id']['url'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][id][otitle]" value="'.$menu_level_2['id']['otitle'].'" />
<input type="text" name="u_arr['.$id1.'][children]['.$id2.'][id][utitle]" value="'.$menu_level_2['id']['utitle'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][id][ttip]" value="'.$menu_level_2['id']['ttip'].'" />
</div>
';
if(isset($menu_level_2['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_2['children'] as $id3=>$menu_level_3)
{
$title_level_3 = implode("///",$menu_level_3['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][id][url]" value="'.$menu_level_3['id']['url'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][id][otitle]" value="'.$menu_level_3['id']['otitle'].'" />
<input type="text" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][id][utitle]" value="'.$menu_level_3['id']['utitle'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][id][ttip]" value="'.$menu_level_3['id']['ttip'].'" />
</div>
';
if(isset($menu_level_3['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_3['children'] as $id4=>$menu_level_4)
{
$title_level_4 = implode("///",$menu_level_4['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][id][url]" value="'.$menu_level_4['id']['url'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][id][otitle]" value="'.$menu_level_4['id']['otitle'].'" />
<input type="text" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][id][utitle]" value="'.$menu_level_4['id']['utitle'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][id][ttip]" value="'.$menu_level_4['id']['ttip'].'" />
</div>
';
if(isset($menu_level_4['children']))
{
echo '<ol class="dd-list">';
foreach($menu_level_4['children'] as $id5=>$menu_level_5)
{
$title_level_5 = implode("///",$menu_level_5['id']);
echo '
<li class="dd-item">
<div class="dd-handle">
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][children]['.$id5.'][id][url]" value="'.$menu_level_5['id']['url'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][children]['.$id5.'][id][otitle]" value="'.$menu_level_5['id']['otitle'].'" />
<input type="text" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][children]['.$id5.'][id][utitle]" value="'.$menu_level_5['id']['utitle'].'" />
<input type="hidden" name="u_arr['.$id1.'][children]['.$id2.'][children]['.$id3.'][children]['.$id4.'][children]['.$id5.'][id][ttip]" value="'.$menu_level_5['id']['ttip'].'" />
</div>
</li>
';
}
echo "</ol>";
}
echo '</li>';
}
echo "</ol>";
}
echo '</li>';
}
echo "</ol>";
}
echo '</li>';
}
echo '</ol>';
}
echo '</li>';
}
}//end if
else
return null;
}
$array_unserial = unserialize($array_serial);
?>
<form method="post" action="">
<?php get_menu_list($array_unserial) ?>
<button type="submit">Submit</button>
</form>

Basic Idea
The idea you are looking for is called Recursion. Recursion works by a named function calling itself until some variety of conditionals are met. For example, the mathematical operator ! (read: "Factorial") is one of the simplest ways to get an idea of how recursion works. A factorial is defined by starting with your given number, say 5, and multiplying by every integer from that number until you reach 1. So 5! is calculated like so: 5*4*3*2*1. In code that may look something like:
function factorial($n){
if($n<=1) return 1;
//If the number being passed is one or lower, no need to call this function again, just return 1.
return $n*factorial($n-1);
//If we got to here, the $n is not 1 or less, so we multiply $n times the answer of factorial($n-1), which will repeat until $n-1 becomes 1.
}
I found this Quora question where I thought both answers helped to explain in different ways the idea of recursion.
Answer
Now, for your question. I've commented everything I can think of, so please let me know if you don't understand anything.
<style>
div.menu-item > div.menu-item {
margin-left:1rem;
}
</style>
<?php
function get_menu_list($selected_menus,$offset_i=false)
{
foreach($selected_menus as $i=>$menu):
//the : is an alternate syntax in PHP for {}, now instead of trying to find a matching }, PHP will look for the keyword "endforeach;"
$id_string = ($offset_i===false) ? $i : $offset_i.'-'.$i;
//If the $offset_i is false, then we are calling this function directly and these are main-level elements.
//If it is not false, this function is being called from itself.
?>
<div class="menu-item">
<label for="text-<?php echo $id_string;?>"><?php echo $menu['id']['otitle'];?></label><input type="text" id="text-<?php echo $id_string?>" value="<?php print($menu['id']['utitle']);?>" />
<?php
//The code above just outputs any information you want into a 'menu-item' div. you can change literally every thing here to your liking. This was fastest for me.
/*
The code below
1. Checks if the $menu array as a key named 'children', and if that is true
2. Checks that the count (or sizeof) the array is greater than 0.
3. If it does, call get_menu_list on the children array, supplying the $id_string we created up top so that we don't have overlapping
ID names in our HTML.
*/
if(array_key_exists('children', $menu) && count($menu['children'])>0){
get_menu_list($menu['children'],$id_string);
}
?></div><?php
//Ends the HTML div we started up top.
endforeach;
//Self explanatory.
}
$array_serial = 'a:2:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:27:"products.php?la=electronics";s:6:"otitle";s:11:"Electronics";s:6:"utitle";s:11:"Electronics";s:4:"ttip";s:11:"Electronics";}s:8:"children";a:2:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:51:"products.php?la=electronics&lb=Computer-Peripherals";s:6:"otitle";s:20:"Computer Peripherals";s:6:"utitle";s:20:"Computer Peripherals";s:4:"ttip";s:34:"Electronics : Computer Peripherals";}s:8:"children";a:1:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:63:"products.php?la=electronics&lb=Computer-Peripherals&lc=Printers";s:6:"otitle";s:8:"Printers";s:6:"utitle";s:8:"Printers";s:4:"ttip";s:45:"Electronics : Computer Peripherals : Printers";}s:8:"children";a:1:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:90:"products.php?la=electronics&lb=Computer-Peripherals&lc=Printers&ld=Single-Function-Printer";s:6:"otitle";s:23:"Single Function Printer";s:6:"utitle";s:23:"Single Function Printer";s:4:"ttip";s:71:"Electronics : Computer Peripherals : Printers : Single Function Printer";}}}}}}i:1;a:1:{s:2:"id";a:4:{s:3:"url";s:38:"products.php?la=electronics&lb=Mobiles";s:6:"otitle";s:7:"Mobiles";s:6:"utitle";s:7:"Mobiles";s:4:"ttip";s:21:"Electronics : Mobiles";}}}}i:1;a:2:{s:2:"id";a:4:{s:3:"url";s:31:"products.php?la=homenfurnitures";s:6:"otitle";s:19:"Home And Furnitures";s:6:"utitle";s:19:"Home And Furnitures";s:4:"ttip";s:19:"Home And Furnitures";}s:8:"children";a:2:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:9:"about.php";s:6:"otitle";s:8:"About Us";s:6:"utitle";s:8:"About Us";s:4:"ttip";s:8:"About US";}}i:1;a:2:{s:2:"id";a:4:{s:3:"url";s:40:"products.php?la=homenfurnitures&lb=Other";s:6:"otitle";s:5:"Other";s:6:"utitle";s:5:"Other";s:4:"ttip";s:27:"Home And Furnitures : Other";}s:8:"children";a:1:{i:0;a:2:{s:2:"id";a:4:{s:3:"url";s:51:"products.php?la=homenfurnitures&lb=Lights-AnD-Lamps";s:6:"otitle";s:14:"Lights & Lamps";s:6:"utitle";s:14:"Lights & Lamps";s:4:"ttip";s:36:"Home And Furnitures : Lights & Lamps";}s:8:"children";a:2:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:12:"contacts.php";s:6:"otitle";s:10:"Contact Us";s:6:"utitle";s:10:"Contact Us";s:4:"ttip";s:10:"Contact US";}}i:1;a:2:{s:2:"id";a:4:{s:3:"url";s:58:"products.php?la=homenfurnitures&lb=Dinnerware-AnD-Crockery";s:6:"otitle";s:21:"Dinnerware & Crockery";s:6:"utitle";s:21:"Dinnerware & Crockery";s:4:"ttip";s:43:"Home And Furnitures : Dinnerware & Crockery";}s:8:"children";a:1:{i:0;a:1:{s:2:"id";a:4:{s:3:"url";s:78:"products.php?la=homenfurnitures&lb=Dinnerware-AnD-Crockery&lc=Cups-AnD-Saucers";s:6:"otitle";s:14:"Cups & Saucers";s:6:"utitle";s:14:"Cups & Saucers";s:4:"ttip";s:60:"Home And Furnitures : Dinnerware & Crockery : Cups & Saucers";}}}}}}}}}}}';
$array_unserial = unserialize($array_serial);
get_menu_list($array_unserial);
?>
On a related note about your data in your serialized
Try to avoid using serialized strings as much as you possibly can. A very simple solution is one I already wrote out to you in the comments, but by creating a table categories with just a few fields you can get the same set of data without having to use array serialization / deserialization. It definitely is a question outside of the topic of this particular question, but I'd feel like I wasn't being very helpful if I didn't at least mention it to you.

Related

Angular - storing checkbox values, and displaying them

Suppose that, you have 27 checkboxes, let's call them 'categories'. These checkboxes are in one section, you can select them multiple, and save.
The eseence is: if you save the form, the categories will be added to your profile, in MySQL.
My question is:
How I should name the models,
How I should store de values after sending the form
I had a solution for this, I saved the nth of the categories, then clicked them back at loading, but that's not the best.
Here is the code:
$scope.getSelectedCats = function() //Returning array: [1,4,5,6]
{
$return_array = [];
$i = 0;
if($scope.whoareu.develop){ $return_array[$i] = 1; $i++;}
if($scope.whoareu.design){ $return_array[$i] = 2; $i++;}
if($scope.whoareu.produce){ $return_array[$i] = 3; $i++;}
if($scope.whoareu.repair){ $return_array[$i] = 4; $i++;}
[...]
return $return_array;
}
HTML
<p>
<input ng-model="whoareu.develop" type="checkbox" value=1 id="WAY8" name="whoareu" />
<label for="WAY8">Develop</label>
</p>
<p>
<input ng-model="whoareu.design" type="checkbox" value=2 id="WAY9" name="whoareu" />
<label for="WAY9">Design</label>
</p>
<p>
<input ng-model="whoareu.produce" type="checkbox" value=3 id="WAY10" name="whoareu" />
<label for="WAY10">Produce</label>
</p>
<p>
<input ng-model="whoareu.repair" type="checkbox" value=4 id="WAY11" name="whoareu" />
<label for="WAY11">Repair</label>
</p>
[...]
And last, a very ugly solution for loading checks:
<?php
//$dbData = Data row from mysql, in object, by Wordpress
echo "setTimeout(function(){";
foreach(explode(',', $dbData->interested_in) as $val)
{
//echo "$('input:checkbox[name=whatareu]').filter('[value=$val]').click();";
echo "$('input:checkbox[name=whatareu]').eq($val-1).click();";
}
echo "}, 1000);";
?>
I don't know if I understand your problem well, see my snippet. If you want, you could create some mapping function setDefaultState(basedOn) which set checked in model checkboxs.
If the problem is that data is lost after you leave the controller, you should use some singleton storage like Angular's factories, and storage the checked categories there.
angular.module('app', [])
.controller('FrameController', ['$injector',
function($injector) {
var vm = this;
vm.checkboxs = [{
id: 'WAY8',
label: 'Develop',
checked: true
}, {
id: 'WAY9',
label: 'Design'
}]
angular.extend(vm, {
save: save
})
function save() {
// API call
console.log('checked: ', vm.checkboxs.filter(function(c) {
return c.checked
}).map(function(c) {
return {
id: c.id
}
}));
}
}
]);
setTimeout(function() {
angular.bootstrap(document.getElementById('body'), ['app']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="body">
<div ng-controller="FrameController as vm">
<ul>
<li ng-repeat="checkbox in vm.checkboxs">
<input ng-model="checkbox.checked" type="checkbox" id="{{checkbox.id}}" name="whoareu" />
<label for="{{checkbox.id}}">{{checkbox.label}}</label>
</li>
</ul>
<button ng-click="vm.save()">
Save
</button>
</div>
</div>

Relating values in a PHP multiple checkbox array

I searched and can't find an answer to this and nothing I try works. In this form, for each image (pix) and there the user enters the number of copies to be produced.
I know how to build the array for each individually when the submit button is clicked but I can't get both arrays to relate to each other. I want to produce something like: 01.jpg - 3 copies, 02.jpg - 1 copy etc etc.
How can I achieve this?
Thanks
This is my form:
<form action="self.php" method="post">
<img src="01.jpg" alt="01.jpg">
<input type="checkbox" name="pix[]" value="01.jpg_album">
<input type="text" name="quantity[]">
<img src="02.jpg" alt="02.jpg">
<input type="checkbox" name="pix[]" value="02.jpg_extra">
<input type="text" name="quantity[]">
<img src="03.jpg" alt="03.jpg">
<input type="checkbox" name="pix[]" value="03.jpg_extra">
<input type="text" name="quantity[]">
<input type="submit" name="submit">
</form>
This is how I extract the values returned:
echo implode('<br>', $_POST['pix']);
echo implode('<br>', $_POST['quantity']);
EDITED: FURTHER to my question above and in response to the second code posted by Rajdeep ... I've separated the two processes. The first was to determine whether the client wanted the image for his wedding album, so I did:
$arr = array("01", "02", "03");
echo "<h3>Images required for album: </h3>";
foreach($_POST as $key => $value){
if(in_array($key, $arr)){
$var = $value . ".jpg";
if(isset($_POST[$value]) && !empty($_POST[$value])){
echo $var."<br />";
}//endif
} //endif
}// end foreach
This output was:
03.jpg
04.jpg
23.jpg
etc
Then, I wanted to know if he needed any additional individual prints and this code (sort of) worked for that:
echo "<h3>Extras required: </h3>";
$noextras = false;
foreach($_POST as $key => $value){
if(in_array($key, $arr)){
$var = $value . ".jpg - ";
if(isset($_POST[$value . "_extra"]) && !empty($_POST[$value . "_extra"])){
$sum = $_POST[$value . '_extra'];
if($sum == 1) {
$var .= $sum ." copy <br />";
} else {
$var .= $sum . " copies <br />";
}
echo $var;
} else if(empty($_POST[$value . "_extra"])) { $noextras = true; }
} //endif in_array
}// end foreach
if($noextras) { echo "No extra copies needed.";}
And the output from this was something like
03.jpg - 5 copies
04.jpg - 2 copies
23.jpg - 1 copy
I then discovered a snag. This permitted extra copied to be selected for ONLY for images that were selected for inclusion in the album. I have tried various variations on the code and I am coming up with a blank.
So, I've changed this to a two step process. First page, the person selects the images for the album, which when submitted go to a confirmation page to show what had been selected. Once he clicks the 'confirm' button an email goes to me and him.
Clicking the confirm button also goes to a Thank You page which then refreshes into the second page for ordering individual prints. Here he can select how many copies of a print he needs and this works well with Rajdeep's first 'merged' code BUT it only works for one selection.
I've expanded the selection and this is where I am currently having trouble. He has a choice to decides how many copies he needs of each of the four different sizes available (7x6, 9x5, 10x8, 12x8). I am able to process one size only but am having trouble with expanding it to four inputs.
Any suggestions?
Thanks.
Instead of two different <input> tags with checkbox and text attribute, use only one <input> with number attribute for each image. And make the name attribute as the name of your image, like this:
<form action="self.php" method="post">
<img src="01.jpg" alt="01.jpg" />
<input type="number" name="01" min="0" />
<img src="02.jpg" alt="02.jpg" />
<input type="number" name="02" min="0" />
<img src="03.jpg" alt="03.jpg" />
<input type="number" name="03" min="0" />
<input type="submit" name="submit" value="submit" />
</form>
And this is how you can process the form,
if(isset($_POST['submit'])){
foreach($_POST as $key => $value){
if($key == "submit"){
continue;
}
if(!empty($value)){
$var = $key . ".jpg - " . $value;
if($value == 1){
$var .= " copy";
}else{
$var .= " copies";
}
$var .= "<br />";
echo $var;
}
}
}
A sample output would be like this:
01.jpg - 3 copies
02.jpg - 1 copy
03.jpg - 5 copies
Edited:
Based on your requirement, use <input type="checkbox" name="xx" value="xx" /> for selecting the image(i.e when user wants this image to be included in photo album) and use <input type="number" name="xx_extra" min="1" /> for keeping track of how many extra copies of this image user wants.
So your HTML code should be like this:
<form action="self.php" method="post">
<img src="01.jpg" alt="01.jpg" />
<input type="checkbox" name="01" value="01" />
<input type="number" name="01_extra" min="1" />
<img src="02.jpg" alt="02.jpg" />
<input type="checkbox" name="02" value="02" />
<input type="number" name="02_extra" min="1" />
<img src="03.jpg" alt="03.jpg" />
<input type="checkbox" name="03" value="03" />
<input type="number" name="03_extra" min="1" />
<input type="submit" name="submit" value="submit" />
</form>
And this is how you can process the form,
<?php
if(isset($_POST['submit'])){
$arr = array("01", "02", "03");
foreach($_POST as $key => $value){
if(in_array($key, $arr)){
$var = $value . ".jpg - ";
if(isset($_POST[$value . "_extra"]) && !empty($_POST[$value . "_extra"])){
$sum = $_POST[$value . '_extra'] + 1;
$var .= $sum . " copies <br />";
}else{
$var .= "1 copy <br />";
}
echo $var;
}
}
}
?>

Only one value from an hidden input is being displayed

<?php
foreach($_color_swatch as $_inner_option_id){
preg_match_all('/((#?[A-Za-z0-9]+))/', $_option_vals[$_inner_option_id]['internal_label'], $matches);
if ( count($matches[0]) > 0 ) {
$color_value = $matches[1][count($matches[0])-1];
?>
<li>
<input type="hidden" id="fakecolor" value="<?php echo $color_value;?>"/>
<div onclick="alert(document.getElementById('fakecolor').value);">
<img src="<?php echo $color_value;?>.png" /></div>
</li>
<?php
}
}
?>
This works for displaying the images, using the $color_value but i need to pass the value from hidden input to another javascript function.
And when i click on div it displays only one value no matter how many are inside the foreach.
Can anyone give me a little help? Thanks.
This is the output:
<li>
<input type="hidden" id="fakecolor" value="red"/>
<div onclick="alert(document.getElementById('fakecolor').value);"><img src="red.png"/></div>
</li>
<li>
<input type="hidden" id="fakecolor" value="blue"/>
<div onclick="alert(document.getElementById('fakecolor').value);"><img src="blue.png"/></div>
</li>
<li>
<input type="hidden" id="fakecolor" value="white"/>
<div onclick="alert(document.getElementById('fakecolor').value);"><img src="white.png"/></div>
</li>
<li>
<input type="hidden" id="fakecolor" value="green"/>
<div onclick="alert(document.getElementById('fakecolorx').value);"><img src="green.png"/></div>
</li>
But when i click on each of the divs, it displays only the value of the second, blue.
Try something like this:
<?php
$cont = 0;
foreach($_color_swatch as $_inner_option_id){
preg_match_all('/((#?[A-Za-z0-9]+))/', $_option_vals[$_inner_option_id]['internal_label'], $matches);
if ( count($matches[0]) > 0 ) {
$color_value = $matches[1][count($matches[0])-1];
?>
<li>
<input type="hidden" id="fakecolor<?php echo $cont; ?>" value="<?php echo $color_value;?>"/>
<div onclick="alert(document.getElementById('fakecolor<?php echo $cont; ?>').value);">
<img src="<?php echo $color_value;?>.png" /></div>
</li>
<?php
}
$cont = $cont + 1;
}
?>
In this way every input hidden have a different id, the same whit the onclick function.
Saludos ;)
I dont quite understand what you're trying to do, still:
<input type="hidden" id="fakecolor" value="<?php echo $color_value;?>"/>
<div onclick="alert(document.getElementById('fakevalue').value);">
First line: you're using an unique id while looping so you'll get several elements with the same id and you'll always end up with the first one with document.getElementById.
Second line: aren't you supposed to get the value of the hidden field ? (ie #fakecolor and not #fakevalue as you're getting).
You have multiple IDs on the same page which will cause getElementById to fail. Why don't you loop and construct your JavaScript like so:
<div onclick="alert("<?php echo $color_value; ?>");">
If you ever move from just alert you can have whatever JavaScript function with a string parameter to accept the color value.

How to make a div appear from a php variable using jquery

I am populating a list of checkboxes from a foreach loop, and giving each an ID. I have added a set of divs below that would appear, depending on which checkbox is created. I was thinking I could load the id variable into a jQuery if statement, and then use a .toggle to show or hide the corresponding div.
<?php
//Call Programs
$getPrograms = Doctrine::getTable('Program')->createQuery()->where('subsection=?', 'mfa')->orWhere('subsection=?', 'mps')->orWhere('subsection=?', 'mat')->orWhere('subsection=?', 'ma')->orderBy('title ASC')->execute(); ?>
<div class="form_row">
<label>
<span><sup class="required_form_item">*</sup>Select Program</span>
</label>
<div class="buttonColumn" style="margin-left:170px;">
//loop the records in with checkboxes
<?php foreach ($getPrograms as $prog): ?>
<?php
$subsection = $prog->getSubsection();
$subsection = strtoupper($subsection);
$trimProg = trim($prog->getTitle(), ' ');
$removeChars = array(" ", "&");
$trimProg = str_replace( $removeChars, '', $trimProg );
$trimProg = preg_replace('/\s\s+/', '_', $trimProg);
?>
//custin id matches record title
<input type="checkbox" name="program" class="isChecked" id="<?php echo $trimProg; ?>" value="<?php echo $subsection . " " . $prog->getTitle() ?>" /><?php echo $subsection . " " . $prog->getTitle() ?><br />
<?php endforeach ?>
</div>
</div>
The following divs would be set to display:none until the matching checkbox is checked.
<div class="form_row sessionTime" id="Program1" style="display:none;">
Please choose an session time:
<input type="checkbox" name="schedule" value="5:00 pm" />5:00 pm<br />
</div>
<div class="form_row sessionTime" id="program2" style="display:none;">
Please choose an session time:
<input type="checkbox" name="schedule" value="10:00 pm" />10:00 pm<br />
</div>
...
And this is what I thought would work...but alas...it doesn't
$('.isChecked').click( function() {
if ( $(this).is(':checked') ) {
$thisID = $(this).attr("id");
$('.'+ $thisID).show();
}
else {
$('.'+ $thisID).hide();
}
}
);
You should be using "Program1" as class name instead of id like this
<div class="form_row sessionTime Program1" style="display:none;">
Please choose an session time:
<input type="checkbox" name="schedule" value="5:00 pm" />5:00 pm<br />
</div>
And your jQuery code should work, which you can simplify as follows:
$('.isChecked').click( function() {
if ( $(this).is(':checked') ) {
$('.'+ this.id).show();
}
else {
$('.'+ this.id).hide();
}
});
I tested this code # home and it works as you might want
<html>
<head>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script>
$(document).ready(
function()
{
$('.isChecked').click(
function()
{
if ( $(this).is(':checked') )
{
$(this).show();
}
else
{
$(this).hide();
}
}
);
}
);
</script>
</head>
<body>
<form>
<input type="checkbox" name="program" class="isChecked"/>
<input type="checkbox" name="program" class="isChecked"/>
<input type="checkbox" name="program" class="isChecked"/>
<input type="checkbox" name="program" class="isChecked"/>
</form>
</body>
I think the problem in your code can come from the $(document).ready() handler that waits for the entire DOM to be loaded before binding action listener to it.
What's more, your jquery code wasn't working for me. My version seems to work, but once checked box hidden, the user cannot handle them anymore.
Otherwise, I think doing some Doctrine requests in your template is a very bad idea.
Good bye !

How to show data with checkboxes in zend Framework

I am using Zend framework. In this i create a model and put my database connection in this model.
Here is my code so far :-
public function getTagusers(){
try {
$stat = $this->db->query("select a.tagCode child, b.tagCode parent " .
"from tag a, tag b where a.tagParentId=b.tagId");
$aResultData = $stat->fetchall();
}
catch(Exception $e){
error_log('Exception in '.__FUNCTION__.' : line '.__LINE__.' : '
. $e->getMessage());
}
return $aResultData;
}
Now I am using action in controller. My code is so far :-
public function listAction()
{
$tagusers =new Admin_Model_DbTable_Tagusers();
$this->view->taguser =$tagusers->fetchall();
}
Now finally i want to echo my data in view list.html. My code is so far :-
<script>
<!-- Begin
function Check(chk)
{
if(document.myform.Check_ctr.checked==true){
for (i = 0; i < chk.length; i++)
chk[i].checked = true ;
} else {
for (i = 0; i < chk.length; i++)
chk[i].checked = false ;
}
}
// End -->
</script>
<?php foreach($this->taguser as $taguser) ?>
<form name="myform" action="checkboxes.asp" method="post">
<b>Select Allowed keywords below:</b><br>
<input type="checkbox" name="Check_ctr" value="yes"
onClick="Check(document.myform.check_list)"><b>Select all keywords</b>
<br>
<input type="checkbox" name="check_list" value="1">
<?php echo $this->escape($taguser->tagCode);?><br>
<input type="checkbox" name="check_list" value="2">
<?php echo $this->escape($taguser->tagParentId);?><br>
</form>
But I am not able to echo the data properly. Can anyone explain me what I can do to echo the result according to my query.
first if you using Zend Framework as a framework as it appears... your first error is it normal for viewscripts to have the .phtml extension (i know you may have changed this).
next your php is incorrect:
<?php foreach($this->taguser as $taguser): //need to colon for alternate loop syntax ?>
<form name="myform" action="checkboxes.asp" method="post">
<b>Select Allowed keywords below:</b><br>
<input type="checkbox" name="Check_ctr" value="yes"
onClick="Check(document.myform.check_list)"><b>Select all keywords</b>
<br>
<input type="checkbox" name="check_list" value="1">
<?php echo $this->escape($taguser->tagCode);
//if this causes errors use
//array notation $taguser['tagCode']?><br>
<input type="checkbox" name="check_list" value="2">
<?php echo $this->escape($taguser->tagParentId);?><br>
</form>
<?php endforeach //need to end the foreach statement alternate syntax?>
I'm not going to critique your form, if you want built a separate form for each record that's your business.
Well, you're printing N forms (where N = count($this->taguser)), each one containing 3 checkboxes with the same value ('yes', '1' and '2', respectively), which makes no sense at all.
If I'm correct, your form should look like this:
<form name="myform" action="checkboxes.asp" method="post">
<b>Select Allowed keywords below:</b><br>
<input type="checkbox" name="Check_ctr" value="yes"
onClick="Check(document.myform.check_list)"><b>Select all keywords</b>
<br>
<?php foreach($this->taguser as $taguser): ?>
<input type="checkbox" name="check_list" value="<?php echo $this->escape($taguser->tagCode);?>">
<br>
<input type="checkbox" name="check_list" value="<?php echo $this->escape($taguser->tagParentId);?>">
<br>
<?php endforeach; ?>
Still, you should read about Zend_Form. It will be hard to understand it in the beginning, but it's totally worth it.

Categories