Prototype find class and replace text - javascript

I am using the prototype framework [requirement by platform] and I am trying to find a ID and replace some text in the ID so that it disappears.
The HTML looks like:
<div id="top">
login | register
</div>
The problem is I don't want the " | " to appear in the ID "top". So I guess it's sort of "find element " | " in ID top and remove"
Event.observe(window, 'load', function() {
try {
if ($$('#top')!=null) {
var topmenu = document.getElementById('top');
var value = topmenu.value;
// define an array of replacements
var replacements = [
{ from: '|', to: ' ' }
];
for (var i = 0, replacement; i < replacements.length, replacement = replacements[i]; i++) {
// replace
value = value.replace(replacement.from, replacement.to);
}
// replace the old text with the new
topmenu.value = value;
} }
catch(ex) {
}
});
Tried with this above but doesn't work. Can anyone assist ?
Thanks

Can't you just use CSS to hide the pipe? Just change the color to match the background-color so that it is invisible.
#top {color: #fff } /* substitute with the right background color if different */
#top a {color: #000 } /* or whatever it has to be */
EDIT: The right property you should be replacing is innerHTML, not value.
var value = topmenu.innerHTML;
// define an array of replacements
var replacements = [
{ from: '|', to: ' ' }
];
for (var i = 0, replacement; i < replacements.length, replacement = replacements[i]; i++) {
// replace
value = value.replace(replacement.from, replacement.to);
}
// replace the old text with the new
topmenu.innerHTML = value;

Looks like you just need quotes around the |. Otherwise it looks okay. Probably don't need the conditional either since you're in a try catch but maybe that's just too loosy goosy.

Related

Function does not work on second occurence?

I am trying to change the color of multiple texts to a certain color by using this code:
var search = "bar";
$("div:contains('"+search+"')").each(function () {
var regex = new RegExp(search,'gi');
$(this).html($(this).text().replace(regex, "<span class='red'>"+search+"</span>"));
});
However, the code does not work a second time, and I am not sure why--it only changes the newest occurrence of the code.
Here is a JSFiddle using it twice where it is only changing the 2nd occurrence: http://jsfiddle.net/PELkt/189/
Could someone explain why it does not work on the 2nd occurrence?
Could someone explain why it does not work on the 2nd occurrence?
By calling .text() you are removing all the HTML markup, including the <span>s you just inserted.
This is the markup after the first replacement:
<div id="foo">this is a new <span class='red'>bar</span></div>
$(this).text() will return the string "this is a new bar", in which replace "new" with a <span> ("this is a <span class='red'>new</span> bar") and set it as new content of the element.
In order to do this right, you'd have to iterate over all text node descendants of the element instead, and process them individually. See Highlight a word with jQuery for an implementation.
It was easy to fix your jsfiddle. Simply replace both .text() with .html() & you'll see that it highlights new & both bars in red.
jQuery's .text() method will strip all markup each time that it's used, but what you want to do is use .html() to simply change the markup which is already in the DOM.
$(document).ready(function () {
var search = "bar";
$("div:contains('"+search+"')").each(function () {
var regex = new RegExp(search,'gi');
$(this).html($(this).html().replace(regex, "<span class='red'>"+search+"</span>"));
});
search = "new";
$("div:contains('"+search+"')").each(function () {
var regex = new RegExp(search,'gi');
$(this).html($(this).html().replace(regex, "<span class='red'>"+search+"</span>"));
});
});
Here is another way of doing it that will allow you to continue using text if you wish
function formatWord(content, term, className){
return content.replace(new RegExp(term, 'g'), '<span class="'+className+'">'+term+'</span>');
}
$(document).ready(function () {
var content = $('#foo').text();
var change1 = formatWord(content, 'bar', 'red'),
change2 = formatWord(change1, 'foo', 'red');
alert(change2);
$('body').html(change2);
});
http://codepen.io/nicholasabrams/pen/wGgzbR?editors=1010
Use $(this).html() instead of $(this).text(), as $.fn.text() strips off all the html tags, so are the <span class="red">foo</span> stripped off to foo.
But let's say that you apply same highlight multiple times for foo, then I would suggest that you should create a class similar to this to do highlighting
var Highlighter = function ($el, initialArray) {
this._array = initialArray || [];
this.$el = $el;
this.highlight = function (word) {
if (this.array.indexOf(word) < 0) {
this.array.push(word);
}
highlightArray();
}
function highlightArray() {
var search;
// first remove all highlighting
this.$el.find("span[data-highlight]").each(function () {
var html = this.innerHTML;
this.outerHTML = html;
});
// highlight all here
for (var i = 0; i < this._array.length; i += 1) {
search = this._array[i];
this.$el.find("div:contains('"+search+"')").each(function () {
var regex = new RegExp(search,'gi');
$(this).html($(this).html().replace(regex, "<span data-highlight='"+search+"' class='red'>"+search+"</span>"));
});
}
}
}
var highlighter = new HighLighter();
highlighter.highlight("foo");

