2013-03-07 2 views
1

Как условно вызывать JavaScript из компонента в JSF 2?Условный вызов JavaScript из bean-компонента

У меня есть класс, который использует PrimeFaces, который загружает файлы пользователя в определенную папку, но если пользователь пытается загрузить файл с тем же именем, что и тот, который уже присутствует, я хочу, чтобы JavaScript в этом случае открыл на экране спрашивает пользователя, хочет ли он перезаписать старый файл или отменить операцию. Если файл с таким именем отсутствует, JavaScript не вызывается.

Я знаю, как проверить, что в папке есть определенный файл, просто мне нужно знать, как вызывать JavaScript условно.

Я бы очень признателен за любые советы по этому вопросу.


Я просмотрел ресурсы variopus в сети, но все еще не могу заставить приложение работать правильно. в основном, это то, что я сделал, в включаемой странице Xhtml У меня есть следующий код для загрузки файла:

<p:fileUpload id="fileUpload" fileUploadListener="#{filters.upload}" 
    allowTypes="#{filters.uploadTypes}" invalidFileMessage="#{filters.uploadBadType}" 
    sizeLimit="#{filters.uploadSize}" invalidSizeMessag="#{filters.uploadBadSize}" 
    update="fileUpload fileTable uploadMessage" description="Select Text File" 
    disabled="#{filters.disableFileUploadButton}"/> 

<!--- Then further in the same file is this: --> 

<p:remoteCommand name="remoteCommandOverwrite" actionListender="#{filters.execOverwrite}"/> 

Родитель Xhtml страница, которая включает в себя выше я имею foolowing JavaScript:

<script type="text/javascript"> 
    function popupConfirm() { 
    var overwrite = confirm('Warning: This will overwrite the existing file - Do you confirm this?'); 
    if (overwrite) remoteCommandOverwrite([{name: overwrite, value: true}]); 
    } 
</script> 

в моем боба у меня есть следующий код в трех способов:

public void upload(FileUploadEvent event) { 
    FacesMessage msg = new FacesMessage("Success! ", event.getFile().getFileName() + " is uploaded."); 
    FacesContext.getCurrentInstance().addMessage(null, msg); 
    overwrite = false; 
    // Do what you want with the file   
    try { 
     copyFile(event.getFile().getFileName(), event.getFile().getInputstream()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

    public void copyFile(String fileName, InputStream in) { 

    // Initialization etc. 

        File file = new File(uploadFull + fileName); 
     if (file.exists()) { 
      RequestContext.getCurrentInstance().execute("popupConfirm()"); 

// Then test to see if overwrite is true or false, and act accordingly 

} 

// Then I am supposed to get the value of overwrite here: 
public void execOverwrite() { 
    System.out.println("### execOverwrite() ###"); 
    FacesContext context = FacesContext.getCurrentInstance(); 
    Map<String, String> map = context.getExternalContext().getRequestParameterMap(); 
    String soverwrite = (String) map.get("overwrite"); 
    if (soverwrite.equals("true")) { 
     overwrite = true; 
     System.out.println("overwrite: true"); 
    } 
} 

То, что я пытаюсь сделать это первым, чтобы вызвать условно функцию popupConfirm JavaScript(). При нажатии кнопки «Загрузить», которая вызывается, если кодировка истинна, это то, что я хочу. Затем это должно быть вызвано

Это работает и отображает окно подтверждения(), но никогда не вызывается, поэтому метод executeOverwrite() в моем компоненте также никогда не вызывается, и я не могу получить возвращаемое значение и передайте его в код внутри метода copyFile(). Что происходит не так?

Я поставил эту проблему на задний план около недели и только что вернулся к ней. Я получил его на работу и могу передать значение обратно в bean-компонент, но мне нужно возобновить выполнение с того места, где вызывается JavaScript.

Для sumarize мой JavaScript содержит следующий код:

<script type="text/javascript"> 
    function popupConfirm() { 
    var overwrite = confirm('Warning: This will overwrite the existing file - Do you confirm this?'); 
    if (overwrite) remoteCommandOverwrite([{name: 'overwrite', value: 'true'}]); 
    } 
</script> 

И в коде Xhtml у меня есть:

<p:fileUpload id="fileUpload" fileUploadListener="#{filters.upload}" ...../> 

<!-- Other code --> 

<p:remoteCommand name="remoteCommandOverwrite" actionListener="#{filters.execOverwrite}"/> 

Затем по нажатию на кнопку загрузки файла после нажатия на кнопку файла выбрать, код в JavaScript, как указано выше, выполнен:

RequestContext.getCurrentInstance().execute("popupConfirm()"); 

Затем при нажатии «OK» в диалоговом окне, этот метод в том же боб называется:

public void execOverwrite() { 
    FacesContext context = FacesContext.getCurrentInstance(); 
    Map<String, String> map = context.getExternalContext().getRequestParameterMap(); 
    String soverwrite = map.get("overwrite"); 
    if (soverwrite.equals("true")) { 
     overwrite = true;  } 
    } 
} 

где флаг «перезаписать», в конечном счете быть проверена, чтобы увидеть, если это правда.

Использование различных операторов печати Я проверяю, что это работает. Тем не менее, код не возобновляет выполнение после столкновения с оператором: RequestContext.getCurrentInstance().выполнить ("popupConfirm()"); независимо от того, я введу «ОК» или «Отмена» в диалоговом окне, и это то, что я хочу сделать. Похоже, что требуется обратный вызов какого-либо типа, и он лучше всего оценит некоторые идеи.

+0

У меня такая же проблема с Primefaces 5.1 и JSF 2.2.6. , у вас есть решение? – Marin

ответ

2

Согласно вашему тегу, вы используете PrimeFaces, поэтому есть простой способ вызвать функцию javascript из метода управляемого обработчиком событий на стороне сервера, когда браузер завершил обработку ответа сервера. PrimeFaces предоставляет вам класс утилиты RequestContext.

public void doActionListenerMethod() { 
    if (!isValid()) { 
    RequestContext.getCurrentInstance().execute("MyJSObject.doClientSideStuff()"); 
    } 
} 

Следующий будет исполнять строковый аргумент как Javascript, когда JSF закончит рендеринг на клиенте.

+0

ОК, большое спасибо, я получил это, чтобы работать с простым полем alert(), которое появляется как быстрый тест. Теперь мне нужно использовать окно подтверждения(), которое появляется, и в зависимости от того, нажимает ли пользователь «ОК» или «Отмена», файл загружается или загрузка отменяется. Каким-то образом это должно быть возвращено к bean-компоненту из JavaScript. – csharp

+0

@csharp Хорошо, если вы используете диалоги PrimeFaces, тогда вы можете указать 'widgetVar', который является переменной Javascript, и они также имеют функцию' show() 'и' hide() 'для клиентской стороны. Честно говоря, что я, вероятно, сделаю, это просто загрузить файл в переменную сеанса сразу, чтобы он сидел в памяти сервера. Затем я был бы внутри формы внутри диалогового окна, у меня были бы кнопки ОК и Отмена в виде команд управления JSF, которые вызывают события сервера, чтобы либо сохранить файл, либо отбросить его из контекста сеанса, если он отменен. Атрибут 'oncomplete'' 'может вызвать функцию' hide() 'JS –

+0

ОК, это полезно, но я хочу, чтобы это было как можно проще. Как вернуть значение из вызова типа RequestContext.getCurrentInstance(). Execute ("confirm ('Warning: Это приведет к удалению всех загруженных файлов - Вы подтверждаете это?')"); где открывается окно «confirm()», то в зависимости от того, как пользователь отвечает, возвращается true или false. Как я могу получить возвращаемое значение из RequestContext, а затем действовать соответственно? – csharp