SSJS выполняется до функции обратного вызова CSJS

Я пытаюсь внедрить библиотеку javascript Sweet Alert в свое приложение.

Вот соответствующий код:

<xp:link escape="true" text="" id="link2" style="color:#4A4A4A">
<i class="fa fa-trash-o fa-lg">
</i>
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="assetList">
<xp:this.action><![CDATA[#{javascript:
var db:NotesDatabase = session.getDatabase(sessionScope.serverPath,sessionScope.dbName);
var id = viewRow.getUniversalID();
var doc:NotesDocument = db.getDocumentByUNID(id);
doc.remove(true);}]]></xp:this.action>
<xp:this.script><![CDATA[swal({   
title: "Are you sure?",
text: "This asset will be permanently deleted",
type: "warning",   
showCancelButton: true,   
confirmButtonColor: "#2196f3",   
confirmButtonText: "Ok", 
cancelButtonColor: "#607D8B",  
cancelButtonText: "Cancel",   
closeOnConfirm: true,   
closeOnCancel: true,
confirmButtonClass: 'confirm-class',   
cancelButtonClass: 'cancel-class' 
}, 
function(isConfirm){   
if (isConfirm) {
return true; 
} else {
return false;
}
});

//if(window.confirm("Are you sure you want to delete the asset?") != true)
return false;]]></xp:this.script>
</xp:eventHandler>
</xp:link>

Щелчок по ссылке удаляет строку независимо от сделанного выбора (Отмена/ОК). Я вижу, как происходит удаление, даже до того, как сделаю свой выбор. У меня такое ощущение, что это как-то связано с порядком выполнения обратного вызова.

Если я использую код, закомментированный в конце (window.confirm), он работает отлично.

Я был бы признателен за ваше руководство по этому поводу.

Спасибо,

Дэн


person Dan Soares    schedule 16.03.2016    source источник
comment
Я подозреваю, что sweetalert может конфликтовать с проблемой AMD XPages. Я пытаюсь подтвердить.   -  person David Leedy    schedule 16.03.2016
comment
Дэвид, нет конфликта AMD. Я получаю предупреждение Sweet. Но код SSJS выполняется еще до того, как у меня появляется возможность выбрать «Отмена» или «ОК».   -  person Dan Soares    schedule 16.03.2016
comment
хм интересно. Я получил ошибку AMD. Как только я добавил SweetAlert на свою страницу и попробовал что-то простое, ничего не выскочило, и даже базовое предупреждение (тест) в CSJS не сработало. Мне пришлось зайти в файл sweetalert-dev.js и изменить параметр amd.define на false. Затем простые вещи начали работать, как и ожидалось.   -  person David Leedy    schedule 16.03.2016
comment
Возможно, я изменил файл js в какой-то момент в прошлом :)   -  person Dan Soares    schedule 16.03.2016
comment
в Firebug нет ошибок?   -  person Frank van der Linden    schedule 16.03.2016
comment
Или, может быть, это может вам помочь, stackoverflow.com/questions/27987071/   -  person Frank van der Linden    schedule 16.03.2016
comment
Фрэнк, это точно. Похоже, я не могу просто заменить Sweet Alert на подтверждение.   -  person Dan Soares    schedule 16.03.2016
comment
мне сделать это ответом, чтобы вы могли его принять?   -  person Frank van der Linden    schedule 17.03.2016
comment
Может быть, это может помочь, stackoverflow.com/questions/27987071/   -  person Frank van der Linden    schedule 17.03.2016
comment
Фрэнк, я опубликовал свое решение проблемы. Я проголосовал за ваш комментарий, так как он указал мне на проблему. Ценю твою помощь.   -  person Dan Soares    schedule 17.03.2016


Ответы (3)


Проблема в том, что сторонние подсказки не блокируются и не ждут ответа, прежде чем продолжить, как это делают собственные подсказки браузера.

В этом сообщении SO показан пример помещения кода в обратный вызов, чтобы попытаться работать с Sweet Alert (но похоже, что вы уже делаете что-то подобное): sweetalert блокируется как обычное приглашение