How to replace font tags with span?

I'm trying to replace all instances of a font
tag that has a color attribute like this:
<font color="red">Some text</font>
with this:
<span style="color: red;">Some text</span>
I did some hunting on StackOverflow and found this link, and modeled my code after it:
Javascript JQuery replace tags
I've created a little jQuery loop below that is supposed to do the following:
Go through the string(contents of a div)
Get the font color attribute
Replace the tags with a
Set a CSS style attribute with the appropriate color.
Right now, it doesn't work. I just get an error stating that 'replaceWith' is not a function.
$('font').each(function () {
var color;
this.$('font').replaceWith(function () {
color = this.attr("color");
return $('<span>').append($(this).contents());
});
this.$("span").attr("style", "color=" + color);
});
Any help would be greatly appreciated!
There is no need for each, replaceWith will do it internally.
$("font").replaceWith( //find all font tags and call replace with to change the element
function(){
var tag = $(this);
return $("<span/>") //create new span
.html(tag.html()) //set html of the new span with what was in font tag
.css("color", tag.attr("color")); //set the css color with the attribute
}
);
JSFiddle: http://jsfiddle.net/qggadmmn/
$('font').each(function () {
var $this = $(this);
var color = $this.attr('color');
var text = $this.text();
var span = $('<span style="' + color '">' + text + '</span>';
$this.before(span);
$this.remove();
});
Quite a late answer, but I think it's still worth it posting.
If your font tags may have other attributes than just color (ie: face, size), this would cover them all:
HTML (Example)
<font color="red" size="3">Some text</font>
<br />
<font color="blue" face="Verdana">Some text</font>
jQuery (Javascript):
$(function () {
var fontSizes = [
'xx-small', // 1
'x-small', // 2
'small', // 3
'medium', // 4
'large', // 5
'x-large', // 6
'xx-large' // 7
];
$('font').replaceWith(function () {
var attrs = this.attributes;
var span = $('<span />').append($(this).contents());
for (var i = 0; i < attrs.length; i++) {
var name = attrs[i].name;
var value = attrs[i].value;
if (name.indexOf('face') >= 0) {
name = 'font-family';
}
if (name.indexOf('size') >= 0) {
name = 'font-size';
value = fontSizes[value - 1];
}
span.css(name, value);
}
return span;
});
});
Demo

CKEDITOR - Apply bold to numbered list including numbers

I am facing an issue with the numbered list in ckeditor. When I try to bold some text in li, only the text is getting bold, without the preceding number. This is how it looks like,
One
Two
Three
It should be like this
2. Two
When I check the source, I found the code like below
<li><strong>Two</strong></li>
I would like to know is there any way to change the working of bold button, so that it will add something like below
<li style="font-weight:bold">Two</li>
<p> Hello <strong>World</strong></p>
I tried to solve your problem.
My solution isn't the best, because I guess that create a bold plugin, that takes care about list items would be the best solution.
I make it without using jQuery; however, using it the code should became simpler and more readable.
First of all, we need to define something useful for the main task:
String trim. See this.
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
};
}
String contains. See this
String.prototype.contains = function(it) {
return this.indexOf(it) != -1;
};
First child element. The following function obtains the first child element, or not-empty text node, of the element passed as argument
function getFirstChildNotEmpty(el) {
var firstChild = el.firstChild;
while(firstChild) {
if(firstChild.nodeType == 3 && firstChild.nodeValue && firstChild.nodeValue.trim() != '') {
return firstChild;
} else if (firstChild.nodeType == 1) {
return firstChild;
}
firstChild = firstChild.nextSibling;
}
return firstChild;
}
Now, we can define the main two functions we need:
function removeBoldIfPresent(el) {
el = el.$;
var elStyle = el.getAttribute("style");
elStyle = (elStyle) ? elStyle : '';
if(elStyle.trim() != '' && elStyle.contains("font-weight:bold")) {
el.setAttribute("style", elStyle.replace("font-weight:bold", ''));
}
}
CKEDITOR.instances.yourinstance.on("change", function(ev) {
var liEls = ev.editor.document.find("ol li");
for(var i=0; i<liEls.count(); ++i) {
var el = liEls.getItem(i);
var nativeEl = el.$.cloneNode(true);
nativeEl.normalize();
var firstChild = getFirstChildNotEmpty(nativeEl);
if(firstChild.nodeType != 1) {
removeBoldIfPresent(el);
continue;
}
var firstChildTagName = firstChild.tagName.toLowerCase()
if(firstChildTagName == 'b' || firstChildTagName == 'strong') {
//TODO: you also need to consider the case in which the bold is done using the style property
//My suggest is to use jQuery; you can follow this question: https://stackoverflow.com/questions/10877903/check-if-text-in-cell-is-bold
var textOfFirstChild = (new CKEDITOR.dom.element(firstChild)).getText().trim();
var textOfLi = el.getText().trim();
if(textOfFirstChild == textOfLi) {
//Need to make bold
var elStyle = el.getAttribute("style");
elStyle = (elStyle) ? elStyle : '';
if(elStyle.trim() == '' || !elStyle.contains("font-weight:bold")) {
el.setAttribute("style", elStyle + ";font-weight:bold;");
}
} else {
removeBoldIfPresent(el);
}
} else {
removeBoldIfPresent(el);
}
}
});
You need to use the last release of CkEditor (version 4.3), and the onchange plugin (that is included by default in the full package).
CKEditor 4.1 remove your classes, styles, and attributes that is not specified in its rules.
If that's the problem, you might want to disable it by adding this line:
CKEDITOR.config.allowedContent = true;
Here is full code to use it:
window.onload = function() {
CKEDITOR.replace( 'txt_description' );
CKEDITOR.config.allowedContent = true; //please add this line after your CKEditor initialized
};
Please check it out here
<ul class="test">
<li><span>hello</span></li>
</ul>
.test li
{
font-weight:bold;
}
.test li span
{
font-weight:normal;
}

