I am building a JavaScript search application that takes a text string and breaks it into multiple parts using spans. A separate function will search either on the entire text or only in one of the previously identified sections.
My problem is that when I attempt to highlight the text after I identify the sections. I can't figure out how to highlight the text contained in multiple spans.
For example if I have the string.
<div id="container">
<span id="sectionOne">This is my first section</span>
and
<span id="sectionTwo">This is my second section</span>
</div>
how would I highlight section and This which is contained in both spans as well as a text element?
Thanks for any help. If it is possible to do this in pure JavaScript that would be most helpful; although, any solution is greatly appreciated.
<input type="text" id="search" />
<div id="container"> <span id="sectionOne">This is my first section</span> <span id="sectionTwo">This is my second section</span>
</div>
<div id="output"></div>
JS
$('#search').keyup(function () {
var self = $(this);
var src_str = $("#container").html();
var term = $('#search').val();
term = term.replace(/(\s+)/, "(<[^>]+>)*$1(<[^>]+>)*");
var pattern = new RegExp("(" + term + ")", "gi");
src_str = src_str.replace(pattern, "<mark>$1</mark>");
src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/, "$1</mark>$2<mark>$4");
$("#output").html(src_str);
});
Fiddle
I managed to get something to work by parsing the string and storing the various parts in a object with the position values. When I want to search on an individual section I simply search within my object then replace the correct part of the original input.
I am sure there is a better way to solve the problem but breaking up the string into an internal object was the only way I could get this to work.
Related
As you can see, my HTML contains multiple references to '0'. I need to change these to '1'.
However, my jQuery isn't working.
jQuery(".create-new-location").click(function() {
jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header-logo" class="header-title location-header-0 title-edit-header" data-row-id="location-header-0" title="Location name (for your reference)">
<div class="input-selection title-edit-header">
<div class="text-input">
<input class="option_textbox col-sm-12 change-width title-edit" placeholder="Location name (for your reference)" value="" type="text" name="bp_theme_options[social][map][locations][0][location_name]">
</div>
</div>
<div class="open-block pencil-edit" data-row-id="location-header-0"></div>
</div>
You have to set the html like this
jQuery(".create-new-location").click(function() {
var the_html = jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']');
jQuery("#header-logo").html(the_html);
});
But this is not a good practice!!
When you need to change only the attribute of an <input>, why change the whole #header-logo, right? When you re-draw html like this, you risk losing event-handlers binded to the elements you have just re-drawn.
jQuery(".create-new-location").click(function() {
var elements = jQuery("#header-logo").find('input[name]'); /*all input with name*/
elements.each(function(el){
var the_name = el.attr('name').replace(/\[0\]/g, '['+(1)+']');
el.attr('name', the_name);
});
});
Regexing the html is never a good idea.
As you can see, my HTML contains multiple references to '0'. I need to change these to '1'.
The approach you used, and even the accepted answer here, will not modify the containing div with id="header-logo" which contains several of these references. Moreover, there are significant issues with simply replacing existing dom elements with freshly regexed ones in validation cases (as in, this may break your validation).
The approach you should use is to specifically target the attributes that contain these references, and then only modify those. Here is a general approach which looks in all attributes and modifies the occurrence of [0 (0 being the value of before) into [1 (1 being the value of after) as well as modifying the occurrence of -0 (before = 0) to -1 (after =1).
This will prevent removing any existing event handlers from the elements, as well as a number of other issues associated with regexing straight html and then replacing the dom element with the that result.
$.fn.indexUpdate = function(before,after){
$("*",this).add(this).each(function(){
$(this.attributes).each(function(){
this.value = this.value.replace(new RegExp('\\b\\-'+before+'\\b','g'), '-'+after);
this.value = this.value.replace(new RegExp('\\['+before, 'g'), '['+after);
});
});
};
$("#header-logo").indexUpdate(0,1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header-logo" class="header-title location-header-0 title-edit-header" data-row-id="location-header-0" title="Location name (for your reference)">
<div class="input-selection title-edit-header">
<div class="text-input">
<input class="option_textbox col-sm-12 change-width title-edit" placeholder="Location name (for your reference)" value="" type="text" name="bp_theme_options[social][map][locations][0][location_name]">
</div>
</div>
<div class="open-block pencil-edit" data-row-id="location-header-0"></div>
</div>
This statement jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']'); retrieve the html inside the element that have id as header-logo and replace every 0 inside the html string with 1 But it doesn't assign the modified string again to the element So you may want to use following code.
jQuery("#header-logo").html(jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']'));
Try this:It will replace all existence of '0' with '##'
$(".create-new-location").click(function() {
$("#header-logo").html().replace(/0/gi, '##')
});
Is it possible to post process data bound with angularjs?
I am writing simple search page and i have generated results with code:
...
<div class="row" ng-repeat="document in sc.searchResult.content">
<blockquote>
{{document.content}}
</blockquote>
</div>
...
The problem is that I need to bold specific words in every result (the words from query box - like in google below)
How to reach that effect?
controller.js
$scope.document.content = someSearchContent.replace(/<searchTerm>/g, '<strong>' + <searchTerm> + '</strong>')
searchTerm is the string that you need to modify. You can use RegExp() to create a regular expresion.
template
<blockquote ng-bind-html="document.content"></blockquote>
I have one problem. On my website, I have <div id="alpha_bravo">, with links inside. It looks like this:
<div id="alpha_bravo">
<p>text text text link</p>
</div>
I want change every <a href...> to funny text like suprise, as an example.
How can I do it?
Since you tagged the question with PHP and from the comments below the question it seems that you may want to use server-side functionality, I'm going to give an example using PHP.
One way is to replace only links. You are looking for preg_replace() function that will replace all substrings in the string based on a regex pattern.
$input = "<div id='alpha_bravo'><p>text text text <a href='...'>link</a> and <a href='...'>another link</a></p></div>";
$output = preg_replace("/<a (.*?)>(.*?)<\/a>/i", "surprise", $input);
You can also just remove all HTML tags in the string using strip_tags() function.
$input = "<div id='alpha_bravo'><p>text text text <a href='...'>link</a> and <a href='...'>another link</a></p></div>";
$output = strip_tags($input);
Given that this is coming from a database, first word of advice is that you filter your input before saving it in database.
Secondly, if you don't want those links to render and replace them with some other value then use PHP's function preg_replace() as already mentioned by PetrHejda..
PHP docs: http://php.net/manual/en/function.preg-replace.php
Your <a ...>...</a> pattern may differ if users insert styling and classes.
Try using this pattern as your solution: preg_replace("/<a(.+?)href=\"(.+?)\"/", "<a$1href=\"your_value_here\"", $yourStringHere);
You may use g or i flags. Start here with regular expressions: http://www.regular-expressions.info/.
I am new to jqmath; I have contained a textarea field in my HTML:
<textarea cols="30" rows="2" id="mathSrc1"></textarea>
I will set mathematical formula in the text area so that it will be displayed in <div> tag:
<div id="mathTgt1"></div>
This code is available in http://mathscribe.com/author/jqmath.html. But I don't know how to use it. Please help me.
Thank you.
i got solution
<input type="textarea" name="formula" id="test_formula" onkeyup="paste_formula()" />
<span id="formula_print"></span>
script code
function paste_formula() {
var val = document.getElementById("test_formula").value;
val = "$$" + val + "$$";
var di = document.getElementById("formula_print");
di.innerHTML = val;
M.parseMath(di);
}
I like Nathan's question - what exactly are you trying to do? The normal case is to have some math in your static web page, which you just surround with $s and it gets parsed and formatted at load time. If you want to create mathematical expressions dynamically (after load time), see Jqmath - apply after page load. You can also look at the jqmath source to see how http://mathscribe.com/author/jqmath.html does it. All these methods end up calling the same functions to do the actual work (parsing and formatting).
I have a simple input line and want to append whatever has been entered each time somebody pushes the OK button. Sounds simple so far, still I am unable to get it working
HTML:
<p>
<input name="todo" id="todo" type="text" value="Set Me To Value" size="32" maxlength="30" />
<p id="status">Ok</p>
<br>
JQuery:
$(document).ready(function(){
$('#status').on('click', function(){
var input = $('input[name=todo]').val();
$('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>').after('#status');
});
});
I also tried my luck with append or appendTo, but both times unsuccessfully.
Just in case here is the JSFiddle: http://jsfiddle.net/NRWzE/
.after() works, but you need to set it up correctly, according to documentation it should be:
.after( content [, content ] )
So the right way is:
$("#status").after('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
Try use jquery insertAfter:
$(document).ready(function () {
$('#status').on('click', function () {
var input = $('input[name=todo]').val();
$('<br><b id="taskz">' + input + '</b> - <b id="statusz">Ok</b>').insertAfter('#status');
});
});
It looks like you meant to use:
$('#status').after('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
(see after docs)
or, alternatively insertAfter:
$('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>').insertAfter('#status');
Try this:
$('#status').click(function(){
var input = $('input[name=todo]').val();
$('#status').append('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
});
There are a few things going on, but the big thing is that you need to research more how after, append and appendTo work. Here's the basic syntax difference in the methods that share a name but one has To on the end:
Newcontent.appendTo(existingElement) returns newElements.
existingElement.append(newContent) returns existingElement.
Additionally, after puts the new element as a sibling of the reference element, whereas append puts the new element as a child. This is an important difference.
So, try this script then:
var taskid = 1;
$('#valueform').on('submit', function(){
var input = $('#todo').val();
$('<br><span id="task' + taskid.toString() + '">' + input
+ '</span> - <span id="status' + taskid.toString()
+ '">Ok</span>').appendTo('#status');
taskid += 1;
$('#todo').focus().select();
return false;
});
$('#todo').focus().select();
See a Live Demo at JSFiddle
Here's the supporting HTML:
<form id="valueform">
<input name="todo" id="todo" type="text" value="Set Me To Value" size="32" maxlength="30" />
<input type="submit" value="OK" id="okbutton">
</form>
<p id="status"></p>
There are some other concerns:
I recommend you study which HTML elements are allowed within which HTML elements.
Instead of putting a <b> tag on each item, use CSS. Additionally, if there is semantic importance for the bolding, then use <strong> instead. <b> also should probably not take an id because it is a presentation tag, not a content tag. When thinking of presentation vs. semantics, one must consider screen readers or browsers that cannot render bold text--in that case, <strong> will allow them to emphasize the text in another way if needed.
Get familiar with the jQuery documentation. Careful reading of what exactly each function does, the object it works on, the parameters expected, and the values returned will enable you to get past barriers in the future without having to ask here.
It looked to me like you wanted to put the new content inside of the #status paragraph, not after it. So I wrote my script that way. If you put it after the way you wrote it, then the most recent status will be on top--but then you have non block-level content (starting with your <br>) outside of any block-level element. So you should be appending <p> elements, or you should put your content inside the existing <p>.
Note: I added a form and made the button type submit instead of button to get easy Enter-key handling. It doesn't have to be this way.