zoukankan      html  css  js  c++  java
  • sharepoint给ribbon添加按钮并提供截图功能

    给ribbon添加按钮是一项比较繁琐的工作,其中需要涉及大量sharepoint内部的东西:

    1.首先添加一个Empty Element文件,sharepoint默认的ribbon按钮都是在C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\GLOBAL\XML\CMDUI.XML定义的,我们可以参照系统的定义来做我们的自定义按钮,参照http://msdn.microsoft.com/en-us/library/ee537543(office.14).aspx。

    2.这里分两种情况,一种是直接给ribbon里添加没有的按钮,这种情况请参照网址:http://www.cnblogs.com/greeny/archive/2010/09/15/1827104.html,
    还有一种就是要修改原有的Button,这是我们现在的情况:想在Editing Tool的Insert项的Picture按钮里添加一个名叫FromCapture的按钮,
    这个Picture按钮其实是一个SplitButton按钮,下属的项目都是从属于这个按钮,
    所以要修改它就有别于上面网址提到的方法,这里我们需要把整个Picture SplitButton用我们自己的覆盖。

    3.我们只要新增一个Button,所以系统量来的两个Button都需要重用,用firebug分析后我们在CMDUI.XML里查找Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromAddress,把其所在的SplitButton复制下来:
            <SplitButton
                      Id="Ribbon.EditingTools.CPInsert.Media.Image"
                      Alt="$Resources:core,ButInsertImageAlt;"
                      Command="InsertImage"
                      CommandMenuOpen="InsertImageMenuOpen"
                      CommandMenuClose="InsertImageMenuClose"
                      Image16by16="/_layouts/$Resources:core,Language;/images/formatmap16x16.png" Image16by16Top="-176" Image16by16Left="-224"
                      Image32by32="/_layouts/$Resources:core,Language;/images/formatmap32x32.png" Image32by32Top="-192" Image32by32Left="-448"
                      LabelText="$Resources:core,cui_ButInsertImage;"
                      MenuAlt="$Resources:core,ButInsertImageMenuAlt;"
                      Sequence="10"
                      TemplateAlias="o1"
                      ToolTipTitle="$Resources:core,cui_ButInsertImage;"
                      ToolTipDescription="$Resources:core,cui_STT_ButInsertImage;">
                      <Menu Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu">
                        <MenuSection
                          Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image"
                          DisplayMode="Menu"
                          Sequence="10">
                          <Controls Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.Controls">
                            <Button
                              Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromComputer"
                              Sequence="10"
                              Alt="$Resources:core,ButFromComputerAlt;"
                              Command="InsertImageUpload"
                              LabelText="$Resources:core,ButFromComputer;"
                              ToolTipTitle="$Resources:core,cui_STT_title_ButInsertImageFromComputer;"
                              ToolTipDescription="$Resources:core,cui_STT_ButInsertImageFromComputer;"/>
                            <Button
                              Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromAddress"
                              Sequence="20"
                              Alt="$Resources:core,ButFromAddressAlt;"
                              Command="InsertImageWeb"
                              LabelText="$Resources:core,ButFromAddress;"
                              ToolTipTitle="$Resources:core,cui_STT_title_ButInsertImageFromAddress;"
                              ToolTipDescription="$Resources:core,cui_STT_ButInsertImageFromAddress;"/>
                          </Controls>
                        </MenuSection>
                      </Menu>
                    </SplitButton>

    4.编辑Elements.xml文件,在<Elements节点内写:
      <CustomAction Id="Ribbon.Image.Image.Edit.ReplacementButton" Location="CommandUI.Ribbon">
        <CommandUIExtension>
          <CommandUIDefinitions>
            <CommandUIDefinition Location="Ribbon.EditingTools.CPInsert.Media.Image">
            </CommandUIDefinition>
          </CommandUIDefinitions>
        </CommandUIExtension>
      </CustomAction>
    其中<CommandUIDefinition 结点的Location是指向要覆盖的控件,所以填写上述3.里SplitButton的ID,表示<CommandUIDefinition 里定义的位置是覆盖同名控件。
    这个CustomAction将完成我们工作:覆盖系统的SplitButton。

    5.在<CommandUIDefinition 结点内部输入第3点里的代码,更改控件ID,并添加一个我们自己的按钮代码,类似的:
           <SplitButton
                    Id="Ribbon.EditingTools.CPInsert.Media.Image.ReplacementButton"
                    Alt="$Resources:core,ButInsertImageAlt;"
                    Command="InsertImage"
                    CommandMenuOpen="InsertImageMenuOpen"
                    CommandMenuClose="InsertImageMenuClose"
                    Image16by16="/_layouts/$Resources:core,Language;/images/formatmap16x16.png" Image16by16Top="-176" Image16by16Left="-224"
                    Image32by32="/_layouts/$Resources:core,Language;/images/formatmap32x32.png" Image32by32Top="-192" Image32by32Left="-448"
                    LabelText="$Resources:core,cui_ButInsertImage;"
                    MenuAlt="$Resources:core,ButInsertImageMenuAlt;"
                    Sequence="10"
                    TemplateAlias="o1"
                    ToolTipTitle="$Resources:core,cui_ButInsertImage;"
                    ToolTipDescription="$Resources:core,cui_STT_ButInsertImage;">
                <Menu Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Replacement">
                  <MenuSection
                    Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.Replacement"
                    DisplayMode="Menu"
                    Sequence="10">
                    <Controls Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.Controls.Replacement">
                      <Button
                        Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromComputer.Replacement"
                        Sequence="10"
                        Alt="$Resources:core,ButFromComputerAlt;"
                        Command="InsertImageUpload"
                        LabelText="$Resources:core,ButFromComputer;"
                        ToolTipTitle="$Resources:core,cui_STT_title_ButInsertImageFromComputer;"
                        ToolTipDescription="$Resources:core,cui_STT_ButInsertImageFromComputer;"/>
                      <Button
                        Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromAddress.Replacement"
                        Sequence="20"
                        Alt="$Resources:core,ButFromAddressAlt;"
                        Command="InsertImageWeb"
                        LabelText="$Resources:core,ButFromAddress;"
                        ToolTipTitle="$Resources:core,cui_STT_title_ButInsertImageFromAddress;"
                        ToolTipDescription="$Resources:core,cui_STT_ButInsertImageFromAddress;"/>
                      <Button Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.CaptureButton"
                    Sequence="30"
                    Command="ScreenshotImageUpload"
                    Alt="Insert Picture From Screenshot"
                    LabelText="From Capture"
                    ToolTipTitle="Insert Picture From Screenshot"
                    ToolTipDescription="Use a useable URL to Screenshot a Picture to Upload."
                      />
                    </Controls>
                  </MenuSection>
                </Menu>
              </SplitButton>
    这里我们的控件ID都比以前多了.ReplacementButton和旧的区分。
    我们还加入了一个<Button Sequence=30表示他处于FromAdress下方,LabelText就是按钮显示的名称,这里特别要关注的属性是command属性,他表示这个按钮点击时会触发的命令。

    6.定义点击FromCapture按钮会触发的命令:在</CommandUIDefinnitions>后输入:
    <CommandUIHandlers>
            <CommandUIHandler
                Command="ScreenshotImageUpload"
                CommandAction="javascript:SP.SOD.executeOrDelayUntilScriptLoaded(initialize, 'SP.js');"></CommandUIHandler>
          </CommandUIHandlers>
    这句话表示我们定义了一个命令,名叫ScreenshotImageUpload,这个命令会触发一个方法,名叫:initialize,这是一个我自定义的js方法,等下将会有这个方法的详细说明。
    这里我解析下为说明CommandAction里要这么写,如果按钮的功能较简单,不会用到大量的js,可以直接在CommandAction=""里写入js方法,比如CommandAction="javascript:alert('Hello world!')",但是考虑到我们的功能比较复杂,需要编写大量的js,我们就可以直接写
    CommandAction="javascript:方法名"这个方法名需要引用一个外部的javascript文件,这就代表我们需要引用这个文件,所以我们在<Element里还需定义一个<CustomAction来引用这个外部javascript文件,具体例如:
    <CustomAction Id="fromScreenshotJS"
                    Location="ScriptLink"
                    ScriptSrc="/_layouts/ScreenshotProject/scripts/FromScreenshot.js"></CustomAction>
    这里引用了FromScreenshot.js文件来调用这个点击按钮要触发的方法。
    我还要解析下SP.SOD.executeOrDelayUntilScriptLoaded(initialize, 'SP.js');这句话的意思,他表示,initialize这个方法在网站下载完sp.js文件后才会被执行,为什么要这样做呢?因为这里我们的功能需要引用网站的站点名称SP.ClientContext.get_current().get_site(),而要获得这个名称就必须等网站下载完SP.js才行,所以这里进行了相应处理。
    这个Elements.xml文件现在看起来像:
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <CustomAction
     Id="Ribbon.Image.Image.Edit.ReplacementButton"
     Location="CommandUI.Ribbon">
        <CommandUIExtension>
          <CommandUIDefinitions>
            <CommandUIDefinition Location="Ribbon.EditingTools.CPInsert.Media.Image">
              <SplitButton
                    Id="Ribbon.EditingTools.CPInsert.Media.Image.ReplacementButton"
                    Alt="$Resources:core,ButInsertImageAlt;"
                    Command="InsertImage"
                    CommandMenuOpen="InsertImageMenuOpen"
                    CommandMenuClose="InsertImageMenuClose"
                    Image16by16="/_layouts/$Resources:core,Language;/images/formatmap16x16.png" Image16by16Top="-176" Image16by16Left="-224"
                    Image32by32="/_layouts/$Resources:core,Language;/images/formatmap32x32.png" Image32by32Top="-192" Image32by32Left="-448"
                    LabelText="$Resources:core,cui_ButInsertImage;"
                    MenuAlt="$Resources:core,ButInsertImageMenuAlt;"
                    Sequence="10"
                    TemplateAlias="o1"
                    ToolTipTitle="$Resources:core,cui_ButInsertImage;"
                    ToolTipDescription="$Resources:core,cui_STT_ButInsertImage;">
                <Menu Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Replacement">
                  <MenuSection
                    Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.Replacement"
                    DisplayMode="Menu"
                    Sequence="10">
                    <Controls Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.Controls.Replacement">
                      <Button
                        Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromComputer.Replacement"
                        Sequence="10"
                        Alt="$Resources:core,ButFromComputerAlt;"
                        Command="InsertImageUpload"
                        LabelText="$Resources:core,ButFromComputer;"
                        ToolTipTitle="$Resources:core,cui_STT_title_ButInsertImageFromComputer;"
                        ToolTipDescription="$Resources:core,cui_STT_ButInsertImageFromComputer;"/>
                      <Button
                        Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromAddress.Replacement"
                        Sequence="20"
                        Alt="$Resources:core,ButFromAddressAlt;"
                        Command="InsertImageWeb"
                        LabelText="$Resources:core,ButFromAddress;"
                        ToolTipTitle="$Resources:core,cui_STT_title_ButInsertImageFromAddress;"
                        ToolTipDescription="$Resources:core,cui_STT_ButInsertImageFromAddress;"/>
                      <Button Id="Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.ScreenshotButton"
                    Sequence="30"
                    Command="ScreenshotImageUpload"
                    Alt="Insert Picture From Screenshot"
                    LabelText="From Screenshot"
                    ToolTipTitle="Insert Picture From Screenshot"
                    ToolTipDescription="Use a useable URL to Screenshot a Picture to Upload."
                      />
                    </Controls>
                  </MenuSection>
                </Menu>
              </SplitButton>
            </CommandUIDefinition>
          </CommandUIDefinitions>
          <CommandUIHandlers>
            <CommandUIHandler
                Command="ScreenshotImageUpload"
                CommandAction="javascript:SP.SOD.executeOrDelayUntilScriptLoaded(initialize, 'SP.js');"></CommandUIHandler>
          </CommandUIHandlers>
        </CommandUIExtension>
      </CustomAction>
      <CustomAction Id="fromScreenshotJS"
                    Location="ScriptLink"
                    ScriptSrc="/_layouts/ScreenshotProject/scripts/FromScreenshot.js"></CustomAction>
    </Elements>
    这时如果我们部署已经可以看到按钮的效果了,但是点击没反应,因为我们还没编写initialize方法。

    7.右击自动生成项目的Layouts文件夹,在Layouts文件夹下新建scripts文件夹,在scripts文件夹里新建FromScreenshot.js文件,编辑这个文件:
    function ScreenshotCallback(dialogResult, returnValue) {

        if (dialogResult == "1") {
            RTE.Cursor.get_range().deleteContent();

            var rng = RTE.Cursor.get_range().$3_0;

            var doc = rng.ownerDocument;
            var imgContent = doc.createElement("img");

            imgContent.setAttribute("src", returnValue);

            SP.UI.UIUtility.insertAfter(imgContent, rng);
        }
        else
        { }
    }

    var ctx;
    var site;
    var screenshotUrl = 'http://win2008web:2013/_layouts/ScreenshotProject/ScreenShotion.aspx';
    function initialize() {
        ctx = new SP.ClientContext.get_current();
        site = ctx.get_site();
        ctx.load(site);
        ctx.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
    }

    function InsertFromScreenshot() {

        var options = {
            url: screenshotUrl,
            tite: 'Screenshot',
            allowMaximize: true,
            showClose: true,
            900,
            height: 600,
            dialogReturnValueCallback: ScreenshotCallback
        };

        SP.UI.ModalDialog.showModalDialog(options);
    }

    function onQuerySucceeded(sender, args) {
        screenshotUrl = site.get_url() + '/_layouts/ScreenshotProject/ScreenShotion.aspx' + '?Url=' + window.location;
        InsertFromScreenshot();
    }

    function onQueryFailed(sender, args) {
        alert('Request filed. Janq ' + args.get_message() + '\n' + args.get_stackTrace());
    }
    这段代码核心思想是:初始化成功后,调用InsertFromScreenshot方法,打开一个模态窗口,这个窗口指向一个叫ScreenShotion.aspx的页面,当这个页面回调时,调用ScreenshotCallback方法,
    if (dialogResult == "1") {
            RTE.Cursor.get_range().deleteContent();

            var rng = RTE.Cursor.get_range().$3_0;

            var doc = rng.ownerDocument;
            var imgContent = doc.createElement("img");

            imgContent.setAttribute("src", returnValue);

            SP.UI.UIUtility.insertAfter(imgContent, rng);
        }
        else
        { }
    dialogResult是回调参数,当回调参数是“1”时,在编辑器目前鼠标停留处插入returnValue参数。
    至此,我们的按钮已经完成,部署后点击按钮,已经可以跳出模态窗口,下面我们来编写这个叫ScreenShotion.aspx的Application页面。

    下面涉及的就是于截图功能相关的内容:
    8.在Layouts的项目文件夹下新建一个ApplicationPage名叫:ScreenShotion.aspx,参考项目编写这个ApplicationPage
    最重要的是截图完成后要做回调:
    this.Page.Response.Clear();
    this.Page.Response.Write("<script>window.frameElement.commonModalDialogClose(1,'" + destUrl + "')</script>");//SP.UI.DialogResult.OK
    this.Page.Response.End();

    http://odyniec.net/projects/imgareaselect/

  • 相关阅读:
    angularIO 路由守卫
    vue-property-decorator用法
    windows mysql 忘记密码
    OSPF 做负载均衡
    NLB 部署网络负载平衡
    flexible.js 布局详解
    python setup.py 构建
    python Zope.interface安装使用
    lnmp菜单
    linux下的文件删除原理
  • 原文地址:https://www.cnblogs.com/lucky_dai/p/1921716.html
Copyright © 2011-2022 走看看