PB11发布的WebFORM应用中RichTextEdit控件的应用修补方法

背景
    在webform应用中,能象word一样对文本进行排版,排版结果对应的DHTML代码要能按文本数据类型保存到数据库中;同时亦能从数据库中读出该文本,然后按文本的DHTML代码反映到webform窗口中的编辑控件内,从而可继续修改。
 
存在的问题
    我们一般做法是在应用中利用PB的RichEdit控件实现类似WORD排版的功能(当然也可使用其他控件,本文不讨论)。在C/S下PB11的控件功能基本能满足要求,但界面就不怎么好看了,如下图所示。
然而如果发布为WEBFORM应用,实现上则不再是那么回事了,虽然发布后能产生比C/S还好看些的界面(见后面的图),也有PBRICHEDIT.JS脚本支持,但找其手册,发现必须要用的函数根本不支持,如copyrtf, pastertf等,试来试去有实际用途的就发现只有READONLY属性了,也就是说输入的内容无法取出来保存到数据库或保存其DHTML代码,也无法设置RICHEDIT的内容,可以说根本不能用。NEWSGROUP上看起来象晒被子的工程师也说什么由于许可证问题不支持(但我搞不清为何有此一说,因为分析发布的应用所对应的HTML页面,richedit的界面显示部分实际上就是最简单不过的html+js代码构成的,根本没有用到什么第三方的东西)。
    基于此,所以开始时本人尝试改为使用典型的在线编辑器FCKEditor代替RICHEDIT,摸索一段时间后发现虽然可运行起来,但在我的问题背景要求下也不好处理立即赋值与取值的问题(有时间还会继续研究,因为FCK确实棒,并且虽然是外来品,但对中文支持却很好),转而又继续研究RICHEDIT,最后从JS脚本上终于找到突破口。
 
实现步骤
   1. 一个DW
   因为要通过JS实现RichEdit应有的功能,那么在PB11下有什么对象可以与JS交互呢?到目前的BUILD6501版本为止,还唯一只有数据窗口对象能担当。所以我们要在窗口上有个DW作为与richEdit之间的一个“桥”,这个DW很简单:
 
上面这个DW是一个freeform-external类型的DW,只有1个字段:xhtml,用于与RichEdit之间传递数据。
  我的相法是: 按照问题的背景要求,必须实现2个功能,其一,可以程序自动控制(不需要键盘/鼠标)将指定的一段DHTML文本放到RichEdit控件中,从而可继续编辑;其二,可以随时取到当前RichEdit控件中已输入内容对于的DHTML文本。
  所以,就只能利用DW来传递DHTML。
  该DW中很重要的是需要在“XHTML”字段的HTML页面上,在“Append HTML Syntax”内写入圈中的JS代码,表示当DW内的这个字段(或所对应页面的HTML对象)发生属性改变时执行客户端的一个脚本函数fun_activertf。  看官可能问,为何不使用DW的itemchanged事件或Clicked事件等等? 是的,本人最先就是这么想的,但要知道,因为我们必须自动控制RichEdit中文本的外观显示和随时取到它的DHTML代码,所以所有交互式的事件都是不能派上用场的。
  2. 一个RichEdit控件
    很简单,直接拖一个到你的window上即可,名字可以任意取。
  3. 窗口
 
4. 代码
 
 window:open

if dw_active_rtf.rowcount()=0 then dw_active_rtf.insertrow(0) //初始化交换DW

 
第1个按钮:Clicked

string ls_xhtml
string ls_rteobj = 'rte_1'   //RichEdit控件的名称
string ls_dwobj = 'dw_active_rtf'   //交换DW的名称

ls_xhtml = '你需要设置的DHTML代码文本'
dw_active_rtf.setitem(1,'xhtml',ls_rteobj + '/' + ls_dwobj + '//' + ls_xhtml )

   
第2个按钮:Clicked

string ls_rteobj = 'rte_1'
string ls_dwobj = 'dw_active_rtf'

