5

I'm trying to slightly modify this so that it prompts for the text to search for, followed by the text to replace with, and when all done processing, show a dialog box letting me know it's done.

I plan to use it on a phpmyadmin database edit page that'll have any number of textboxes filled with text (which is what I need it to search and replace in). Also, the text to search for and replace may or may not be multi-line, so I've added the 'm' param in the regex, and also, since I'll be doing searches/replaces that may contain html, they'll often have quotes/double quotes in them. ex:

Search for:

<img height="76" width="92" src="http://www.gifs.net/Animation11/Hobbies_and_Entertainment/Games_and_Gambling/Slot_machine.gif" /></div>
<div class="rtecenter"> <strong><em><font color="#ff0000">Vegas Baby!<br />
</font></em></strong></div>

and maybe replace with nothing (just to erase all that code), or some other html. So far this is the bookmarklet I've come up with, (javascript, and especially bookmarklets aren't something I mess with often) however, it does nothing as far as finding/replacing, although it does do the prompting correctly.

javascript:var%20scrEl=document.createElement('script');scrEl.setAttribute('language','javascript');scrEl.setAttribute('type','text/javascript');scrEl.setAttribute('src','http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js');function%20htmlreplace(a,b,element){if(!element)element=document.body;var%20nodes=$(element).contents().each(function(){if(this.nodeType==Node.TEXT_NODE){var%20r=new%20RegExp(a,'gim');this.textContent=this.textContent.replace(r,b);}else{htmlreplace(a,b,this);alert('Done%20processing.');}});}htmlreplace(prompt('Text%20to%20find:',''),prompt('Replace%20with:',''));

Anyone have any ideas?

Community
  • 1
  • 1
J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94

3 Answers3

5

Here is the most direct conversion of the original function to search/replace textarea and text inputs instead of HTML. I also added 'm' to regex and added alert('done') at end. However, I think that using 'm' may not solve your problem perfectly, but I may be wrong.

function htmlreplace(a, b, element) {
    if (!element) element = document.body;    
    var nodes = element.childNodes;
    for (var n=0; n<nodes.length; n++) {
        if ( nodes[n].type && (nodes[n].type.toLowerCase() == 'textarea' || nodes[n].type.toLowerCase() == 'text') ) {
            var r = new RegExp(a, 'gim');
            nodes[n].value = nodes[n].value.replace(r, b);
        } else {
            htmlreplace(a, b, nodes[n]);
        }
    }
}

htmlreplace(prompt('find'), prompt('replace'));
alert('done');

Here it is as a bookmarklet.

javascript:function htmlreplace(a,b,element){if(!element)element=document.body;var nodes=element.childNodes;for(var n=0;n<nodes.length;n++){if(nodes[n].type&&(nodes[n].type.toLowerCase()=='textarea'||nodes[n].type.toLowerCase()=='text')){var r=new RegExp(a,'gim');nodes[n].value=nodes[n].value.replace(r,b)}else{htmlreplace(a,b,nodes[n])}}}htmlreplace(prompt('find'),prompt('replace'));alert('done');
DG.
  • 3,417
  • 2
  • 23
  • 28
  • Thanks, I gave it a try and nothing happened though. (Prompts, but No replacement at all). – J. Scott Elblein Sep 20 '12 at 22:17
  • I just retested it in Firefox on a web page with a textarea and a text input. It works. If it doesn't work for you, there is some detail you have not explained. – DG. Sep 21 '12 at 18:30
  • I condensed your code into a bookmarklet (removed spaces, added javascript:, etc.): Here's a screencast of it not working. [link](http://screencast.com/t/imfNn01s) In it I first show the bookmarklet code, then show an attempt at doing a find/replace using a dash (-) as the Find string and the letter "T" as the Replacement string while the line is highlighted. The second time I do the same except the line isn't highlighted, and I use an asterisk. Am I doing something wrong? This was in Firefox 15.01. – J. Scott Elblein Sep 23 '12 at 03:27
  • Here's the actual code I used: `javascript:function%20htmlreplace(a,b,element){if(!element)element=document.body;varnodes=element.childNodes;for(varn=0;n – J. Scott Elblein Sep 23 '12 at 03:29
  • 1
    You made an error compressing the code. I have updated my answer with the code in bookmarklet form. For the future, I recommend this site: http://javascriptcompressor.com/ – DG. Sep 23 '12 at 14:45
2

This worked for me:

javascript:function%20htmlreplace(a,b,element){if(!element)element=document.body;var%20nodes=element.childNodes;for(var%20n=0;n<nodes.length;n++){if(nodes[n].nodeType==Node.TEXT_NODE){nodes[n].textContent=nodes[n].textContent.replace(new%20RegExp(a,'gi'),b);}else{htmlreplace(a,b,nodes[n]);}}}htmlreplace(prompt("Text%20to%20replace:","old"),prompt("Replacement%20text:","new"));

All I did was replace the old and new with a prompt() function. good bookmarklet.

biegleux
  • 13,179
  • 11
  • 45
  • 52
I'm nobody
  • 507
  • 4
  • 3
1

A search landed me here, and the stuff above is wrong (or at least outdated), and I went through the trouble of updating it until it worked, so I figured I'd paste it here:

javascript:var count=0;
function htmlreplace(a,b,element){
if(!element)element=document.body;
var nodes=element.childNodes;
for(var n=0;n<nodes.length;n++){
   if(nodes[n].type&&nodes[n].type.toLowerCase()=='textarea'){
      var r=new RegExp(a,'gim');
      if(nodes[n].value.match(r)){
        count++;
      }
      nodes[n].value=nodes[n].value.replace(r,b)
    }
    else if(nodes[n].nodeValue && nodes[n].nodeValue.length > 0){
      var r=new RegExp(a,'gim');
      if(nodes[n].nodeValue.match(r)){
        count++;
      }
      nodes[n].nodeValue=nodes[n].nodeValue.replace(r,b)
    }
    else{
      htmlreplace(a,b,nodes[n])
    }
  }
}
htmlreplace(prompt('find'),prompt('replace'));
alert('replaced '+count+' words.');

(Tested in Chrome) It's got a word count instead of just a 'done' message. I changed it to scan through all textNode elements. (I suppose MOST people wouldn't care about replacing all text on the page, but that's the use case that brought me here.)

Peter
  • 10,492
  • 21
  • 82
  • 132
Michael K
  • 11
  • 1