Highlight images on page when the user clicks on them - javascript

I want to add CSS style with JavaScript: "padding", "background", and "border" to the image clicked by the user, when the user clicks again on that image, the highlight effect is removed.
var imagesProp = {
'padding': '3px',
'backgroundColor': '#eded01',
'borderSize': '1ps',
'borderStyle': 'dashed',
'borderColor': '#0001fe'
};
function highlightimages() {
var allimages = document.getElementsByid('images');
//How do i start from here
}

var imagesProp = {
'padding': '3px',
'backgroundColor': '#eded01',
'borderSize': '1ps',
'borderStyle': 'dashed',
'borderColor': '#0001fe'
};
function highlightImages() {
//You do not use getElementsByid but getElementsByTagName
var allimages = document.getElementsByTagName('img');
var nrallimgs = allimages.length;
// traverses the <img> elements, and register onclick to each one
// else, apply the properties defined in $imagesProp
for(i=0; i<nrallimgs; i++) {
allimages[i].onclick=function() {
if(this.style.borderStyle == imagesProp.borderStyle) {
this.style.padding = 'auto';
this.style.background = 'none';
this.style.border = 'none';
}
else {
this.style.padding = imagesProp.padding;
this.style.backgroundColor = imagesProp.backgroundColor;
this.style.borderSize = imagesProp.borderSize;
this.style.borderStyle = imagesProp.borderStyle;
this.style.borderColor = imagesProp.borderColor;
}
}
}
}
// calls the highlightImages() function to apply the effect
highlightImages();

Create a css class
highlighted {
padding: '3px';
backgroundColor: '#eded01';
borderSize: '1ps';
borderStyle: 'dashed';
borderColor: '#0001fe'
}
Using jQuery:
var $element = $('#elementid');
$element.click(function () {
$(this).toogleClass('highligted');
});

Related

How to change color of the background in table cell for two seconds? and go back to default

In the below javaScript code:
function webSocketStart()
{ //onclick() of a button
document.getElementById("button").disabled = true;
var wsock = new WebSocket("ws://127.0.0.1:1234/websock");
wsock.onmessage = function (evt)
{
var map = JSON.parse(evt.data)
var myTable = document.getElementById("myTable");
var rows = myTable.getElementsByTagName("tr")
var existing = false
for (var i = 1; i < rows.length; i++) {
if (rows[i].getElementsByTagName("td").length > 0) {
if (rows[i].cells[0].textContent.trim().localeCompare(map['Key'].trim()) == 0){
rows[i].cells[1].textContent = map['Value'] // cell color should change and unchange for two seconds
existing = true
break
}
}
}
if (!existingApp){
var row = myTable.insertRow(1); // New row at the first position
var keyCell = row.insertCell(0)
keyCell.textContent = map['Key']
keyCell.style.backgroundColor = 'yellow'
setInterval(function(){
keyCell.style.backgroundColor = 'white'
}, 2000);
var valueCell = row.insertCell(1)
valueCell.textContent = map['Value']
valueCell.style.backgroundColor = 'yellow'
setTimeout(function(){
valueCell.style.backgroundColor = 'white'
}, 2000);
}
Line 17, 26 & 27 have comments for color change and unchange
Edit:
Made code changes with setTimeout() but some cells does not change back to white
for (var i = 1; i < rows.length; i++) {
if (rows[i].getElementsByTagName("td").length > 0) {
if (rows[i].cells[0].textContent.trim().localeCompare(map['Key'].trim()) == 0){
rows[i].cells[1].textContent = map['Value']
rows[i].cells[1].style.backgroundColor = 'yellow' // color change
existing = true
setTimeout(function(){
rows[i].cells[1].style.backgroundColor = 'white'
}, 2000);
break
}
}
}
if (!existing){
var row = myTable.insertRow(1);
keyObj = row.insertCell(0)
keyObj.textContent = map['Key']
keyObj.style.backgroundColor = 'yellow' // color change
setInterval(function(){
keyObj.style.backgroundColor = 'white'
}, 2000);
keyObj = row.insertCell(1)
keyObj.textContent = map['Value']
keyObj.style.backgroundColor = 'yellow' // color change
setTimeout(function(){
keyObj.style.backgroundColor = 'white'
}, 2000);
}
Using CSS & JavaScript,
1) How to change and unchange the color of the background in table cell, for 2 seconds? after setting of values in table cell
2)
As table element has style properties, Can we achieve the same without CSS rules? rows[i].cells[1].style.backgroundColor = 'yellow'
You can just use sleep function with the seconds inside like sleep(2) for 2 seconds
Is it what's you want
You're already getting the element so you would add a class in JS like this:
el.classList.add('className'); Then you need to set a timer setInterval(function, milliseconds) that removes the class after a set amount of time. The CSS will then revert back to default. I added a CSS transition to the color so it's not as jarring when it changes.
(click handler is just for the example)
var removeClass = function(targ){
if(targ.classList.contains('highlight')){
targ.classList.remove('highlight');
}
}
document.getElementById('myEl').addEventListener('click', function () {
var myEl = this
myEl.classList.add('highlight');
var myTimer = setInterval(function(){removeClass(myEl)},2000);
});
#myEl {
width: 30px;
height: 30px;
margin: 10px;
background-color: aqua;
transition: background 0.25s ease;
}
#myEl.highlight {
background-color: orange;
}
<div id='myEl'></div>
Click the box to activate the timer

