Solved

How do I Substitute Values in a Multidimensional Associative Array

Posted on 2015-02-13
15
83 Views
Last Modified: 2015-02-19
I have a table that the user can sort using drag/drop method.  The table is created dynamically through a odbc_fetch_array to a sql server database.  For purposes of the attached illustration, I created a similar array and named it $original.
The user can reorder the rows through drag/drop and when the user clicks the button, I want the values in the last column 'New Sort Order' to to substitute into the original array.

I am a newbie to php programming, so any help you can give me is much appreciated.
sjstable2.php
vendor.css
application.css
application.js
0
Comment
Question by:SueJStevens
  • 5
  • 5
  • 4
  • +1
15 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Here are some "getting started" resources.  Later this morning, I'll look at the attachments and see if I can help.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_11769-And-by-the-way-I-am-new-to-PHP.html
0
 
LVL 13

Expert Comment

by:NUKIT
Comment Utility
What is the end purpose for updating the array?  

Your code is working perfectly, but naturally can't update the array because it was made in PHP and was written server side/executed server side.

Once the page is rendered you can only access the html output of it.  

If you want to save the new order then you will need to send that data back to the server (you can do that using AJAX if desired).
0
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 250 total points
Comment Utility
There are too many moving parts here to answer all of this in a single question, so I'll show a solution to the PHP part of things.  When you have complex interactions between subsystems, it's often useful to extract the SSCCE for each of the components.  Then you can solve each piece of the problem independently of the other parts.  Once you have a collection of working parts, it's easier to assemble them into the "big picture" solution.

Please see http://iconoun.com/demo/temp_suejstevens.php

Check line 20.  This array is a simulation of the chosen sort order that might be created by the client-side jQuery.
<?php // demo/temp_suejstevens.php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28616873.html?cid=1752
 */
error_reporting(E_ALL);
echo '<pre>';

// AN ORIGINAL PIECE OF DATA - AN ARRAY OF ARRAYS
$original
= array
( [ "Column A"=>"A Item 1", "Column B"=>"B item 1", "Original Sort Order"=>1, "New Sort Order"=>0 ]
, [ "Column A"=>"A Item 2", "Column B"=>"B item 2", "Original Sort Order"=>2, "New Sort Order"=>0 ]
, [ "Column A"=>"A Item 3", "Column B"=>"B item 3", "Original Sort Order"=>3, "New Sort Order"=>0 ]
, [ "Column A"=>"A Item 4", "Column B"=>"B item 4", "Original Sort Order"=>4, "New Sort Order"=>0 ]
, [ "Column A"=>"A Item 5", "Column B"=>"B item 5", "Original Sort Order"=>5, "New Sort Order"=>0 ]
)
;

// AN ARBITRARILY CHOSEN NEW SORT ORDER
$new_order = [ 4, 3, 1, 5, 2 ];


// COPY THE ORIGINAL AND INJECT THE NEW SORT ORDER
$working_copy = [];
foreach ($original as $key => $collection)
{
    $collection["New Sort Order"] = $new_order[$key];
    $working_copy[$key] = $collection;
}


// DEFINE AND APPLY A USER-SORT FUNCTION
function comparison_callback($a, $b)
{
    if     ($a["New Sort Order"] == $b["New Sort Order"]) return 0;
    return ($a["New Sort Order"] <  $b["New Sort Order"]) ? -1 : 1;
}
usort($working_copy, 'comparison_callback');


// SHOW THE WORK PRODUCT
print_r($working_copy);

Open in new window

To see an example of how you can use jQuery to communicate with the server, please check this article.
http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Jquery/A_10712-The-Hello-World-Exercise-with-jQuery-and-PHP.html

HTH, ~Ray
0
 

Author Comment

by:SueJStevens
Comment Utility
Ray,
You've gone to a lot of trouble to help out this newbie--so a big Thank you!