changing CSS class definition

Suppose I have this class:
.MyClass{background:red;}
This class applies to several divs. I want to change the color of the background to orange by changing the color defined in MyClass.
Now, I know I could do $('.MyDiv').css('background', 'orange');
But my question is really this: how do I change the CSS class definition so that MyClass elements now have background:orange;? I want to be able to change several CSS color properties from one color to another.
Thanks.
Actually altering your stylesheet is pretty challenging. Much more easily, though, you can switch out your stylesheet for a different one, which may be sufficient for your purposes. See How do I switch my CSS stylesheet using jQuery?.
For actually altering the stylesheet content, How to change/remove CSS classes definitions at runtime? will get you started.
It is difficult to find the rule you want because you have to iterate through the document.styleSheets[i].cssRules array. (and compare your class name with the selectorText attribute)
So my solution to this problem is to add a new CSS class, remove the old CSS class from the HTML element and add this class instead of it.
var length = getCssRuleLength();
var newClassName = "css-class-name" + length;
//remove preview css class from html element.
$("#your-html-element").removeClass("css-class-name");
$("#your-html-element").removeClass("css-class-name" + (length-1));
$("#your-html-element").addClass(newClassName);
//insert a css class
insertCssRule("." + newClassName + ' { max-width: 100px; }', length);
function getCssRuleLength() {
var length = 0;
if (document.styleSheets[1].cssRules) {
length = document.styleSheets[1].cssRules.length;
} else if (document.styleSheets[1].rules) { //ie
length = document.styleSheets[1].rules.length;
}
return length;
}
function insertCssRule(rule, index) {
if (document.styleSheets[1].cssRules) {
document.styleSheets[1].insertRule(rule, index);
} else if (document.styleSheets[1].rules) { //ie
document.styleSheets[1].addRule(rule, index);
}
}
Here's my answer in case anyone stumbles upon this. Give your elements a new class name that doesn't already exist, then dynamically add a style segment:
var companyColor = 'orange' //define/fetch the varying color here
var style = '<style>.company-background {background-color: ' + companyColor + '; color: white;}</style>';
$('html > head').append($(style));
//give any element that needs this background color the class "company-background"
You have 2 options
add a new stylesheet that overrides this .MyClass
have a second class with the different property, and change the class Name on these elements
Looking at your question, I think a better approach is to switch MyClass with something else using JavaScript rather than to change the properties of the class dynamically.
But if you are still keen you can switch CSS stylesheets with jQuery http://www.cssnewbie.com/simple-jquery-stylesheet-switcher/
var changeClassProperty = function(sheetName, className, propertyName, newValue, includeDescendents) {
var ending = '$';
setValue = '';
if (includeDescendents === true) {
ending = '';
}
if (typeof(newValue) != 'undefined') {
setValue = newValue;
}
var list = document.styleSheets;
for (var i = 0, len = list.length; i < len; i++) {
var element = list[i];
if (element['href'] && element['href'].match(new RegExp('jquery\.qtip'))) {
var cssRules = element.cssRules;
for (j = 0, len2 = cssRules.length; j < len2; j++) {
var rule = cssRules[j];
if (rule.selectorText.match(new RegExp(className + ending))) {
cssRules[j].style.backgroundColor = setValue;
console.log(cssRules[j].style.backgroundColor);
}
}
}
}
}
changeClassProperty('jquery.qtip', 'tipsy', 'backgroundColor', 'yellow');
You'd be much better off adding and removing classes instead of attempting to change them.
For example
.red {
background: red;
}
.orange {
background: orange;
}
$('#div').click(function(){
$(this).removeClass('red').addClass('orange');
});