How trigger event listening for shapes on a layer when button clicked?

In KonvaJS, is it possible to make a layer inactive (but not invisible) upon clicking a button, then active on clicking another button? I've tried "text_overlay.listening(false);" but it doesn't work. I can deactivate individual textNodes with "textNode0.listening(false);", which does prevent the user from editing that text, but these textNodes are positioned over polygons, some of which are quite small (e.g., Luxembourg on a map of Europe) and the textarea prevents the user from clicking the polygon underneath (e.g., to change its fill color). Also, there will be over 40 textNodes to deal with, so deactivating 1 layer is far preferable!
Here's the button section of the HTML file:
<script src="js/text-input21.js"></script>
<!-- button events -->
<script>
// button states on load
var btnLabelClicked = true;
var btnColorClicked = false;
var btnDrawLinesClicked = false;
//color chip buttons
var btnViolet = document.getElementById("fillViolet");
var btnOrange = document.getElementById("fillOrange");
var btnYellow = document.getElementById("fillYellow");
//color chip buttons' fill when btnLabelClicked = true
btnViolet.style.background = disableBtnFill;
btnOrange.style.background = disableBtnFill;
btnYellow.style.background = disableBtnFill;
var buttonID = 'btnLabel';
function replyClick(clickedID) {
buttonID = (clickedID);
if (buttonID === 'btnColor') {
textNode0.listening(false);
textNode15.listening(false);
textNode16.listening(false);
btnViolet.disabled = false;
btnViolet.style.background = '#842dce';
btnOrange.disabled = false;
btnOrange.style.background = '#ffa500';
btnYellow.disabled = false;
btnYellow.style.background = '#ffff00';
btnLabelClicked = false;
btnColorClicked = true;
btnDrawLinesClicked = false;
} else if (btnColorClicked && (buttonID === 'fillViolet' || buttonID === 'fillOrange' || buttonID === 'fillYellow')) {
//text_overlay.listening(false);
textNode0.listening(false);
textNode15.listening(false);
textNode16.listening(false);
newFill = document.getElementById(buttonID).style.background;
} else if (buttonID === 'btnLabel' || buttonID === 'btnDrawLines' || buttonID === 'btnEraseLines' || buttonID === 'btnExport') {
//disable color buttons
btnColorClicked = false;
btnViolet.disabled = true;
btnViolet.style.background = disableBtnFill;
btnOrange.disabled = true;
btnOrange.style.background = disableBtnFill;
btnYellow.disabled = true;
btnYellow.style.background = disableBtnFill;
if (buttonID === 'btnLabel') {
textNode0.listening(true);
textNode15.listening(true);
textNode16.listening(true);
btnLabelClicked = true;
btnDrawLinesClicked = false;
} else { //buttonID is not btnLabel or any of the color buttons
textNode0.listening(false);
textNode15.listening(false);
textNode16.listening(false);
btnLabelClicked = false;
btnDrawLinesClicked = true;
}
}
}
</script>
And here's the text-input21.js file containing the text_overlay layer:
var text_overlay = new Konva.Layer({
listening: true
});
stage.add(text_overlay);
var textNode0 = new Konva.Text({
text: 'X',
x: 80, // centered between Ireland & Great Britain
y: 125,
width: 150,
height: 15,
fontFamily: 'Arial, Helvetica, "sans-serif"',
fontSize: 14,
align: 'center',
listening: true
});
var textNode15 = new Konva.Text({
text: 'X',
x: 230, // Luxembourg
y: 225,
width: 100,
height: 15,
fontFamily: 'Arial, Helvetica, "sans-serif"',
fontSize: 14,
align: 'center',
listening: true
});
var textNode16 = new Konva.Text({
text: 'X',
x: 175, // France
y: 290,
width: 100,
height: 15,
fontFamily: 'Arial, Helvetica, "sans-serif"',
fontSize: 14,
align: 'center',
listening: true
});
text_overlay.add(textNode0);
text_overlay.add(textNode15);
text_overlay.add(textNode16);
text_overlay.draw();
console.log(text_overlay.getZIndex());
textNode0.on('click', () => {
// create textarea over canvas with absolute position
// first we need to find its position
var textPosition = textNode0.getAbsolutePosition();
var stageBox = stage.getContainer().getBoundingClientRect();
var areaPosition = {
x: textPosition.x + stageBox.left,
y: textPosition.y + stageBox.top
};
// create textarea and style it
var textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.value = textNode0.text();
textarea.style.textAlign = 'center';
textarea.style.resize = 'none';
textarea.style.position = 'absolute';
textarea.style.left = areaPosition.x + 'px'; //positioning needs work
textarea.style.top = areaPosition.y + 'px';
textarea.style.width = textNode0.width();
textarea.style.background = 'transparent';
textarea.style.border = 1; // final border = 0
textarea.style.outline = 'none';
textarea.style.fontFamily = 'Arial, Helvetica, "sans-serif"';
textarea.style.fontSize = 14;
textarea.focus();
textarea.addEventListener('keydown', function (e) {
// hide on enter
if (e.keyCode === 13) {
textNode0.text(textarea.value);
text_overlay.draw();
document.body.removeChild(textarea);
}
});
})
textNode15.on('click', () => {
// create textarea over canvas with absolute position
// first we need to find its position
var textPosition = textNode15.getAbsolutePosition();
var stageBox = stage.getContainer().getBoundingClientRect();
var areaPosition = {
x: textPosition.x + stageBox.left,
y: textPosition.y + stageBox.top
};
// create textarea and style it
var textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.value = textNode15.text();
textarea.style.textAlign = 'center';
textarea.style.resize = 'none';
textarea.style.position = 'absolute';
textarea.style.left = areaPosition.x - 20 + 'px'; //positioning needs work
textarea.style.top = areaPosition.y - 20 + 'px';
textarea.style.width = textNode15.width();
textarea.style.background = 'transparent';
textarea.style.border = 1; // final border = 0
textarea.style.outline = 'none';
textarea.style.fontFamily = 'Arial, Helvetica, "sans-serif"';
textarea.style.fontSize = 14;
textarea.focus();
textarea.addEventListener('keydown', function (e) {
// hide on enter
if (e.keyCode === 13) {
textNode15.text(textarea.value);
text_overlay.draw();
document.body.removeChild(textarea);
}
});
})
textNode16.on('click', () => {
// create textarea over canvas with absolute position
// first we need to find its position
var textPosition = textNode16.getAbsolutePosition();
var stageBox = stage.getContainer().getBoundingClientRect();
var areaPosition = {
x: textPosition.x + stageBox.left,
y: textPosition.y + stageBox.top
};
// create textarea and style it
var textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.value = textNode16.text();
textarea.style.textAlign = 'center';
textarea.style.resize = 'none';
textarea.style.position = 'absolute';
textarea.style.left = areaPosition.x - 45 + 'px'; //positioning needs work
textarea.style.top = areaPosition.y - 20 + 'px';
textarea.style.width = textNode16.width();
textarea.style.background = 'transparent';
textarea.style.border = 1; // final border = 0
textarea.style.outline = 'none';
textarea.style.fontFamily = 'Arial, Helvetica, "sans-serif"';
textarea.style.fontSize = 14;
textarea.focus();
textarea.addEventListener('keydown', function (e) {
// hide on enter
if (e.keyCode === 13) {
textNode16.text(textarea.value);
text_overlay.draw();
document.body.removeChild(textarea);
}
});
})
// add the layer to the stage
stage.add(text_overlay);
From experiment, layer.listening() sets listening on the layer but not its contents. Its not intuitive, but it makes sense because a layer is actually an HTML5 canvas. For example, you could want to toggle tracking of mouse movement over the layer background but have the layers child shapes still be listening continuously, so then you need this.
You can set listening on the children using the getchildren function
// get all children
var children = layer.getChildren();
Then iterate the list and use setListening() on each member. The getChildren() function can be combined with the className filter to create subsets of child objects, so you could toggle all text elements, or all polygons, or all circles, etc. It's quite funky.
As a side note, and don't take this as criticism, your coding style seems not to be DRY. What I mean is, your click events for the textNode0, textNode15 and textNode16 are repetitive - I guess each time you realise you need to make a change to one you have to make it manually to all. That leaves you open to bugs by cut & paste or omission. Better to make a standard myTextNode object and have it include all the functionality that you want in a textNode, then pass in the unique parameters when you create each object. That way making a change to the myTextNode 'class' affects all of them at once. The label for this is 'JS Objects', but if you Google that you will be overloaded with information. Have a read of this at W3 Schools for a 'way in' to the subject. Forgive me if you know all this but there are a lot of countries for your textNodes.

