Replace only words inside a paragraph - javascript

I am using a regex replace to <mark></mark> input text. The problem I am running into is that it takes all text from a holder div and replaces it into a variable and adds the mark tags. Then places it back into the div holder. When I do this, if I type in "<p>", it highlights the actual <p> and outputs it back into the div.
Is there anyway to get around this? Here is my marking code:
function Search() {
var Notes = document.getElementById("NoteHolder").innerHTML;
var i = document.getElementById("Bar").value;
var inputReOne = $.trim(i);
var inp = inputReOne.replace(".", "\.").replace("<", "").replace(">", "").replace(
"/", "").replace(/\\/, "");
document.getElementById("Bar").value = inp;
if ($.trim(inp) !== '') {
var InpComp = inp.toUpperCase();
var Ind = tags.indexOf(InpComp);
if (Ind === -1) {
var inpReg = new RegExp(inp, "im");
var WordCheck = Notes.match(inpReg);
if (WordCheck !== null) {
tags.push(InpComp);
var SearchReq = new RegExp("(" + inp + ")", "gim");
var after = Notes.replace(SearchReq, "<mark class=" +
ColorOptionReady + ">$1</mark>");
document.getElementById("NoteHolder").innerHTML = after;
}
HTML:
<body>
<div>
<p id="form">
<input class="SearchInp" autocomplete="off" id="Bar" name="Input" type="text" placeholder="Search for word or phrase">
<input class="SearchInp" type="submit" id="sea" onClick="Search ()" value="Search"> <div id="NoteHolder">
</p>
<p class="NoteOp" id="NoteOne">This is a test paragraph uses to TeSt filters.</p>
<p class="NoteOp" id="NoteTwo">Random words, I need to see if it will mess up mark</p>
</div>
<script src="Test.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"> </script>
</body>

Rather than searching and replacing in the #NoteHolder element, why not loop through each .NoteOp and replace in there?
function search() {
var notes = document.getElementsByClassName("NoteOp");
var s = document.getElementById("Bar").value.trim();
for (var i = 0; i < notes.length; i++) {
var n = notes[i];
n.innerHTML = n.textContent.replace(new RegExp("(" + s + ")", "gim"), "<mark>$1</mark>");
}
}
<input class="SearchInp" autocomplete="off" id="Bar" name="Input" type="text" placeholder="Search for word or phrase">
<input class="SearchInp" type="submit" id="sea" onClick="search()" value="Search">
<div id="NoteHolder">
<p class="NoteOp" id="NoteOne">This is a test paragraph uses to TeSt filters.</p>
<p class="NoteOp" id="NoteTwo">Random words, I need to see if it will mess up mark</p>
</div>
Note: Storing the contents of each .NoteOp in an object, working with the text in there and simply setting the content of each .NoteOp after every search would be easier and cleaner.

Related

find the longest word using javascript / html form

I tried to run the code but nothing is showing on my page.
i'm not sure where the mistakes are. I tried typing javaScript code to find the longest word in a html form/input,then showing the output on the html body.
function fnLongestWord(string){
var words = str.split(" ");
console.log(words);
var findlongest=document.forms["Longestword"],
var longest = "";
for(let i=0; i < findlongest.length; i++){
console.log(findlongest[i]);
}
if ( longest.length > findlongest.length) findlongest = longest;
}
console.log(longest);
document.getElementById("showResult1") = "Number of vowels: "+ longest;
<div id="LongWord" class="Tab">
<form id="Longestword">
<label>Enter text: <input name="text "></label>
<button type="button" onclick="fnLongestWord()"> Find longest word</button>
</form>
<!--here the output show-->
<p id="showResult1"></p>
</div>
Errors
;Here you are calling fnLongestWord but not passing any argument while fnLongestWord expects a value
var words = str.split(" "); str is no where defined inside the function
You need to put this line document.getElementById("showResult1") = "Number of vowels: "+ longest; inside the function and this is an invalid assingment. You need to use innerHTML and assign the value to it
function fnLongestWord(string) {
var str = document.getElementById('input').value || string
var words = str.split(" ");
var longest = words.sort((a, b) => {
return b.length - a.length;
})
document.getElementById("showResult1").innerHTML = "Number of vowels: " + longest[0];
}
<div id="LongWord" class="Tab">
<form id="Longestword">
<label>Enter text: <input id = 'input' name="text "></label>
<button type="button" onclick="fnLongestWord()"> Find longest word</button>
</form>
<!--here the output show-->
<p id="showResult1"></p>
</div>
You've got a few mistakes in your code that need fixing.
Firstly, you call fnLongestWord() when you click the button, thus you are not passing in the string from the form. You need to get the string from the form by using:
var str = document.getElementById('longestWord').value;
This will get the value (the text) of the element with the id longestWord. This will get the text from the textbox (as I've given it the id="longestWord")
Now you want to loop over your array of words. You can use words.length in the for loop to do this.
Next, you want to fix your if statement. Currently your syntax and logic are incorrect. Instead, you need to make it if(longest.length < words[i].length) longest = words[i]; which reads that if the longest word currently found is smaller than our current word, set the new longest word equal to the current word (word[i]).
Lastly, you're not adding the answer to the page correctly. Instead, you should do:
document.getElementById("showResult1").textContent += "Longest word is: " + longest;
To set the longest word into the showResult1 paragraph.
See working example below:
function fnLongestWord() {
var str = document.getElementById('longestWord').value;
var words = str.split(" ");
var longest = "";
for (let i = 0; i < words.length; i++) {
if (longest.length < words[i].length) longest = words[i];
}
document.getElementById("showResult1").textContent += "Longest word is: " + longest;
}
<div id="LongWord" class="Tab">
<form id="Longestword">
<label>Enter text: <input id="longestWord" name="text "></label>
<button type="button" onclick="fnLongestWord()"> Find longest word</button>
</form>
<!--here the output show-->
<p id="showResult1"></p>
</div>

How can I get the matched element's parent div attribute by regular express using Javascript

Have a html string see below.
<div sentence="11">
<p>
how are you Tom, how are you Tom
</p>
</div>
<div sentence="12">
<p>
how are you Tom
</p>
</div>
When user select the name 'Tom', I will replace the string 'Tom' using a name tag with some html style. The result what I want see below.
<div sentence="11">
<p>
how are you <span class="ano-subject" data-oristr="Tom" data-offset="1" data-sentence="11"><NAME></span>, how are you <span class="ano-subject" data-oristr="Tom" data-offset="2" data-sentence="11"><NAME></span>
</p>
</div>
<div sentence="12">
<p>
how are you <span class="ano-subject" data-oristr="Tom" data-offset="1" data-sentence="12"><NAME></span>
</p>
</div>
I will using the code below to do the replace.
var content = HTML CODE ABOVE;
var selectText = 'Tom';
var regex = new RegExp('(?=\\s|^|\\b)(?:' + selectText + ')(?=\\s|$|\\b)', "g");
var pre_sentence = 0;
var offset = 0;
content = content.replace(regex, function(match, position) {
var curr_sentence = ???; // how can I get this element's parent div attribute 'sentence' ?
if(pre_sentence != cur_sentence){
// this is new sentence.
offset = 1;
pre_sentence = curr_sentence;
} else {
offset++;
}
var replace = '<span class="ano-subject" data-oristr="Tom" data-offset="'+offset+'" data-sentence="'+curr_sentence+'"><NAME></span>';
return replace;
});

Is there a way to dynamically create nested divs onclick?

I'm attempting to create a page where the user is able to customize the form to their needs by adding in extra divs or nested divs (as many layers deep as they'd like). Within each div I'd like to have text input and a button which adds another div on the same level and a button that nests a div within it. Both divs should again have a text input and a button which does the same thing.
However I've gotten a bit stuck. When I attempt to create a nested div I always end up adding it at the very bottom instead of inside its parent.
<html>
<script type="text/javascript">
var counter = 1;
function addNode() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs'>";
document.getElementById("dynamicInput").appendChild(newDiv);
var newButton = document.createElement('button');
newButton.type = "button";
newButton.onclick = addSub;
document.getElementById("dynamicInput").appendChild(newButton);
}
function addSub() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs' style='margin:10px'>";
document.getElementById("subInput").appendChild(newDiv);
}
</script>
<form class="form" method="POST">
<div id="dynamicInput" name="dynamicInput" multiple="multiple">
Entry 1<br><input type="text" name="myInputs">
<div id="subInput" name="subInput" multiple="multiple">
<input type="button" value="add nested" onClick="addSub();">
</div>
</div>
<input type="button" value="Add another text input" onClick="addNode();" >
<input type="submit" value = "answer" multiple="multiple"/>
</form>
</html>
Here is a complete solution for you keep in mind that if you need to bind extra events on your produced inputs and buttons you ll have to do it inside the functions addNode or addSub as i did for the click event on the buttons.
Working example : https://jsfiddle.net/r70wqav7/
var counter = 1;
function addNode(element) {
counter++;
var new_entry="Entry "+counter+"<br><input type='text' name='myInputs'><br>";
element.insertAdjacentHTML("beforebegin",new_entry);
}
function addSub(element) {
counter++;
var new_sub_entry="<div class='block'>"
+"Entry "+counter+"<br><input type='text' name='myInputs'><br>"
+"<div class='buttons'>"
+"<input class='add_sub_button' type='button' value='add nested'>"
+"<input class='add_button' type='button' value='Add another text input' >"
+"</div>"
+"</div><br />"
+"</div>";
element.insertAdjacentHTML("beforebegin",new_sub_entry);
var blocks=element.parentNode.getElementsByClassName("block");
blocks[blocks.length-1].getElementsByClassName("add_sub_button")[0].addEventListener("click",function(){
addSub(this.parentNode);
});
blocks[blocks.length-1].getElementsByClassName("add_button")[0].addEventListener("click",function(){
addNode(this.parentNode);
});
}
var buttons=document.getElementsByClassName("add_button");
for(i=0;i<buttons.length;i++){
buttons[i].addEventListener("click",function(){
addNode(this.parentNode);
});
}
var nested_buttons=document.getElementsByClassName("add_sub_button");
for(i=0;i<buttons.length;i++){
nested_buttons[i].addEventListener("click",function(){
addSub(this.parentNode);
});
}
div.block{
padding:5px;
border:2px solid #000;
}
<form class="form" method="POST">
<div class="block">
Entry 1<br><input type="text" name="myInputs"><br>
<div class="buttons">
<input class="add_sub_button" type="button" value="add nested">
<input class="add_button" type="button" value="Add another text input" >
</div>
</div><br />
<input type="submit" value = "answer" multiple="multiple"/>
</form>
EDITED : There was an error binding the click event on nested items updated to work properly
Here's another worked example which makes use of the concepts I mentioned in an earlier comment. I've moved the Add-Item button outside the form and altered the method used to determine the text for each new item added. Rather than keep a counter, I count the number of existing items in the document and increment it, using this as as the n in the string "Entry n"
I should have added(appended) the sub-item before the button that creates new ones, but was lazy and just called appendChild on the button after the other new element was added - the end result is the same, but it's less efficient and will cause slower performance/shorter battery life.
I was going to use the .cloneNode method of the .dynamicInput div, when clicking "Add new item", however this will copy all subitems of the chosen target and we still need to call addEventListener for the button anyway, so I've opted to simply create each input-item added with the "Add new item" button instead.
<!doctype html>
<html>
<head>
<script>
"use strict";
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
function allByClass(className,parent){return (parent == undefined ? document : parent).getElementsByClassName(className);}
function allByTag(tagName,parent){return (parent == undefined ? document : parent).getElementsByTagName(tagName);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('addNewInputBtn').addEventListener('click', myAddNewItem, false);
var subItemBtn = document.querySelectorAll('.dynamicInput button')[0];
subItemBtn.addEventListener('click', myAddSubItem, false);
}
function makeNewItem(titleStr)
{
var div = newEl('div');
div.className = 'dynamicInput';
var heading = newEl('h3');
heading.innerText = titleStr;
div.appendChild(heading);
var input = newEl('input');
div.appendChild(input);
var btn = newEl('button');
btn.innerText = 'Add sub-items';
btn.addEventListener('click', myAddSubItem, false);
div.appendChild(btn);
return div;
}
function myAddNewItem(evt)
{
var numAlreadyExisting = allByClass('dynamicInput').length; // count number of divs with className = dynamicInput
var newNum = numAlreadyExisting + 1;
var newInputPanel = makeNewItem('Entry ' + newNum);
byId('myForm').appendChild(newInputPanel);
return false;
}
function myAddSubItem(evt)
{
evt.preventDefault(); // stops this button causing the form to be submitted
var clickedBtn = this;
var inputDiv = clickedBtn.parentNode;
var newInput = newEl('input');
inputDiv.appendChild(newInput);
inputDiv.appendChild(clickedBtn);
}
</script>
</head>
<body>
<form id='myForm'>
<div class='dynamicInput'>
<h3>Entry 1</h3>
<input type='text'/><button>Add sub-item</button>
</div>
</form>
<button id='addNewInputBtn'>Add new item</button>
</body>
</html>

Get content of span

how can I get the contents of span ?
I'm looking for a way for all of this to be vanilla, not jQuery
javascript (and a little jQuery)
var swear_words_arr=new Array("bad","evil","freak");
var regex = new RegExp('\\b(' + swear_words_arr.join('|') + ')\\b', 'i' );
function validate_user_text() {
var text = document.getElementById('myInput');
text.text();
if(regex.test(text)) {
window.location="http://www.newlocation.com";
return false;
}
}
var myVar=setInterval(function(){validate_user_text()},1000);change
here's my html
<div id="textArea">
<span id="myInput" contenteditable="true">kfjdkfj</span>
</div>
<br />
<form name="form1" method="post" action="">
<textarea rows="3" cols="40" name="user_text" style="border:2 solid #808080; font-family:verdana,arial,helvetica; font-weight:normal; font-size:10pt" onclick="select_area()"></textarea>
<br />
<input type="button" value="Submit" onclick="return validate_user_text();"></form>
Thank You
Give this a shot:
var input = document.getElementById("myInput");
var text = input.innerHTML;
You can use textContent
Taken from MDN:
// Given the following HTML fragment:
// <div id="divA">This is <span>some</span> text</div>
// Get the text content:
var text = document.getElementById("divA").textContent;
// |text| is set to "This is some text".
// Set the text content:
document.getElementById("divA").textContent = "This is some text";
// The HTML for divA is now:
// <div id="divA">This is some text</div>
There is an issue here:
var text = document.getElementById('myInput');
text.text();
You never assigned the text of the input to any variable.
Following your pattern above, you could do:
var txt = document.getElementById('myInput'),
txt = text.text();
The second variable updates the previous variable 'txt' to hold the text of the original 'txt' variable, which was a selector.
You could do this as well (vanilla javascript, jsfiddle):
var txt = document.getElementById('myInput').innerHTML;
//or
var txt = document.getElementById('myInput').textContent;
Instead of using...
text.text();
Try using...
text.innerHTML;
I've only found .text() to work when you're using a jQuery selector.
$('#myInput').text();
var text = (document.getElementById("myInput")).innerHTML
or the abridged form:
var text = $('#myInput').text()

storing user input in array

I need to do the following (I'm a beginner in programming so please excuse me for my ignorance): I have to ask the user for three different pieces of information on three different text boxes on a form. Then the user has a button called "enter"and when he clicks on it the texts he entered on the three fields should be stored on three different arrays, at this stage I also want to see the user's input to check data is actually being stored in the array. I have beem trying unsuccessfully to get the application to store or show the data on just one of the arrays. I have 2 files: film.html and functions.js. Here's the code. Any help will be greatly appreciated!
<html>
<head>
<title>Film info</title>
<script src="jQuery.js" type="text/javascript"></script>
<script src="functions.js" type="text/javascript"></script>
</head>
<body>
<div id="form">
<h1><b>Please enter data</b></h1>
<hr size="3"/>
<br>
<label for="title">Title</label> <input id="title" type="text" >
<br>
<label for="name">Actor</label><input id="name" type="text">
<br>
<label for="tickets">tickets</label><input id="tickets" type="text">
<br>
<br>
<input type="button" value="Save" onclick="insert(this.form.title.value)">
<input type="button" value="Show data" onclick="show()"> <br>
<h2><b>Data:</b></h2>
<hr>
</div>
<div id= "display">
</div>
</body>
</html>
var title=new Array();
var name=new Array();
var tickets=new Array();
function insert(val){
title[title.length]=val;
}
function show() {
var string="<b>All Elements of the Array :</b><br>";
for(i = 0; i < title.length; i++) {
string =string+title[i]+"<br>";
}
if(title.length > 0)
document.getElementById('myDiv').innerHTML = string;
}
You're not actually going out after the values. You would need to gather them like this:
var title = document.getElementById("title").value;
var name = document.getElementById("name").value;
var tickets = document.getElementById("tickets").value;
You could put all of these in one array:
var myArray = [ title, name, tickets ];
Or many arrays:
var titleArr = [ title ];
var nameArr = [ name ];
var ticketsArr = [ tickets ];
Or, if the arrays already exist, you can use their .push() method to push new values onto it:
var titleArr = [];
function addTitle ( title ) {
titleArr.push( title );
console.log( "Titles: " + titleArr.join(", ") );
}
Your save button doesn't work because you refer to this.form, however you don't have a form on the page. In order for this to work you would need to have <form> tags wrapping your fields:
I've made several corrections, and placed the changes on jsbin: http://jsbin.com/ufanep/2/edit
The new form follows:
<form>
<h1>Please enter data</h1>
<input id="title" type="text" />
<input id="name" type="text" />
<input id="tickets" type="text" />
<input type="button" value="Save" onclick="insert()" />
<input type="button" value="Show data" onclick="show()" />
</form>
<div id="display"></div>
There is still some room for improvement, such as removing the onclick attributes (those bindings should be done via JavaScript, but that's beyond the scope of this question).
I've also made some changes to your JavaScript. I start by creating three empty arrays:
var titles = [];
var names = [];
var tickets = [];
Now that we have these, we'll need references to our input fields.
var titleInput = document.getElementById("title");
var nameInput = document.getElementById("name");
var ticketInput = document.getElementById("tickets");
I'm also getting a reference to our message display box.
var messageBox = document.getElementById("display");
The insert() function uses the references to each input field to get their value. It then uses the push() method on the respective arrays to put the current value into the array.
Once it's done, it cals the clearAndShow() function which is responsible for clearing these fields (making them ready for the next round of input), and showing the combined results of the three arrays.
function insert ( ) {
titles.push( titleInput.value );
names.push( nameInput.value );
tickets.push( ticketInput.value );
clearAndShow();
}
This function, as previously stated, starts by setting the .value property of each input to an empty string. It then clears out the .innerHTML of our message box. Lastly, it calls the join() method on all of our arrays to convert their values into a comma-separated list of values. This resulting string is then passed into the message box.
function clearAndShow () {
titleInput.value = "";
nameInput.value = "";
ticketInput.value = "";
messageBox.innerHTML = "";
messageBox.innerHTML += "Titles: " + titles.join(", ") + "<br/>";
messageBox.innerHTML += "Names: " + names.join(", ") + "<br/>";
messageBox.innerHTML += "Tickets: " + tickets.join(", ");
}
The final result can be used online at http://jsbin.com/ufanep/2/edit
You have at least these 3 issues:
you are not getting the element's value properly
The div that you are trying to use to display whether the values have been saved or not has id display yet in your javascript you attempt to get element myDiv which is not even defined in your markup.
Never name variables with reserved keywords in javascript. using "string" as a variable name is NOT a good thing to do on most of the languages I can think of. I renamed your string variable to "content" instead. See below.
You can save all three values at once by doing:
var title=new Array();
var names=new Array();//renamed to names -added an S-
//to avoid conflicts with the input named "name"
var tickets=new Array();
function insert(){
var titleValue = document.getElementById('title').value;
var actorValue = document.getElementById('name').value;
var ticketsValue = document.getElementById('tickets').value;
title[title.length]=titleValue;
names[names.length]=actorValue;
tickets[tickets.length]=ticketsValue;
}
And then change the show function to:
function show() {
var content="<b>All Elements of the Arrays :</b><br>";
for(var i = 0; i < title.length; i++) {
content +=title[i]+"<br>";
}
for(var i = 0; i < names.length; i++) {
content +=names[i]+"<br>";
}
for(var i = 0; i < tickets.length; i++) {
content +=tickets[i]+"<br>";
}
document.getElementById('display').innerHTML = content; //note that I changed
//to 'display' because that's
//what you have in your markup
}
Here's a jsfiddle for you to play around.

Categories

Resources