Jump to content

Search text in UniHTMLMemo


artem_niko

Recommended Posts

Hello everybody!
This question arose.
There is UniHTMLMemo1, into which the text is loaded.
I need to find a word in UniHTMLMemo1 and if the search word is found, then highlight, for example, in green, this word in UniHTMLMemo1.
For example, there is a text like this UniHTMLMemo1:
In UniHTMLMemo1:
"This is just test text."

I enter the word "text" into UnIEdit1 and
As a result, in UniHTMLMemo1 you need to highlight the words "text" in green.

How to organize highlighting in UniHTMLMemo? If it was necessary to develop on VCL, then there was used the RichEdit component and that's it. But it should be on UniGUI.

Link to comment
Share on other sites

Hello,

maybe this will help you: https://stackoverflow.com/questions/51005351/change-text-color-of-a-part-of-paragraph-in-js/51005464

<!DOCTYPE html>
<html>
<body>

<script>
function n() {
  var a = {
    German: ["German1", "German2"],
    plays: ["plays1", "plays2"],
    forward: ["forward1", "forward2"]
  };
  var p = document.getElementById("p1"),
      keys = Object.keys(a);

  for (j = 0; j < keys.length; j++) {
    p.innerHTML = p.innerHTML.replace( new RegExp("\\b"+keys[j]+"\\b","g"),"<span style='color:red'>" + keys[j] + "</span>")
  }
}

</script>

<p id="p1">Marco Reus is a German professional footballer who plays as a forward for Borussia Dortmund and the Germany national team. He is renowned for his versatility, speed and technique, but also for proneness to injury.</p>

<button name="b1" onclick="n()">Next</button>
</body>
</html>

Result: 

image.thumb.png.74cbb060b07e085e5616ce9d2520ff7f.png

Link to comment
Share on other sites

29 minutes ago, irigsoft said:

Hello,

maybe this will help you: https://stackoverflow.com/questions/51005351/change-text-color-of-a-part-of-paragraph-in-js/51005464

<!DOCTYPE html>
<html>
<body>

<script>
function n() {
  var a = {
    German: ["German1", "German2"],
    plays: ["plays1", "plays2"],
    forward: ["forward1", "forward2"]
  };
  var p = document.getElementById("p1"),
      keys = Object.keys(a);

  for (j = 0; j < keys.length; j++) {
    p.innerHTML = p.innerHTML.replace( new RegExp("\\b"+keys[j]+"\\b","g"),"<span style='color:red'>" + keys[j] + "</span>")
  }
}

</script>

<p id="p1">Marco Reus is a German professional footballer who plays as a forward for Borussia Dortmund and the Germany national team. He is renowned for his versatility, speed and technique, but also for proneness to injury.</p>

<button name="b1" onclick="n()">Next</button>
</body>
</html>

Result: 

image.thumb.png.74cbb060b07e085e5616ce9d2520ff7f.png

And how apply this JS code, If I using UniEdit1 and UniHTMLMemo?

Link to comment
Share on other sites

Hello,

At one time, I did search with selection and navigation between the found elements...

But now, I found another solution on the Internet.

https://markjs.io/

Simple usage, but not optimal :) 

1. CustomFiles

files/jquery.mark.min.js

2. UniEdit1 -> OnChange

procedure TMainForm.UniEdit1Change(Sender: TObject);
begin
  (Sender as TUniEdit).JSInterface.JSCode(
    '$('+ UniHTMLMemo1.JSName +'.getDoc()).unmark({'+
    '    done: function() {'+
    '        $('+ UniHTMLMemo1.JSName +'.getDoc()).mark("'+ (Sender as TUniEdit).Text +'", {});'+
    '    }'+
    '});'
  )
end;

 

Link to comment
Share on other sites

18 hours ago, Sherzod said:

Hello,

At one time, I did search with selection and navigation between the found elements...

But now, I found another solution on the Internet.

https://markjs.io/

Simple usage, but not optimal :) 

1. CustomFiles


files/jquery.mark.min.js

2. UniEdit1 -> OnChange


procedure TMainForm.UniEdit1Change(Sender: TObject);
begin
  (Sender as TUniEdit).JSInterface.JSCode(
    '$('+ UniHTMLMemo1.JSName +'.getDoc()).unmark({'+
    '    done: function() {'+
    '        $('+ UniHTMLMemo1.JSName +'.getDoc()).mark("'+ (Sender as TUniEdit).Text +'", {});'+
    '    }'+
    '});'
  )
end;

 

Thanks a lot for the answer, everything works!
The only thing I have 2 questions:
1. How (and where in the code) change the color from yellow to some other color?
2. How to make it case sensitive and not search by occurrences (see attachment)?

