ASP.NET HTML Editor - Knowledge Base

« Back to Knowledge Base list

Find & Replace

Q:

I need to implement "Find & Replace" feature with obout HTML Editor.

A:

Here is an example how to do it.
This example works with HTML Editor version 1.10.414.1 and later.

<ed:Editor PathPrefix="Editor_data/" id="editor" runat="server"/>
Find: <asp:TextBox runat="server" id="toFind" Text=""/>
Replace with: <asp:TextBox runat="server" id="replaceWith" Text=""/>
<
asp:Button runat="server" Text="Find& Replace" onclientclick="return tryFR();" />
...
<script type="text/JavaScript">
function
tryFR() {
  var editor = oboutGetEditorByClientId("<%= editor.ClientID %>");
  var toFind = document.getElementById("<%= toFind.ClientID %>").value.replace(/\s/g,"");
  var replaceWith = document.getElementById("<%= replaceWith.ClientID %>").value.replace(/\s/g,"");

  // fields should not be empty
  if(toFind.length > 0 && replaceWith.length > 0) {
    findAndReplace(editor, toFind, replaceWith, true);
  }
  return false;
}

function findAndReplace(editor, toFind, replaceWith, ignoreCase) {
  // select all if no selection
  if (!editor.TextSelected()) {
    editor.selectAll();
  }
  // get selected text nodes
  var dirtyNodes = editor.SelectedTextNodes();
  editor.selectNone();
  // collect 'good' text nodes
  var nodes = [];
  var temp = editor.getDocument().createElement("div");
  for(var i=0; i < dirtyNodes.length; i++) {
    temp.innerHTML = dirtyNodes[i].data;
    if (temp.innerHTML.replace(/\&nbsp;/g,"").replace(/\s/g,"").length > 0) {
      nodes.push(dirtyNodes[i]);
    }
  }
  delete temp;

  editor.SaveContent(); // for 'undo' operation
  // find & replace in all text nodes
  var found = false;
  for(var i=0; i < nodes.length; i++) {
    var text = (ignoreCase)?nodes[i].data.toLowerCase():nodes[i].data;
    var seek = (ignoreCase)?toFind.toLowerCase():toFind;
    var confirmation = true;
    var from =0;

    // find & replace in current text node
    var index;
    while((index = text.substr(from).indexOf(seek)) >= 0) {
      // highlight found text
      var tempNodes = highlight(editor, nodes[i], from+index, seek.length);
      var skip = seek.length;
      confirmation = confirm("Replace the found text?");
      if(confirmation) {
        skip = replaceWith.length;
        // change the text node data
        var data = nodes[i].data;
        data = data.substr(0,from+index)+replaceWith+data.substr(from+index+seek.length);
        nodes[i].data = data;
        text = (ignoreCase)?data.toLowerCase():data;
      }
      from += index+skip;
      // unhighlight found text
      unhighlight(editor, nodes[i], tempNodes, from);
      found = true;
      if(!confirmation) { // stop Find & Replace on cancel
        break;
      }
    }
    if(!confirmation) { // stop Find & Replace on cancel
      break;
    }
  }
  if(!found) {
    alert("Text not found");
  }
}

function highlight(editor, textNode, from, length) {
  var range = editor.getRange() ;
  if(HTMLEditor.is_ie) { // IE
    var tempNodes = [];
    var nodeToSelect = textNode;
    if(!(from == 0 && (from+length) == textNode.data.length)) {
      var data = textNode.data;
      var node1 = null, node3 = null;
      if(from >0) {
         node1 = editor.getDocument().createTextNode(data.substr(0,from))
      }
      nodeToSelect = editor.getDocument().createTextNode(data.substr(from,length))
      if((from+length) < textNode.data.length) {
        node3 = editor.getDocument().createTextNode(data.substr(from+length))
      }
      tempNodes.push(nodeToSelect);
      if(node1) {
        tempNodes.push(node1);
        textNode.parentNode.insertBefore(node1, textNode);
      }
      textNode.parentNode.insertBefore(nodeToSelect, textNode);
      if(node3) {
        tempNodes.push(node3);
        textNode.parentNode.insertBefore(node3, textNode);
      }
      textNode.parentNode.removeChild(textNode);
    }
    var span = editor.getDocument().createElement("SPAN");
    nodeToSelect.parentNode.insertBefore(span, nodeToSelect);
    span.appendChild(nodeToSelect);
    range.moveToElementText(span);
    range.select();
    return tempNodes;
  } else {
    var sel = editor._getSelection();
    editor._removeAllRanges(sel);
    range.setStart(textNode, from);
    range.setEnd  (textNode, from+length);
    editor._selectRange(sel,range);
    return null;
  }
}