I need to take some time to absorb everything you've provided but obviously you are getting me on the right track.  I will come back later today to either close the question and award points or post something that will further this question to a solution.

The link 'http://iconoun.com/demo/temp_suejstevens.php' doesn't seem to be working.
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Sue: I've had some issues with my hosting company, but this could also be something related to the fact that the link above has a spurious quote mark.  Try this link.  Then click the obvious one in the list ;-)

http://iconoun.com/demo/
0
 

Author Comment

by:SueJStevens
Comment Utility
Ray,
That link isn't working either.

So far, I've been able to take the scripts you've provided and use them in my project.  I've learned a lot by what you've provided.  Still, this is using a hard-coded array in the variable $new_order.  

I need to not hard-code the array but instead I need to capture it from the table after the user is done ordering the table rows.

As I'm reading through the response you've given to me it seems I have some work to do learning how to use JQuery to capture that information.   I have been successful in creating the 'Hello World' example you provided and I was successful in modifying that so I could capture an array based on the variable 'indata' shown in your example.  In my 'Hello World' I substituted the hard-coded array.  But I'm still stuck on how to capture the array from the table after the user is done ordering the table rows.

If you have another useful hint, i'll take it, or if I'm moving into a new question please let me know and I'll award points.

Thanks again,
Sue
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
That link isn't working either.
Don't know what to say - can you tell me the symptom that makes you think it's not working?  Is your browser cache turned off?  You can copy the script I posted above and install it on your own server to see it in action, so if you can't get to my server, that may be be helpful.

I think it might be easier to digest all of this in smaller bites.  There isn't much we can do with 147K of JavaScript - this is an all-volunteer forum and we just don't have the time to design and write entire applications.  But if you can break it down into some sample code that addresses a specific part of the problem, we might be able to do a better job for you.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 33

Expert Comment

by:Slick812
Comment Utility
greetings

@Ray , Your links do not work for me, It times Out, , you might check your Domain registrar to see if your Domain name lookup to IP is still viable.

@ SueJStevens, , I looked at your jaavascript, and you use TWO functions, but you do not need to do that.

here is some untested JS code, to use this you Must change the <tbody> in you table to     <tbody id="tb">     with an ID of "tb"
function newSortOrder() {
var oOrder = "";
var tbody = document.getElementById("tb");
for (var r =0; r < tbody.rows.length; ++r) {
  oOrder += tbody.rows[r].cells[2].innerHTML+"_";
  tbody.rows[r].cells[3].innerHTML = r;
  }
oOrder = oOrder.substr(0, oOrder.length-1);
tbody.rows[0].cells[1].innerHTML = oOrder;

$.post( "test.php", { oOrd: oOrder })
  .done(function( received ) {
    alert( "received: " + received );
  });
}

Open in new window


On the server side you get the  $_POST["oOrd"], maybe like
$oOrd = $_POST["oOrd"];
// turn the delimited text to an array with explode()
$oOrd = explode("_", $oOrd);

and then check to see if the Post array has same count as first array and ext to error control if not;
if (count($oOrd) ! = count($firstO) ) {
   //do error control here,
   }

make a new array
$newAry = array();
now send the $firstO into the  $newAry with the numbers from the  $oOrd
for ($i = 0; $i < count($oOrd); ++$i) {
   $newAry[$i] = $firstO[(int) $oOrd[$i] ];
   }

Now  $newAry has reordered content of $firstO .
this is untested code but you should be able to get a fair idea of the steps, methods and progression of code.

You do NOT indicate what Server PHP RESPONSE you NEED to go back to the browser AJAX javascript to be displayed on the page, or an error if Ajax up text has a problem, this is many times a very important consideration for AJAX, you need to have thought through ALL three steps-processes in the ajax exchange (browser - server - browser) and do code to get three separate code results, working together.

Ask questions if you need more info
0
 

Author Comment

