Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Expand AJAX based tree view

Posted on 2009-07-06
14
Medium Priority
?
822 Views
Last Modified: 2012-05-07
All,

I have a database table that has username, positionid,parentid fields. I have built a tree in PHP such that all the parent nodes load first. When a node is clicked, if it has children, then an ajax call is made to expand the node. Since expanding each node individually can becoming annoying, I was wondering if I can incorporate an "Expand All/ Collapse All" functionality to it. If the user clicks "Expand All", then all the ajax loads should happen simultaneously and the tree should expand.

How can I do this?

Any ideas?

Thanks
0
Comment
Question by:niftyhawk
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 7
14 Comments
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 24790921
That's more of a Javascript question. It depends on what you're using for the tree (custom-made script or something pre-made?), how the AJAX call is triggered (e.g. is it a function that calls another function or has a "success" callback function like the jQuery AJAX functions) and what kind of data comes back.
0
 
LVL 1

Author Comment

by:niftyhawk
ID: 24791380
I am using a custom made script for the tree. I have 3 functions in PHP. countChildren, listChildren and displayTree. countChildren takes parentid and returns the count of children underneath it. listChildren returns a recordset of children for a parentid. displayTree displays the data returned from listChildren in a tree structure. For each node that is clicked, I use a javascript ajax call which calls the php page passing parentid and calling displayTree function. displaytree inturn calls listChildren to get the children. The expand and collapse options for the tree nodes are controlled in javascript.

That is the code structure..  How can we modify this to make sure the entire tree opens up when "Expand All" hyperlink is clicked?

Thanks
0
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 24793711
The AJAX call is probably the important piece here. How do you make the AJAX call - are you using a 3rd-party library like jQuery, ExtJS, YUI, phpLiveX, etc... or is the AJAX call also custom?

You said the AJAX call calls the page and passes in the parentID, but what comes back? For example, if I click on a node called "I'm a Parent!" - does the AJAX call go look up the child data, and then return something like a JSON-encoded string that is then processed into more nodes? Or does it just return a chunk of HTML that is dynamically inserted into the page?

Do you have a URL where we can see the tree in action?
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:niftyhawk
ID: 24793908
The AJAX call is custom made too.. It returns a chunk of HTML generated by displaytree function that gets dynamically inserted. Following is code I am using a slightly modified version of this PHP Class:

http://www.phpclasses.org/browse/package/4110.html

I am sorry that we can't see the demo online..I will attach the code snippet..

Thanks
class.database.php
------------------
<?php
/*
* MARCO VOEGELI 31.12.2005
* www.voegeli.li
* This class provides one central database-connection for
* al your php applications. Define only once your connection
* settings and use it in all your applications.
*/
 
 class Database  { // Class : begin
	 var $host;  		//Hostname, Server
	 var $password; 	//Passwort MySQL
	 var $user; 		//User MySQL
	 var $database; 	//Datenbankname MySQL
	 var $link;
	 var $query;
	 var $result;
	 var $rows;
 
	function Database() { // Method : begin
		$this->rows = 0;
		if($_SERVER['HTTP_HOST'] == 'localhost' || ereg('^192\.168\.0\.[0-9]+$', $_SERVER['HTTP_HOST'])) {
			/* Local connetion vars */
			$this->host = "localhost";
			$this->password = "";
			$this->user = "root";
			$this->database = "database";
		} else {
			/* Internet connetion vars */
			$this->host = "server";
			$this->password = "password";
			$this->user = "user";
			$this->database = "database";
			}
	} // Method : end
 
	function OpenLink()  { // Method : begin
		$this->link = @mysql_connect($this->host,$this->user,$this->password); // or die (print "Class Database: Error while connecting to DB (link)");
		if(mysql_error()) {
			$this->connected = false;
			$this->error = mysql_error();
		} else {
		}
		return $this->connected;
	} // Method : end
 
	function SelectDB() { // Method : begin
		if(!@mysql_select_db($this->database,$this->link)) {   //; or die (print "Class Database: Error while selecting DB");
			$this->connected = false;
			$this->error = mysql_error();
		} else {
			$this->connected = true;
		}
	} // Method : end
 
	function CloseDB() { // Method : begin
		mysql_close();
	 } // Method : end
 
	function Query($query) { // Method : begin
		$this->OpenLink();
		$this->SelectDB();
		$this->query = $query;
		$this->result = mysql_query($query,$this->link) or die (print "Class Database: Error while executing Query");
		$this->error = mysql_error();
		// $rows=mysql_affected_rows();
 
		if(ereg("SELECT",$query)) {
			$this->rows = mysql_num_rows($this->result);
		}
		$this->CloseDB();
	} // Method : end
 
	// Return true if there was an error
	function is_error() {
		return (!empty($this->error)) ? true : false;
	}
 
	function fetchRow() { // Method : begin
		return mysql_fetch_array($this->result);
		$this->error = mysql_error();
	} // Method : end
 
	function getResult($row,$field) { // Method : begin
		return mysql_result($this->result,$row,$field);
	} // Method : end
 
	function getError() { // Method : begin
		return mysql_error();
	} // Method : end
 
	function getNumRows() { // Method : begin
		return $this->rows;
	} // Method : end
 
 } // Class : end
 
