PDA

View Full Version : Javascript Integration Woes


Tyler
June 12th, 2007, 21:23
Hiya All,

Seems like I only post a new thread when I need help :oops:

I found a nice AJAX Todo List (http://www.codepost.org/view/120) the other day after a long time of searching for one.

I played around with it yesterday, and got the basics of implementation finished, I decided to finish the rest of it today.

After much much (did I say much?) fighting, I finally got it to add a new item, and save to the database. But now the problem is that it will not delete nor modify. After diagnosing as much as I can (my JS skills lack me severely), I found that the item id is returning invalid. I believe this is because I have a header and a footer, and using Smarty to display the AJAX form.

Here is what it returns (when editing), if the AJAX form is displayed at the end (with a header):

id=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>Freelancer Panel Administration</title><link href="admin-css.css" rel="stylesheet" type="text/css" />

Here is what it returns, when AJAX form is at the top (no header):

id= <div class="notelist"> <ol id="list"> </ol> </div> <script type="text/javascript" src="todo.js"></script> <script type="text/javascript" src="main.php?action=projects&subaction=todo&init=1&actionid=9"></script> </div>37<div id="column"><div style="background:#fff; border: 1px solid #c0c0c0; padding:2px;">Welcome

And finally at the end without a header:

id=38 <div class="notelist"> <ol id="list"> </ol> </div> <script type="text/javascript" src="todo.js"></script> <script type="text/javascript" src="main.php?action=projects&subaction=todo&init=1&actionid=9"></script>

I removed the rest of the HTML, as it was very long.

Here is the PHP code that I am using:


else
{
// request for a new ids
if (isset($_GET['getid']))
{
// insert a new empty note and return it's id
$test = @str_replace('?','',$actionid);

$query = mysql_query("INSERT INTO todo (text,projectid) VALUES('','$test')");

if($query == true)
{
echo mysql_insert_id();
}
else
{
echo 'it failed!'; // the insert somehow failed (should add more error handling)
}
}

// init the list with all current notes
elseif(isset($_GET['init']))
{
// first do a cleanup of the notes list (remove notes which are added but not edited)
@$db->query("DELETE FROM todo WHERE text = ''");

//Select all todo for this project.
$query = $db->query("SELECT todoid,text FROM todo WHERE projectid='$actionid'");

@header('Content-type: text/javascript');


while ($row = $db->fetch_array($result))
{
$text = trim(new_line($row['text']));

// we are returning javascript code which will call the addnote function
echo "addnote({$row['todoid']}, '$text'); \n";
}
}

// delete a note
elseif(isset($_GET['del']) && is_numeric($_GET['del']))
{
$id = get_id('del');
@$db->query("DELETE FROM todo WHERE todoid ='$id'");
}

// update the contents of a note
elseif(isset($_POST['id']) && is_numeric($_POST['id']))
{
// strip the tags from the note text
$text = trim(htmlspecialchars($_POST['text']));

$id = trim(intval($_POST['id']));

$db->query("UPDATE todo SET text='$text' WHERE todoid='$id'");
}

//We need to display the AJAX HTML.
$tpl->assign('pid',$actionid);
$tpl->display('admincp/ajax.tpl');
}
}


Javascript:

// the list element
var list = document.getElementById('list');

//Project id
var pid = location.search;
pid = pid.replace(/&/,"");
pid = pid.replace(/&/,"");
pid = pid.replace(/action=projectssubaction=todoactionid=/,"");
pid = pid.replace("?","");

// seperator between the actual list and the add link
var sep = list.appendChild(document.createElement('br'));

// the add link
var add = list.appendChild(document.createElement('li'));
add.innerHTML = '<a href="#" onclick="return false">click here to add a new item</a>';
add.value = '';


// from: http://www.codepost.org/view/59
function createXMLHttpRequest() {
var types = [
'Microsoft.XMLHTTP',
'MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP'
];

for (var i = 0; i < types.length; i++) {
try {
return new ActiveXObject(types[i]);
} catch(e) {}
}

try {
return new XMLHttpRequest();
} catch(e) { }

return false; // XMLHttpRequest not supported
}


// this function will be called when the add link is pressed
// and when loading the list at startup
function addnote(id, text) {
var item = list.insertBefore(document.createElement('li'), sep);

// span containing the html
var html = item.appendChild(document.createElement('span'));

// input for editing
var edit = item.appendChild(document.createElement('input'));
edit.type = 'text';
edit.value = text;
edit.maxLength = 100;
edit.size = 100;

// image for the delete button
var dele = item.appendChild(document.createElement('img'));
dele.src = 'images/delete.gif';
dele.style.display = edit.style.display = 'none';

// new note?
if (id == -1) {
// use an xmlhttprequest to get a new id for the note
var req = createXMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
item.id = req.responseText;
}
}
};
req.open('GET', 'main.php?action=projects&subaction=todo&getid=1&actionid=' + pid, true);
req.send('');
} else {
item.id = id;
}


item.onclick = function() {
// switch the note to edit mode
html.style.display = 'none';
dele.style.display = edit.style.display = 'inline';

edit.focus();
};


edit.onblur = function() {
var t = edit.value;
t = t.replace(/!(.+)!/g, '<i>$1</i>'); // replace !...! by italic text
t = t.replace(/\*(.+)\*/g, '<b>$1</b>'); // replace *..* by bold text

// has the contents of the note changed?
if (html.innerHTML != t) {
// use an xmlhttprequest to update the note contents in the database
var req = createXMLHttpRequest();
req.open('POST', 'main.php?action=projects&subaction=todo&actionid2=' + pid, true);
alert('main.php?action=projects&subaction=todo&actionid=' + pid);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send('id=' + item.id + '&text=' + escape(edit.value));
alert('id=' + item.id + '&text=' + escape(edit.value));
}

html.innerHTML = t;

// switch the note to display mode
html.style.display = 'inline';
dele.style.display = edit.style.display = 'none';
}

// catch the enter key to finish editing the note
edit.onkeydown = function(e) {
var key = 0;
if (window.event) {
key = window.event.keyCode;
} else if (e) {
key = e.keyCode; // e.which
}

if (key == 13) { // 13 is the enter key
edit.onblur();
}
}


dele.onmousedown = function() {
// ask the user if he/she really wants to delete the note
if (confirm('are you sure?')) {
// use an xmlhttprequest to remove the note from the database
var req = createXMLHttpRequest();
req.open('GET', 'main.php?action=projects&subaction=todo&actionid=' + pid + '&del='+item.id, true);
req.send('');

list.removeChild(item);
}
}

// trigger onblur to switch the note to display mode and update it's innerHTML
edit.onblur();
}


add.onclick = function() {
// -1 indicates a new note
addnote(-1, 'click *here* to edit');
}


Thanks! I really appreciate this. I just can't figure this out, and my JS skills are really very narrow.

Edit - Forgot my ajax.tpl:


<div class="notelist">
<ol id="list">
</ol>
</div>

<script type="text/javascript" src="todo.js"></script>
<script type="text/javascript" src="main.php?action=projects&subaction=todo&init=1&actionid={$pid}"></script>
</div>

Tyler
June 12th, 2007, 23:48
I just discovered another bug too. :(

It won't fetch the existing items. I thought it had to do with the header() returning errors, so I removed my header, and no errors were returned, but it still wasn't working.

If I go directly to the URL, PHP works.

addnote(2, 'Testing'); addnote(48, '85');

So once again it must be the JS. :(

Tyler
June 14th, 2007, 21:46
In order to fix this, a special &ajax had to be added so nothing was displayed. :)