image.thumb.png.d62e0d9493a5518cfecbf424118f158c.png

Link to comment
Share on other sites

1 hour ago, Артем said:

There is no color information in the file you specified. Not even a word "color"...

Please check the documentation here: https://markjs.io/

"

3.4 Styling

mark.js will wrap matches with a specified element and optionally with an assigned class. When not changing the default element mark, browsers will ensure that it looks highlighted by default. However, you may want to customize the style of it. This can be done using e.g. the following CSS:

mark{
    background: orange;
    color: black;
}

If you've customized the default element or class, make sure to modify the selector.

"

maybe this will help you.

Link to comment
Share on other sites

2 hours ago, Артем said:

1. How (and where in the code) change the color from yellow to some other color?

Hello,

Try this:

UniHTMLMemo1 -> ClientEvents -> ExtEvents -> 

function initialize(sender, eOpts)
{
    sender.iframeEl.dom.contentDocument.head.innerHTML += '<style>mark {background: green; color: white;}</style>';
}

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, Sherzod said:

Hello,

Try this:

UniHTMLMemo1 -> ClientEvents -> ExtEvents -> 


function initialize(sender, eOpts)
{
    sender.iframeEl.dom.contentDocument.head.innerHTML += '<style>mark {background: green; color: white;}</style>';
}

 

Perfect! Working :)

How about this second question?

How to make it case sensitive and not search by occurrences?

image.thumb.png.956a08506699939856d0407e88418047.png

Only the word Classes should be highlighted.

Link to comment
Share on other sites

16 minutes ago, Артем said:

Only the word Classes should be highlighted.

@Sherzod Maybe this will help (from documentation): https://markjs.io/

 

"

4.2 mark()

A method to highlight custom search terms.

Syntax

JavaScript:

var context = document.querySelector(".context");
var instance = new Mark(context);
instance.mark(keyword [, options]);

jQuery:

$(".context").mark(keyword [, options]);

Note: Even if this is a chaining method and therefore allows you to call further methods on the returning object, it's recommended to always use the done callback as mark.js works asynchronous.

Parameters

keyword

Type: string or array of string

The keyword to be marked. Can also be an array with multiple keywords. Note that keywords will be escaped. If you need to mark unescaped keywords (e.g. containing a pattern), have a look at the markRegExp() method below.

options

Type: object

Optional options:

Option Type Default Description
element string "mark" HTML element to wrap matches, e.g. span
className string "" A class name that will be appended to element
exclude array [ ] An array with exclusion selectors. Matches inside these elements will be ignored. Example: "filter": ["h1", ".ignore"]
separateWordSearch boolean true Whether to search for each word separated by a blank instead of the complete term
accuracy string or object "partially" Either one of the following string values:
  • "partially": When searching for "lor" only "lor" inside "lorem" will be marked
  • "complementary": When searching for "lor" the whole word "lorem" will be marked
  • "exactly": When searching for "lor" only those exact words with a word boundary will be marked. In this example nothing inside "lorem". This value is equivalent to the previous option wordBoundary
Or an object containing two properties:
  • "value": One of the above named string values
  • "limiters": A custom array of string limiters for accuracy "exactly" or "complementary". Read more about this in the tutorials section

"

  • Upvote 1
Link to comment
Share on other sites

4 hours ago, Артем said:

2. How to make it case sensitive and not search by occurrences (see attachment)?

procedure TMainForm.UniEdit1Change(Sender: TObject);
begin
  (Sender as TUniEdit).JSInterface.JSCode(
    '$('+ UniHTMLMemo1.JSName +'.getDoc()).unmark({'+
    '    done: function() {'+
    '        $('+ UniHTMLMemo1.JSName +'.getDoc()).mark("'+ (Sender as TUniEdit).Text +'", {caseSensitive: true, accuracy: "exactly"});'+
    '    }'+
    '});'
  );
end;

 

  • Like 1
Link to comment
Share on other sites

On 5/26/2021 at 1:44 PM, Sherzod said:

Hello,

At one time, I did search with selection and navigation between the found elements...

But now, I found another solution on the Internet.

https://markjs.io/

Simple usage, but not optimal :) 

1. CustomFiles


files/jquery.mark.min.js

2. UniEdit1 -> OnChange


procedure TMainForm.UniEdit1Change(Sender: TObject);
begin
  (Sender as TUniEdit).JSInterface.JSCode(
    '$('+ UniHTMLMemo1.JSName +'.getDoc()).unmark({'+
    '    done: function() {'+
    '        $('+ UniHTMLMemo1.JSName +'.getDoc()).mark("'+ (Sender as TUniEdit).Text +'", {});'+
    '    }'+
    '});'
  )