?>
 
 
class.tree.php
--------------
 
<?php
/*
* -------------------------------------------------------
* CLASSNAME:        Tree
* GENERATION DATE:  02.09.2007
* FOR MYSQL TABLE:  Defined by user
* DESCRIPTION:		This class generate a dynamic tree ajax directory of items retrieved from MySQL dabatase tables.
*					Could be used to load folders/categories/directories.
* -------------------------------------------------------
*/
 
include_once("class.database.php");
 
// ********************** DECLARACION DE LA CLASE
 
class Tree { // clase : inicio
 
// ********************** DECLARACION DE ATRIBUTOS
 
	var $id = 1;
 
	var $database; // Instancia de la base de datos
 
	var $table = "carpetas";
	var $fieldId = "idCarpeta";
	var $fieldFrom = "intDeCarpeta";
	var $fieldView = "chrNombre";
 
// ********************** METODO CONSTRUCTOR
 
	function Tree($id) {
		$this->id = $id;
		$this->database = new Database();
		if(!isset($this->id))
			$this->id = 0;
	}
 
 
// ********************** METODO LIST
 
	function countSub($id) {
		$sql =  "SELECT COUNT($this->fieldId) AS subOptions FROM $this->table";
		$sql.= " WHERE $this->fieldFrom = $id;";
		//echo $sql;
		$this->database->rows = $this->database->getResult($this->database->query($sql),"subOptions");
	}
 
	function listSub($id) {
		$sql =  "SELECT $this->fieldId,$this->fieldView FROM $this->table";
		$sql.= " WHERE $this->fieldFrom = $id;";
		//echo $sql;
		return $this->database->query($sql);
	}
 
	function display() {
		$this->listSub($this->id);
		if($this->database->getNumRows() > 0) {
			while($row=$this->database->fetchRow()) {
 
				$tree_sub=new Tree($row[$this->fieldId]);
				$tree_sub->countSub($row[$this->fieldId]);
 
				echo "<div class=\"fld_ln\">";
				echo (($tree_sub->database->getNumRows() > 0)?"<a href=\"Javascript:loadTree(".$row[$this->fieldId].")\">[+]</a>":"[-]");
				echo "&nbsp;".$row[$this->fieldView]."\n";
				echo "<div id=\"c".$row[$this->fieldId]."\" class=\"fld_ln\" style=\"display:none;\"></div>";
				echo "</div><br style=\"clear:both\">";
			}
		}
	}
 
} // clase : fin
 
?>
 
Ajax.js
-------
		//<![CDATA[
 
		/** XHConn - Simple XMLHTTP Interface - bfults@gmail.com - 2005-04-08        **
		 ** Code licensed under Creative Commons Attribution-ShareAlike License      **
		 ** http://creativecommons.org/licenses/by-sa/2.0/                           **/
		function XHConn()
		{
		  var xmlhttp, bComplete = false;
		  try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
		  catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
		  catch (e) { try { xmlhttp = new XMLHttpRequest(); }
		  catch (e) { xmlhttp = false; }}}
		  if (!xmlhttp) return null;
		  this.connect = function(sURL, sMethod, sVars, fnDone)
		  {
			if (!xmlhttp) return false;
			bComplete = false;
			sMethod = sMethod.toUpperCase();
 
			try {
			  if (sMethod == "GET")
			  {
				xmlhttp.open(sMethod, sURL+"?"+sVars, true);
				sVars = "";
			  }
			  else
			  {
				xmlhttp.open(sMethod, sURL, true);
				xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
				xmlhttp.setRequestHeader("Content-Type",
				  //"multipart/form-data");
				  //"text/javascript");
				  "application/x-www-form-urlencoded");
			  }
			  xmlhttp.onreadystatechange = function(){
				if (xmlhttp.readyState == 4 && !bComplete)
				{
				  bComplete = true;
				  fnDone(xmlhttp);
				}};
			  xmlhttp.send(sVars);
			}
			catch(z) { return false; }
			return true;
		  };
		  return this;
		}
 
		//]]>
 