by:SueJStevens
Comment Utility
Slick 812,
Thank you.  This looks promising.  I need a bit of time to digest this and apply it to my project.  I appreciate your offer to assist if I have more questions which I'm sure I will.
-Sue
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
I think my host has gotten the issues resolved.
http://iconoun.com/demo/temp_suejstevens.php
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 250 total points
Comment Utility
Had time today, did this development mock up, I dod not do any Drag and drop Table rows, instead I just used PHP array  shuffle( ) to get different arrangements, This uses Jquery for AJAX, -
<?php
$original = array( array("Column A"=>"A Item 1", "Column B"=>"B item 1" , "Original Sort Order"=>1 , "New Sort Order"=>0),
  array("Column A"=>"A Item 2", "Column B"=>"B item 2" , "Original Sort Order"=>2, "New Sort Order"=>0),
  array("Column A"=>"A Item 3", "Column B"=>"B item 3" , "Original Sort Order"=>3, "New Sort Order"=>0), 
  array("Column A"=>"A Item 4", "Column B"=>"B item 4" , "Original Sort Order"=>4, "New Sort Order"=>0), 
  array("Column A"=>"A Item 5" , "Column B"=>"B item 5" , "Original Sort Order"=>5 , "New Sort Order"=>0) 
  );

// just to save time I use the same PHP page for both Table display AND AJAX return
if (count($_POST) && !empty($_POST['nOrd']) ) { // test for POST
  $nPost = $_POST['nOrd']; // get Ajax send up
  $nOrd = explode('_', $nPost);
// test for array match count
  if (count($nOrd) != count($original)) exit('#ERROR: Server Mis-Match');
  $newAry = array();
  for ($i = 0; $i < count($nOrd); ++$i) { // rearrange the $original
    $original[(int) $nOrd[$i]]['New Sort Order'] = $i+1;
    $newAry[$i] = $original[(int) $nOrd[$i] ];
// $newAry now has rearranged rows
    }
  echo '~Success: New Order of Arrangement as '.$nPost;
  exit;
  }
//I do NOT HAVE DRAG AND DROP SO I JUST SHUFFLE THEM
shuffle($original);
?><!doctype html><html><head><title>Array drag shuffle</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>/* <![CDATA[ */
function newSortOrder() {
var nOrder = "";
var tbody = document.getElementById("tb");
for (var r =0; r < tbody.rows.length; ++r) {
  nOrder += tbody.rows[r].cells[2].innerHTML+"_";
  tbody.rows[r].cells[3].innerHTML = r;
  }
nOrder = nOrder.substr(0, nOrder.length-1);
//tbody.rows[0].cells[1].innerHTML = nOrder;

$.post( "eeAry.php", { nOrd: nOrder })
  .done(function( received ) {
    alert( "received: " + received );
  });
}
/* ]]> */</script></head>
<body bgcolor="#FFE3F7">
<h3>Array drag shuffle</h3>
<table><thead>
  <tr>
    <th><?php echo implode('</th><th>', array_keys(current($original))); ?></th>
  </tr>
  </thead><tbody id="tb">
<?php foreach ($original as $row): array_map('htmlentities', $row); ?>
    <tr>
      <td><?php echo implode('</td><td>', $row); ?></td>
    </tr>
<?php endforeach; ?>
  </tbody>
</table>
<button onclick="newSortOrder()">Update Sort Order</button>
</body></html>

Open in new window

this PHP page is eeAry.php on my server, SEE the javascript line -
   $.post( "eeAry.php", { nOrd: nOrder })
where you place your OWN php address for the Ajax address

AGAIN, I do no final page update from the Ajax server return, I only show an alert, because YOU have not defined what page change you wish to show on the sever return.
0
 

Author Comment

by:SueJStevens
Comment Utility
Slick 812
Yes, this is getting me on the right track.  I'm going to have time to work on this more tomorrow and will post back here the results and/or any questions I might have.

Ray,
I enjoyed the articles you pointed me toward.