jQuery putting content of a paragraph in a textarea

I tried to do this for replacing a paragraph with a text area with the same content.
function edit() {
var wdith = $("p").css('width')
$("p:first").replaceWith("<textarea class='edit'>" + $("p:first").text() + "</textarea>")
$(".edit").css("width", wdith)
}
$("#replace").click(edit);
Demo
But it doesn't work correctly. There are spaces before and after the text.
How do I fix it?
You script is doing as it says on the tin. You're getting spaces because you have spaces and line breaks within your <p> tags.
To remove the text formatting, try this: http://jsfiddle.net/z9xCm/18/
function edit() {
var wdith = $("p").css('width');
var p = $("p:first");
var t = p.text().replace("\n", "").replace(/\s{2,}/g, " ").trim();
p.replaceWith("<textarea class='edit'>" + t + "</textarea>")
$(".edit").css("width", wdith)
}
$("#replace").click(edit);
First, we remove the line breaks, then removed multiple repeated spaces, then trim spaces at the beginning and end of the text.
Somewhat off topic, but that can also be rewritten as : http://jsfiddle.net/z9xCm/52/
$("#replace").click(function() {
var p = $("p:first");
p.replaceWith($("<textarea/>", {
"class": "edit",
"text": p.text().replace("\n", "").replace(/\s{2,}/g, " ").trim(),
"css": { "width": p.css('width') }
}));
});
Here's the same thing, but in a less compact and commented form.
$("#replace").click(function() { /* assign anonymous function to click event */
var p = $("p:first"); /* store reference to <p> element */
/* get p.text() without the formatting */
var t = p.text().replace("\n", "").replace(/\s{2,}/g, " ").trim();
/* create new textarea element with additional attributes */
var ta = $("<textarea/>", {
"class": "edit",
"text": t,
"css": {
"width": p.css('width')
}
});
p.replaceWith(ta); /* replace p with ta */
});
Note that the $("...", {...}) syntax for creating new elements with attributes was only introduced in jquery 1.4.
You can use the method $.trim() to remove the spaces at the begin and end:
$.trim($("p:first").text());
You could trim each line manually: http://jsfiddle.net/z9xCm/14/.
function edit() {
var wdith = $("p").css('width');
var spl = $("p").text().split("\n");
spl = spl.map(function(v) {
return v.trim();
});
var txt = spl.join(" ").trim();
$("p:first").replaceWith("<textarea class='edit'>" + txt + "</textarea>")
$(".edit").css("width", wdith)
}
$("#replace").click(edit);
You're paragraph has leading spaces at the start of each line. These are remaining when you convert it to a textarea. So remove the spaces from the <p> block to fix the issue.
Updated demo
Also remove line breaks if you don't want them to remain.
Updated demo without line breaks either
Use the following with a regular expression replacement (updated Fiddle):
function edit() {
var wdith = $("p").css('width')
$("p:first").replaceWith("<textarea class='edit'>" + $("p:first").text().replace(/[\n\r](\s*)/g," ").trim() + "</textarea>")
$(".edit").css("width", width)
}
$("#replace").click(edit);

Categories

Resources