Tree.js
--------
		//<![CDATA[
 
		// Funtion that show/hide layers and call the Ajax object
		function loadTree(id){
			if (document.getElementById("c"+id).style.display=="none"){
				document.getElementById("c"+id).style.display="inline";
 
			if(document.getElementById("c"+id).innerHTML == ""){
				document.getElementById("c"+id).innerHTML="loading...";  // place to insert a preloading icon .... web2.0 like
 
				target = document.getElementById("c"+id);
				var myConn = new XHConn();
				if (!myConn) alert("XMLHTTP not available. Try a newer/better browser.");
				myConn.connect("tree_sub.php", "POST", "id="+id, showTree);
				}
			} else {
				document.getElementById("c"+id).style.display="none";
				}
		}
 
		// Funtion whenDone XHConn is complete
		showTree = function(oXML) {
			target.innerHTML = oXML.responseText;
			if(oXML.responseText == "")
				target.style.display="none";
		}
 
		//]]>

Open in new window

0
 
LVL 35

Accepted Solution

by:
gr8gonzo earned 2000 total points
ID: 24794234
Try replacing the display method with this:

(Apologies if it doesn't work right away - I don't have the data to test with, so I'm just going off of what I assume to be the flow of the program.)

Then, make the "Expand All" link/button run the AJAX script on the top-level tree node, and have it pass in an argument like "expandAll=true" or something. On the PHP side, just check the incoming request, and make sure you pass in the correct expandAll value to the display() method.

Hope that makes sense!
	function display($expandAll = false) {
		$this->listSub($this->id);
		if($this->database->getNumRows() > 0) {
			while($row=$this->database->fetchRow()) {
 
				$tree_sub=new Tree($row[$this->fieldId]);
				$tree_sub->countSub($row[$this->fieldId]);
 
				echo "<div class=\"fld_ln\">";
				echo ((($tree_sub->database->getNumRows() > 0) && !$expandAll)?"<a href=\"Javascript:loadTree(".$row[$this->fieldId].")\">[+]</a>":"[-]");
				echo "&nbsp;".$row[$this->fieldView]."\n";
				
				echo "<div id=\"c".$row[$this->fieldId]."\" class=\"fld_ln\" style=\"display:".($expandAll ? "inline":"none").";\"></div>";
				if($expandAll)
				{
					$tree_sub->display($expandAll);
				}
				echo "</div><br style=\"clear:both\">";
			}
		}
	}

Open in new window

0
 
LVL 1

Author Comment

by:niftyhawk
ID: 24795517
Thanks a bunch.. Your code worked after a few tweaks..However, I have one more question. My tree has + and - images next to each node.. When "Expand all" is clicked, and the tree unfolds, all the plus images should change to minus images.. but it happens only for the root node.. The modified loadtree function is as under:

Am I missing something?
		// Funtion that show/hide layers and call the Ajax object
		function loadTree(id,expandall,expandsinglenode){
			if (document.getElementById("c"+id).style.display=="none"){
				document.getElementById("c"+id).style.display="inline";
				document.getElementById("p"+id).innerHTML="<img src='minus.gif' border=0>";
 
			if(document.getElementById("c"+id).innerHTML == ""){
				document.getElementById("p"+id).innerHTML="<img src='minus.gif' border=0>";
				document.getElementById("c"+id).innerHTML="loading...";  // place to insert a preloading icon .... web2.0 like
 
				target = document.getElementById("c"+id);
				var myConn = new XHConn();
				if (!myConn) alert("XMLHTTP not available. Try a newer/better browser.");
				myConn.connect("ptreegc2.php", "GET", "action=displaytree&ajax=1&expandall="+expandall+"&expandsinglenode="+expandsinglenode+"&parentid="+id, showTree);
				}
			} else {
				document.getElementById("c"+id).style.display="none";
				document.getElementById("p"+id).innerHTML="<img src='plus.gif' border=0>";
				}
		}

Open in new window

0
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 24796517
I'm not sure where the "p"+id elements are coming from. The display method generates a [+] and [-]  (text links, not images), so I'm not sure where the images are coming from, either. If the images are generated within the display method, you could do a:

$variable_containing_img = str_replace("plus.gif","minus.gif",$variable_containing_img);

Or, if the <div id="p###"> elements have a specific class, you could always use something like jQuery to change all of the divs matching that class so that they contain minus.gif images.
0
 
LVL 1

Author Comment

by:niftyhawk
ID: 24797602
The "p"+id elements are span tags in the code which contain the plus and minus image files. I modified my code to display them accordingly when a div gets expanded or collapsed.. I basically now have something like the attached code snippet.:

The major thing I am now facing is:

When I press "Expand All", I see that the root node and all the subsequent nodes expand fine. When I close the root node by clicking on it's minus image, it collapses the entire tree, which is fine.
But when I hit minus image next to the any sub-parent, it tries to load a new div instead of collapsing the already opened one.. What could be going wrong?

Thanks

							if($_GET["ajax"]==1 && $_GET["expandall"]=="true")
							{
								$html .= (($tree_sub->countChildren($positionid) > 0)?"<a href=\"Javascript:loadTree(".$positionid.",0,1".")\"><span id=\"p".$positionid."\" ><img src='minus.gif' border=0></span></a>":"<img src=arrow.gif>&nbsp;");
							}
							else
							{
								$html .= (($tree_sub->countChildren($positionid) > 0)?"<a href=\"Javascript:loadTree(".$positionid.$expandstring.$expandsingleparent.")\"><span id=\"p".$positionid."\" ><img src='plus.gif' border=0></span></a>":"<img src=arrow.gif>&nbsp;");
							}

Open in new window

0
 
LVL 1

Author Comment

by:niftyhawk
ID: 24797763
I found out that when "Expand All" generates the tree recursively, the divs for each parent node does not have any value except the root node. That's when when I hit the "minus" button, it doesn't find any thing to collapse and hence generates new child data. When we expand the tree, we have to make sure the sub-parent div tags hold the information for their children. Any ideas on modifying your code to this?

Thanks


0
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 24799222
I understand the idea behind the problem, but it would be helpful to see the HTML that is being generated from the Expand All AJAX call. Could you copy that HTML and paste it here (or if it's long, maybe enough to show a node that is more than 1 layer deep)?
0
 
LVL 1

Author Comment

by:niftyhawk
ID: 24802855
The attached snippet is part of the HTML being generated when expand all is clicked. It is only HTML for a few nodes. When the page loads, the HTML of the parent node is already written on the screen. The attached HTML occurs under the parent node. That's why you might see a mismatch of some of the </td></tr></table> tags.

Thanks
<!-- Javascript class -->
 
<script type="text/javascript" src="ajax.js"></script>
 
<script type="text/javascript" src="tree.js"></script>
 
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
    <td></td>
    <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src=arrow.gif>&nbsp;<a href='mytree.php?action=view&id=1118'>Jack Bauer</td>
    <td width=25%>24</td>
    <td width=25%>Action Hero</td>
    <td width=25%>Fox Serial</td>
  </tr>
  <tr>
    <td colspan=7><hr></td>
  </tr>
</table>
<div id="c1118" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
    <td></td>
    <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;
       <a href="Javascript:loadTree(1003,0,1)"><span id="p1003" ><img src='minus.gif' border=0></span></a>
         <b><a href='mytree.php?action=view&id=1003'>Tony Almeida</b>
    </td>
    <td width=25%><b>24</b></td>
    <td width=25%><b>CTU Agent</b></td>
    <td width=25%><b>Fox Serial</b></td>
  </tr>
  <tr>
    <td colspan=7><hr></td>
  </tr>
 </table>
<div id="c1003" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
    <td></td>
    <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src=arrow.gif>&nbsp;<a href='mytree.php?action=view&id=1005'>Chloe O'Brien</td>
    <td width=25%>24</td>
    <td width=25%>Computer Programmer</td>
    <td width=25%>Fox Serial</td>
  </tr>
  <tr>
    <td colspan=7><hr></td>
  </tr>
</table>
<div id="c1005" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
    <td></td>
    <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src=arrow.gif>&nbsp;<a href='mytree.php?action=view&id=1006'>Janette </td>
    <td width=25%>24</td>
    <td width=25%>FBI Agent</td>
    <td width=25%>Fox Serial</td>
  </tr>
  <tr>
    <td colspan=7><hr></td>
  </tr>
</table>
<div id="c1006" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
    <td></td>
    <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src=arrow.gif>&nbsp;<a href='mytree.php?action=view&id=1004'>David</td>
    <td width=25%>24</td>
    <td width=25%>FBI Agent</td>
    <td width=25%>Fox Serial</td>
  </tr>
  <tr>
    <td colspan=7><hr></td>
  </tr>
</table>
<div id="c1004" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
    <td></td>
	<td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;<a href="Javascript:loadTree(1372,0,1)"><span id="p1372" ><img src='minus.gif' border=0></span></a><b><a href='mytree.php?action=view&id=1372'>John</b></td>
	<td width=25%><b>24</b></td>
	<td width=25%><b>Villain</b></td>
	<td width=25%><b>Fox Serial</b></td>
  </tr>
  <tr>
    <td colspan=7><hr></td>
  </tr>
</table>
<div id="c1372" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
   <td></td>
   <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;<a href="Javascript:loadTree(1817,0,1)"><span id="p1817" ><img src='minus.gif' border=0></span></a><a href='mytree.php?action=view&id=1817'>Julie</td>
   <td width=25%>24</td>
   <td width=25%>Villain 2</td>
   <td width=25%>Fox Serial</td>
  </tr>
  <tr>
   <td colspan=7><hr></td>
  </tr>
</table>
<div id="c1817" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
  <tr>
   <td></td>
   <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src=arrow.gif>&nbsp;<a href='mytree.php?action=view&id=1818'>Mark</td>
   <td width=25%>24</td>
   <td width=25%>Villain 3</td>
   <td width=25%>Fox Serial</td>
  </tr>
  <tr>
   <td colspan=7><hr></td>
  </tr>
</table>
<div id="c1818" style="display:none";"></div>
</td>
</tr>
</table>
<table width="98%" border="0" cellpadding="0" cellspacing="0" style='min-width: 950px;'>
 <tr>
   <td></td>
   <td width=25%>&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src=arrow.gif>&nbsp;<a href='mytree.php?action=view&id=1819'>Edward</td>
   <td width=25%>24</td>
   <td width=25%>Villain 4</td>
   <td width=25%>Fox Serial</td>
 </tr>
 <tr>
   <td colspan=7><hr></td>
 </tr>
</table>

Open in new window

0
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 24804822
I must be missing something, then. In the display method I had provided, the display style should never be "none" if $expandAll is true. Also, if $expandAll is true, then the contents of the "c" divs should never be empty. Theoretically speaking, it should be something like:

<!-- Parent node is 1001, for example... -->
<div id="c1001" style="display:inline">

   <div id="c1002" style="display:inline">
        <div id="c1003" style="display:inline">
        </div> <!-- End of node c1003 -->
    </div> <!-- End of node c1002 -->

    <div id="c1004" style="display:inline">
    </div> <!-- End of node c1004 -->

</div> <!-- End of parent node 1001 -->

However, the code you're showing doesn't seem to match up with the expected output from the display method that I provided (even knowing that you made a few tweaks to it).

It seems like there might be a privacy or legal restriction on allowing me (or other EE experts) to see the full / true code and output. That's understandable, but at this point, I'm not sure if anyone can help further without being able to correlate the code with the output. It's sort of like that TV commercial where the doctor is trying to talk a guy through his own surgery. :) If you'd like further help, we can switch to private messaging/email so you can disclose more information. Not sure if that's an option.
0
 
LVL 1

Author Comment

by:niftyhawk
ID: 24825681
Thanks a bunch and sorry for the delayed reply.. With your inputs above, I figured it out finally and got it working.. :) Thanks for bearing with me on this and providing A+ grade solution.
0
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 24827878
Glad to hear it worked out!
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
3 proven steps to speed up Magento powered sites. The article focus is on optimizing time to first byte (TTFB), full page caching and configuring server for optimal performance.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses

610 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