how to make space must be remains same after replacing text? - javascript

I have text, in which on selection I need to replace the text.
Here my requirement is, the space must be remain same after replacing the characters which contains spaces between them.
JavaScript:
function getSel() {
// obtain the object reference for the textarea>
var txtarea = document.getElementById("mytextarea");
// obtain the index of the first selected character
var start = txtarea.selectionStart;
// obtain the index of the last selected character
var finish = txtarea.selectionEnd;
//obtain all Text
var allText = txtarea.value;
// obtain the selected text
var sel = Array(finish - start).join("*");
//append te text;
var newText = allText.substring(0, start) + sel + allText.substring(finish, allText.length);
txtarea.value = newText;
$('#newpost').offset({ top: 0, left: 0 }).hide();
}
$(document).ready(function () {
var position;
$('#newpost').hide();
$('#mytextarea').on('select', function (e) {
$('#newpost').offset(position).show();
var txtarea = document.getElementById("mytextarea");
var start = txtarea.selectionStart;
var finish = txtarea.selectionEnd;
$('#newpost p').text(Array(finish - start).join("*"));
}).on('mousedown', function (e) {
position = { top: e.pageY-5, left: e.pageX};
});
$('#newpost').hide();
});
Here is my plunker
I am getting output as shown in above image but in expected output the space must not be replaced with asterisk .

Use string.replace instead, try this:
console.log('g2ggg gggGG'.replace(/[a-zA-Z0-9]/g, '*'))
Your all string manipulation logic will be only 1 line:
newText = allText.replace(/[a-zA-Z0-9]/g, '*')

I'm not very good at regex so I used a for-loop but maybe this still helps you.
$(document).ready(function () {
$('#mytextarea').on('select', function (e) {
var $output = $("#output");
var $txtarea = $("#mytextarea");
var start = $txtarea[0].selectionStart;
var finish = $txtarea[0].selectionEnd;
var subtext = $txtarea.text().substr(start, finish);
var out = "";
for (var i = 0; i < subtext.length; i++) {
var char = subtext[i];
if (char == " ") {
out += " ";
} else {
out += "*";
}
}
$output.text(out);
});
});
Based on your code you can see the working example in this fiddle:

Related

How can I replicate a set of characters every time they are typed using JavaScript?

I currently have a form and what I would like is that every time a "Tag" is mentioned, denoted by being surrounded by double square brackets (i.e [[Tag]]), the same tag is repeated once.
This would mean that when I type [[Tag]], I would immediately see [[Tag]][[Tag]]. This idea is that someone would then be able to type text in between the two tags.
I have the following JavaScript:
function newNote() {
const note_button = document.getElementById("new_note_button")
const note = document.getElementById("new_note_form_container");
if (note.style.display === "none") {
note.style.display = "block";
note_button.innerHTML = "Only show notes"
} else {
note.style.display = "none";
note_button.innerHTML = "Create a new note"
}
}
document.addEventListener('DOMContentLoaded', function(){
let input_note = document.getElementById('note_text');
input_note.addEventListener('input', upThing)
})
function upThing(ev) {
let note_form = ev.target.value;
let regex = /(?=\[\[).*?(?<=\]\])/g;
let first_position = 0;
let result = note_form.substring(first_position);
let open_bracket = result.indexOf("[[") + 2;
let close_bracket = result.indexOf("]]");
if (close_bracket > open_bracket) {
let tag = result.substring(open_bracket, close_bracket);
console.log(tag)
ev.target.value = ev.target.value + "[[" + tag + "]]";
}
}
This JavaScript does produce the desired [[Tag]] to [[Tag]][[Tag]]. However, every time I continue to type another [[Tag]] appears. So this does not serve the purpose.
I need it so that I can repeat this process for [[Tag 2]], [[Tag 3]] etc.
It would be helpful to understand how to move the tags to bold when enclosed by [[ ]]
This will work when the ]] is at the end of string. This can be extended to any position though.
Update: should work even if on middle of text.
document.querySelector('.btex').addEventListener('keyup', function(ev) {
if (ev.key == ']') {
var val = this.value;
var start = this.selectionStart;
if (start > 1 && val.substring(start - 2, start) == "]]") {
var pos = val.lastIndexOf("[[", start);
var word = val.substring(pos, pos + start);
if (start > pos) {
var end = this.selectionEnd;
this.value = val.substring(0, start) + word + val.substring(end);
this.selectionStart = this.selectionEnd = start;
return false;
}
}
}
});
<textarea class="btex" rows="4" style="width:100%"></textarea>