Инициирование события нажатия кнопки, которая запустит код на стороне сервера, выполнит свою работу. Если вы хотите, чтобы он работал асинхронно (но вам не нужно обновлять страницу на стороне клиента), вы можете запустить метод json rpc в обратном вызове или сделать вызов пользовательской службы REST для запуска кода на стороне сервера вместо запуска скрытая кнопка.

person Brad Balassaitis    schedule 16.03.2016

Я решил это, создав скрытую кнопку. Я удалил код SSJS из своей ссылки и из CSJS ссылки, вызванной событием нажатия скрытой кнопки для выполнения SSJS.

Вот обновленный код:

<xp:link escape="true" text="" id="link2" style="color:#4A4A4A">
<i class="fa fa-trash-o fa-lg">
</i>
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="assetList">
<xp:this.script><![CDATA[swal({   
title: "Are you sure?",
text: "This asset will be permanently deleted",
type: "warning",   
showCancelButton: true,   
confirmButtonColor: "#2196f3",   
confirmButtonText: "Ok", 
cancelButtonColor: "#607D8B",  
cancelButtonText: "Cancel",   
closeOnConfirm: true,   
closeOnCancel: true,
confirmButtonClass: 'confirm-class',   
cancelButtonClass: 'cancel-class' 
}, 
function(response){   
if (response == true) {
var deleteAssetBtn = '#{javascript:getClientId("deleteAsset")}';
document.getElementById(deleteAssetBtn).click();
return true; 
} else {
return false;
}
});
]]></xp:this.script>
<xp:this.action><![CDATA[#{javascript:viewScope.docID = viewRow.getUniversalID();}]]>
</xp:this.action>
</xp:eventHandler>
</xp:link>

А вот код скрытой кнопки, которая собственно и выполняет удаление документа:

<!-- Hidden button -->
<xp:button value="Delete Asset" id="deleteAsset" style="display:none">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
    <xp:this.action><![CDATA[#{javascript:try {
var db:NotesDatabase = session.getDatabase(sessionScope.serverPath,sessionScope.dbName);
var doc:NotesDocument = db.getDocumentByUNID(viewScope.docID);
doc.remove(true);
viewScope.docID = "";
} catch(e) {
requestScope.errstatus = e.toString();
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>

Если у кого-то есть лучший способ добиться этого результата, я открыт для предложений :)

person Dan Soares    schedule 16.03.2016
comment
Я вижу пост в блоге ;-) - person Frank van der Linden; 17.03.2016

Вы можете добавить дополнительное событие вместо добавления скрытой кнопки.
Т.е. в следующем коде у вас есть радио с 2 событиями:
- onchange - это стандартное событие, при котором запускается ваш CSJS
- onchangepost - это дополнительное событие, содержащее ваш код, который будет оценивается после события onchange (недоступно в интерфейсе конструктора, его необходимо добавить вручную).

Я предполагаю, что ваш код onchange асинхронный. Если у вас есть раздел onEnd/onComplete, вы можете добавить код, который будет оцениваться после завершения своей работы (возможно, вы нажмете там кнопку). Это место, где вы можете запустить свой код onchangepost, например, с помощью фрагмента события пожара (https://openntf.org/XSnippets.nsf/snippet.xsp?id=manually-fire-attached-event)

<xp:radioGroup id="myRadio" required="false">
    <xp:selectItem itemLabel="Option a"
        itemValue="A">
    </xp:selectItem>
    <xp:selectItem itemLabel="Option b" itemValue="B">
    </xp:selectItem>
    <xp:eventHandler event="onchange" submit="false">
        <xp:this.script>
            <![CDATA[
                doYourClientJS(
                    {onComplete: fireEvent(dojo.byId('#{id:myRadio}'), 'changepost')
                });                     
            ]]></xp:this.script>
    </xp:eventHandler>
    <xp:eventHandler event="onchangepost"
        submit="true" refreshMode="partial" refreshId="otherUserInnerRefreshSection"
        execMode="partial" execId="otherUserRefreshSection"
        disableValidators="true">
        <xp:this.action><![CDATA[#{javascript:doYourSSJS;}]]></xp:this.action>
    </xp:eventHandler>
</xp:radioGroup>
person dj_universe    schedule 17.03.2016