f:ajax 上的 onevent 导致模型未更新
我在网站上添加了 TinyMCE(JSF-2、Tomcat 7、Mojarra 2.1.6)。当用户单击“刷新”按钮时,编辑器内的 html 文本将被解析并打印到页面上的其他位置。
我必须在 Ajax 请求之前关闭 TinyMCE(否则我最终会得到两个编辑器)。 TinyMCE 文档中也建议这样做。
因此,我向按钮添加了一个 f:ajax 事件:
<h:commandButton value="#{msg['rt.refresh']}" action="#{updateTextAction.execute}" onclick="cleanupRte();">
<f:ajax event="action" execute="@this" render="@all" onevent="disposeTinyMce" />
</h:commandButton>
正确调用了 javascript 函数:
function cleanupRte() {
tinyMCE.triggerSave();
return true;
}
以及 onevent 方法:
function disposeTinyMce(e) {
if(e.status == 'begin') {
tinyMCE.triggerSave();
var elem = document.getElementById("mainForm:rteExtAdr:input");
alert(elem.value);
tinyMCE.execCommand('mceRemoveControl', false, 'mainForm:rteExtAdr:input');
}
if(e.status == 'complete') {
}
if(e.status == 'success') {
tinyMCE.execCommand('mceAddControl', false, 'mainForm:rteExtAdr:input');
}
return true;
}
该方法禁用编辑器并将其添加回页面。这工作正常。
问题是尽管警报显示了正确的值,但模型并未使用文本字段中的值进行更新。该请求还包含文本字段中的“旧”值。
是否有什么东西会阻止 ajax 调用查看当前表单值? 或者它是否在执行 onevent 函数之前读取值?
如果我完全删除 f:ajax 标签,模型会更新,但我会遇到 TinyMce 编辑器在响应后重复的问题。
init 调用:
tinyMCE.init({
mode : "textareas",
theme : "advanced",
editor_selector : "sesamWysiwyg",
language : "de",
force_br_newlines : true,
force_p_newlines : false,
inline_styles : false,
forced_root_block : '', // Needed for 3.x
plugins : "autolink,lists,style,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,searchreplace,print,paste,directionality,noneditable,visualchars,nonbreaking,xhtmlxtras,wordcount,advlist",
formats : {
underline : {inline : 'u', exact : true},
strikethrough : {inline : 'del', exact : true}
},
theme_advanced_buttons1 : "bold,underline,strikethrough,|,cut,copy,paste,pastetext,pasteword,search,replace,|,undo,redo,|,code,removeformat,|,charmap",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_buttons4 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
content_css : "css/content.css",
});
任何想法或建议都会很棒!
谢谢 :)
I've added TinyMCE on a website (JSF-2, Tomcat 7, Mojarra 2.1.6). When a user clicks on a 'refresh' button the html text inside the editor is parsed and printed somewhere else on the page.
I have to turn off TinyMCE before the Ajax request (otherwise I will end up with two editors). This is also recommended in the TinyMCE documentation.
So I added an f:ajax event to the button:
<h:commandButton value="#{msg['rt.refresh']}" action="#{updateTextAction.execute}" onclick="cleanupRte();">
<f:ajax event="action" execute="@this" render="@all" onevent="disposeTinyMce" />
</h:commandButton>
the javascript functions are called properly:
function cleanupRte() {
tinyMCE.triggerSave();
return true;
}
and the onevent method:
function disposeTinyMce(e) {
if(e.status == 'begin') {
tinyMCE.triggerSave();
var elem = document.getElementById("mainForm:rteExtAdr:input");
alert(elem.value);
tinyMCE.execCommand('mceRemoveControl', false, 'mainForm:rteExtAdr:input');
}
if(e.status == 'complete') {
}
if(e.status == 'success') {
tinyMCE.execCommand('mceAddControl', false, 'mainForm:rteExtAdr:input');
}
return true;
}
which disables the editor and adds it back to the page. This is working fine.
The problem is the model is not updated with the value from the textfield although the alert shows the correct value. The request also contains the 'old' value from the textfield.
Is there something that would prevent the ajax call to see the current form values?
or does it read the values before it executes the onevent function?
If I remove the f:ajax tag completely the model is updated but then I have the issues with the TinyMce editor getting duplicated after the response.
the init call:
tinyMCE.init({
mode : "textareas",
theme : "advanced",
editor_selector : "sesamWysiwyg",
language : "de",
force_br_newlines : true,
force_p_newlines : false,
inline_styles : false,
forced_root_block : '', // Needed for 3.x
plugins : "autolink,lists,style,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,searchreplace,print,paste,directionality,noneditable,visualchars,nonbreaking,xhtmlxtras,wordcount,advlist",
formats : {
underline : {inline : 'u', exact : true},
strikethrough : {inline : 'del', exact : true}
},
theme_advanced_buttons1 : "bold,underline,strikethrough,|,cut,copy,paste,pastetext,pasteword,search,replace,|,undo,redo,|,code,removeformat,|,charmap",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_buttons4 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
content_css : "css/content.css",
});
Any ideas or suggestions would be great!
thanks :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这不是由
onevent
处理函数引起的。这是由execute="@this"
属性引起的。@this
基本上意味着只有当前 组件将被执行/处理。如果您想处理整个表单,包括所有包含的输入元素,则需要使用execute="@form"
。这样,模型将使用所有已处理输入元素的值进行更新。
或者,如果您只想处理某些输入,则需要使用例如
execute="input"
,其中input
是输入组件的 ID。它可以采用空格分隔的(相对)客户端 ID 字符串。至于重新发明轮子,看组件库就知道了。 PrimeFaces 例如有 一个
组件。这样就可以轻松使用自定义脚本了。
This is not caused by the
onevent
handler function. This is caused by theexecute="@this"
attribute. The@this
basically means that only the current component will be executed/processed. If you want to process the entire form, including all the containing input elements, you need to useexecute="@form"
instead.This way the model will be updated with the values of all processed input elements.
Or if you want to process certain inputs only, you need to use for example
execute="input"
whereinput
is the ID of the input component. It can take a space separated string of (relative) client IDs.As to reinventing the wheel, just look at component libraries. PrimeFaces for example has a
<p:editor>
component. It's then a matter of onlywithout any hassle with custom scripts.