How to dynamically add <a> tags given an index of HTML page's string?

I'm making a search function for my website. So far, I've found the string the user searches for in the whole website, and I'm able to print the string and the context of the string. I have achieved this by using $.get on my HTML pages, then stripping the HTML to leave the pure text I want to search in. I then find the index of the string I'm looking for, then use substr to find the context of the input string (a few indexes ahead and behind).
Now, I need to link to the original page when a user clicks on a search result. My research says to use <a> tags, but how do I dynamically insert those into the HTML page with the index I have? And the index I have isn't even the complete page; it's stripped of tags.
These are the relevant parts of my code:
JavaScript:
function getIndicesOf(searchStr, str) { //get the indices of searchStr inside of str
var searchStrLen = searchStr.length;
if (searchStrLen == 0) {
return [];
}
var startIndex = 0, index, indices = [];
str = str.toLowerCase();
searchStr = searchStr.toLowerCase();
while ((index = str.indexOf(searchStr, startIndex)) > -1) {
indices.push(index);
startIndex = index + searchStrLen;
}
return indices;
}
function search() {
obj=document.getElementById("searchButton");
obj.onclick = function() {
var searchInput = document.getElementById('searchBox').value;
var allPageContent = ['chap/telem.php', 'chap/nestor.php', 'chap/aeolus.php', 'chap/calypso.php', 'chap/circe.php', 'chap/cyclops.php', 'chap/eumaeus.php', 'chap/hades.php','chap/ithaca.php', 'chap/lestry.php', 'chap/lotus.php', 'chap/nausicaa.php', 'chap/oxen.php', 'chap/penelope.php', 'chap/proteus.php', 'chap/scylla.php', 'chap/sirens.php', 'chap/wrocks.php']; //contains all text
var allText = '';
for (var i = 0; i < allPageContent.length; i++){
$.get(allPageContent[i], function(data){
var div = document.createElement("div");
div.innerHTML = data;
//allText = div.textContent || div.innerText || ""; //gets the text to search in, stripped of html
alltext = data;
allText = allText.replace(/(\r\n\t|\n|\r\t)/gm," ");
console.log(data);
var indices = getIndicesOf(searchInput, allText); //the variable indices is the array that contains the indices of the searched text in the main text
indices.forEach(findContext);
})
}
localStorage.output = '';
function findContext(currentValue, index) {
if (currentValue <= 16) {
searchContext = "..." + allText.substr(currentValue, 100) + "...";
} else {
searchContext = "..." + allText.substr(currentValue-15, 100) + "...";
}
localStorage.output = localStorage.output + searchContext + "<br /><br />";
}
console.log(localStorage.output);
};
};
HTML:
<script>document.getElementById("output").innerHTML = localStorage.output;</script>
It's a bit confusing what you're trying to achieve, considering your HTML, but replying to this
My research says to use <a> tags, but how do I dynamically insert
those into the HTML page with the index I have?
this would do the trick
var output = document.getElementById("output");
var a = document.createElement("a");
var linkText = document.createTextNode("my linked text");
a.appendChild(linkText);
a.href = "http://example.com";
output.appendChild(a);

Limit length of textarea in Words using Javascript?