SVG Map w/ JS- Changing the states of multiple paths on hover

I'm working on a clickable SVG map using the Raphael library and referencing details from this tutorial. I've also set up a working jsfiddle here. Basically, for each state in the map, I have paths defined for the map shape itself and for a state abbreviation label—in the case of the fiddle, I'm showing one state, PA, for demonstration purposes. I have separate arrays defined for "regions" and "labels". Currently, I have the hover state working for the state shape (changing its color to a dark blue), but would also like the state abbreviation label to change to white while hovering on the state.
I have the following arrays and loop defined to handle the hover and click events for the regions (shapes), and I would like to add logic that finds the matching label and changes its fill attribute to white on hover (and reverts on mouseout):
// REGION ARRAY
var regions = {};
regions["pennsylvania"] = {href: "#", path: map.path("path here")};
// LABEL ARRAY
var labels = {};
labels["pennsylvania"] = {href: "#", path: map.path("path here")};
// REGION STYLES
var animationSpeed = 500;
var shapeStyle = {
fill: "#cdd6e9",
stroke: "#fff",
"stroke-width": 0.25,
"stroke-linejoin": "round",
cursor: "pointer"
};
var hoverStyle = {
fill: "#0a3a62"
}
// REGION LOOP
for (var regionName in regions) {
(function(region) {
region.path.attr(shapeStyle);
region.path[0].addEventListener("mouseout", function() {
region.path.animate(shapeStyle, animationSpeed);
}, true);
region.path[0].addEventListener("mouseover", function() {
region.path.animate(hoverStyle, animationSpeed);
}, true);
region.path[0].addEventListener("click", function() {
location.href = region.href;
}, true);
})(regions[regionName]);
}
Thus, in looping through the regions array, how would I adjust the script to find the matching label in the labels array and change its fill state? Thanks for any insight here.
Set the label events while you're setting your region events so you can match on the regionName. You can either use the let keyword on your for loop or you can pass the regionName or both (regions[regionName],labels[regionName]) to the immediate function as #Ian suggested.
var labelHoverStyle = { // add
fill: '#FFFFFF'
}
var labelStyle = {
fill: "#0a3a62",
stroke: "#0a3a62",
"stroke-width": 0.25,
"stroke-linejoin": "round",
cursor: "pointer"
}
Using Let
for(let regionName in regions) { // notice the variable declaration
(function (region) {
if (regionName == "district-of-columbia") {
region.path.attr(shapeStyle2);
region.path[0].addEventListener("mouseout", function() {
region.path.animate(shapeStyle2, animationSpeed);
labels[regionName].path.animate(labelStyle, animationSpeed);
}, true);
} else {
region.path.attr(shapeStyle);
region.path[0].addEventListener("mouseout", function() {
region.path.animate(shapeStyle, animationSpeed);
labels[regionName].path.animate(labelStyle, animationSpeed);
}, true);
}
region.path[0].addEventListener("mouseover", function() {
region.path.animate(hoverStyle, animationSpeed);
labels[regionName].path.animate(labelHoverStyle, animationSpeed);
}, true);
region.path[0].addEventListener("click", function() {
location.href = region.href;
}, true);
})(regions[regionName]);
}
Passing regionName or (regions[regionName],labels[regionName])
for(var regionName in regions) {
(function (region, label) { // notice the parameters
if (region.href.indexOf('district-of-columbia') > -1) {
region.path.attr(shapeStyle2);
region.path[0].addEventListener("mouseout", function() {
region.path.animate(shapeStyle2, animationSpeed);
label.path.animate(labelStyle, animationSpeed);
}, true);
} else {
region.path.attr(shapeStyle);
region.path[0].addEventListener("mouseout", function() {
region.path.animate(shapeStyle, animationSpeed);
label.path.animate(labelStyle, animationSpeed);
}, true);
}
region.path[0].addEventListener("mouseover", function() {
region.path.animate(hoverStyle, animationSpeed);
label.path.animate(labelHoverStyle, animationSpeed);
}, true);
....
})(regions[regionName], labels[regionName]); // notice the arguments
}