function unhighlight(editor, textNode, tempNodes, from) {
  var range = editor.getRange() ;
  if(HTMLEditor.is_ie) { // IE
    var span = ((tempNodes.length==0)?textNode:tempNodes[0]).parentNode;
    span.parentNode.insertBefore(textNode,span);
    for(var i=0; i < tempNodes.length; i++) {
      tempNodes[i].parentNode.removeChild(tempNodes[i]);
    }
    range.moveToElementText(span);
    var fromTheEnd = textNode.length-from;
    if(fromTheEnd > 0) { // cursor should be set inside the text node
      range.move("character", -fromTheEnd);
    }
    range.select();
    span.parentNode.removeChild(span);
  } else {
    var sel = editor._getSelection();
    editor._removeAllRanges(sel);
    range.setStart(textNode, from);
    range.setEnd(textNode, from);
    editor._selectRange(sel,range);
 }
}
</script>
obout.com
obout.com Home
News
HTML Editor Home
HTML Editor Home
Why the best?
Download
Site Map
Examples - 80
Appearance - 10
Full button set
Lite button set
Custom button set
Design-mode textbox
How to fit into small space
Page maker
Default font
Initially without toolbar
Preview mode
"Read only" mode New
Content - 16
Read-only and custom tags
Shadow for Image
External image gallery
Upload images
Copy/paste formatting
Preview Document appearance
Keys used for editing
.NET validation
Documents Generator
Upload documents
Convert to PDF
FullHTML
Editor and database
Spell Checker - 3
Spell checking
Spell Checker dictionaries
Several dictionaries
Localization - 2
Localization
RTL support
Integration - 9
Inside Flyout
Inside Grid
Inside Window
With Color PickerNew
Google AJAX Language API New
Inside AJAX Page
Inside CallbackPanel
MultiView
Wizard
ASP.NET AJAX ControlToolkit - 5
Collapsible panel
Tabs
Editor in each TabPanel New
Timer
Modal popup
Server-Side API - 13
Content counters
Plain text length control
Show plain text
Enable editor on focus
Set caret position on load
Add CSS files New
Hide HTML Editor until needed
FixedToolBar
CSS file for quick format
Set HTML view on load
Enable browse button for images
Enable browse button for URLs
Disable Wait message New
Server-Side Events - 5
ClickSubmit event
ClickCancel event
ContentChanged event
CallbackContent
ClientCancel
Client-Side API - 10
Working with selected text
Set design/HTML view on load
Show/hide HTML Editor
Get/set content
Surround HTML
Insert HTML
Style selected content
Exec command
Query command
'Not Set' in dropdowns New
Customize - 17
Custom editor toolbar in VS
Custom fonts
Custom font sizes
How to add icons
Custom Popup Windows
Custom Buttons
Custom Context Menu
Popup Properties Disabling
Default Table Properties
Custom toggle button
Custom select button
Textarea popup
Custom 'Quote' button New
Show/hide submit button
Show/hide Design/HTML view
Show/hide quick format panel
Width & Height
Knowledge Base - 1
Knowledge Base
Documentation - 23
Server side
HTML Editor properties & events
HTML Editor inner properties
Custom toolbar
Custom fonts
Custom font sizes
Custom Context Menu
Dictionaries for spell checker
Hot keys definition
Disabling Context Menu items
Additional CSS files New
Client side
Main functions and interfaces
Custom Context Menu support
Custom Popup Window support
Top toolbar buttons' methods
State functions
Suppress Context Menu
Spelling dictionary
Dictionary structure
Affix rules
Phonetic rules
Generate phonetic code
How to add new word
Supported browsers
ChangeLog
Tutorials - 6
Using the correct path
Autosave implementation
Full custom buttons set
Editor_data for several sites
Use with database
Template XML file use New