dw_active_rtf.setitem(1,'xhtml',ls_rteobj + '/' + ls_dwobj + '//' + mle_1.text )

mle_1 是个多行文本框,用于检验你在其中输入的DHTML代码,也可立即作用到RichEdit控件外观上。
 
第3个按钮:Clicked

string ls_xhtml
string ls_rteobj = 'rte_1'
string ls_dwobj = 'dw_active_rtf'
string ls_opcommand

ls_opcommand = ls_rteobj + '/' + ls_dwobj + '//' + 'GETHTML'
dw_active_rtf.setitem(1,'xhtml',ls_opcommand)

dw_active_rtf.setfocus()
ls_xhtml = dw_active_rtf.getitemstring(1,'xhtml')

 
第4个按钮:Clicked

string ls_xhtml
ls_xhtml = dw_active_rtf.getitemstring(1,'xhtml')
messagebox ('这是取到的RTF控件中的DHTML代码', ls_xhtml)

5. JS函数

fun_activertf

function fun_activertf ( sender )
{
    if(event.propertyName!='bIsInit') return;
//这句话好关键啊,研究了好几天才发现
    shtml = sender.value;
// 其中包含了RichEdit控件名和HTML代码,形如:rte_name/dw_name//HTML.....
    
//从中分离控件名和HTML代码部分
    ps1 = shtml.indexOf('/');
    ps2 = shtml.indexOf('//');
    rtf_name = shtml.substring(0,ps1);
    dw_name = shtml.substring(ps1+1,ps2);
    shtml = shtml.substring(ps2+2,shtml.length);
    instance_input_name = RTF_GetRTFAreaName(rtf_name);
//PB对RichEdit会自动产生,形如:inputWW_C_1_rte_1
    instance_editor_name = instance_input_name.substring(5,instance_input_name.length)+"editor";

    if(shtml=='GETHTML' && instance_input_name!='')
//表示是取RichEdit控件的内容
    {
        
//shtml = unescape ( document.getElementsByName(instancename)[0].value );
        shtml = document.getElementById(instance_editor_name).innerHTML
        var objdw = eval('obj'+dw_name);
// 得到dw对象目标
        objdw.SetItem(1,'xhtml',shtml);
        objdw.AcceptText();
        return 1;
    }
    if (rtf_name!='')
    {
        if(instance_input_name!='' && instance_editor_name!='')
        {
            document.getElementById(instance_editor_name).innerHTML = shtml;
            document.getElementsByName(instance_input_name)[0].value = escape(shtml);
        }
    }
}

JS 子函数:RTF_GetRTFAreaName

function RTF_GetRTFAreaName ( rtf_areaname )
{
    
//------由于PB对RichEdit控件在其HTML中生成的ID号的前缀是动态的,
    
//------所以需要知道现在网页内的这个对象的ID号实际是什么,以下程序就是查找它。
    var allRTFs = document.getElementsByTagName("input");
//PB生成一个隐含的INPUT域存放RichEdit控件的内容
    var itag = 0;
    for (var i=0; i<allRTFs.length; i++) {
     ortf = allRTFs[i];
     oname = ortf.name;
    
/* 隐含域的名称以'input'开头,加W是为了与生成的另一个以inputrtf开头的域区别
     形如: <input name="inputWW_1_C_rte_1" type="hidden" value="" />
                      <input name="inputrtfWW_1_C_rte_1" type="hidden" value="" />
     */

     ps1 = oname.lastIndexOf('inputW');
     ps2 = oname.lastIndexOf(rtf_areaname);
     if ( ps1==0 && ps2>0)
     {
        instancename = ortf.name ;
        itag = 1;
        break;
     }
    }
    if(itag==0)
    {
        
//alert('必须在PB窗口上放置一个名为'+rtf_areaname+'的RichEdit控件');
        return '';
    }
    else
    {
        return instancename;
    }
}

 
 
运行情况
 
1. 点击第1个按钮
 
2. 多行文本框中输入内容后 点击第2个按钮
 
3. 点击第3个按钮
 
4. 点击第4个按钮
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值