Str_replace static text with dynamic text for each result

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
enatefox
Forum Newbie
Posts: 11
Joined: Fri Apr 04, 2008 12:58 pm

Str_replace static text with dynamic text for each result

Post by enatefox »

Hello,

I've yet to find a suitable answer for this:

I have a page that prints from a DB and has active text that a user can modify inline. When the user mouses over, there's a tooltip window with some options and the selected one updates the text in the paragraph

Ex: The patient hurt his (left/right/both) hand.
The tooltip for the parentheses lets the user click one of the three and the sentence updates with the choice.

My problem is this: the text from the DB column has that parenthetical statement and I want to use 'str_replace' to replace the text with a span that activates the tooltip. The trouble is that I need an unique ID for each replacement but 'str_replace' only does one iteration.


The most basic form:

Code: Select all

 
$DB_Column_Text = str_replace("(A/B/C)" , "<span class=ttipshower onmouseover=showtool(this.id) >(A/B/C)</span>" , $DB_Column_Text);
 
My trials and tribulations:

Code: Select all

 
function produceavalue($what) {
     return "<span class=ttipshower onmouseover=showtool(this.id) id=".rand().">$what</span>"
}
$DB_Column_Text = str_replace("(A/B/C)" , produceavalue("(A/B/C)"); , $DB_Column_Text);
 

The bottom example actually does work in that it generates a random element ID however, the 2nd and 3rd elements for some weird reason (user error?) have the same ID but the rest are ok.


Any ideas?
WebbieDave
Forum Contributor
Posts: 213
Joined: Sun Jul 15, 2007 7:07 am

Re: Str_replace static text with dynamic text for each result

Post by WebbieDave »

  1. I'm not sure which platform your using but generating randomness can be troublesome at times. You can try mt_rand() which is superior to rand().
  2. Why must the id's be random numbers? Could you use the primary key of the row as the id? If that's not feasible, what about just using sequential id's?
enatefox
Forum Newbie
Posts: 11
Joined: Fri Apr 04, 2008 12:58 pm

Re: Str_replace static text with dynamic text for each result

Post by enatefox »

I'm not asking this correctly I don't think:

I've got a row from a database that prints a title and body text (2 columns). Some of the rows have body text that I need to find&replace keywords with some HTML goodness. The problem is that 'str_replace' does this in one step. Therefore, I cannot make the replaced code have anything unique (like the element IDs).

So here is an example row of body text:
"Motor nerve conduction studies of (left/right/bilateral) median and ulnar nerves reveal normal distal latencies. Sensory nerve conduction studies of (left/right/bilateral) median and ulnar nerves reveal normal peak latencies "

I need to replace:
"(left/right/bilateral)"
with:
"<span onmouseover=showtooltip(this.id) id=ttip_someunique# >(left/right/bilateral)</span>"

The problem is that all occurences will be replaced with the same text including IDs. I tried to make a function that will return the <span> text with a randomly generated number for the ID (first post) but that's not very reliable for a couple of reasons. I know this isn't best practice anyways.

I tried 'preg_replace' and 'substr_count' to do a FOR loop but since I'm surrounding the search term with code, the next iteration through the loop will find the same string again and again. The problem with that was:

Code: Select all

 
$replaceme = "(left/right/bilateral)";
$withme     = "<span onmouseover=showtooltip(this.id) id=ttip_someunique# >(left/right/bilateral)</span>";
$thecount = substr_count($item_text, $replaceme);
 
for ($p = 0; $p < $thecount; $p++) {
     $item_text = preg_replace($replaceme, $withme, $item_text);
}
 
which will clearly keep running on the first match over and over again. I ended up with a set of parentheses for each occurence plus one recursively.
For example, if there were 3 matches, I would have ((((first match)))) (((second match))) ((third match)) since there was already a set of parentheses to start with. This is insane.


I just need an unique ID for each replacement string so that the tooltip will be able to reach that particualr SPAN to update the text. If there are 3 matches, then all three would be updated since their IDs match.
enatefox
Forum Newbie
Posts: 11
Joined: Fri Apr 04, 2008 12:58 pm

Re: Str_replace static text with dynamic text for each result

Post by enatefox »

I'm still hoping for a solution but I thought I would post what I did in the meantime. Negative on PHP because I just don't see a function that would be suitable so here's the javascript version:

Code: Select all

 
function grabttips(){
    var x=document.getElementsByTagName("span")
    for (b=0;b<x.length;b++){
        if(x[b].id=='') {
            x[b].id = 'ttip'+b
        }
        else{}
    }
}
 
Yea, I know it's not the best but oh well. If anyone wants to use this I should also mention a couple of quirks with it:

I'm loading menus dynamically via AJAX and when the response comes through, you'd think you could run the script but it seems to just freeze the response or something because the elements will not populate.
If I have a link that runs the script and click that only once the whole document is available from the request it will work.
I instead made it so that when the tooltip function is called it will run the script which only changes IDs if they're null. I did not specify an ID originally so it should only run on the first tooltip.

Please let me know what else would work (PHP preferably)
WebbieDave
Forum Contributor
Posts: 213
Joined: Sun Jul 15, 2007 7:07 am

Re: Str_replace static text with dynamic text for each result

Post by WebbieDave »

enatefox wrote:Negative on PHP because I just don't see a function that would be suitable
8O ??? PHP has one of the richest library sets ever

Regex is the way to go. If you need different replacements for multiple occurrences of a pattern, try a callback function:

Code: Select all

function getSpan($matches) {
    global $spanIdNum;
    return '<span id="tip_' . $spanIdNum++ . '>' . $matches[0] . '</span>';
}
$pattern = '/\(left\/right\/bilateral\)/';
$body = 'Motor nerve conduction studies of (left/right/bilateral) median and ulnar nerves reveal normal distal latencies. Sensory nerve conduction studies of (left/right/bilateral) median and ulnar nerves reveal normal peak latencies';
$spanIdNum = 1;
 
$body = preg_replace_callback($pattern, 'getSpan', $body);
enatefox
Forum Newbie
Posts: 11
Joined: Fri Apr 04, 2008 12:58 pm

Re: Str_replace static text with dynamic text for each result

Post by enatefox »

Thanks for the reply.
That's more of what I was looking for. I've never even dabbled with that though...


Code: Select all

 
function getSpan($matches) {
   global $spanIdNum;
   return '<span id="tip_' . $spanIdNum++ . '>' . $matches[0] . '</span>';
}
   $pattern = '/\(left\/right\/bilateral\)/';
   $body = 'Motor nerve conduction studies of (left/right/bilateral) median and ulnar nerves reveal normal distal latencies. Sensory nerve conduction studies of (left/right/bilateral) median and ulnar nerves reveal normal peak latencies';
   $spanIdNum = 1;
 
   $body = preg_replace_callback($pattern, 'getSpan', $body);
 
Sorry if it's noobish but I'm not used to callback functions.
As my first post stated, the best idea I had that was similar was to call a function that adds a random number to the end of the static replacement text. This was beyond unreliable so how would I implement this?



What I don't get:
Can you explain what $matches would have that the [0] index is always returned in the function?
Also, the $spanIdNum would be what when I need it to generate on the fly. I don't know if there are 3,5,20 replacements and I don't want to have to count first... Am I supposed to define an array of numbers to feed getSpan()? That seems counterproductive.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Str_replace static text with dynamic text for each result

Post by VladSun »

Example #2 at http://bg2.php.net/manual/en/function.p ... llback.php will make it clear for you.
There are 10 types of people in this world, those who understand binary and those who don't
enatefox
Forum Newbie
Posts: 11
Joined: Fri Apr 04, 2008 12:58 pm

Re: Str_replace static text with dynamic text for each result

Post by enatefox »

Thanks for the feedback. All is working as desired for the most part.

I did this:

Code: Select all

 
$ttiparray = array("/\(left\/right\/bilateral\)/","/\(median\/ulnar\)/");
$item_text =  preg_replace_callback($ttiparray[0],"proc_tooltips_TYPE1",$item_text[$a]);
$item_text =  preg_replace_callback($ttiparray[1],"proc_tooltips_TYPE2",$item_text[$a]);
....
 
function proc_tooltips_TYPE1($matches){
  return "<span class=spncls onmouseover=\"showtool(this,'TYPE1')\" id='".rand()."' >[LEFT/RIGHT/BILATERAL]</span>";
}
 

Ok, now I'm up to my next set of problems...
There are multiple types of replacements depending on the search string (around 15 so far...).
I do not see a way of passing this to the new function proc_tooltips(); although I tried.

What I need is for the proc_tooltips() function to be able to tell the text it found (even the array index for $ttiparray would work) so that the text inside the span that I'm inserting has the same keywords it had originally:

As a non-working example:

Code: Select all

 
$ttiparray = array("one","fish","two");
$item_text = preg_replace_callback($ttiparray[0],"proc_tooltips($ttiparray[0])",$item_text);
...
 
function proc_tooltips($matches,$orig_text) {
     return "<span id='".rand()."' >" .$orig_text. "</span>";
}
 

So that:
"the original keyword"
Becomes:
<span>"the original keyword"</span>


How about that?
Post Reply