Пример голосовалки с Ajax на Jquery

NetWood

Lotus team
17.04.2008
372
19
#1
Не оставляя своих попыток разобраться с AJAX, была слегка допилена базка с codestore.
Что она делает:
- работа с фреймворком mootools заменено на jQuery (желающие, в соответствии с новой религией, могут сделать dojo :ya_lamo: )
- голосовалка с с простым подсчетом голосов на ajax (форма Proposal)
- выбор вариантов ответов и отображение ответов без перезагрузки страницы через ajax с запоминанием IP и гистограммами ответов (форма Survey)
- мультиголосовалка для примера тоже с гистограммами (форма SurveyMulti)


В бщем и целом разобрался с ajax, прямо красота :), но поскольку я полный и звенящий ноль в java, то осталось несколько вопросов:
1. Ответ сервера для отображения в событии выдается целиком в html
Код:
 	success: function(data){
$("#result_container").html(data);
Он формируется на LS агентом wqs Choice просто как html. Все замечательно отображается и работает, но одним блоком - один ответ - одно отображение. Параметров типа data.note из html никак не вытащить.

Сам html распарсить я не умею, а стоит задача в ответе получить параметры, чтобы потом их отобразить под разными id в разных местах страницы. Соответственно тут путь только через json или xml в качестве ответа чтобы сделать например так:
$('#result_container').append('To: ' + data.to + '<br/>');
$('#result_container2').append('note: ' + data.note + '<br/>');

Сам json можно формировать также в агенте как текст {'to':'данные','note':'данные'}, однако при попытке сделать в аяксе dataType : "json" возникает ошибка по
Код:
	error: function (){
alert('Ошибка соединения');
}, .
dataType : "xml" тоже не пашет :(

В чем траблы? Кто подскажет допилить пример для получения параметров в ответе и выводом под разным ID на страничке?

ky: там по базе есть куча заремленных пробных вариантов - это потуги :)
ку2: ajax dataType : "script" переваривается нормально, но как из этого скриптового ответа параметры вытащить?
 

Вложения

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#2
есть у мя код, кот. dojo подсовывает JSON из LS агента
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"кусок агента"</div></div><div class="sp-body"><div class="sp-content">
Код:
Sub Initialize
'isDebug=True
Set ses=New NotesSession()
Set db=ses.Currentdatabase
'Set view=db.Getview(viewName)
'Set nav=view.Createviewnav()
Set curdoc=ses.Documentcontext
Call PrintHeader()
Dim v
v=Split(DT_PARAM, SEP_PARAM)
ForAll m In v
paramList(m)={}
paramCount=paramCount+1
End ForAll
Dim international As NotesInternational
Set international = ses.International

if ParseInput() Then
Dim dts As NotesDateTime, dte As NotesDateTime
If international.Isdatedmy Then Set dts=toDMY(paramList(DTS_PARAM)):Set dte=toDMY(paramList(DTE_PARAM))
If international.Isdatemdy Then Set dts=toMDY(paramList(DTS_PARAM)):Set dte=toMDY(paramList(DTE_PARAM))
If international.Isdateymd Then Set dts=toYMD(paramList(DTS_PARAM)):Set dte=toYMD(paramList(DTE_PARAM))
Dim res
res=GetSchedule(dts, dte)
If Not IsEmpty(res) Then Call PrintMsg(ParseOutPut(res))
End If
End Sub
%REM
Function PrintHeader
Description: начало вывода информации
%END REM
Function PrintHeader()
If headerPrinted Then Exit function
headerPrinted=True
Print "Content-type: application/json; charset=UTF-8"
End Function
%REM
Function PrintMsg
Description: wrapper для системного Print
%END REM
Function PrintMsg(xMsg As String)
If isDebug Then MsgBox xMsg:Exit Function
Print xMsg
End Function
%REM
Function ParseOutput
Description: вывод данных в нужном формате (JSON)
%END REM
Function ParseOutput(xList As Variant) As String
If IsEmpty(xList) Then Exit Function
Dim sBuf As New StringBuffer(DEF_BUFFER)
Dim isNext As Boolean
Dim c As Long
sBuf.Append(|results: [ |)
ForAll m In xList
If Not isNext Then
sBuf.Append(m):isNext=True
Else
sBuf.Append(|,|):sBuf.Append(m)
End If
c=c+1
End ForAll
sBuf.Append(|]}|)
ParseOutput=| { numresults: |& CStr(c) & |, | & sBuf.toString()
End Function
по сути: вызываем печать PrintHeader() (кот. и определяет формат), далее PrintMsg (просто выводит текст в выходной поток), а он может принимать на вход отформатированный текст из ParseOutput
 

NetWood

Lotus team
17.04.2008
372
19
#3
по сути: вызываем печать PrintHeader()
Дык там тоже через Print поток выводится. С этим проблем нет. Хочешь плайном хочешь скриптом его назови
Код:
				Print "content-type: text/html"
'Print "content-type: text/javascript"
'Print "<?xml version="1.0" encoding="UTF-8"?>"
'Print({<script language=Javascript>} & Chr(10))
Print GetResultsHTML(vThisdatabase, doc) +Chr(10) + "Your vote for <b>" + vWebDocument.Choice(0) + "</b> has been registered!"
'Print "{'note':'"+GetResultsHTML(vThisdatabase, doc) +"'}" ' попытка сделать json
'Print({</script>} & Chr(10))
Проблем в обработке полученного. ajax dataType: json и xml вызывают ошибку, а плайн html распарсить никак.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#4
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"получение dojo"</div></div><div class="sp-body"><div class="sp-content">
JavaScript:
dojo.xhrGet({
url: geturl,
handleAs:"json",
preventCache: true,
/*
content: {
username: "George",
password: "curious"
},
*/
load: function(data, ioargs) {
//alert("XHR returned HTTP status: " + ioargs.xhr.status);
var s="";
if (data.toplevel){
//выводит системные собщения (если присутствуют)
if (data.toplevel[0].Status){
msgDlg.attr("content",data.toplevel[0].Status);
console.log("Status:"+data.toplevel[0].Status);
msgDlg.show();
setTimeout(function(){ 
msgDlg.hide(); 
}, 500); 
}
//будет выводить ошибки, в том числе - в скрипте (агенте)
if (data.toplevel[0].Error){
msgDlg.attr("content",data.toplevel[0].Error);
msgDlg.show();
}
}
if (data.numresults){
iterateResult(data);
}
},
error: function(error, ioargs) {
msgDlg.attr("content", "An unexpected error occurred: " + error);
msgDlg.show();
}		
/*		timeoutSeconds: 5,
timeout: function(type, data, evt){
alert("I am tired of waiting.");
},
*/
}, 1000);
перебор в цикле:
JavaScript:
/*
* обрабатываем строки результата
*/
function iterateResult(data){
var s="";
var lastrow=new Array(sc_cnt);
var lastel=new Array(sc_cnt);
for(var i = 0; i < data.numresults; i++){
Добавлено: т.е. json итерируем как массив (потому как его так и создавали)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#6
так отправляете?
JavaScript:
$.ajax({
url: '/ajax/example.html',			 // указываем URL и
dataType : "json",					 // тип загружаемых данных
success: function (data, textStatus) { // вешаем свой обработчик на функцию success
$.each(data, function(i, val) {	// обрабатываем полученные данные
/* ... */
});
}
});
 

NetWood

Lotus team
17.04.2008
372
19
#7
так отправляете?
JavaScript:
$.ajax({
dataType : "json",					 // тип загружаемых данных
Ну да. По букварю. dataType : "html" "scripts" перевариваются, а "json" и "xml" из которых можно параметры вытащить - нет.

Подробнее - так. dataType для html можно явно не указывать, однако если сказать dataType : "json", то ошибка
Код:
//http://www.codething.ru/ajax.php
function doAjaxVote2(docid, vote){
$.ajax({
type: "post",
url: "vote?CreateDocument",
data: {'vote':vote, 'action':'vote', 'docid':docid, 'ajax':'true'},
error: function (){
alert('Ошибка соединения');
},
beforeSend: function(){ // Эффекты jquery
$("vote_link2").fadeOut();
},
complete: function(){
$("vote_link2").fadeIn(); // Эффекты jquery
},
success: function(data){
$("#vote_link2").html('');
$("#vote_link2").html(data).fadeIn("slow");
} 
});
}
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#10
тока шо оттрейсил под файрбагом - запрос уходит и ответ есть, просто он не парсится, ежели формат возвращаемых данных не соответствует. Потому и ошибка

Добавлено: замените:
JavaScript:
/*  	 $.ajax({
type: "post",
url: "choice?CreateDocument",
dataType: "json",
data:{'docid':frm.DocID.value, 'choice': choice, 'ajax':'true'},
error: function (){
alert('Ошибка соединения');
},
success: function(response){
$('#result_container').html(response);
$('#choice_form').html("<p>Thank you. Your vote has been registered.</p>");
}
});
*/
$.post("choice?CreateDocument", { 'docid':frm.DocID.value, 'choice': choice, 'ajax':'true' },
function(data){
alert("Hello");
}, "html");
ежели html заменить на json - запрос всёравно уйдет, просто ответ не попадёт в обработчик - т.к. возврат не json
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#11
вот исправленный код wqs Choice:
Код:
			If vWebDocument.Ajax(0)="true" Then
Print "Content-type: application/json; charset=UTF-8"
'				Print "content-type: text/html"
'Print "content-type: text/javascript"
'Print "<?xml version="1.0" encoding="UTF-8"?>"
'Print |{results_html: "|+Replace(Replace(GetResultsHTML(vThisdatabase, doc), |"|, |\"|), Chr(10), "\n") +|"}| '"Your vote for " + vWebDocument.Choice(0) + " has been registered!"
'Print Replace(Replace(GetResultsHTML(vThisdatabase, doc), |"|, |\"|), Chr(10), "\n") + Chr(10) + "Your vote for " + vWebDocument.Choice(0) + " has been registered!"
'для jQuery убраны реплейсы и results_html: - так работает!
'Print({<script language=Javascript>} & Chr(10))
'Print ("var test = 'ntrcn'; " & Chr(10))
Print |{toplevel:[{Status:"| & |JSON: Hello| & |"}]}|
'				Print GetResultsHTML(vThisdatabase, doc) +Chr(10) + "Your vote for <b>" + vWebDocument.Choice(0) + "</b> has been registered!"
'Print "{'note':'"+GetResultsHTML(vThisdatabase, doc) +"'"
'Print({</script>} & Chr(10))
и меняем html на json - получим алерт:
JavaScript:
$.post("choice?CreateDocument", { 'docid':frm.DocID.value, 'choice': choice, 'ajax':'true' },
function(data){
alert(data.toplevel[0].Status);
}, "json");
 

NetWood

Lotus team
17.04.2008
372
19
#12
Ок. В очередной раз благодарен :blush:
Задышало кроме усложнений:

Если заменить в коде
Print |{toplevel:[{Status:"| & |JSON: Hello| & |"}]}|
на
Print |{toplevel:[{Status:"| & GetResultsHTML(vThisdatabase, doc) & |"}]}|
то не выводится ответ. GetResultsHTML собственно формирует саму табличку с данными.

Выводил вот так
Код:
			 function(data){
//alert(data.toplevel[0].Status);
$("#result_container").html('');
$("#result_container").append(data.toplevel[0].Status);
upd: Нда пришлось парсить функу
Код:
Print |{toplevel:[{Status: "|+ Replace(Replace( (GetResultsHTML(vThisdatabase, doc) + "Your vote for <b>" + vWebDocument.Choice(0) + "</b> has been registered!" ) , |"|, |\"|), Chr(10), "\n") + |"}]}|
Ожило.

И для полного счастья с "синим ведерком" на крыше
Код:
	$.post("choice?CreateDocument", 
{ 'docid':frm.DocID.value, 'choice': choice, 'ajax':'true', 
beforeSend: function(){$("#result_container").fadeOut();},
complete: function(){$("#result_container").fadeIn();}
},
function(data){
//alert(data.toplevel[0].Status);
$("#result_container").html('');
$("#result_container").append(data.toplevel[0].Status).fadeIn("slow");
}, "json");
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#13
ну я-то приводил пример JSON контейнера, с моей стр-рой
а можно сделать любую, и не пихать всё в статус
налепить типа:
|{toplevel:[{Status:"| & |JSON: Hello| & |"},
{html:"|& txtHTML &|",
to:"|& txtTo &|",
note:"|& txtNote &|"}
]}|
тока без переводв каретки (ато пайпы их передадут как есть)
можно и без toplevel (это я для примера делал)
а обращаться data.toplevel[1].html
ежели не напутал :blush: