5

ユーザーが入力したテキストと一緒に送信される非表示のテーブルが事前に入力された CKEDITOR フォームがあります。これは正常に機能しますが、ユーザーがバックスペースを何度も押して、非表示のテーブルを削除することがあります。

ckeditor textarea 内のこの隠しテーブルの編集をブロックする方法はありますか? したがって、ユーザーがバックスペースを押しても、非表示のテーブルは影響を受けずに残ります。

CKEDITOR インスタンスの準備が整うとすぐに、このソース (以下) が CkEditor Textarea 内に配置され (setData() 属性を使用)、ユーザーには返された<p></p>値のみが表示されます。この場合、その<p>I really think I can do this!</p>. それは彼のプロフィールの説明であり、彼はそれを保持して編集することができます. 残りは非表示で、フォームが送信されたときに電子メールでのみ表示されます。一番上にあるのは奇妙です<p></p>が、ユーザーがバックスペースを数回押すと、テーブルが削除され、送信されません。

    <span id="messageTemplate1" class="message">

<p>I really think I can do this!</p>

<table class="hide" style="font-size: 12px;">
    <tbody>
        <tr class="hide">
            <td>
            Application sent by <strong><a href="http://www.globalcastingcenter.com/talent/jack-bolton">Matt Faro</a></strong> for Audition: <a href="http://www.globalcastingcenter.com:80/CustomContentRetrieve.aspx?ID=4185493">Actors Needed</a>
            </td>
        </tr>
        <tr class="hide">
            <td>
            Reply to applicant directly: mantas@mantas.co or visit full profile: http://www.globalcastingcenter.com/talent/jack-bolton
            </td>
        </tr>
    </tbody>
</table>
<table class="hide" style="font-size: 12px;">
    <tbody>
        <tr class="hide">
            <td><strong>Short Profile Summary:</strong></td>
        </tr>
    </tbody>
</table>
<table class="hide" style="font-size: 12px;">
    <tbody>
        <tr class="hide">
            <td>
            <a href="http://www.globalcastingcenter.com/talent/jack-bolton"><img alt="" src="http://globalcastingcenter.com/talent_images/4164035_258551_foto.png?Action=thumbnail&amp;Width=144&amp;Height=215" /></a>
            </td>
        </tr>
    </tbody>
</table>
<table style="font-size: 12px;" class="hide">
    <tbody>
        <tr class="hide">
            <td><strong>Areas:</strong></td>
            <td>Actor,Extra</td>
        </tr>
        <tr class="hide">
            <td><strong>Country:</strong></td>
            <td>WORLDWIDE,Any</td>
        </tr>
        <tr class="hide">
            <td><strong>Age:</strong></td>
            <td>26</td>
        </tr>
    </tbody>
</table>
</span>

プラグインをロードすると、CKeditor ボックスが消えます。テスト ページhttp://gcc-july.themantas.co.uk/auditions/actors-neededで「適用」を押してください。まずログインして、メッセージ ボックスにアクセスできるようにしてください。名前: tiknius@gmail.com PSSW: テスト

私の設定ファイル:

CKEDITOR.editorConfig = function( config )
{
    config.toolbar = 'MyToolbar';

    config.toolbar_MyToolbar =
    [

        { name: 'clipboard', items : [ 'Undo','Redo' ] },           
        { name: 'styles', items : ['FontSize' ] },
        { name: 'basicstyles', items : [ 'Bold','Italic'] },
        { name: 'paragraph', items : ['Outdent','Indent' ] },

    ];

    config.removePlugins = 'contextmenu';
    config.forcePasteAsPlainText = true;   
    config.pasteFromWordRemoveFontStyles = true;
    config.pasteFromWordRemoveStyles = true;
    config.extraPlugins = 'cwjdsjcsconfineselection';
    config.startupShowBorders = false;
    config.disableObjectResizing = true;

};

これは、プラグインを無効にすると、ボックスがどのように見えるかです: http://screencast.com/t/Kc2bIOU8md2

提案された HTML 構造を使用します。

4

3 に答える 3

4

それを機能させるには、少しいじる必要がありました。プラグイン コードに多くのドキュメントを追加しました。それを読んだ後に質問がある場合は、私に知らせてください。

コンテンツ ブロックとプラグイン コード ブロックの更新版を含めます。


これが更新されたコンテンツ ブロックです。<span>タグでラップするとうまくいかなかったので、表でラップしました。

データ セルの周囲に表示される境界線とサイズ変更のアウトラインが気に入らない場合は、次の設定を構成に追加します。
config.startupShowBorders = false;
config.disableObjectResizing = true;

いくつかの注意事項:開始コンテンツが必要になる前に
<td>が必要です。これにより、ユーザーは「Ctrl A」を使用して非表示のテーブルを削除できるすべてのものを選択できなくなります。

<p>この構造ではファンキーに振る舞うので、開始コンテンツからタグを削除しました。

非表示の<td>テーブルを保持する には&nbsp;文字があり、ユーザーが「Ctrl A」を使用して非表示のテーブルを削除できるすべてのものを選択できないようにします。カーソルの右側にあるものをすべて削除すると、カーソルが失われますが、コンテンツをクリックすると、編集を再開できます。

このcontenteditable="false"属性は CkEditor によって使用され、必要とされますが、すべての機能を実行するわけではありません。プラグインをアクティブ化せずに新しい HTML を試して、プラグイン自体の効果を確認できます。

プラグイン コードには、使用したクラスと ID に関するメモがあります。

<!-- Begin Wrapper Table that Replaces <span> element -->
<table id="messageTemplate1" class="message cwjdsjcs_editable">
    <tbody>
        <tr>
            <td class="cwjdsjcs_not_editable" contenteditable="false">
            </td>
            <td id="cwjdsjcs_editable_id">
                I really think I can do this!
            </td>
        </tr>

        <tr class="cwjdsjcs_not_editable" contenteditable="false">
            <td colspan="2">
                &nbsp;

                <!-- Begin Original Content -->
                <table class="hide" style="font-size: 12px; display:none;">
                    <tbody>
                        <tr class="hide">
                            <td>
                            Application sent by <strong><a href="http://www.globalcastingcenter.com/talent/jack-bolton">Matt Faro</a></strong> for Audition: <a href="http://www.globalcastingcenter.com:80/CustomContentRetrieve.aspx?ID=4185493">Actors Needed</a>
                            </td>
                        </tr>
                        <tr class="hide">
                            <td>
                            Reply to applicant directly: mantas@mantas.co or visit full profile: http://www.globalcastingcenter.com/talent/jack-bolton
                            </td>
                        </tr>
                    </tbody>
                </table>
                <table class="hide" style="font-size: 12px; display:none;">
                    <tbody>
                        <tr class="hide">
                            <td><strong>Short Profile Summary:</strong></td>
                        </tr>
                    </tbody>
                </table>
                <table class="hide" style="font-size: 12px; display:none;">
                    <tbody>
                        <tr class="hide">
                            <td>
                            <a href="http://www.globalcastingcenter.com/talent/jack-bolton"><img alt="" src="http://globalcastingcenter.com/talent_images/4164035_258551_foto.png?Action=thumbnail&amp;Width=144&amp;Height=215" /></a>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <table style="font-size: 12px; display:none;" class="hide">
                    <tbody>
                        <tr class="hide">
                            <td><strong>Areas:</strong></td>
                            <td>Actor,Extra</td>
                        </tr>
                        <tr class="hide">
                            <td><strong>Country:</strong></td>
                            <td>WORLDWIDE,Any</td>
                        </tr>
                        <tr class="hide">
                            <td><strong>Age:</strong></td>
                            <td>26</td>
                        </tr>
                    </tbody>
                </table>
                <!-- End Original Content -->

            </td>
        </tr>
    </tbody>
</table>
<!-- End Wrapper Table that Replaces <span> element -->

これがプラグイン コードです。「cwjdsjcsconfineselection」と呼ばれます。

プラグインを追加するには:
plugins ディレクトリに「cwjdsjcsconfineselection」というフォルダーを作成しますckeditor/plugins/
。そのディレクトリに「plugins.js」というファイルを作成し、以下のコードをそのファイルに貼り付けます。私の間違い: ファイルの名前は plugin(s).js ではなく、plugin.js です。

追加のプラグインが既にある場合は、「cwjdsjcsconfineselection」を extraPlugins 構成設定に追加します。そうでない場合は、この設定を構成に追加します。
config.extraPlugins = 'cwjdsjcsconfineselection';

次回エディターをロードしたときに、プラグインが機能するはずです。

私の状況では、ユーザーが編集不可の領域をクリックすると、カーソルが前の選択に戻った理由を説明するダイアログ ボックスが表示されます。それはあなたの使い方には必要ないようですので、コメントアウトしました。

/*
  Plugin that prevents editing of elements with the "non-editable" class as well as elements outside of blocks with "editable" class.
*/

//* **************************  NOTES  ***************************  NOTES  ****************************
/*
  The "lastSelectedElement" variable is used to store the last element selected.

  This plugin uses the "elementspath" plugin which shows all elements in the DOM
  parent tree relative to the current selection in the editing area.

  When the selection changes, "elementsPathUpdate" is fired,
  we key on this and loop through the elements in the tree checking the classes assigned to each element.

  Three outcomes are possible.

  1) The non-editable class is found:
  Looping stops, the current action is cancelled and the cursor is moved to the previous selection.
  The "selectionChange" hook is fired to set the reverted selection throughout the instance.

  2) The editable class is found during looping, the "in_editable_area" flag is set to true.

  3) Neither the editable or the non-editable classes are found (user clicked outside your main container).
  The "in_editable_area" flag remains set to false.

  If the "in_editable_area" flag is false, the current action is cancelled and the cursor is moved to the previous location.
  The "selectionChange" hook is fired to set the reverted selection throughout the instance.

  If the "in_editable_area" flag is true,
  the "lastSelectedElement" is updated to the currently selected element and the plugin returns true.

---------------
  If you don't want the elements path to be displayed at the bottom of the editor window,
  you can hide it with CSS rather than disabling the "elementspath" plugin.

  The elementspath plugin creates and is left active because we are keying on changes to the path in our plugin.
  #cke_path_content
  {
    visibility: hidden !important;
  }

---------------
  CSS Classes and ID that the plugin keys on. Use defaults or update variables to use your preferred classes and ID:

  var starting_element_id = ID of known editable element that always occurs in the instance.
  Don't use elements like <table>, <tr>, <br /> that don't contain HTML text.
  Default value = cwjdsjcs_editable_id

  var editable_class = class of editable containers.
  Should be applied to all top level elements that contain editable elements.
  Default = cwjdsjcs_editable

  var non_editable_class = class of non-editable elements within editable containers
  Apply to elements where all child elements are non-editable.
  Default = cwjdsjcs_not_editable

*/

//* **************************  END NOTES  ***************************  END NOTES  ****************************