Thanks,
Sue
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
I will mention that most everyone, beginning in the browser AJAX functioning, can fell really unsure, or confused about what are all the parts and pieces needed, and how to do a step wise progression of methods to get from the browser, to the server, and back to the browser, with the useful result you think you want. For me and many others it was not easy to learn, and required a long time of use and experiments to see what happends, when you change the very many options for how to collect  input or changes in the browser, how you need to order and separate this data to send up to the server through the javascript. Then how to find and or use the POST references to get a PHP base of operations, and then do the PHP code , but NOT IN THE AJAX, at first, to get the PHP code in  workable state, you may need to do the first PHP as a stand alone page, with fake data posts and on workin, you then try and use it in the javascript AJAX.

The examples you see given are usually so simple like -

$.post( "eeAry.php", { nOrd: nOrder })
  .done(function( received ) {
    alert( "received: " + received );
  });

that people can not see how to expand the functionality, to do more complex turnarounds from the server. That usually takes some research from web searches and AJAX "How To" sites.
0
 

Author Closing Comment

by:SueJStevens
Comment Utility
I really want to thank Slick812 and Ray Passeur for your time on my question.  Today I was able to get to a working solution in my application and I did use a variation of each of your examples.  Equally important, I learned a lot from your feedback and from going through the exercise of trying to understand your examples as I tried to incorporate them into my application.  I wish Experts Exchange would let me assign 500 points to each of you.
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
tank 4 points, I did this right after I did the comment, and was waiting to hear your questions, you did not ask, so I will post now, since I already did this. I will tell you, that many do not realize ,  the ajax communication between browser and server, is ALL TEXT, you can not push Arrays, Objects or functions through any Ajax, its all just text. To send Data that has several pieces or separate segments (as in an Array), you can use "Delimited" text or <XML> text. In my xample i use the "_" as a delimiter for Three number values. In almost all of my Ajax text push from server to browser, I use delimited text (using the "\n" and "\r" quite a bit, for two level segmentation, and others like "\0"), which are exactly the same escaped symbols in PHP and JS. Pleas consider usin delimited text for low levels of segmentation, instead of the mostly unneeded html JSON format.

<?php
$original = array(
  array("Column A"=>"A Item 1", "Column B"=>"B item 1", "Original Sort Order"=>1, "New Sort Order"=>0),
  array("Column A"=>"A Item 2", "Column B"=>"B item 2", "Original Sort Order"=>2, "New Sort Order"=>0),
  array("Column A"=>"A Item 3", "Column B"=>"B item 3", "Original Sort Order"=>3, "New Sort Order"=>0), 
  array("Column A"=>"A Item 4", "Column B"=>"B item 4", "Original Sort Order"=>4, "New Sort Order"=>0), 
  array("Column A"=>"A Item 5", "Column B"=>"B item 5", "Original Sort Order"=>5, "New Sort Order"=>0) 
  );

if (count($_POST) && !empty($_POST['nOrd']) ) {
  $nPost = $_POST['nOrd'];
  $nOrd = explode('_', $nPost);
  if (count($nOrd) != count($original))
    exit('#*Server Mis-Match*Server unable to finish request, error code: cnt511');
/*
to signal the ajax javascipt return, I pre-tend the return string
with a "#" for errors, and a "~" for success.
   ALSO
I place the "*" character as a string Delimiter, to divide the return
string into 3 segments, and then use  rAry = received.split("*"); in JS
*/
  $newAry = array();
  for ($i = 0; $i < count($nOrd); ++$i) {
    $original[(int) $nOrd[$i]]['New Sort Order'] = $i+1;
    $newAry[$i] = $original[(int) $nOrd[$i] ];
    }
  $nPost = str_replace('_', ', ', $nPost);
  echo '~*Sort Order is Updated*New Sort Order Arrangement as '.$nPost;
  exit;
  }

//I do NOT HAVE DRAG AND DROP SO I JUST SHUFFLE THEM
shuffle($original);
?><!doctype html><html><head><title>Array drag suffle</title>
<style>
#drTable {position: relative;}