I have the following bind on keyup which alerts if they go over 150 characters, but you can just press okay and keep typing and then just keep pressing okay.
I want to crop them at 150 words (not characters) and if they type over it, remove the extras. But I can't seem to figure out how to do it, I can figure out characters. But not words.
jQuery('textarea').keyup(function() {
var $this, wordcount;
$this = $(this);
wordcount = $this.val().split(/\b[\s,\.-:;]*/).length;
if (wordcount > 150) {
jQuery(".word_count span").text("150");
return alert("You've reached the maximum allowed words.");
} else {
return jQuery(".word_count span").text(wordcount);
}
});
/**
* jQuery.textareaCounter
* Version 1.0
* Copyright (c) 2011 c.bavota - http://bavotasan.com
* Dual licensed under MIT and GPL.
* Date: 10/20/2011
**/
(function($){
$.fn.textareaCounter = function(options) {
// setting the defaults
// $("textarea").textareaCounter({ limit: 100 });
var defaults = {
limit: 100
};
var options = $.extend(defaults, options);
// and the plugin begins
return this.each(function() {
var obj, text, wordcount, limited;
obj = $(this);
obj.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">Max. '+options.limit+' words</span>');
obj.keyup(function() {
text = obj.val();
if(text === "") {
wordcount = 0;
} else {
wordcount = $.trim(text).split(" ").length;
}
if(wordcount > options.limit) {
$("#counter-text").html('<span style="color: #DD0000;">0 words left</span>');
limited = $.trim(text).split(" ", options.limit);
limited = limited.join(" ");
$(this).val(limited);
} else {
$("#counter-text").html((options.limit - wordcount)+' words left');
}
});
});
};
})(jQuery);
Load that up and then you can use the following to make it work:
$("textarea").textareaCounter({ limit: 100 });
http://bavotasan.com/2011/simple-textarea-word-counter-jquery-plugin/
If you want to prevent the typing itself (when count > 150) you can do as following:
Use keypress instead of keyup
Instead of return alert() first do an alert() and then return false;
You may also want to add change (or blur) event handler to handle text pasting.
var maxWords = 150;
jQuery('textarea').keypress(function() {
var $this, wordcount;
$this = $(this);
wordcount = $this.val().split(/\b[\s,\.-:;]*/).length;
if (wordcount > maxWords) {
jQuery(".word_count span").text("" + maxWords);
alert("You've reached the maximum allowed words.");
return false;
} else {
return jQuery(".word_count span").text(wordcount);
}
});
jQuery('textarea').change(function() {
var words = $(this).val().split(/\b[\s,\.-:;]*/);
if (words.length > maxWords) {
words.splice(maxWords);
$(this).val(words.join(""));
alert("You've reached the maximum allowed words. Extra words removed.");
}
});​
Fiddle here
Check jQuery: Count words in real time
and this example: http://jsfiddle.net/gilly3/YJVPZ/1/
Then, if you want to cut the extra words... you could do something like:
var maxWords = 10;
if(finalCount > maxWords){
$("#a").val(a.value.slice(0,-2)); // the -2 is to remove the extra space at the end
};
Here is a working example http://jsfiddle.net/YJVPZ/80/
Hope it helps, Good Luck!
Try this function. The value argument should be your textarea value.
jQuery('textarea').val();
function wordcount(value)
{
value = value.replace(/\s+/g," ");
var andchr = value.split(" & ").length - 1;
var char_count = value.length;
var fullStr = value + " ";
//word count for regional language
v = value.split(' ');
var word_count1 = v.length;
var cheArr = Array('#','.','"',"'",'_','-','+','=',';','&','*','\(','\)','{','}','[','}','|','\\','\,','/');
for(i=0; i<=cheArr.length; i++)
{
word_count1 = word_count1 + value.split(cheArr[i]).length - 1;
}
//word count for all languages
var initial_whitespace_rExp = /^[^A-Za-z0-9]+/gi;
var left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");
var non_alphanumerics_rExp = rExp = /[^A-Za-z0-9]+/gi;
var cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");
var splitString = cleanedStr.split(" ");
var word_count = (splitString.length - 1) + andchr;
if(word_count1 > word_count)
{
word_count = word_count1;
}
if(value == '' || value == null || typeof(value) == 'undefined'){
word_count = 0;
}
alert(word_count);
}
$("textarea").keyup(function(){
var obj = $(this);
var maxLen = 150;
var val = obj.val();
var chars = val.length;
if(chars > maxLen){
obj.val(val.substring(0,maxLen));
}
});
Register to these events:
$('textarea').on('paste cut keydown', function(){...});