end;

 

Hi Sherzod

I need similar solution to find text on the entire page  (UniGuiForm) not UniHTMLMemo1 , the form have hundreds of uniPanels Each have one label

(need the same exact behavior as a browser find).

can I use this .

regards

 

Link to comment
Share on other sites

1 hour ago, M.Ammar said:

I need similar solution to find text on the entire page  (UniGuiForm) not UniHTMLMemo1 , the form have hundreds of uniPanels Each have one label

(need the same exact behavior as a browser find).

can I use this .

Hi,

You can try using something like this:

procedure TMainForm.UniEdit1Change(Sender: TObject);
begin

  (Sender as TUniEdit).JSInterface.JSCode(
    '$(document).unmark({'+
    '    done: function() {'+
    '        $(document).mark("'+ (Sender as TUniEdit).Text +'", {caseSensitive: true, accuracy: "exactly"});'+
    '    }'+
    '});'
  );

end;

documentFindText.png.caff1da761ac27a80c478ebd4f1aca50.png

  • Like 1
Link to comment
Share on other sites

20 minutes ago, Sherzod said:

Hi,

You can try using something like this:


procedure TMainForm.UniEdit1Change(Sender: TObject);
begin

  (Sender as TUniEdit).JSInterface.JSCode(
    '$(document).unmark({'+
    '    done: function() {'+
    '        $(document).mark("'+ (Sender as TUniEdit).Text +'", {caseSensitive: true, accuracy: "exactly"});'+
    '    }'+
    '});'
  );

end;

documentFindText.png.caff1da761ac27a80c478ebd4f1aca50.png

thanks for reply

it working great thanks,

one missing behavior thought , if the found text not in the displayed area need to auto scroll the base panel to display it.

best regards

 

Link to comment
Share on other sites

1 hour ago, M.Ammar said:

if it is possible 

For example:

MainForm, MainForm.AutoScroll = True

MainForm.Script:

  var $results,
  currentClass = "current",
  offsetTop = 50,
  currentIndex = 0;
    
  function jumpTo() {
    if ($results.length) {
      var position,
        $current = $results.eq(currentIndex);
      $results.removeClass(currentClass);
      if ($current.length) {
        
        $current.addClass(currentClass);
        position = $current.offset().top - offsetTop;
        MainForm.form.scrollTo(0, position);
      }
    }
  }

UniEdit1 -> OnChange:

procedure TMainForm.UniEdit1Change(Sender: TObject);
begin
  (Sender as TUniEdit).JSInterface.JSCode(
    '$(document).unmark({'+
    '    done: function() {'+
    '        $(document).mark("'+ (Sender as TUniEdit).Text +'", {caseSensitive: true, accuracy: "exactly", '+
    '            done: function(){$results = $(document).find("mark");'+
    '                currentIndex = 0;'+
    '                jumpTo();'+
    '            }'+
    '        });'+
    '    }'+
    '});'
  );

end;
  

Source:

https://jsfiddle.net/julmot/973gdh8g/

Link to comment
Share on other sites

hi Sherzod

I appreciate your effort to help me, I have trayed to put the script in the main form as well as on my form but but I couldn't get it to work, I get error 

 

jumpTo is not defined

_rsov_(O3DE,2);$(document).unmark({    done: function() {        $(document).mark("1", {caseSensitive: true, accuracy: "exactly",             done: function(){$results = $(document).find("mark");                currentIndex = 0;                jumpTo();            }        });    }});

 

-----

instead I made a deferent  solution using database search to find the panel name

here is the code if anyone interested

  QuotedStr := '''%' + UniESearch.Text + '%''';
  FDQUnits.Filter := 'unit_name_2 Like ' + QuotedStr ;
  if FDQUnits.FindFirst then
   begin
      UnitPanelBase := UnitTablePanel.FindChildControl('UnitPanelBase_' + (FDQUnitsUnitUnkId.AsString)) as TUniContainerPanel;
      UnitPanelBase.JSInterface.JSCode('document.getElementById('#1'.id).scrollIntoView(false);');
   end;

the last line is from another post by you also,  working fine

thanks again

Link to comment
Share on other sites

  • 3 months later...

Using CustomFiles.Add('files\jquery.mark.min.js');

Any suggestions on how to mark case insensitive words in HtmlFrame ?

    if TopChoice > 0 then begin
      InfoHTMLFrame.JSInterface.JSCode('$('+ InfoHTMLFrame.JSName +'.getDoc()).unmark'+
      '({ '+
      '   done: function() {'+
      '                      $('+ InfoHTMLFrame.JSName +'.getDoc()).mark("healthy", {});'+
      '                    }'+
      '});'
      );
    end;
 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...