Hi.
I hope I can ask questions about ht-simple-ajax here. If not, please tell me where I can. I'm trying out ht-simple-ajax but it doesn't work. I have:
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(defun-ajax say-hi (name) (*ajax-processor*) (concatenate 'string "Hi " name))
(setq *dispatch-table* (list 'dispatch-easy-handlers (create-ajax-dispatcher *ajax-processor*)))
And then I go to: http://localhost/ajax/SAY-HI?name=Martin but nothing happens ?
Thanks
Did you start the Hunchentoot web server?
(defparameter *my-server* (start (make-instance 'acceptor :address "localhost" :port 8000)))
I tested the example on http://martin-loetzsch.de/ht-simple-ajax/%C2%A0and it worked for me.
andy
On Sun, Apr 3, 2011 at 6:23 AM, Haris fbogdanovic@xnet.hr wrote:
Hi.
I hope I can ask questions about ht-simple-ajax here. If not, please tell me where I can. I'm trying out ht-simple-ajax but it doesn't work. I have:
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(defun-ajax say-hi (name) (*ajax-processor*) (concatenate 'string "Hi " name))
(setq *dispatch-table* (list 'dispatch-easy-handlers (create-ajax-dispatcher *ajax-processor*)))
And then I go to: http://localhost/ajax/SAY-HI?name=Martin but nothing happens ?
Thanks
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
Here is the complete code, (I start Hunchentoot from REPL and use parenscript)
(defpackage :ajax (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax)) (in-package ajax)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(defun-ajax say-hi (name) (*ajax-processor*) (concatenate 'string "Hi " name))
(define-easy-handler (main-page :uri "/") () (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (:title "ht-simple-ajax demo") (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps (defun callback (response) (alert (@ response firstChild firstChild nodeValue)))
(defun sayHi () (ajax_say_hi (chain document (getElementById "name") value) callback))))))
(:body (:p "Please enter your name: " (:input :id "name" :type "text")) (:p (:a :href "javascript:sayHi()" "Say Hi!"))))))
I see two problems:
1. You do not inform Hunchentoot about your ajax-dispatcher you need to add this: (setq *dispatch-table* (list 'dispatch-easy-handlers (create-ajax-dispatcher *ajax-processor*))) above as in the example of ht-simple-ajax. Instead, I normally use: (push (create-ajax-dispatcher *ajax-processor*) *dispatch-table*)
2. Do not use camel-case in parenscript. Parenscript is not case-sensitive. Parenscript uses the lisp standard of hyphens which translates to the javascript standard camel-case.
AJAX> (ps getElementByID) "getelementbyid;" AJAX> (ps firstChild) "firstchild;" AJAX> (ps get-element-by-id) "getElementById;" AJAX> (ps first-child) "firstChild;" Similarly See also "sayHi" and "nodeValue"
On Sun, Apr 3, 2011 at 10:37 AM, Haris fbogdanovic@xnet.hr wrote:
Here is the complete code, (I start Hunchentoot from REPL and use parenscript)
(defpackage :ajax (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax)) (in-package ajax)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(defun-ajax say-hi (name) (*ajax-processor*) (concatenate 'string "Hi " name))
(define-easy-handler (main-page :uri "/") () (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (:title "ht-simple-ajax demo") (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps (defun callback (response) (alert (@ response firstChild firstChild nodeValue)))
(defun sayHi () (ajax_say_hi (chain document (getElementById "name") value) callback))))))
(:body (:p "Please enter your name: " (:input :id "name" :type "text")) (:p (:a :href "javascript:sayHi()" "Say Hi!"))))))
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
I changed the code. When I click on say-hi link it goes to: http://localhost/sayHi(); and the page says: Hunchentoot Default page. Where is the problem now ?
------------------------------------------------------------------------------------------------------
(defpackage :ajax (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax)) (in-package ajax)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(push (create-ajax-dispatcher *ajax-processor*) *dispatch-table*)
(defun-ajax say-hi (name) (*ajax-processor*) (concatenate 'string "Hi " name))
(define-easy-handler (main-page :uri "/") () (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (:title "ht-simple-ajax demo") (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps (defun callback (response) (alert (@ response first-child first-child node-value)))
(defun say-hi () (ajax_say_hi (chain document (get-element-by-id "name") value) callback))))))
(:body (:p "Please enter your name: " (:input :id "name" :type "text")) (:p (:a :href (ps (say-hi)) "Say Hi!"))))))
Use the parenscript function ps-inline instead of ps (:a :href (ps-inline (say-hi)) "Say Hi!")
AJAX> (ps-inline (say-hi)) "javascript:sayHi()"
On Sun, Apr 3, 2011 at 1:40 PM, Haris fbogdanovic@xnet.hr wrote:
I changed the code. When I click on say-hi link it goes to: http://localhost/sayHi(); and the page says: Hunchentoot Default page. Where is the problem now ?
(defpackage :ajax (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax)) (in-package ajax)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(push (create-ajax-dispatcher *ajax-processor*) *dispatch-table*)
(defun-ajax say-hi (name) (*ajax-processor*) (concatenate 'string "Hi " name))
(define-easy-handler (main-page :uri "/") () (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (:title "ht-simple-ajax demo") (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps (defun callback (response) (alert (@ response first-child first-child node-value)))
(defun say-hi () (ajax_say_hi (chain document (get-element-by-id "name") value) callback))))))
(:body (:p "Please enter your name: " (:input :id "name" :type "text")) (:p (:a :href (ps (say-hi)) "Say Hi!"))))))
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
Use the parenscript function ps-inline instead of ps (:a :href (ps-inline (say-hi)) "Say Hi!")
I did that and now when I click Say hi link I just get Error on page on the bottom of the page, javascript error I guess. Here is html generated from my code, maybe the error is more obvious this way
---------------------------------------------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns='http://www.w3.org/1999/xhtml'> <head> <title> ht-simple-ajax demo </title><script type='text/javascript'> //<![CDATA[ function fetchURI(uri, callback) { var request; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else { try { request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ee) { request = null; }}} if (!request) alert("Browser couldn't make a request object.");
request.open('GET', uri, true); request.onreadystatechange = function() { if (request.readyState != 4) return; if (((request.status>=200) && (request.status<300)) || (request.status == 304)) { var data = request.responseXML; if (callback!=null) { callback(data); } } else { alert('Error while fetching URI ' + uri); } } request.send(null); delete request; }
function ajax_call(func, callback, args) { var uri = '/ajax/' + encodeURIComponent(func) + '/'; var i; if (args.length > 0) { uri += '?' for (i = 0; i < args.length; ++i) { if (i > 0) { uri += '&' }; uri += 'arg' + i + '=' + encodeURIComponent(args[i]); } } fetchURI(uri, callback); }
function ajax_say_hi (name, callback) { ajax_call('SAY-HI', callback, [name]); } //]]> </script> <script type='text/javascript'>function callback(response) { return alert(response.firstChild.firstChild.nodeValue); }; function sayHi() { return ajax_say_hi(document.getElementById("name").value, callback); }; </script> </head> <body> <p> Please enter your name: <input id='name' type='text' /> </p> <p> <a href='javascript:sayHi()'> Say Hi! </a> </p> </body> </html>
Your html is correct and works. I used hunchentoot to dispatch it as a static html file and it communicates with the ajax-processor I created from your previous code. The problem is probably with your ajax response. If using chrome, developer tools will show the ajax request/response. If using Firefox, use firebug.
andy
On Sun, Apr 3, 2011 at 7:10 PM, Haris fbogdanovic@xnet.hr wrote:
Use the parenscript function ps-inline instead of ps (:a :href (ps-inline (say-hi)) "Say Hi!")
I did that and now when I click Say hi link I just get Error on page on the bottom of the page, javascript error I guess. Here is html generated from my code, maybe the error is more obvious this way
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns='http://www.w3.org/1999/xhtml'> <head> <title> ht-simple-ajax demo </title><script type='text/javascript'> //<![CDATA[ function fetchURI(uri, callback) { var request; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else { try { request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ee) { request = null; }}} if (!request) alert("Browser couldn't make a request object.");
request.open('GET', uri, true); request.onreadystatechange = function() { if (request.readyState != 4) return; if (((request.status>=200) && (request.status<300)) || (request.status == 304)) { var data = request.responseXML; if (callback!=null) { callback(data); } } else { alert('Error while fetching URI ' + uri); } } request.send(null); delete request; }
function ajax_call(func, callback, args) { var uri = '/ajax/' + encodeURIComponent(func) + '/'; var i; if (args.length > 0) { uri += '?' for (i = 0; i < args.length; ++i) { if (i > 0) { uri += '&' }; uri += 'arg' + i + '=' + encodeURIComponent(args[i]); } } fetchURI(uri, callback); }
function ajax_say_hi (name, callback) { ajax_call('SAY-HI', callback, [name]); } //]]> </script> <script type='text/javascript'>function callback(response) { return alert(response.firstChild.firstChild.nodeValue); }; function sayHi() { return ajax_say_hi(document.getElementById("name").value, callback); }; </script> </head> <body> <p> Please enter your name: <input id='name' type='text' /> </p> <p> <a href='javascript:sayHi()'> Say Hi! </a> </p> </body>
</html>
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
It works correctly in Firefox. I used Interenet Explorer before. What does that mean; Internet Explorer doesn't support ajax correctly ? Anyway, thanks for all the help.
When you are testing in IE, you could really use MSVS, it has a free version. The free version has limited debugging capabilities less templates / documentation. But, at least, you could have a debugger for JavaScript, and that would help you find, not only this, but other JavaScript related problems in IE. http://www.microsoft.com/express/Web/
From what I can tell, there are strange places in your code. For example,
returning alert() doesn't make sense because alert() returns undefined. You don't really have to call request.send(null), you could do request.send(), but if you wanted to encode name-value pairs, this function is the right place to do it (when sending POST requests). http://www.w3.org/TR/XMLHttpRequest/#the-send-method http://msdn.microsoft.com/en-us/library/ms536736%28v=vs.85%29.aspx In your example, you are sending a GET request, therefore, you don't need any arguments. Also, there may be subtle differences in how browsers will treat non-significant white space in XML, so response.firstChild.firstChild.nodeValue may be just a couple of blanks, depending on how your XML looks like, or it may give you an error, if the response.firstChild is a text node. delete request; - is a useless line, JavaScript is a managed runtime, so any local variable will seize to exist once the function returns, unless it was referenced outside the function's scope (in which case "deleting" it will have no effect). It is different, from, for example, C++ where delete would free memory. In JavaScript it is used to remove dynamic references from where they existed (essentially, someObject.someProperty = undefined is the same as delete someObject.someProperty). HTH.
I removed some of the code but it doesn't work anymore. What's the minimum code I have to add to make it works ? I don't really get response and callback terms in ajax ? I'm only interested in ajax now to be able to work with session values with javascript. Now when I click on Say hi link, I only get messagge box with value "undefined".
-------------------------------------------------------------------------------
(defpackage :sessions (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax))
(in-package sessions)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(push (create-ajax-dispatcher *ajax-processor*) *dispatch-table*)
(defun-ajax say-hi () (*ajax-processor*) (write-to-string (incf (session-value 'x))))
(define-easy-handler (main-page :uri "/") () (start-session) (setf (session-value 'x) 10) (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (:title "ht-simple-ajax demo") (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps
(defun say-hi () (alert (ajax_say_hi)))))))
(:body (:p "Please enter your name: " (:input :id "name" :type "text")) (:p (:a :href (ps-inline (say-hi)) "Say Hi!"))))))
Here I changed the function names to reflect the code:
-------------------------------------------------------------------------------
(defpackage :sessions (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax))
(in-package sessions)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(push (create-ajax-dispatcher *ajax-processor*) *dispatch-table*)
(defun-ajax show-x () (*ajax-processor*) (write-to-string (incf (session-value 'x))))
(define-easy-handler (main-page :uri "/") () (start-session) (setf (session-value 'x) 10) (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps
(defun show-x () (alert (ajax_show_x))))))
(:body (:p (:a :href (ps-inline (show-x)) "Show X"))))))
I know this isn't exactly what you've requested, but it does show how to get a session value and display it in the browser. It's been tested in the latest Chrome, IE, and Firefox, and uses Hunchentoot. http://paste.lisp.org/display/121215 Sometimes simpler is better.
On Wed, Apr 6, 2011 at 10:21 AM, Haris fbogdanovic@xnet.hr wrote:
Here I changed the function names to reflect the code:
(defpackage :sessions (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax))
(in-package sessions)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(push (create-ajax-dispatcher *ajax-processor*) *dispatch-table*)
(defun-ajax show-x () (*ajax-processor*) (write-to-string (incf (session-value 'x))))
(define-easy-handler (main-page :uri "/") () (start-session) (setf (session-value 'x) 10) (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps
(defun show-x () (alert (ajax_show_x))))))
(:body (:p (:a :href (ps-inline (show-x)) "Show X"))))))
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
I had to move to Internet Explorer again because it stopped working in Firefox. I started to debug javascript and on alert (response.firstNode.firstNode.nodcValue) it says that firstNode.firstNode is not an object ?
---------------------------------------------------------------------------------------------------------------
(defpackage ajax (:use :cl :hunchentoot :cl-who :parenscript :ht-simple-ajax)) (in-package ajax)
(setf *access-log-pathname* "c:/lisp/hunchentoot-log/access.log") (setf *message-log-pathname* "c:/lisp/hunchentoot-log/message.log")
(setf *js-string-delimiter* #")
(defparameter *ajax-processor* (make-instance 'ajax-processor :server-uri "/ajax"))
(push (create-ajax-dispatcher *ajax-processor*) *dispatch-table*) (push (create-prefix-dispatcher "/" 'index) *dispatch-table*)
(defun-ajax show-number () (*ajax-processor*) "10")
(defun index () (with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" (:head (:title "ht-simple-ajax demo") (princ (generate-prologue *ajax-processor*)) (:script :type "text/javascript" (str (ps (defun callback (response) (alert (chain response first-node first-node node-value)) ; ERROR: firstNode.firstNode 0))))) ; is not an object
(:body (:p (:a :href (ps-inline (ajax_show_nuimber callback)) "Show number"))))))