I have written a basic testing framework and am challenging myself to make a single page app in vanilla Javascript.
I've been struggling to work out why my test for view is not recognizing the 'list' constructor when I run it.
My specrunner has all the files loaded into it, and my previous tests on my model works fine. Also, imitating the test using the browser console in Specrunner gives the correct output as well.
Feel free to clone my repo if that is quicker here.
Note that my testing framework "espresso" uses expect in the place of assert and also has an extra parameter for the description of test.
espresso.js
var describe = function(description, test) {
document.getElementById("output").innerHTML +=
"<br><b>" + description + "</b></br>";
try {
test();
} catch (err) {
document.getElementById("output").innerHTML +=
"<br><li>error: " + err.message + "</li></br>";
console.log(err);
}
};
var expect = {
isEqual: function(description, first, second) {
if (first === second) {
document.getElementById("output").innerHTML +=
description +
"<br><li><font color='green'>PASS: [" +
first +
"] is equal to [" +
second +
"]</li></br>";
} else {
document.getElementById("output").innerHTML +=
"<br><li><font color='red'>FAIL: [" +
first +
"] is not equal to [" +
second +
"]</li></br>";
}
}
}
Specrunner.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Expresso Spec Runner</title>
</head>
<body>
<h1><u>Expresso Spec Runner</u></h1>
<br>
<div id="output"></div>
<script src="expresso/expresso.js"></script>
<!-- include source files here... -->
<script src="lib/list-model.js"></script>
<script src="lib/note-model.js"></script>
<script src="lib/list-view.js"></script>
<!-- include spec files here... -->
<script src="tests/expresso-test.js"></script>
<script src="tests/model-tests.js"></script>
<script src="tests/view-tests.js"></script>
</body>
</html>
list-model.js
(function(exports) {
"use strict";
function List() {
this.notelist = [];
}
List.prototype.add = function(text) {
let note = new Note(text);
this.notelist.push(note);
};
exports.List = List;
})(this);
// note-model.js
(function(exports) {
"use strict";
function Note(text) {
this.text = text;
}
Note.prototype.show = function() {
return this.text;
};
exports.Note = Note;
})(this);
list-view.js
(function(exports) {
"use strict";
function View() {
this.test = "hello there";
View.prototype.convert = function(note) {
var output = [];
list.notelist.forEach(function(element) {
output.push("<br><ul>" + element.text + "</ul></br>");
});
console.log(output);
return output;
};
}
exports.View = View;
})(this);
model-test.js
describe("List #initialize", function() {
var list = new List();
expect.isEqual("blank array is loaded", list.notelist.length, 0);
});
describe("List #add", function() {
var list = new List();
list.add("hello");
expect.isEqual(
"can create and store a note",
list.notelist[0].show(),
"hello"
);
list.add("goodbye");
expect.isEqual(
"second note says goodbye",
list.notelist[1].show(),
"goodbye"
);
expect.isEqual("there are two notes in the list", list.notelist.length, 2);
});
view-tests.js (the failing test)
describe("View #convert", function() {
var view = new View();
expect.isEqual(
"converts the note into a HTML list",
view.convert(list.notelist),
"<br><ul>hello</ul></br>"
);
});
Thanks in advance.
You need to define list in view-test.js.
describe("View #convert", function() {
var list = new List();
// ...
});
If you need to define list outside of this test function, then you would either need to pass it in as an argument, or define it on the window object so it's globally accessible.
Related
I have /Views/Movies/Index.cshtml with
<input type="button" id="getmoviex" value="Get moviex" />
<ul id="moviex_list"/>
<p>
Title: #Html.TextBox("SearchTitle") <br />
</p>
I have /Controllers/MoviesController.cs with
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult moviex(string SearchGenre, string SearchTitle, string SearchActor)
{
var db = new CinemaContext();
db.Configuration.ProxyCreationEnabled = false;
var Movie = from m in db.Movie
select m;
if (!String.IsNullOrEmpty(SearchTitle))
{
Movie = Movie.Where(s => s.Title.Contains(SearchTitle));
}
return Json(db.Movie.ToList(), JsonRequestBehavior.AllowGet);
}
I have Javascript.js with
$(document).ready(function () {
$('#getmoviex').click(function () {
$.getJSON("/Movies", null, getmoviex);
});
});
Have I correctly written /Movies? Or this should be /Views/Movies?
function getmoviex(moviex) {
$("#moviex_list").text("");
$.each(moviex, function (i) {
$("#moviex_list").append("<li>" + this + "</li>");
});
}
How can I display info or list info from my query? Or view some output with error?
First make sure you button click does not trigger a request to server. Preventing default behavior is a standard way of doing it:
$('#getmoviex').click(function (event) {
$.getJSON("/Movies", null, getmoviex);
event.preventDefault();
});
As for the URL, it should not be to view, but to action instead. Your action is moviex and controller is Movies, so
$.getJSON("/Movies/moviex", null, getmoviex);
The rest looks fine, so that should do it.
you need to pass your arguments as well in url (GET).
Something like this could work:
$('#getmoviex').click(function(event) {
event.preventDefault();
$.getJSON("/Movies/moviex?SearchGenre=yuorgenre&SearchTitle=Cal&SearchActor=youractor", function(moviex) {
var lis;
//please check the console
console.log(moviex);
$.each(moviex, function(b) {
lis += "<li id='" + b.Id + "'>" + b.Title + "</li>");
}); document.getElementById("moviex_list").innerHTML += lis;
});
});
To avoid circular reference in Serializing you may use:
if (String.IsNullOrEmpty(SearchTitle)) {
return View("Error");
}
var db = new CinemaContext();
var Movie = (from m in db.Movie
Where m.Title.Contains(SearchTitle)
select new {
Id = m.MovieID,
Title = m.Title // can add more properties
}).ToList();
return Json(Movie, JsonRequestBehavior.AllowGet);
I'm looking for a filter to replace "href" in a TextEntity of an API. The "text" can contains 3 different kind of URLs. After the replacement I want to open the corrected URLs in a new separate window.
I receive from the textvalue the following information:
1. link - this is an example for a all kind of external links. Can be mysite.com/mypage.html or any other valid url. Like everything with a http://, https://, ftp:// in the startof the url.
2. internal page - Can includes all other files. like mypdf.pdf or mydoc.doc or other stuff, but without http://mydomain.tdl
3. mymail#domain.tdl
I tried something but it doesn't work.
.filter('parseText', function ($sce, $sanitize) {
var mydomain = 'http://www.mydomain.tdl';
return function (text) {
var newStringUrlReplace = $sanitize(text).replace('href="','href="'+mydomain);
var regex = /href="([\S]+)"/g;
var newString = newStringUrlReplace.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('$1', '_blank', 'location=yes')\"");
return $sce.trustAsHtml(newString);
}
});
I need this output the "text" ran went through the filter:
1. link
2. internal page
3. mymail#domain.tdl
To make it easier to understand:
I need a function which turns this types of URLs.
URL TO A EXTERNAL PAGE
internal page of the CMS
into
URL TO A EXTERNAL PAGE
internal page
Here's a version working based on your original code:
(function() {
angular
.module('app', ['ngSanitize'])
.controller('MainCtrl', MainCtrl)
.filter('parseText', parseText);
function MainCtrl($scope) {
$scope.array = [
'link',
'internal page',
'mymail#domain.tdl',
'URL TO A EXTERNAL PAGE',
'internal page of the CMS'
];
}
function parseText($sce) {
var myDomain = 'http://www.mydomain.tdl/';
var externalRegex = /([http|https|ftp]+:\/\/[^"]*)/g;
var internalRegex = /(href=)"([^"]*)/g;
return function(input) {
if (!input) return;
if (input.indexOf('mailto: ') !== -1) return input;
var url = '';
if (externalRegex.test(input)) {
url = input.replace(externalRegex, '$1" class="externalURL" onClick="cordova.InAppBrowser.open(\'$1\', \'_blank\', \'location=yes\')');
} else {
url = input.replace(internalRegex, '$1 ' + myDomain + '$2' + ' class="externalURL" onClick="cordova.InAppBrowser.open(\'' + myDomain + '$2' + '\', \'_blank\', \'location=yes\')');
}
return $sce.trustAsHtml(url);
}
}
})();
<!DOCTYPE html>
<html ng-app="app" >
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-sanitize.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<p ng-repeat="url in array track by $index">
<span ng-bind-html="url | parseText"></span>
</p>
</body>
</html>
Hm,
well i have a solution now...
.filter('parseText', function ($sce, $sanitize) {
return function ( text ) {
var mydomain = 'http://www.mydomain.tdl';
text = $sanitize(text);
var source,sear,repl;
var newString;
var regex = /href="([\S]+)"/g;
var extMatch = /http|https|\/\//g;
var mtMatch = /mailto:/g;
var div = document.createElement("div");
div.innerHTML = text;
var aList = div.getElementsByTagName("a");
var aListNew = new Array();
var href,t;
if(aList.length>0){
for(var i = 0; i<aList.length; i++ ){
href = aList[i].getAttribute("href");
t = aList[i].outerHTML;
t = $sanitize(t);
if(href.match(extMatch)!=null){
newString = t.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('$1', '_blank', 'location=yes')\"");
} else if(href.match(mtMatch)!=null){
newString = t;
} else{
newString = t.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('"+mydomain+"$1', '_blank', 'location=yes')\"");
}
source = text;
sear = t;
repl = newString;
text = text.replace(t,newString);
}
}
return $sce.trustAsHtml(text);
};
});
I have been learning javascript for the past couple weeks and up until now I have been utilizing procedural programming to create my documents. I'm currently learning object-oriented programming, and while I know some java, it's been a while and I'm having trouble with these finicky objects. I want to take user input for a face value and suit of a card and use that data to instantiate an object from a constructor function. I know there are easier ways to do this but that would defeat the purpose of the lesson I'm trying to learn. Here's my code:
<!DOCTYPE html>
<html>
<head>
<title>Card Constructor</title>
<h1 style="text-align:center">Create a playing card!</h1>
<script>
function Card(){
this.face=" ";
this.suit=" ";
this.info="You made a "+face+" of "+suit"!";
this.showInfo=function(){
alert(this.info);
}
this.setFace=function(newFace){
this.face=newFace;
}
this.setSuit=function(newSuit){
this.suit=newSuit;
}
}
function userCard(){
var goodCard=new Card();
goodCard.setFace=document.getElementById('faceInput').value=this.face;
goodCard.setSuit= document.getElementById('suitInput').value=this.suit;
goodCard.showInfo();
document.getElementById('faceInput').value=" ";
document.getElementById('suitInput').value=" ";
}
</script>
</head>
<body style="text-align: center">
<p>Please enter a face</p>
<input type="text" id="faceInput" name="face" value=" "/>
<p>And now a suit</p>
<input type="text" id="suitInput" name="suit" value=" "/></br>
</br><input type="button" value="Go!" onClick="userCard()"/>
</body>
Now, the problem is that my button doesn't work. If change my onClcik to onClick=alert('you clicked') I get a response. So I know I must have screwed something up in my script. Can anyone help a noob out?
For anyone curious on how I ended up getting this to work, or if you have an assignment in your textbook that calls for creating objects with set methods and you're stuck, this is how I ended up doing mine. Note: I have two set methods that modify my one info method.
<html>
<head>
<title>Card Constructor</title>
<h1 style="text-align:center">Create a playing card!</h1>
<script>
function Card(face, suit){
this.face="";
this.suit="";
this.info=face+" "+suit;
this.setFace=function(newFace){
this.face=newFace;
}
this.setSuit=function(newSuit){
this.suit=newSuit;
}
this.showInfo=function(){
this.info="You made a "+this.face+" of "+this.suit+"!";
alert(this.info);
}
}
function userCard(){
var goodCard=new Card();
goodCard.setFace(document.getElementById('faceInput').value);
goodCard.setSuit(document.getElementById('suitInput').value);
goodCard.showInfo();
document.getElementById('faceInput').value="";
document.getElementById('suitInput').value="";
}
</script>
</head>
<body style="text-align: center">
<p>Please enter a face</p>
<input type="text" id="faceInput" name="face" value=""/>
<p>And now a suit</p>
<input type="text" id="suitInput" name="suit" value=""/></br>
</br><input type="button" value="Go!" onClick="userCard()"/>
</body>
</html>
replace your javascript code:
UPDATED:
1.There is your code has optimized.
Your this.face and this.suit is public variable, so there are this.setFace and `this.setSuit' unnecessary methods.
You just write goodCard.face = ... and goodCard.suit = ... instead of addressing to method
function Card(faceVal, suitVal) {
this.face = faceVal;
this.suit = suitVal;
this.info = "";
this.showInfo = function () {
this.info = "You made a " + this.face + " of " + this.suit + "!";
alert(this.info);
}
}
function userCard() {
var goodCard = new Card(document.getElementById('faceInput').value, document.getElementById('suitInput').value);
goodCard.showInfo();
document.getElementById('faceInput').value = "";
document.getElementById('suitInput').value = "";
}
2.Also, I suggest other way to declare Card function.
There are private variables, getter/setter(also, you can use only setters or getters) as well as other public methods(like java class).
function Card(faceVal, suitVal) {
//private variables
var _face = faceVal || "",
_suit = suitVal || "",
_info = "";
Object.defineProperties(this, {
//region <Getter & Setter>
face: {
get: function () {
return _face;
},
set: function (val) {
_face = val;
},
enumerable: true
},
suit: {
get: function () {
return _suit;
},
set: function (val) {
_suit = val;
},
enumerable: true
},
info: {
get: function () {
return _info;
},
set: function (val) {
_info = val;
},
enumerable: true
}
});
//other public methods
this.showInfo = function () {
_info = "You made a " + _face + " of " + _suit + "!";
alert(_info);//or alert(this.info)
}
}
var goodCard = new Card();//you can define object outside without params
function userCard() {
goodCard.face = document.getElementById('faceInput').value;
goodCard.suit = document.getElementById('suitInput').value;
goodCard.showInfo();
document.getElementById('faceInput').value = "";
document.getElementById('suitInput').value = "";
}
My scenario: I have an application that is 9 pages long for a total of about 125 inputs of varying types and sizes (only input, textarea, radio, and selects). I'd like to use local storage to save the form values. The user can move between the pages (e.g. to review before submitting the application) so I don't want to clear the local storage until they submit the application and if they change from page to page, the form should reload its values from local storage. Once they submit the form, then I'll clear the local storage but until then, the local storage should be retained.
I found this great jquery plugin and a demo page which appears to almost do what I'm looking for - well, with two exceptions:
1) The plugin prompts the user if they want to restore their previously entered info which I'd prefer to not have (I'd rather have the data just be there). My navigational buttons at the bottom of the form are simply "Previous" and "Continue" (on the first page, it is just "Continue" and on the last page they would be "Previous" and "Submit Application").
2) The plugin will prompt the user even if there is no data to load (this would be a non-issue if I can just have it load data if there is any and skip it if there is not). For example, the very first visit to the page will prompt the user to restore previously entered data.
Here is a link to the jquery.remember-state.js used in the demo page.
=======================================================
I took the demo above and tweaked the jquery.remember-state.js to try and make it do what I need but it isn't working correctly.
Here is my (jsFiddle).
NOTE 1: the jsFiddle is meant to just show my code and is not a necessarily a working example in the jsFiddle environment. If you copy the code to your local environment, you should be able to access the console.log to see if/what gets saved to the localStorage.
NOTE 2: S.O. wants formatted code inline so I'll see what I can do to make it format correctly.
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<title>LocalStorage and Unload State Save</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="../jQueryPlugins/RememberState/form.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<!-- use the modified jquery.remember-state.js code in the JavaScript panel instead
the script tag below is the original js file
<script src="http://shaneriley.com/jquery/remember_state/jquery.remember-state.js"></script>-->
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
(function($) {
/* jQuery form remember state plugin
Name: rememberState
Version: 1.3
Description: When called on a form element, localStorage is used to
remember the values that have been input up to the point of either
saving or unloading. (closing window, navigating away, etc.) If
localStorage isn't available, nothing is bound or stored.
The plugin looks for an element with a class of remember_state to show
a note indicating there is stored data that can be repopulated by clicking
on the anchor within the remember_state container. If the element doesn't
exist, it is created and prepended to the form.
Usage: $("form").rememberState("my_object_name");
Notes: To trigger the deletion of a form's localStorage object from
outside the plugin, trigger the reset_state event on the form element
by using $("form").trigger("reset_state");
*/
if (!window.localStorage || !window.JSON) {
if (console && console.log) {
!window.localStorage && console.log("ERROR: you browser does not support" +
" localStorage (use this polyfill https://gist.github.com/350433)");
!window.JSON&& console.log("ERROR: you browser does not support" +
" JSON (use this polyfill http://bestiejs.github.com/json3/)");
}
return $.fn.rememberState = function() { return this; };
}
var remember_state = {
name: "rememberState",
clearOnSubmit: false, //default was true;
// ****************************
/*noticeDialog: (function() {
return $("<p />", {"class": "remember_state"})
.html('Do you want to restore your previously entered info?');
})(),*/
// ****************************
ignore: null,
noticeSelector: ".remember_state",
use_ids: false,
objName: false,
clickNotice: function(e) {
var data = JSON.parse(localStorage.getItem(e.data.instance.objName)),
$f = $(this).closest("form"),
$e;
for (var i in data) {
$e = $f.find("[name=\"" + data[i].name + "\"]");
if ($e.is(":radio, :checkbox")) {
$e.filter("[value=" + data[i].value + "]").prop("checked", true);
}
else if ($e.is("select")) {
$e.find("[value=" + data[i].value + "]").prop("selected", true);
}
else {
$e.val(data[i].value);
}
$e.change();
}
e.data.instance.noticeDialog.remove();
e.preventDefault();
},
chooseStorageProp: function() {
if (this.$el.length > 1) {
if (console && console.warn) {
console.warn("WARNING: Cannot process more than one form with the same" +
" object. Attempting to use form IDs instead.");
}
this.objName = this.$el.attr("id");
}
},
errorNoID: function() {
if (console && console.log) {
console.log("ERROR: No form ID or object name. Add an ID or pass" +
" in an object name");
}
},
saveState: function(e) {
var instance = e.data.instance;
var values = instance.$el.serializeArray();
// jQuery doesn't currently support datetime-local inputs despite a
// comment by dmethvin stating the contrary:
// http://bugs.jquery.com/ticket/5667
// Manually storing input type until jQuery is patched
instance.$el.find("input[type='datetime-local']").each(function() {
var $i = $(this);
values.push({ name: $i.attr("name"), value: $i.val() });
});
values = instance.removeIgnored(values);
values.length && internals.setObject(instance.objName, values);
},
save: function() {
var instance = this;
if (!this.saveState) {
instance = this.data(remember_state.name);
}
instance.saveState({ data: { instance: instance } });
},
removeIgnored: function(values) {
if (!this.ignore) { return values; }
$.each(this.ignore, function(i, name) {
$.each(values, function(j, input) {
if (name === input.name) { delete values[j]; }
});
});
return values;
},
init: function() {
var instance = this;
// ****************************
/* if (instance.noticeDialog.length && instance.noticeDialog.jquery) {
instance.noticeDialog.find("a").bind("click." + instance.name, {
instance: instance
}, instance.clickNotice);
}*/
// ****************************
instance.chooseStorageProp();
if (!instance.objName) {
instance.errorNoID();
return;
}
if (localStorage[instance.objName]) {
// ****************************
/*if (instance.noticeDialog.length && typeof instance.noticeDialog === "object") {
instance.noticeDialog.prependTo(instance.$el);
}
else {
instance.$el.find(instance.noticeSelector).show();
}*/
// ****************************
}
if (instance.clearOnSubmit) {
instance.$el.bind("submit." + instance.name, function() {
instance.$el.trigger("reset_state");
$(window).unbind("unload." + instance.name);
});
}
instance.$el.bind("reset_state." + instance.name, function() {
localStorage.removeItem(instance.objName);
});
// ****************************
/*$(window).bind("unload." + instance.name, { instance: instance }, instance.saveState);
instance.$el.find(":reset").bind("click.remember_state", function() {
$(this).closest("form").trigger("reset_state");
});*/
}
};
var internals = {
setObject: function(key, value) { localStorage[key] = JSON.stringify(value); },
getObject: function(key) { return JSON.parse(localStorage[key]); },
createPlugin: function(plugin) {
$.fn[plugin.name] = function(opts) {
var $els = this,
method = $.isPlainObject(opts) || !opts ? "" : opts;
if (method && plugin[method]) {
plugin[method].apply($els, Array.prototype.slice.call(arguments, 1));
}
else if (!method) {
$els.each(function(i) {
var plugin_instance = $.extend(true, {
$el: $els.eq(i)
}, plugin, opts);
$els.eq(i).data(plugin.name, plugin_instance);
plugin_instance.init();
});
}
else {
$.error('Method ' + method + ' does not exist on jQuery.' + plugin.name);
}
return $els;
};
}
};
internals.createPlugin(remember_state);
})(jQuery);
});//]]>
</script>
<script>
var thisPage = 'page1'; //defines the variable to use for local storage
$(function() {
$("form")
.rememberState({objName: thisPage})
.submit(function() {localStorage.setItem(thisPage, $(this).serializeArray());
return true;
});
});
</script>
</head>
<body>
<form method="post" action="page2.cfm">
<fieldset>
<dl>
<dt><label for="first_name">First Name</label></dt>
<dd><input type="text" name="first_name" id="first_name" /></dd>
<dt><label for="last_name">Last Name</label></dt>
<dd><input type="text" name="last_name" id="last_name" /></dd>
</dl>
</fieldset>
<fieldset class="actions">
<input type="submit" value="Continue" />
</fieldset>
</form>
</body>
</html>
I thought this was going to be tougher than it was. Here is the solution I came up with:
On the form page when the submit button is pressed:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var thisPageID = 'page1'; // each page gets its own
$('form').submit(function() {
var formFields = $(this).serialize();
localStorage.setItem(thisPageID, formFields);
data = localStorage.getItem(thisPageID);
return true;
});
});
</script>
Then on the final page, I retrieve the data for each page by its page id from the local storage and populate my div tags with the data.
function getLocalData(id){
var ApplicantData;
ApplicantData = localStorage.getItem(id);
if (ApplicantData){
$.each(ApplicantData.split('&'), function (index, elem) {
var vals = elem.split('=');
var $div = $("#"+vals[0]);
var separator = '';
// console.log($div);
if ($div.html().length > 0) {
separator = ', ';
}
$div.html($div.html() + separator + decodeURIComponent(vals[1].replace(/\+/g, ' ')));
});
}
}
Some of the Articles that helped me (some SO, some external):
- Clear localStorage
- http://www.simonbingham.me.uk/index.cfm/main/post/uuid/using-html5-local-storage-and-jquery-to-persist-form-data-47
- http://www.thomashardy.me.uk/using-html5-localstorage-on-a-form
There were more but this is all I still had open in tabs.
I am using Javascript to display headers on a SharePoint site, according to a column that I have specified HTML in. Here is the HTML.
<DIV style ='text-align:center; font-weight:bold; font-size: 20px;'>◆</DIV>
The problem is that the script, while rendering the HTML properly within the page, does not do the same for header. It works 90% of the way, but instead of displaying the unicode "◆", it renders "â".
I've already tried modifying the Javascript to try to account for the unicode \u25c6, but I'm failing miserably. Can anyone help me out or provide me some clues as to why this is happening?
Here is the Javascript.
<script type="text/javascript">
// Find all Web Parts in the page
var listWP = [],
calWP = [],
divs = document.getElementById("MSO_ContentTable").getElementsByTagName("div");
var count=divs.length;
for (i=0;i<count;i++) {
try {
if (divs[i].id.indexOf("WebPartWPQ")==0){
if (divs[i].innerHTML.indexOf("ViewDefault_CalendarView")>=0) {
// Calendars
calWP.push(divs[i].id);
} else {
// Other Web Parts
listWP.push(divs[i].id);
}
}
}
catch(e){}
}
function TextToHTML(NodeSet, HTMLregexp) {
var CellContent = "";
var i=0;
while (i < NodeSet.length){
try {
CellContent = NodeSet[i].innerText || NodeSet[i].textContent;
if (HTMLregexp.test(CellContent)) {
NodeSet[i].innerHTML = CellContent;
}
}
catch(err){}
i=i+1;
}
}
var regexpA = new RegExp("\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
var WP = new Object;
function UpdateWP() {
if (calWP.length>0){
for (i=0;i<calWP.length;i++) {
WP=document.getElementById(calWP[i]);
if (WP.innerHTML.indexOf("<\;")>=0) {
TextToHTML(WP.getElementsByTagName ("a"),regexpA);
}
}
}
if (listWP.length>0){
for (i=0;i<listWP.length;i++) {
WP=document.getElementById(listWP[i]);
if (WP.innerHTML.indexOf("<\;")>=0) {
TextToHTML(WP.getElementsByTagName ("td"),regexpTD);
}
}
}
// Check every 200000000 ms, forever
setTimeout("UpdateWP()",200000000);
}
UpdateWP();
function HeaderToHTML(){
var headers=document.getElementById("MSO_ContentTable").getElementsByTagName("li");
var regexpTR1 = new RegExp("FilterValue1=([\\S\\s]*)'\\)");
var regexpTR2 = new RegExp("FilterValue2=([\\S\\s]*)'\\)");
for (i=0;i<headers.length;i++) {
try{
var sp=headers[i].getElementsByTagName("span");
for (j=0;j<sp.length;j++) {
var test = sp[j].innerText || sp[j].textContent || " ";
//var test = sp[j].innerText;
if (test.indexOf("...")>0) {
//alert(test);
//var value = regexpTR1.exec(headers[i].innerHTML)[1];
var inner = headers[i].innerHTML;
var value = (inner.indexOf("FilterValue2")>0) ? regexpTR2.exec(headers[i].innerHTML) [1] : regexpTR1.exec(headers[i].innerHTML)[1];
//alert(value);
//alert(value.replace(/\\u00/g,"\%"));
value=value.replace(/\\u00/g,"%");
sp[j].innerHTML=unescape(unescape(value)).replace(/8_/," ");
}
}
}catch(e){}
}
}
setInterval(function(){HeaderToHTML();},100);
</script>
I would suggest using the html dex/dec for the symbols.
that is,
◆ = ◆
◆ = ◆
Wikipedia has a nice list of them broken into categories here.
I found the black diamond you're trying to write here
I think a solution could be to render your character in its encoding and let browser know about it via:
<meta http-equiv="Content-Type" content="text/html; charset="...">
For example, if you are using UTF-8:
<meta http-equiv="Content-Type" content="text/html; charset="UTF-8">