суббота, сентября 23, 2006

Sharepoint и history.back

Давно висела задача не дать пользователям возможности уйти с открывшейся страницы не предусмотренным способом с сохранением введённых данных или с удалением незаполненных записей, а при помощи кнопки Back в браузере. Такой "уход" приводит к появлению пустых записей в списках и другим нежелательным эффектам типа воплей о пропавших данных.

При внимательном рассмотрении выяснилось, что "легальная" смена УРЛа происходит при помощи трёх элементов - Button, LinkButton и HyperLink. Для каждого из них требуется специфическое решение для занесения в history адреса перехода (что и даёт эффект "очистки" истории и "блокировки" кнопки Back).

HyperLink

Для этого элемента просто переопределяем реакцию на нажатие:

//Настройка элемента
HyperLink link = new HyperLink();
l
ink.Text = ...;
link.NavigateUrl = ...;
//обработчик нажатия на клиенте
link.NavigateUrl = "javascript:window.location.replace('"+link.NavigateUrl+"')";

LinkButton

Для этого элемента кроме переопределения реакции на нажатие требуется добавить на страницу скрипт и передать в элементе hidden адрес перехода (такая передача требуется на случай, если таких элементов на странице больше одного):

//Настройка элемента
LinkButton linkButton =
new LinkButton();
linkButton.Text = ...;
linkButton.Click += new EventHandler(linkButton_Click);
//обработчик нажатия на клиенте
linkButton.Attributes.Add("onclick", "javascript:SetBack('"+this.ClientID+"')");
//функция настройки адреса перехода
string _backScript = @"<SCRIPT language=""javascript"" type=""text/javascript"" >
var __BackUrl__="""";
function SetBack(id){
var hf=document.getElementById(""_backurl_""+id);
if(hf){ __BackUrl__=hf.value; }
} </SCRIPT>"
;
if(!this.Page.IsClientScriptBlockRegistered("_SetBack"))
   
this.Page.RegisterClientScriptBlock("_SetBack", _backScript);

//функция подмены адреса history.back
string _OnUnloadScript = @"<SCRIPT language=""javascript"" type=""text/javascript"" FOR=window EVENT=onunload>
if(__BackUrl__ != """"){window.location.replace(__BackUrl__);}
</SCRIPT>"
;
if(!this.Page.IsStartupScriptRegistered("_OnUnload"))
   
this.Page.RegisterStartupScript("_OnUnload", _OnUnloadScript);

//адрес перехода
this.Page.RegisterHiddenField("_backurl_" + this.ClientID, <url>);

Button

Для элемента Button настройки аналогичны элементу LinkButton.

 

После таких модификаций переходы по нажатию на такие элементы приводят в "блокировке" кнопки Back браузера.

Естественно, нашлась ложка дёгтя - при наличии на странице других элементов, не обладающих таким же поведением, "блокировка" кнопки Back может быть нарушена. Таким элементом, например, является пункт меню "Изменить общую веб-часть..." :-(

суббота, сентября 16, 2006

XmlViewer и Office Extensions

Объявили ещё зимой конкурс, выставил на него в апреле примочку, до сих пор её "тестируют". Скоро уже никому не надо станет - новая версия Шарепойнта на подходе.

Решил на Гугле вывесить, может, кому пригодится...

P.S. Это веб-часть такая для Шарепонт'а.

XmlViewer and Office Extensions

MSFT have declared even in the winter competition, I have exposed on it in April a lotion, till now "testing". Soon nobody becomes already necessary - new version of Sharepoint on the approach.

Has decided on Google to hang out, maybe to whom it is useful...

It is useful webpart for Sharepoint 2003...

Little toy

For rest and a relaxation has composed utility for copying files on post servers.

Now backup of my the projects I do on a disk by nnbackup and on mail servers (gmail, hotmail, mail.ru) by eMailBackup - there should be an advantage of greater boxes, not only a spam to collect...

Игрушечка

Для отдыха и расслабления сочинил утилитку для копирования файлов на почтовые серверы.

Теперь бекап своих проектов делаю на диск при помощи nnbackup и на почту (gmail, hotmail, mail.ru) при помощи eMailBackup - должна же быть польза от больших ящиков, не только спам собирать...

суббота, сентября 02, 2006

Правка настроек.

В приложении использую конфиг-файл, в котором пользователи пишут значения руками. Естественно, ляпают. Как правило, лишние символы в конце и в начале. Но соответствующие свойства класса Settings оказываются readonly (настройки для всего приложения). Да к тому же тип у настроек - StringCollection.

В итоге пришлось соорудить функцию

public delegate bool goodString(string o);
public delegate string clearString(string o);

public
StringCollection CloneCollection(StringCollection src, goodString goodFunc, clearString clearFunc) {
  
StringCollection rv = new StringCollection();
  
foreach (string t in src) {
     
string tc = clearFunc == null ? t : clearFunc(t);
     
if (goodFunc == null || goodFunc(tc))
         rv.Add(tc);
   }
  
return rv;
}

Вызов такой:

setsSearchSites = CommonTools.CloneCollection(sets.SearcSites,
delegate(string s) { return !string.IsNullOrEmpty(s); },
delegate(string s) { return s.Trim().TrimEnd("/".ToCharArray()); });

А в приложении пользуюсь уже исправленной копией параметров, с вычищенными пробелами и слешами на концах.