// Register the plugin with the editor.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.plugins.html
CKEDITOR.plugins.add( 'cwjdsjcsconfineselection',
{
  requires : [ 'elementspath' ],

  // The plugin initialization logic goes inside this method.
  // http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.pluginDefinition.html#init
  init: function( editor )
  {
    editor.on( 'instanceReady', function( instance_ready_data )
    {
      // Create variable that will hold the last allowed selection (for use when a non-editable selection is made)
      var lastSelectedElement;
      editor.cwjdsjcs_just_updated = false;

      // This section starts things off right by selecting a known editable element.
      // *** Enter the ID of the element that should have initial focus *** IMPORTANT *** IMPORTANT ***
      var starting_element_id = "cwjdsjcs_editable_id";

      var resInitialRange = new CKEDITOR.dom.range( editor.document );

      resInitialRange.selectNodeContents( editor.document.getById( starting_element_id ) );
      resInitialRange.collapse();

      var selectionObject = new CKEDITOR.dom.selection( editor.document );

      editor.document.focus();
      selectionObject.selectRanges( [ resInitialRange ] );

      var sel = editor.getSelection();
      var firstElement = sel.getStartElement();
      var currentPath = new CKEDITOR.dom.elementPath( firstElement );

      // Set path for known editable element, fire "selectionChange" hook to update selection throughout instance.
      editor._.selectionPreviousPath = currentPath;
      editor.fire( 'selectionChange', { selection : sel, path : currentPath, element : firstElement } );
    }); // *** END - editor.on( 'instanceReady', function( e )


    // When a new element is selected by the user, check if it's ok for them to edit it,
    // if not move cursor back to last know editable selection
    editor.on( 'elementsPathUpdate', function( resPath )
    {
      // When we fire the "selectionChange" hook at the end of this code block, the "elementsPathUpdate" hook fires.
      // No need to check because we just updated the selection, so bypass processing.
      if( editor.cwjdsjcs_just_updated == true )
      {
        editor.cwjdsjcs_just_updated = false;
        return true;
      }

      var elementsList = editor._.elementsPath.list;
      var in_editable_area = false;
      var non_editable_class = "cwjdsjcs_not_editable";
      var editable_class = "cwjdsjcs_editable";

      for(var w=0;w<elementsList.length;w++){
        var currentElement = elementsList[w];

        // Sometimes a non content element is selected, catch them and return selection to editable area.
        if(w == 0)
        {
          // Could change to switch.
          if( currentElement.getName() == "tbody" )
          {
            in_editable_area = false;
            break;
          }

          if( currentElement.getName() == "tr" )
          {
            in_editable_area = false;
            break;
          }
        }

        // If selection is inside a non-editable element, break from loop and reset selection.
        if( currentElement.hasClass(non_editable_class) )
        {
          in_editable_area = false;
          break;
        }

        if( currentElement.hasClass(editable_class) ) {
          in_editable_area = true;
        }
        console.log(currentElement);
        console.log(currentElement.getName());
      }

      // if selection is within an editable element, exit the plugin, otherwise reset selection.
      if( in_editable_area ) {
        lastSelectedElement = elementsList[0];
        return true;
      }

      var resRange = new CKEDITOR.dom.range( editor.document );

      resRange.selectNodeContents( lastSelectedElement );
      resRange.collapse();
      editor.getSelection().selectRanges( [ resRange ] );
      resRange.endContainer.$.scrollIntoView();

      // Open dialog window:
      // It tells user they selected a non-editable area and cursor has been returned to previous selection
//      currentEditorName = editor.name;
//      openResDefaultDialog(currentEditorName);

      try
      {
        var sel = editor.getSelection();
        var firstElement = sel.getStartElement();
        var currentPath = new CKEDITOR.dom.elementPath( firstElement );
        editor.cwjdsjcs_just_updated = true;

        editor._.selectionPreviousPath = currentPath;
        editor.fire( 'selectionChange', { selection : sel, path : currentPath, element : firstElement } );

      }
      catch (e)
      {}
    });
  } // *** END - init: function( editor )
}); // ************************************************************************************* END - CKEDITOR.plugins.add

プラグインがロードされていることをテストするには、インスタンスの準備完了トリガーの後にアラートを追加します。

    editor.on( 'instanceReady', function( instance_ready_data )
    {
      alert("instanceReady");

選択が変更されたときにプラグインがトリガーされていることをテストするには、elementsPathUpdate トリガーの後にアラートを追加します。

    editor.on( 'elementsPathUpdate', function( resPath )
    {
      alert("elementsPathUpdate");
于 2012-07-06T22:40:01.293 に答える
2

これはクローズされて解決されていることを認識していますが、次のオプションがあります。

ユーザーがフォームを送信した後、または CKE コンテンツが使用された直後にテーブルを追加します。非表示のテーブルを追加しないでください。ただし、ユーザーが「送信」をクリックしたときに、投稿されているものに追加してください。または、後で編集する必要がある場合は、エディターに挿入する前に削除し、投稿する前にジャスト イン タイムでもう一度追加します。アクションはCKEの外部で発生するため、CKEコアのハッキングやプラグインは必要ありません。

于 2012-09-12T12:28:45.057 に答える