Hi all,

I'm having a problem with a combination of Ajax / PHP / Javascript and I'm stuck. I've spent a fair amount of time googling possible solutions but I can't find anything.

What I am trying to do
I am using Ajax to query a MySQL database using an input text box. Typing into this input text box will fill the contents of a DIV located below the text box. For example, if the user wants to find a person with the surname "Smith" then they can type this into the input textbox and the ajax functionality will bring back all people with a first or surname containing "smith".

Now, next to each name displayed is a checkbox, and the idea behind this is that the user checks the checkbox if they want to select that particular person, and then if they want to also select someone with the surname "bloggs" they can replace the contents of the input textbox with "bloggs" (instead of "smith") and the ajax functionality will bring back all people with a first or surname containing "bloggs" and the user can then check that particular person too (i.e. they now have two people selected, "smith and "bloggs")

If you have ever organised an event on facebook then you may know what I am talking about - when you invite guests you can use the search filter above to filter names and then check/select the people you want to add.

My Problem
I know how to do almost all of the above, however the problem I am experiencing is that when the user checks the checkbox next to "smith" and then uses the search filter to search for something different (e.g. "smi") then the checkbox next to smith is re-loaded through ajax and is given a default state of unchecked. This is a problem as it is confusing to the user - they will think it is not selected when it actually is.

I have tried to find a solution to this but I can't, so I am resorting to this cry for help! My code so far is below:

BASIC HTML
Here I have the input field and the results div.

<input type="text" name="input_players" onkeyup="showPlayers(this.value)" />
<br />
<div id="dbResults"></div>

JAVASCRIPT CODE, INCLUDING AJAX STUFF
This is pretty basic AJAX / Javascript I think.

function showPlayers(str){

	//HTTP REQUEST CODE
	if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();} // code for IE7+, Firefox, Chrome, Opera, Safari
	else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}// code for IE6, IE5
	  	
	
	xmlhttp.onreadystatechange=function(){
		if (xmlhttp.readyState==4 && xmlhttp.status==200){
			document.getElementById("dbResults").innerHTML=xmlhttp.responseText;
		}
	}
	
	xmlhttp.open("GET","ajax/get_players.php?q="+str,true);
	xmlhttp.send();
	
}

PHP CODE, INCLUDING DB CALL
This is the get_players.php page referenced in the above javascript.

<? 
    //DETERMINE INPUT VALUE 
    $input_value=$_GET["q"]; 
     
    //CONNECT TO DATABASE 
    $con = mysql_connect("localhost","root","password"); 
    if (!$con){die('Could not connect: ' . mysql_error());} 
     
    //SELECT DATABASE 
    mysql_select_db("db_players", $con); 
     
    //QUERY 
    $query = "SELECT player_id, player_first_name, player_last_name FROM tbl_player " 
            ."WHERE (player_first_name LIKE '%".$input_value."%' OR player_last_name LIKE '%".$input_value."%') " 
            ."ORDER BY player_last_name, player_first_name"; 

    //EXECUTE QUERY 
    $db_results = mysql_query($query) or die(mysql_error()); 
     
    //PUT RESULTS IN AN ARRAY 
    $results_array = array(); 
    while($row = mysql_fetch_assoc($db_results)){ 
        $results_array[$row['player_id']]['p_id'] = $row['player_id']; 
        $results_array[$row['player_id']]['p_first_name'] = $row['player_first_name']; 
        $results_array[$row['player_id']]['p_last_name'] = $row['player_last_name']; 
    } 
     
    //DISPLAY RESULTS 
    if(sizeof($results_array)>0){ 
        foreach($results_array as $dbr_id => $result_details){ 
            //DECLARE VARIABLES 
            $p_full_name=$result_details['p_last_name'].", ".$result_details['p_first_name']; 
            $return_value .= "<input id='chk_box_".$dbr_id."' type='checkbox' />&nbsp;".$p_full_name."<br />"; 
        } 
    } 
    echo $return_value; 
     
    //CLOSE CONNECTION     
    mysql_close($con); 
?>

I think that's all the code I need to include. I am thinking that maybe I need to write some sort of function that checks the status of the checkbox each time the ajax db results are refreshed and checks the checkbox again if it was already checked previously?

I'm not sure. Any help or advice would be greatly appreciated!

Urban, you can ultimately get this to work as you have conceived it but I think you will find it much easier to run with a different way to accumulate the selected names.

Personally, I would have a third element (eg a UL) to which selected names are appended (as LIs).

Thus, your current names-div is relegated to displaying the current server-generated list, not accumulating the selections. With "Bloggs" in the text box, the names-div would need only show Bloggs; it would not need to be concerned with any previously selected Smiths.

There's still a bit of work to do:

  • Attaching a click handler to the names-div which puts names into the accumulator. Be sure to avoid duplicate entries by checking UIDs (the names themselves may not be unique). Possibly manage the server-generated list to suppress/disable/highlight entries that are already in the accumulator.
  • Providing a means for removal of entries (LIs) from the UL (ensuring that the current names-list is kept up to date with regard to suppress/disable/highlight).

Airshow

Hi Airshow,

Yes I think I understand what you are saying. what I don't know how to do is to:

Possibly manage the server-generated list to suppress/disable/highlight entries that are already in the accumulator.
[/LIST]
Airshow

I think if I could do that then it would actually solve my original problem, as instead of suppress/disable/highlight the entries it would simple retain a CHECK in thier checkbox?


I have tried to implement a hidden input box with a javascript function so that each time a checkbox is checked the function scans all available checkboxes (i.e. getElementsByClass) and places the unique ID of each checkbox in the input box, delimited by a comma. I think can get the function to convert the contents of the input box into an array and loop through it, etc. and I can even get it to change the state of the desired checkboxes, however whenever another letter is typed into the search textbox (i.e. onkeyup) the ajax script is triggered and it unsets all the checkboxes again.

I don't mind your approach to things, but I don't know how to get the ajax NOT to uncheck the checkbox. Hmmm... i've just had an idea.... I might be able to pass this array to the get_players.php page... I'll experiment with that but in the mean time if anone has a better solution then I'm all ears!

The bit you are having a problem with (maintaining checkbox status) is exactly what would give me or anybody else a problem. It's not, in itself, insurmountable but is avoidable by adopting the alternative approach.

If you want to persist, then you need to store references to checked names (eg a js array of their UIDs) then reset "checked" checkmarks after every update of the list (ie in the ajax success callback).

But even with that in place, you still have the problem that the list of names in "dbResults" will only reflect what is currently in the input field - ie. a list of Smiths OR Bloggs OR Jones. Unless you adopt my suggestion of a third element (or some seriously convoluted list management), there will be no representation in the DOM of ALL selected names (potentially Smith(s) AND Bloggs(s) AND Jones(s)).

The consequence of not displaying such a list is that there will be no mechanism for the user to manage it (ie delete entries).

The more I think about it the more I think you will struggle to make "dbResults" serve a dual purpose - "selector" and "accumulator". Strongly suggest you use "dbResults" as a straightforward "selector" with a third DOM element as an "accumulator".

Airshow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.