Wrap individual character in <span> on keyUp using jQuery - javascript

I want to wrap each character to wrapped in a <span></span> and desire output is <span>a</span><span>b</span><span>c</span>.
I have tried following but its not helping.
JSFIDDLE
<div contenteditable="true" id="text1" type="text" placeholder="type something...">
$(function() {
$("#text1").keyup(function(event) {
$(this).wrapInner( "<span class='test'></span>" )
});
});
It outputs following; which is not what I required. Any help?
<span class="test">
<span class="test">
<span class="test">
<span class="test">ffdf</span>
</span>
</span>
</span>

Here is my solution. There is tag code below the input div, for control what is content of the div:
txt = $("#text1").html();
$("#out").text(txt);
$(function() {
$("#text1").keyup(function(event) {
txt = txt + "<span class='test'>"+String.fromCharCode(event.which)+"</span>";
$(this).html(txt);
$("#out").text($(this).html());
});
});
#text1 {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
<code id="out"></code>
Pure function of replacing char looks like:
txt = $("#text1").html();
$(function() {
$("#text1").keyup(function(event) {
txt += "<span>" + String.fromCharCode(event.which) + "</span>";
$(this).html(txt);
});
});
Here is another one where case-sensitive func keypress used along with preventDefault() to prevent a redundant character appear:
txt = $("#text1").html();
$(function() {
$("#text1").keypress(function(event) {
txt += "<span>" + String.fromCharCode(event.which) + "</span>";
event.preventDefault();
$(this).html(txt);
$("#out").text(txt);
});
});
#text1 {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
<code id="out"></code>

is this what you need ?
$(function(){
$("#text1").keyup(function(event) {
$('.test').each(function (index) {
var characters = $(this).text().split("");
$this = $(this);
$this.empty();
$.each(characters, function (i, el) {
$this.append("<span>" + el + "</span");
});
});
});
});
#text1 {
background: #ccc none repeat scroll 0 0;
height: 24px;
width: 127px;
}
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
<span class="test">ffdf</span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

May be try using text() and do substr() ti get last character entered recently and add the <span>
$(document).ready(function() {
$("#text1").keyup(function(event) {
var txt = $(this).text();
$(this).wrapInner("<span class='test'>" + txt.substr(txt.length, txt.length - 1) + "</span>");
});
});
#text1 {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something...">