Javascript to render kbd tagged elements

I would like to write a (Javascript?) function to be included in HTML pages that allows me to render the function arguments tagged as kbd separated by "+"s and able to take an arbitrary number of input arguments.
So, for example, fnRenderKBD(Ctrl+X, Y, Z) would render as Ctrl+X+Y+Z.
The important thing is that the function should be able to take a variable number of arguments.
Is it possible to write such a function (if so, how)? I have next to no knowledge of JS.
My answer at the bottom is not the best thing I have ever written. A better solution would look something like:
function fnRenderKBD(elem, keysToDisplay) {
var delimiter = '';
var content = null;
for(var i = 0, length = keysToDisplay.length; i < length; i++) {
var renderedKey = document.createElement('kbd');
renderedKey = setText(renderedKey, keysToDisplay[i]);
if (i > 0) {
elem.appendChild(document.createTextNode('+'));
}
elem.appendChild(renderedKey);
}
}
function setText(elem, text) {
if (elem.textContent){
elem.textContent = text;
}else{
elem.innerText = text;
}
return elem;
}
(function() {
var keys = [
'Ctrl+X',
'Y',
'Z'
];
var elem = document.getElementById('display');
fnRenderKBD(elem, keys);
}());​
Demo: http://jsfiddle.net/wPg7z/
Something like this should work:
function fnRenderKBD(elem, keysToDisplay)
{
var delimiter = '';
var content = '';
for(var i = 0, length = keysToDisplay.length; i < length; i++) {
content+= delimiter + '<kbd>' + keysToDisplay[i] + '</kbd>';
delimiter = '+';
}
elem.innerHTML = content;
}
(function() {
var keys = [
'Ctrl+X',
'Y',
'Z'
];
var elem = document.getElementById('display');
fnRenderKBD(elem, keys);
})();
​
Demo: http://jsfiddle.net/gTYxP/1/

How to get the word on which a click was made in javascript

can we get the word on which a right click was made and x,y coordinates of that word ?
i tried:
document.onclick=getTextOnClick;
function getTextOnClick(e)
{
console.log(e);
if (window.getSelection) {
txt = window.getSelection();
console.log(">>>"+txt);
} else if (document.getSelection) {
// FireFox
txt = document.getSelection();
console.log(txt);
} else if (document.selection) {
// IE 6/7
txt = document.selection.createRange().text;
console.log(txt);
}
}
Now this code works if i select some text, but can i get the same when i just eight click or click on certain word ? And event object is giving me coordinates of click. can i get coordinates of the word on which the click was made ? Plz help
This can be done with pure JavaScript, assuming your container contain "simple" words only:
window.onload = function() {
var oDiv = document.getElementById("Container");
var rawHTML = oDiv.innerHTML;
var arrWords = rawHTML.split(" ");
oDiv.innerHTML = "";
for (var i = 0; i < arrWords.length; i++) {
var curWord = arrWords[i];
var curSpan = document.createElement("span");
curSpan.innerHTML = curWord;
if (i < (arrWords.length - 1))
curSpan.innerHTML += " ";
curSpan.onclick = WordClicked;
curSpan.oncontextmenu = WordClicked;
oDiv.appendChild(curSpan);
}
};
function WordClicked() {
var word = this.innerHTML;
alert("You clicked: " + word);
return false;
}
Live test case - handles both left and right click.
One way that comes to mind is putting each word in a span of its own. Apart from that, I think it will be difficult to find a solution that runs consistently on all browsers.
Thy this ?
Text ->
<div id="foo">Hello I am a text. I have no clue why I am here or
what I am good for, but I have QUOTES and other things I can offer.</div>
jQuery ->
$('#foo').contents().each(function(_, node) {
var nodelist = node.textContent.split(/\s/).map(function( word ) {
return $('<span>', {
text: word + ' ',
click: function() {
alert( $(this).text() );
}
}).get(0);
});
$('#foo').empty().append(nodelist);
});
Demo -> http://jsfiddle.net/qLuEF/

Categories

Resources