#ajPop {position: absolute;
  display: none;
  top: 2px;
  left: 2px;
  width: 326px;
  height: 113px;
  background: #efe;
  border: 3px outset #969;
  }

#pTitle {color: #06b;
  margin-top:1px;
  margin-bottom:6px;
  }

.xBut{
position:relative;
top:1px;
right:1px;
width:1em;
height:1em;
font-weight:bold;
float:right;
line-height:98%;
cursor:pointer;
font-family:arial,sans-serif;
background:red;
color:white;
text-align:center;
border:1px solid white;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>/* <![CDATA[ */
function newSortOrder() {
var nOrder = "";
var tbody = document.getElementById("tb");
for (var r =0; r < tbody.rows.length; ++r) {
  nOrder += tbody.rows[r].cells[2].innerHTML+"_";
  tbody.rows[r].cells[3].innerHTML = r+1;
  }
nOrder = nOrder.substr(0, nOrder.length-1);
//tbody.rows[0].cells[1].innerHTML = nOrder;


var ajPost = $.post( "eeAry.php", { nOrd: nOrder });

ajPost.done(function( received ) {
// separate the received string into array with .split("*")
  var rAry = received.split("*");
// the rAry array will have 3 elements with success
// the first rAry[0] has the return signal character (not used)
// the second rAry[1] has the Title, and rAry[2] hs the message
  var title = document.getElementById("pTitle");
  var message = document.getElementById("pMess");
  
  switch (received.charAt(0)){
    case "~": // Success has a ~ begining
    title.style.backgroundColor = "#fff";
	title.innerHTML = rAry[1];
    message.innerHTML = rAry[2];
    break;
	
    case "#": // Error has # beginning
    title.style.backgroundColor = "#feb";
	title.innerHTML = "ERROR: "+rAry[1];
    message.innerHTML = rAry[2];
    break;
	
    default: // ALL PHP warning Errors do not have the ~ or #
// to see the errors look in browser page analysis Console
    console.log( received );
	title.style.backgroundColor = "#fcd";
	title.innerHTML = "ERRROR: Server Responce";
    message.innerHTML = "PHP did NOT complete without Problems. "+ajPost.status;
  }
  document.getElementById("ajPop").style.display = "block";
  }); // end of  ajPost.done(

}
/* ]]> */</script></head>
<body bgcolor="#FFE3F7">
<h3>Array drag suffle</h3>
<table id="drTable"><thead>
  <tr>
    <th>
	<div id="ajPop">
	<div class="xBut" onclick="$('#ajPop').hide();">X</div>
	<h3 id="pTitle">None</h3><span id="pMess">Message</span>
	</div>
  <?php echo implode('</th><th>', array_keys(current($original))); ?></th>
  </tr>
  </thead><tbody id="tb">
<?php foreach ($original as $row){ array_map('htmlentities', $row); ?>
    <tr>
      <td><?php echo implode('</td><td>', $row); ?></td>
    </tr>
<?php } ?>
  </tbody>
</table>
<button onclick="newSortOrder()">Update Sort Order</button>
</body></html>

Open in new window


I have used a hidden <div> to show on the ajax return with a "Title" and a "Message"

please notice how I used -
     switch (received.charAt(0)){

to analyze the received sendback to Change the processing of the browser, for different types of results gathered by the PHP processes, also look at the default, PHP writes Errors, warnings, , and starts with a <b> on most servers, so the default will know that there was a non programmed text entry into the output (by PHP).
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This article describes how to create custom column layout styles for Bootstrap. The article uses 5 columns to illustrate the concept, but the principle can be extended to any number of columns.
In this tutorial viewers will learn how to embed videos in a webpage using HTML5. Ensure your DOCTYPE declaration is set to HTML5: "<!DOCTYPE html>": Use the <video> tag to insert a video. Define the src as the URL of your video; this is similar to …
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now