You need to split the content by .split("")
var myText = $("#text").html();
var myTextArr = myText.split("");
$("#text").empty();
myTextArr.forEach(function(val, idx){
$("#text").append("<span class='test'>" + val + "</span>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='text'>ABC</div>

Since goal is to type/replace (simultaneously!), i have used this:
arr=[];
$(function() {
$("#text1").keyup(function(event) {
clean=$( this )
.contents()
.filter(function() {
return this.nodeType === 3;
}).text();
output="";
arr.push(clean.charAt(clean.length-1));
for(i=0;i<arr.length;i++) {
output+="<span class='test'>"+arr[i]+"</span>";
}
$(this).html(output);
//console.log(output);
});
});
#text1 {
border: 1px solid #ccc;
height:200px;
}
.test {
background:pink;
color:white;
margin-left:3px;
display:inline-block;
width:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
So, first - filter just text inside div, and wrap it with desired html.
P.S. span CSS is here just for test purposes.
P.S. 2 Not sure about white spaces (and desired functionality) - but they can be removed, too...
Test without span CSS: https://jsfiddle.net/aau75w9q/4/ (produced HTML is what is required, if i understand correctly)

What about splitting your string first ?
$(function() {
$("#text1").keyup(function(event) {
$(this).text().split('').wrapInner( "<span class='test'></span>" )
});
});

Related

Highlight matched text

I want to implement highlight feature of Notepad++ in HTML, where notepad++ highlights selected words if found in the file. I have been able to mimic a bit only where the highlight happens only on a mouse click in the same div.
I want to change it so the highlight happens in div2 when text is selected in div1 and is found in div2, else div2 is same as div1. Also it should work except any mouse click and with multi words.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>highlight matching text</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
.found {
color: red;
}
</style>
<script>
function replaceText() {
$("#div1").find(".found").removeClass("found");
var searchword = $("#searchtxt").val();
var custfilter = new RegExp(searchword, "ig");
var repstr = "<span class='found'>" + searchword + "</span>";
if (searchword != "") {
$('#div1').each(function() {
$(this).html($(this).html().replace(custfilter, repstr));
})
}
}
</script>
</head>
<body>
<input type="text" id="searchtxt" placeholder="keyword" />
<input type="button" value="search" onClick="replaceText();" id="highlightButton" />
<p id="div1">I'm here but not here. Not here also. But I'm here too.</p>
<p id="div2"> </p>
</body>
</html>
Try this:
const div1 = document.getElementById("div1"),
div2 = document.getElementById("div2"),
isParent = (obj, parent) => !obj || obj === parent ? obj : isParent(obj.parentNode, parent);
/*
isParent is a short version of:
function isParent(obj, parent)
{
if (!obj || obj === parent)
{
return obj;
}
else
{
return isParent(obj.parentNode, parent);
}
}
*/
div1.addEventListener("click", e =>
{
const sel = document.getSelection();
/*
sel.anchorNode: element the selection started at
sel.focusNode: element the selection ended at
we only accept selection of div1 text
check if both of these elements are children of div1, otherwise exit
*/
if (!isParent(sel.anchorNode, div1) || !isParent(sel.focusNode, div1))
return;
const text = sel.toString() //get selected text
.trim() //trim trailing white spaces
//make it html friendly
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
//make it regex friendly
.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
if (text === "")
return;
div2.innerHTML = div2.innerHTML
//remove old highlightings
.replace(/<mark>([^<]*)?<\/mark>/g, "$1")
// convert selected text into regex,
// search and enclose found strings with <mark></mark>
.replace(new RegExp("(" + text + ")", "gi"), '<mark>$1</mark>'); //add new highlighting
});
/*
second paragraph marks
*/
p:first-child + p mark {
background-color: lightgreen;
}
#div1, #div2
{
border: 1px solid black;
padding: 1em;
}
#div2
{
background-color: #E0E0E0;
margin-top: -1px;
}
<div id="div1">
<p>I'm here but not here. Not here also. But I'm here too. <span>blah</span></p>
</div>
<div id="div2">
<p>But I'm here too. <span>blah</span> <span>blah</span></p>
<p>And also here.</p>
<p>Third paragraph, has "And also here."</p>
</div>

Add text to specific DIV

How to append text to a specific <div> if i know the ID of the <div>?
For example, here's my code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
function appendDIV(idDIV, txt) {
$("#" + idDIV).append('<p>' + txt + '</p>');
}
appendDIV("content-01", "some text");
</script>
<div id="content-01" style="float: left; width: 150px; height: 150px; border: 2px solid red;"></div>
Function accepts the ID of the <div> and some text, but nothing happens.
What's going wrong?
code for getting each p in side div you should do like this
Working
// Shorthand for $( document ).ready()
$(function() {
appendDIV("content-01", "some text");
//get all p element and go through each
$('#content-01 > p').each(function( index ) {
console.log( index + ": " + $( this ).text() );
console.log( "id of element" + $(this).attr('id'));
});
});
function appendDIV(idDIV, txt) {
$("#" + idDIV).append('<p>' + txt + '</p>');
}
Working Demo
you should allows to load DOM first before doing any manipulation , so for that you should write you code in document.ready method provided in jquery, which get called when DOM is ready
// Shorthand for $( document ).ready()
$(function() {
appendDIV("content-01", "some text");
});
add code as above. that will do . Read here : $( document ).ready()
You might also consider a custom trigger, passing values, for example if you want a click event on the DIV, then insert some stuff:
$('body').on('appenddiv', function(event, idDIV, txt) {
$("#" + idDIV).append('<p>' + txt + '</p>');
});
// some where later in code:
$(".mydiv-group").on('click', function() {
let myid = $(this).attr('id');
let mytext = myid + ": some text";
$('body').trigger('appenddiv', [myid, mytext]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mydiv-group" id="content-01" style="float: left; width: 150px; height: 150px; border: 2px solid red;"></div>
<div class="mydiv-group" id="content-02" style="float: left; width: 150px; height: 150px; border: 2px solid red;"></div>

How to select the previous element using jquery "on"?

I am trying to edit the text on a label.
I want to:
Show a label and hidden text Box.
On click of label: label gets hide and text Box shows where I can edit text.
On Enter, text Box should hide and label should display the entered text.
Here is the sample code.
But its not working as expected.
<h4>Editable labels (below)</h4>
<span class="k-link">
<label class="pull-left">Dashboard</label>
<input class="clickedit" type="text" id="731"/>
</span>
Demo
Check out this Demo.
Change the code from
$('.k-link').on('click', ".clickedit.prev()", function (event) {..
into
$('.k-link').on('click', ".pull-left", function (event) {..
And add inline css style for
<input class="clickedit" type="text" id="731" style="display:none"/>
Is this the functionality you want?
$(document).on('click', '#label', function() {
var that = $(this);
that.hide();
$('#731').removeClass('hidden');
});
$(document).on('focusout', '#731', function() {
var that = $(this);
var val = that.val();
that.hide();
$('#label').after('<span>' + val + '</span>');
});
.hidden { display:none }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h4>Editable labels (below)</h4>
<span class="k-link">
<label id="label" class="pull-left">Dashboard</label>
<input class="clickedit hidden" type="text" id="731"/>
</span>
This works:
$(document).ready(function(){
$(".clickedit").hide()
$(".pull-left").on("click", function(){
$(this).hide()
$(".clickedit").show()
});
$(".clickedit").on("blur", function(){
$(this).hide()
$(".pull-left").text($(this).val()).show()
});
});
this is working check it
i have just edit the selector it was .clickedit.prev() and i have change it to .pull-left
$('.k-link').on('click', ".pull-left", function (event) {
$(this).hide();
$(this).next().show().focus();
event.stopPropagation();
});
http://jsfiddle.net/anisboukhris/qho0uLzv/
may be try this:
$(document).ready(function(){
$("#f1").hide();
$("#text").hide();
var $curr = $( "#start" );
$curr.css( "background", "#f99" );
$( "button" ).on('click',function() {
$curr = $curr.prev();// this will go to previous div as you have asked how to get previous element.
$curr.show();
});
$( "#label" ).on('click',function() {
$("#label").hide();
$("#text").show();
$( "#text" ).blur(function() {
$("#label").show();
$("#text").hide();
$("#label").html($("#text").val());
});
});
});
div {
width: 150px;
height: 40px;
margin: 10px;
float: left;
border: 2px blue solid;
padding: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="f1"><span id="label">Came to previous div</span><input type="text" id="text" /></div>
<div id="start"></div>
<p><button>Go to Prev</button></p>

Custom html tab implementation problems

my use case : create tab like experience. clicking on add button creates a (horz tab button) and a corresponding div, which is linked via onclick listener, dynamically.
problems :
on clicking add button, values from previous tabs are reset (which is obvious wrt to the way $tabs_prev & $menu_prev is populated) and
their respective js goes away (which I can't understand, why?)
a remove tab implementation (because the way I've coded these tabs, removing a tab and corresponding div isn't really simple, so, any clues in this direction, maybe?)
code : fiddle : http://jsfiddle.net/g58fzs75/1/
HTML:
<body>
<input id="hidden" type="hidden" value="1"></input>
<div id="template_tabBtn" style="display:none">
<input type="button" value="add" onclick="addTab()"></input>
</div>
<ul id="menu">
</ul>
<div id="tabs">
</div>
<div id="template_tabBar" style="display:none">
<li>
<input type="button" id="tab_btn" class="template_tabBar" value="Tab" onclick="tabClick(this)"></input>
</li>
</div>
<div id="template_tabs" style="display:none">
<div id="tabs" class="template_tabs tab_div" value="1">
<input type="text" id="txt" class="template_tabs" value="alert"></input>
<input type="button" id="btn" class="template_tabs" value="alert"></input>
</div>
</div>
</body>
CSS:
<style>
ul#menu {
padding: 0;
}
ul#menu li {
display: inline;
}
ul#menu li input {
background-color: black;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 4px 4px 0 0;
}
ul#menu li input:hover {
background-color: orange;
}
</style>
jQuery :
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script>
$tabs_prev = "";
$menu_prev = "";
$add_btn = "";
$current_tabID = "";
function tabClick(id) {
showCurrent($(id).attr('id'));
}
function addTab() {
var tabCount = parseInt($('#hidden').val()) + 1;
$('#hidden').val(tabCount);
run(tabCount);
showCurrent($('#tabs-' + tabCount).attr('id'));
}
$(document).ready(function() {
$add_btn = "<li>" + $('#template_tabBtn').html() + "</li>";
run(1);
});
function run(tabCount) {
//$tabs_prev += main($('#template_tabs'),tabCount);//alert("tabs\n"+$tabs_prev);
$menu_prev += main($('#template_tabBar'), tabCount); //alert("menu\n"+$menu_prev);
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
$('#menu').html($menu_prev + $add_btn);
logic(tabCount);
}
function main(target, tabCount) {
$htmlBackup = $(target).html();
$('.' + $(target).attr('id')).each(function() {
$(this).attr('id', $(this).attr('id') + "-" + tabCount).removeClass($(target).attr('id'));
$(this).attr('value', $(this).attr('value') + "-" + tabCount);
});
$html = $(target).html();
$(target).html($htmlBackup);
return $html;
}
function logic(tabCount) {
$('#btn-' + tabCount).click(function() {
alert($('#txt-' + tabCount).val());
});
}
function showCurrent(current_id) {
$('.tab_div').each(function() {
var id = $(this).attr('id');
var id_num = id.substr(id.lastIndexOf('-') + 1, id.length);
var current_id_num = current_id.substr(current_id.lastIndexOf('-') + 1, current_id.length);
if (id_num == current_id_num) {
$("#tabs-" + id_num).show();
$('#tab_btn-' + id_num).css({
"background-color": "orange"
});
} else {
$("#tabs-" + id_num).hide();
$('#tab_btn-' + id_num).css({
"background-color": "black"
});
}
});
}
</script>
The reason why your javascript is disappearing is because resetting the innerHTML deletes the onclick handlers on the elements. Why: the original elements are destroyed, including references to events and new elements are created.
The code responsible for this:
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
Please use jQuery's appending of an element by cloning the template tab:
$('#tabs').append($('#template_tabs').clone(true));
Append appends htmlstrings or elements to an parent element. It's a buffed up version of the documents native 'appendChild'.
clone clone the template element (makes a copy). You can do this in your function main and return it to the append function.
function main(tabCount)
{
var node = $('#template_tabs').clone(true));
//do things with the node, like setting an onclick handler, or id.
//example
node.setAttribute("id", "tab" + tabCount);
}
Removing can be done also:
function removeNode(node)
{
//provide a node via jQuery
//example: removeNode($("#tab2")) <-- now tab2 will be removed from the DOM.
node.remove();
}

jQuery insert after the last element

I want to add elements after the last one.
My current code
<div class="find"><div id="FirstElement"> /*First element loaded first */ </div><div>
$('#AddNextElement' + id).click(function (e) {
$('<div id="NextElement' + id +'">' + /*Add after the last element*/ + '</div>').insertAfter($("#FirstElement"));
}
Current it adds only it after the first element:
1
4
3
2
I want it to add after the last element every time:
1
2
3
4
I've followed these links and I didn't find what I'm looking for:
jQuery insertAfter last item
insertAfter specific element based on ID
jQuery: Add element after another element
Thank you in advance!.
How I fixed it:
$('#AddNextElement' + id).click(function (e) {
$('<div id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>').insertAfter($("#FirstElement").parent().find('.Finder').last());
}
I found the .parent().find('.find').last(); then insert after the last
Just you need last() method
$('<div id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>')
.insertAfter($('[id^="NextElement"]').last());
How about adding a class to all elements? It will be easier to find the last:
$('.element-class:last').after('<div class="element-class" id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>');
This of course means that your First element must also have the class:
<div class="element-class" id="FirstElement"> /*First element loaded first */ </div>
Find the last element in the DOM, in your case it'll be 'NextElementxx' and then use 'after':
$('#NextElement2').after( ..new stuff.. );
HTML:
<div id="FirstElement"> First element loaded first </div>
<div id="AddNextElement">Click me</div>
JS:
var current = 0;
$('#AddNextElement').click(function (e) {
var $el = (current == 0) ? $("#FirstElement") : $("#NextElement"+current);
current++;
$('<div id="NextElement' + current +'">Other element '+current+'</div>').insertAfter($el);
});
Try yourself on jsfiddle
You can just use this:
jQuery('##AddNextElement').last().after();
one way is to store the last element.
<div id="FirstElement"> /*First element loaded first */ </div>
var lastElement = $('#FirstElement');
$('#AddNextElement' + id).click(function (e) {
var element = $('<div id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>'));
element.insertAfter(lastElement);
lastElement = element;
}
You can try below code, it will add the new div after the last "NextElement" div
JS Code:
$(function(){
$('#AddNextElementButton').on("click", function (e) {
var id = $("[id^='NextElement']").length ? $("[id^='NextElement']").length+1 : 1;
if($("[id^='NextElement']").length){
$('<div id="NextElement'+ id +'">Add after the last element</div>').insertAfter($('[id^="NextElement"]').last());
} else {
$('<div id="NextElement'+ id +'">Add after the last element</div>').insertAfter($('#FirstElement'));
}
});
});
**hope this will make you understand well GitHub:Omar-baksh **
// code by GitHub: omar-baksh
// jquery is required online !!
/*
//this scricp test if jquery loded
window.onload = function() {
if (window.jQuery) {
// jQuery is loaded
alert("Yeah!");
} else {
// jQuery is not loaded
alert("Doesn't Work");
}
}
*/
var gfather = document.getElementsByClassName('Gfather');
var father = document.getElementsByClassName('father');
var son = document.getElementsByClassName('son');
function gf(argument) {
$(gfather).mouseenter(function(){
for (let i = 0; i < father.length; i++) {
father[i].style.display='block';
};
// show father fun() body show body last ...
});
$(father).mouseenter(function(){
for (let i = 0; i < son.length; i++) {
son[i].style.display='block';
};
// son show body last ...
});
// gf body last ...
}
// show form setting bottun fun()
function add(){
const x = document.getElementById("frm").style.display='block';
alert('setting opened');
}
// form add element fun()
var clslist=document.getElementsByClassName("list");
var inher =document.getElementById("level");
var num =document.getElementById("num").value;
var txt =document.getElementById("inp-text");
// var add-btn = document.getElementById("btn-secsuce");
/*
$("#inher").change(function () {
alert(inher);
document.getElementById("inp-text")="you selected"+ document.getElementById("level").value;
// body...
});
*/
var clss ="";
var ii;
$( "#btn-secsuce" ).click(function () {
//txt.value="class name "+inher.value;
if( String(inher.value) =="Grand father"){
clss ="Gfather";
jQuery('<div/>', {
id: Math.ceil(Math.random() * 999),
text:txt.value,
"class": clss,
title: clss+clss.length
}).appendTo(clslist);
alert("add class "+inher.value+gfather.length);
}
else { // alert("class enhhert is roung you chose " +inher.value )
}
/// add father to g father
if( String(inher.value) =="father"){
var txt2 = $("<div class="+"father"+"></div>").text(txt.value);
$(father[num-1]).after(txt2);
}
else{
}
});
.Gfather{
width: 60px;
height: auto;
border-left: 6px dashed red;
border-bottom: 6px dashed red;
 background-color: silver;
top:0;
display:block;
position:relative ;
margin-left:9px;
white-space: nowrap;
}
.father{
width: 60px;
border-left: 6px dashed red;
border-bottom: 6px dashed red;
bottom:0;
padding-top:0px;
border-right-width: small;
left:66px;
white-space: nowrap;
position:relative ;
background-color: #550088;
color:white;
display: block;
}
<head>
<title>tree js</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="./tree.css">
</head>
<body>
<div class="list">
<div class ="Gfather" onmouseover="gf();">
grand father 1
</div>
<div class ="father">
father
</div>
<div class ="son">son
</div>
<div class ="son">son
</div>
</div>
<!-- add element show setting btn -->
<button id="add" onclick="add()" > add setting</button>
<form id="frm">
<h6>1</h6>
<select id="level">
<option>Grand father</option>
<option>father</option>
<option>son</option>
</select>
<h6>2</h6>
<select id="num">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
</select>
<br>
<h6>3</h6>
<input id="inp-text" type="text">
<h5 >4</h5>
<button type="button" id="btn-secsuce" >Add The Element </button>
</form>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<script type="text/javascript" src="./tree.js"></script>

Categories