Андрей
На форме оформляешь
форму (NotesForm) с окном сообщения. Располагаешь на форме поле типа RichTextItem, называешь его, например, "Body". В свойствах поля на закладке "Advanced" в секции "Help Description" прописываешь, например, "[<rows=8 cols=85>]" - высота 8, ширина 85. Далее, допустим, располагаем ниже три кнопочки: "Сохранить" (сохранение сообщения на форуме), "Отмена" (Undo), "Удалить" (удаление собственного сообщения на форуме). В свойствах формы на закладке "Defaults" в секции "On Open" ставишь галочку "Automatically Enable Edit Mode". Для оформления тэгов HTML на форме необходимо выполнить следующее: прямо на форме записать нужные тэги, выделить их, через меню "Text" для выделенного текста установить признак "Pass-Thru HTML". Фон тэгов должен полсле этого принять серый цвет. (Например, таким образом можно оформить отступы на форме между ее элементами: <br>).
В кнопках по событию "onClick" необходимо расположить JavaScript код либо вызов функций JavaScript. В последнем случае все функции JavaScript необходимо расположить в секции формы "JS Header". Кнопки можно оформлять в виде картинок для лучшего стилистического оформления. (Картинкам кнопок можно придать иллюзию их нажатия при наведении курсора мышки на них. Для этого необходимо расположить две картинки (кнопка в ненажатом состоянии и кнопка в нажатом состоянии) рядом с отступом по горизонтали в один пиксел между ними. Все картинки естественно лучше хранить в базе данных в секции "Shared Resources - Images". Кроме того, чтобы этот эффект работал в свойствах картинки на секции "Basics - Advanced" для свойства "Images across" необходимо выставить "2", для свойства "Images down" необходимо выставить "1" и поставить птичку "Web browser compatible").
Итак, на кнопке "Отмена" у нас происходит вызов
стандартной процедуры JavaScript "reset()".
На кнопке "Сохранить" у нас происходит вызов процедуры JavaScript "RefreshDoc()":
Код:
function RefreshDoc(){
document.forms[0].action.value = "refreshing_doc";
document.forms[0].submit();
}
"action" - название скрытого поля на форме, который хранит значения выполняемых действий с документом. В данном случае мы хотим документ сохранить в базе данных (на форуме) и снова отобразить его на экране (возможно сделать так, что после сохранения нового сообщения на форме орывается не текущая форма документа, а уже другая, которая, например, содержит список всех сообщений данной темы, как в стандартных форумах это принято).
По команде "submit()" вызывается агент, прописанный в секции формы "WebQuerySave". В моем случае там прописано следуюющее: "@Command([ToolsRunMacro]; "board")", где "board" - название агента.
Рассмотрим этот агент. В свойствах агента на закладке "Basics" в секции "Runtime" он имеет свойства: "Trigger On event Action menu selection, Target None".
Код:
(Declarations)
Dim session As NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim profile As NotesDocument
Dim view As NotesView
Dim item As NotesItem
Код:
Sub Initialize
Set session = New NotesSession
Set db = session.CurrentDatabase
Set doc = session.DocumentContext
Set view = db.GetView("($profile)")
Set profile = view.GetFirstDocument
If doc.action(0) = "refreshing_doc" Then Call RefreshDoc(doc)
If doc.action(0) = "deleting_doc" Then Call DeleteMsg(doc)
End Sub
Код:
Sub RefreshDoc(doc As NotesDocument)
Set item = doc.GetFirstItem("body")
doc.msg_to_display = item.Text
doc.msg_attr = " Автор: " + doc.user_name(0) + Chr(10) + "Дата: " + doc.cur_date(0)
Call doc.Save(True, True)
Call doc.ComputeWithForm(False, False)
Print "[" + profile.db_directory(0) + "/" + db.FileName + "/0/" + doc.UniversalID + "?OpenDocument]"
End Sub
Код:
Sub DeleteMsg(doc As NotesDocument)
Set send_confirmation = New NotesDocument(db)
send_confirmation.Form = "send_confirmation"
send_confirmation.is_draft = 1
send_confirmation.title = "Подтверждение удаления документа"
send_confirmation.msg = "Документ успешно удален."
send_confirmation.action = doc.action(0)
send_confirmation.updating_doc_unid = doc.UniversalID
Call send_confirmation.Save(True, True)
Print "[" + profile.db_directory(0) + "/" + db.FileName + "/0/" + send_confirmation.UniversalID + "?OpenDocument]"
End Sub
В секции "Initialize" агент инициирует профильный документ текущей базы данных "profile" и в зависимости от кода поля текущей формы "action" вызывает определенную функцию LotusScript. В данном случае - "RefreshDoc". Что делает эта функция? Получает доступ к полю "body" и в скрытое поле "msg_to_display" копирует текст сообщения. В поле "msg_attr" заносятся атрибуты сообщения: автор и дата сообщения, которые берутся из скрытых полей "user_name"
Код:
(value="name := @Left(@V3UserName; "/");")
и "cur_date"
Код:
(value="@Left(@Text(@Now); " ")")
. Затем документ сохраняется в базе данных и переоткрывается в броузере. Поле профильного документа текущей базы данных: "db_directory"
Код:
(value=directory := @LeftBack(@Subset(@DbName;-1);"\\"); "/" + @ReplaceSubstring(directory; "\\"; "/" ))
.
По кнопке "Удалить" происходит выхов функции JavaScript "DeleteMsg()":
Код:
function DeleteMsg(){
var flag;
flag = confirm("Внимание: документ будет безвозвратно удален.\r\rПродолжить?");
if(flag == true){
document.forms[0].action.value = "deleting_doc";
document.forms[0].submit();
}
}
Данная процедура вызывает функцию LotusScript "DeleteMsg" в агенте "board". Данная функция выводит в броузере форму подтверждения удаления документа. При создании данного документа на событии формы этого документа "WebQueryOpen" вызывается фунция другого агента, которая находит помеченный документ на удаление по его UNID и удаляет из базы данных.
_________________
Естественно необходимо сделать так, чтобы доступ не радактирование и удаление сообщений форума давался только опредленному кругу лиц - его создателю и группе привилегированных пользователей и в определенных случаях.
На форме сообщения в событиии "WebQueryOpen" вызывается агент "refresh_access", который определеят текущий уровень доступа текущего пользователя к документу:
Код:
(Declarations)
Dim session As NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Код:
Sub Initialize
Dim user_name, owner_name As Variant
Set session = New NotesSession
Set db = session.CurrentDatabase
Set doc = session.DocumentContext
user_name = Evaluate("@UserNamesList", doc)
user_name = Strleft(Strright(Cstr(user_name(0)), "="), "/")
owner_name = Evaluate("@Left(@Right(NotesName; ""=""); ""/"")", doc)
doc.name1 = user_name
doc.name2 = Cstr(owner_name(0))
If user_name = Cstr(owner_name(0)) Then
doc.is_owner = 1
Else
doc.is_owner = 0
End If
Call doc.ComputeWithForm(False, False)
End Sub
Данный агент сравнивает имя владельца документа и имя теущего пользователя и в зависимости от результата сравнения заполняет скрытое поле "is_owner".
Поле "body" и кнопки располагаются в секции "Section - Controlled Access", тип которой "Computed":
Код:
@If(
@IsNewDoc; "[consultant]" : "[request_author]" : "[coordinator]";
is_owner = 0; "[coordinator]";
"[consultant]" : "[request_author]" : "[coordinator]"
)
Все комбинации с ролевым доступом к документу необходимо выполнять, используя поля типа "Readers" и "Authors"
(В квадратных скобках - названия ролей (roles) в текущей базе данных).
Сообщения форума можно отобразить посредством внедренного представления документов (Embedded View) на форме.