How to access the index position i in the drag stop handler of snapsvg

I'm grouping a few elements using snapSVG's group method, pushing them to an array and applying the drag method on the array elements by looping through each element.
Could you please help me in accessing the index postion of the dragged element (grps[i]) in the drag stop handler.
g1 and var g2 are the two gropus.
grps is the array that holds the two groups.
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
</head>
JavaScript
var s = Snap(800, 600);
var grps = [];
var objects = [];
var red = s.rect(50, 50, 200, 200).attr({
fill: "red"
});
var green = s.rect(60, 60, 100, 100).attr({
fill: "green"
});
var g1 = s.group(red, green);
grps.push(g1);
var red = s.rect(300, 50, 200, 200).attr({
fill: "red"
});
var green = s.rect(310, 60, 100, 100).attr({
fill: "green"
});
var g2 = s.group(red, green);
grps.push(g1, g2);
var drag_move = function(dx, dy) {
this.attr({
transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
});
};
var drag_start = function() {
this.data('origTransform', this.transform().local);
};
var drag_stop = function(i) {
console.log("finished dragging");
console.log(i);
};
for (i = 0; i < grps.length; i++) {
grps[i].drag(drag_move, drag_start, drag_stop);
}
JsBin Link: http://jsbin.com/tonazosicu/10/edit?js
Thanks
You can using Function.prototype.bind() to preset some parameters like below
for (i = 0; i < grps.length; i++) {
grps[i].drag(drag_move, drag_start, drag_stop.bind(null, i));
}
Then on drag_stop you can access them like below.
var drag_stop = function(index, event) {
console.log("finished dragging");
console.log(index);
console.log(event);
};
One can achieve the same thing (in lastest versions of Snap I think) with...
grps.ForEach( function( el, i ) {
el.drag(drag_move, drag_start, drag_stop.bind(null, i))
};
But ultimately you don't need to use i, if you just use 'this' in the handler in most cases, and can simply do....
grps.ForEach( function( el ) {
el.drag(drag_move, drag_start, drag_stop)
};

Highlight text inside of a textarea

Is it possible to highlight text inside of a textarea using javascript? Either changing the background of just a portion of the text area or making a portion of the text selected?
Try this piece of code I wrote this morning, it will highlight a defined set of words:
<html>
<head>
<title></title>
<!-- Load jQuery -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<!-- The javascript xontaining the plugin and the code to init the plugin -->
<script type="text/javascript">
$(function() {
// let's init the plugin, that we called "highlight".
// We will highlight the words "hello" and "world",
// and set the input area to a widht and height of 500 and 250 respectively.
$("#container").highlight({
words: ["hello","world"],
width: 500,
height: 250
});
});
// the plugin that would do the trick
(function($){
$.fn.extend({
highlight: function() {
// the main class
var pluginClass = function() {};
// init the class
// Bootloader
pluginClass.prototype.__init = function (element) {
try {
this.element = element;
} catch (err) {
this.error(err);
}
};
// centralized error handler
pluginClass.prototype.error = function (e) {
// manage error and exceptions here
//console.info("error!",e);
};
// Centralized routing function
pluginClass.prototype.execute = function (fn, options) {
try {
options = $.extend({},options);
if (typeof(this[fn]) == "function") {
var output = this[fn].apply(this, [options]);
} else {
this.error("undefined_function");
}
} catch (err) {
this.error(err);
}
};
// **********************
// Plugin Class starts here
// **********************
// init the component
pluginClass.prototype.init = function (options) {
try {
// the element's reference ( $("#container") ) is stored into "this.element"
var scope = this;
this.options = options;
// just find the different elements we'll need
this.highlighterContainer = this.element.find('#highlighterContainer');
this.inputContainer = this.element.find('#inputContainer');
this.textarea = this.inputContainer.find('textarea');
this.highlighter = this.highlighterContainer.find('#highlighter');
// apply the css
this.element.css('position','relative');
// place both the highlight container and the textarea container
// on the same coordonate to superpose them.
this.highlighterContainer.css({
'position': 'absolute',
'left': '0',
'top': '0',
'border': '1px dashed #ff0000',
'width': this.options.width,
'height': this.options.height,
'cursor': 'text'
});
this.inputContainer.css({
'position': 'absolute',
'left': '0',
'top': '0',
'border': '1px solid #000000'
});
// now let's make sure the highlit div and the textarea will superpose,
// by applying the same font size and stuffs.
// the highlighter must have a white text so it will be invisible
this.highlighter.css({
'padding': '7px',
'color': '#eeeeee',
'background-color': '#ffffff',
'margin': '0px',
'font-size': '11px',
'font-family': '"lucida grande",tahoma,verdana,arial,sans-serif'
});
// the textarea must have a transparent background so we can see the highlight div behind it
this.textarea.css({
'background-color': 'transparent',
'padding': '5px',
'margin': '0px',
'font-size': '11px',
'width': this.options.width,
'height': this.options.height,
'font-family': '"lucida grande",tahoma,verdana,arial,sans-serif'
});
// apply the hooks
this.highlighterContainer.bind('click', function() {
scope.textarea.focus();
});
this.textarea.bind('keyup', function() {
// when we type in the textarea,
// we want the text to be processed and re-injected into the div behind it.
scope.applyText($(this).val());
});
} catch (err) {
this.error(err);
}
return true;
};
pluginClass.prototype.applyText = function (text) {
try {
var scope = this;
// parse the text:
// replace all the line braks by <br/>, and all the double spaces by the html version
text = this.replaceAll(text,'\n','<br/>');
text = this.replaceAll(text,' ',' ');
// replace the words by a highlighted version of the words
for (var i=0;i<this.options.words.length;i++) {
text = this.replaceAll(text,this.options.words[i],'<span style="background-color: #D8DFEA;">'+this.options.words[i]+'</span>');
}
// re-inject the processed text into the div
this.highlighter.html(text);
} catch (err) {
this.error(err);
}
return true;
};
// "replace all" function
pluginClass.prototype.replaceAll = function(txt, replace, with_this) {
return txt.replace(new RegExp(replace, 'g'),with_this);
}
// don't worry about this part, it's just the required code for the plugin to hadle the methods and stuffs. Not relevant here.
//**********************
// process
var fn;
var options;
if (arguments.length == 0) {
fn = "init";
options = {};
} else if (arguments.length == 1 && typeof(arguments[0]) == 'object') {
fn = "init";
options = $.extend({},arguments[0]);
} else {
fn = arguments[0];
options = $.extend({},arguments[1]);
}
$.each(this, function(idx, item) {
// if the component is not yet existing, create it.
if ($(item).data('highlightPlugin') == null) {
$(item).data('highlightPlugin', new pluginClass());
$(item).data('highlightPlugin').__init($(item));
}
$(item).data('highlightPlugin').execute(fn, options);
});
return this;
}
});
})(jQuery);
</script>
</head>
<body>
<div id="container">
<div id="highlighterContainer">
<div id="highlighter">
</div>
</div>
<div id="inputContainer">
<textarea cols="30" rows="10">
</textarea>
</div>
</div>
</body>
</html>
This was written for another post (http://facebook.stackoverflow.com/questions/7497824/how-to-highlight-friends-name-in-facebook-status-update-box-textarea/7597420#7597420), but it seems to be what you're searching for.
Easy script I wrote for this: Jsfiddle
OPTIONS:
Optional char counter.
Highlight several patterns with different colors.
Regex.
Collect matches to other containers.
Easy styling: fonts color and face, backgrounds, border radius and lineheight.
Ctrl+Shift for direction change.
//include function like in the fiddle!
//CREATE ELEMENT:
create_bind_textarea_highlight({
eleId:"wrap_all_highlighter",
width:400,
height:110,
padding:5,
background:'white',
backgroundControls:'#585858',
radius:5,
fontFamilly:'Arial',
fontSize:13,
lineHeight:18,
counterlettres:true,
counterFont:'red',
matchpatterns:[["(#[0-9A-Za-z]{0,})","$1"],["(#[0-9A-Za-z]{0,})","$1"]],
hightlightsColor:['#00d2ff','#FFBF00'],
objectsCopy:["copy_hashes","copy_at"]
//PRESS Ctrl + SHIFT for direction swip!
});
//HTML EXAMPLE:
<div id="wrap_all_highlighter" placer='1'></div>
<div id='copy_hashes'></div><!--Optional-->
<div id='copy_at'></div><!--Optional-->
Have Fun!
Improved version from above, also works with Regex and more TextArea fields:
<html>
<head>
<title></title>
<!-- Load jQuery -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<!-- The javascript xontaining the plugin and the code to init the plugin -->
<script type="text/javascript">
$(function() {
// let's init the plugin, that we called "highlight".
// We will highlight the words "hello" and "world",
// and set the input area to a widht and height of 500 and 250 respectively.
$("#container0").highlight({
words: [["hello","hello"],["world","world"],["(\\[b])(.+?)(\\[/b])","$1$2$3"]],
width: 500,
height: 125,
count:0
});
$("#container1").highlight({
words: [["hello","hello"],["world","world"],["(\\[b])(.+?)(\\[/b])","$1$2$3"]],
width: 500,
height: 125,
count: 1
});
});
// the plugin that would do the trick
(function($){
$.fn.extend({
highlight: function() {
// the main class
var pluginClass = function() {};
// init the class
// Bootloader
pluginClass.prototype.__init = function (element) {
try {
this.element = element;
} catch (err) {
this.error(err);
}
};
// centralized error handler
pluginClass.prototype.error = function (e) {
// manage error and exceptions here
//console.info("error!",e);
};
// Centralized routing function
pluginClass.prototype.execute = function (fn, options) {
try {
options = $.extend({},options);
if (typeof(this[fn]) == "function") {
var output = this[fn].apply(this, [options]);
} else {
this.error("undefined_function");
}
} catch (err) {
this.error(err);
}
};
// **********************
// Plugin Class starts here
// **********************
// init the component
pluginClass.prototype.init = function (options) {
try {
// the element's reference ( $("#container") ) is stored into "this.element"
var scope = this;
this.options = options;
// just find the different elements we'll need
this.highlighterContainer = this.element.find('#highlighterContainer'+this.options.count);
this.inputContainer = this.element.find('#inputContainer'+this.options.count);
this.textarea = this.inputContainer.find('textarea');
this.highlighter = this.highlighterContainer.find('#highlighter'+this.options.count);
// apply the css
this.element.css({'position':'relative',
'overflow':'auto',
'background':'none repeat scroll 0 0 #FFFFFF',
'height':this.options.height+2,
'width':this.options.width+19,
'border':'1px solid'
});
// place both the highlight container and the textarea container
// on the same coordonate to superpose them.
this.highlighterContainer.css({
'position': 'absolute',
'left': '0',
'top': '0',
'border': '1px dashed #ff0000',
'width': this.options.width,
'height': this.options.height,
'cursor': 'text',
'z-index': '1'
});
this.inputContainer.css({
'position': 'absolute',
'left': '0',
'top': '0',
'border': '0px solid #000000',
'z-index': '2',
'background': 'none repeat scroll 0 0 transparent'
});
// now let's make sure the highlit div and the textarea will superpose,
// by applying the same font size and stuffs.
// the highlighter must have a white text so it will be invisible
var isWebKit = navigator.userAgent.indexOf("WebKit") > -1,
isOpera = navigator.userAgent.indexOf("Opera") > -1,
isIE /*#cc_on = true #*/,
isIE6 = isIE && !window.XMLHttpRequest; // Despite the variable name, this means if IE lower than v7
if (isIE || isOpera){
var padding = '6px 5px';
}
else {
var padding = '5px 6px';
}
this.highlighter.css({
'padding': padding,
'color': '#eeeeee',
'background-color': '#ffffff',
'margin': '0px',
'font-size': '11px' ,
'line-height': '12px' ,
'font-family': '"lucida grande",tahoma,verdana,arial,sans-serif'
});
// the textarea must have a transparent background so we can see the highlight div behind it
this.textarea.css({
'background-color': 'transparent',
'padding': '5px',
'margin': '0px',
'width': this.options.width,
'height': this.options.height,
'font-size': '11px',
'line-height': '12px' ,
'font-family': '"lucida grande",tahoma,verdana,arial,sans-serif',
'overflow': 'hidden',
'border': '0px solid #000000'
});
// apply the hooks
this.highlighterContainer.bind('click', function() {
scope.textarea.focus();
});
this.textarea.bind('keyup', function() {
// when we type in the textarea,
// we want the text to be processed and re-injected into the div behind it.
scope.applyText($(this).val());
});
scope.applyText(this.textarea.val());
} catch (err) {
this.error(err)
}
return true;
};
pluginClass.prototype.applyText = function (text) {
try {
var scope = this;
// parse the text:
// replace all the line braks by <br/>, and all the double spaces by the html version
text = this.replaceAll(text,'\n','<br/>');
text = this.replaceAll(text,' ',' ');
text = this.replaceAll(text,' ',' ');
// replace the words by a highlighted version of the words
for (var i=0;i<this.options.words.length;i++) {
text = this.replaceAll(text,this.options.words[i][0],'<span style="background-color: #D8DFEA;">'+this.options.words[i][1]+'</span>');
//text = this.replaceAll(text,'(\\[b])(.+?)(\\[/b])','<span style="font-weight:bold;background-color: #D8DFEA;">$1$2$3</span>');
}
// re-inject the processed text into the div
this.highlighter.html(text);
if (this.highlighter[0].clientHeight > this.options.height) {
// document.getElementById("highlighter0")
this.textarea[0].style.height=this.highlighter[0].clientHeight +19+"px";
}
else {
this.textarea[0].style.height=this.options.height;
}
} catch (err) {
this.error(err);
}
return true;
};
// "replace all" function
pluginClass.prototype.replaceAll = function(txt, replace, with_this) {
return txt.replace(new RegExp(replace, 'g'),with_this);
}
// don't worry about this part, it's just the required code for the plugin to hadle the methods and stuffs. Not relevant here.
//**********************
// process
var fn;
var options;
if (arguments.length == 0) {
fn = "init";
options = {};
} else if (arguments.length == 1 && typeof(arguments[0]) == 'object') {
fn = "init";
options = $.extend({},arguments[0]);
} else {
fn = arguments[0];
options = $.extend({},arguments[1]);
}
$.each(this, function(idx, item) {
// if the component is not yet existing, create it.
if ($(item).data('highlightPlugin') == null) {
$(item).data('highlightPlugin', new pluginClass());
$(item).data('highlightPlugin').__init($(item));
}
$(item).data('highlightPlugin').execute(fn, options);
});
return this;
}
});
})(jQuery);
</script>
</head>
<body>
<div id="container0">
<div id="highlighterContainer0">
<div id="highlighter0"></div>
</div>
<div id="inputContainer0">
<textarea id="text1" cols="30" rows="15">hello world</textarea>
</div>
</div>
<h1> haus </h1>
<div id="container1">
<div id="highlighterContainer1">
<div id="highlighter1"></div>
</div>
<div id="inputContainer1">
<textarea cols="30" rows="15">hipp hipp
hurra,
[b]ich hab es jetzt![/b]</textarea>
</div>
</div>
</body>

Categories

Resources