How to get Tooltipster to access data in a js array - javascript

Using Tooltipster, I want to populate tooltips with words selected from a English/Thai glossary set up as a js 2D array. The intention is that as an English word is tooltipped it will be used to access and display the paired Thai word(s). All of this is in a modal dialog. Here is the html:
<div id="modal_text">
<p id="modal_text01">The <span class="tooltip">boy</span> is <span class="tooltip">walking</span><span> </span><span class="tooltip" >home</span></p>
here is the js code (the array is set as a global variable)
var eng_thai_glossary=[["the","คำนำหน้านามเจาะจง"], ["and","และ"], ... ["dependent","ซึ่งพึ่งพา ผู้อาศัย"]];
jQuery(document).ready(function () {
"use strict";
var modalIndex = "";
var ws_dlog = jQuery("div#ws_dialog").dialog({
... /* dialog setup */
jQuery("span.ws_dialog_icon").on("click",function(evnt) {
evnt.stopPropagation();
ws_dlog.dialog("open");
jQuery("#ui-dialog-title-dialog").hide();
jQuery(".ui-dialog-titlebar").removeClass('ui-widget-header');
var elementId = evnt.target.id;
modalIndex = elementId.substr(7);
var modalId = "modal_text" + modalIndex,
modalText = document.getElementById(modalId).innerHTML;
var ws_modal_html = '<div class = "ws_dialog_box"><p class = "ws_dialog_text">Here is the word in a sentence</p><p class="ws_dialog_thai">คำในประโยค</p><p class = "ws_dialog_sentence"></p><p><span class="fa fa-volume-up fa_volume_ws"></span></p></div>';
ws_dlog.html(ws_modal_html);
jQuery("div.ws_dialog_box p.ws_dialog_sentence").append(modalText);
jQuery('span.tooltip').tooltipster({
functionAfter: function(evnt) {
var eng_word = jQuery(this).evnt.innerHTML,
thai_word = "";
for( var i=0; i<eng_thai_glossary.length; i++) {
if(eng_thai_glossary[i][0] === eng_word) {
thai_word = eng_thai_glossary[i][1];
return thai_word;
}
}
}
});
});
... /* audio code */
});
Firebug shows the class "tooltipstered" is being added to the html indicating Tooltipster is being initialized. I'm a bit lost beyond this point. I'm not sure whether functionAfter is the right way to go here, or any of the other code for that matter. Any advice would be most welcome

OK, this is the solution I arrived at for the above issue. Pretty standard stuff, I guess. The toLowerCase method covers the English convention of capitalizing the first character of a sentence.
jQuery('span.tooltip').tooltipster({
functionBefore: function(origin, continueTooltip) {
var eng_word = jQuery(origin).text().toLowerCase(),
thai_word = "",
gloss_length = eng_thai_glossary.length;
for(var i=0; i<gloss_length; i++){
if(eng_thai_glossary[i][0] === eng_word) {
thai_word = eng_thai_glossary[i][1];
break;
}
}
origin.tooltipster( "content", thai_word);
continueTooltip();
}
});

Related

javascript dynamically remove text

I have successfully created a button which adds text to the webpage however I do not know a viable way to remove text once this has been created. The js code I have is:
var addButtons = document.querySelectorAll('.add button');
function addText () {
var self = this;
var weekParent = self.parentNode.parentNode;
var textarea = self.parentNode.querySelector('textarea');
var value = textarea.value;
var item = document.createElement("p");
var text = document.createTextNode(value);
item.appendChild(text)
weekParent.appendChild(item);
}
function removeText() {
//document.getElementbyId(-).removeChild(-);
}
for (i = 0; i < addButtons.length; i++) {
var self = addButtons[i];
self.addEventListener("click", addText);
}
I have viewed various sources of help online including from this site however I simply cannot get any to work correctly. Thank you in advance.
Sure, it should be easy to locate the added <p> tag relative to the remove button that gets clicked.
function removeText() {
var weekParent = this.parentNode.parentNode;
var item = weekParent.querySelector("p");
weekParent.removeChild(item);
}
If there is more than 1 <p> tag inside the weekParent you will need a more specific querySelector.

Automatically Highlight Specific Word in Browser

In the content scripts of my chrome extension I am trying to inject code that highlights a specific word in the page.
In this instance, I am viewing espn.com and would like to have all instances of 'bryant' highlighted in the text immediately as the page is loaded.
This is the current code I have customized after viewing several questions similar to mine:
var all = document.getElementsByTagName("*");
highlight_words('Bryant', all);
function highlight_words(keywords, element) {
if(keywords) {
var textNodes;
keywords = keywords.replace(/\W/g, '');
var str = keywords.split(" ");
$(str).each(function() {
var term = this;
var textNodes = $(element).contents().filter(function() { return this.nodeType === 3 });
textNodes.each(function() {
var content = $(this).text();
var regex = new RegExp(term, "gi");
content = content.replace(regex, '<span class="highlight">' + term + '</span>');
$(this).replaceWith(content);
});
});
}
}
In my jquery-ui.css I have the following code. I understand it does not highlight at this moment but I am just trying to get a proof of concept:
.highlight {
font-weight: bold;
}
At this time everything loads properly but no iteration of 'bryant' is read in bold.
Thanks!
The fastest way to do this is to define the what are you want to search for highlight, for example:
You have 3 parts on site, the navbar on left, the title on the top and the content.
Lets attach .foo class to article.
var list = document.getElementsByClassName("foo")
var search_word = ""
var contents = []
for(var i = 0; i < list.length; i++){
var contents = list[i].textContext.split(search_word)
list[i].textContext = contents.join('<span class="heighlight\">'+search_word+'</span>')
}
Hope it will help.
(The highlight is bound to elements that have .foo class)
some example: https://jsfiddle.net/Danielduel/0842qntu/2/

Auto highlighting part of word

I'm trying to build a "search in the shown elements" function with jquery and css.
Here's what I got so far:
http://jsfiddle.net/jonigiuro/wTjzc/
Now I need to add a little feature and I don't know where to start. Basically, when you write something in the search field, the corresponding letters should be highlighted in the list (see screenshot, the blue highlighted part)
Here's the script so far:
var FilterParticipants = function(options) {
this.options = options;
this.participantList = [];
this.init = function() {
var self = this;
//GENERATE PARTICIPANTS OPBJECT
for(var i = 0; i < this.options.participantBox.length ; i++) {
this.participantList.push({
element: this.options.participantBox.eq(i),
name: this.options.participantBox.eq(i).find('.name').text().toLowerCase()
})
}
//ADD EVENT LISTENER
this.options.searchField.on('keyup', function() {
self.filter($(this).val());
})
}
this.filter = function( string ) {
var list = this.participantList;
for(var i = 0 ; i < this.participantList.length; i++) {
var currentItem = list[i];
//COMPARE THE INPUT WITH THE PARTICIPANTS OBJECT (NAME)
if( currentItem.name.indexOf(string.toLowerCase()) == -1) {
currentItem.element.addClass('hidden');
} else {
currentItem.element.removeClass('hidden');
}
}
}
this.init();
}
var filterParticipants = new FilterParticipants({
searchField: $('#participants-field'),
participantBox: $('.single_participant'),
nameClass: 'name'
});
I think you're just complicating things too much... You can do this easily in a few lines. Hope this helps:
var $search = $('#participants-field');
var $names = $('.single_participant p');
$search.keyup(function(){
var match = RegExp(this.value, 'gi'); // case-insensitive
$names
.hide()
.filter(function(){ return match.test($(this).text()) })
.show()
.html(function(){
if (!$search.val()) return $(this).text();
return $(this).text().replace(match, '<span class="highlight">$&</span>');
});
});
I used hide and show because it feels snappier but you can use CSS3 animations and classes like you were doing.
Demo: http://jsfiddle.net/elclanrs/wTjzc/8/
Here`s the way to do it with jQuery autocomplete so question
If you want to build it on your own you can do the following:
1. Get the data of every item.
2. Make render function in which you will substitute say "Fir" in Fire word to Fire
3. Every time you change the text in the input you can go through the items and perform substitution.

How to interate an array with navigation menu buttons (first, previous, next, last)

Well, one more question. Since I started learning javascript short time ago, I am almost obsessed trying new things! Here it goes:
Let's say that I have an array of strings and I want to iterate on it with a navigation menu with the buttons FIRST, PREVIOUS, NEXT, LAST.
Look at this code:
var thearray = ["article1", "article2", "article3"];
var thebody = document.getElementsByTagName('body')[0];
var divcontainer = document.createElement("div");
var divpage = document.createElement("div");
function generatepage(article) {
var paragraph = document.createElement("p");
var name = document.createTextNode(thearray[article]);
paragraph.appendChild(name);
divpage.appendChild(paragraph);
}
divcontainer.appendChild(divpage);
thebody.appendChild(divcontainer);
generatepage(0); // that would be for the first article
I also figured out that generatepage(thearray.length -1)would be the call for the last article, so I have solved two buttons (before generating new content I would erase it with innerHTMLbut what I cannot think about how to do are the PREVIOUS and NEXT buttons...
Do you have any suggestion about how should I get started to make working PREVIOUS and NEXT?
I attach a JSFiddle
Thank you so much for any advice!
You can save the active page in a variable outside the function:
var page = 0;
Then you don’t need to bring any page into generatepage():
function generatepage() {
var paragraph = document.createElement("p");
var name = document.createTextNode(thearray[page]);
paragraph.appendChild(name);
divpage.appendChild(paragraph);
}
Now you can control the page from outside the function:
var next = function() {
if ( page < page.length-1 ) { page++; }
}
var prev = function() {
if ( page ) { page--; }
}
So to show the first page:
page = 0;
generatepage()
And the next:
next();
generatepage()
etc.... There are other ways too of course but this might give you an idea.
You can save a variable outside the scope of the function to memorize the current article
when you add Eventlisteners to the buttons you can call the next and previous item
but you should somehow replace the content of the div with the next one instead of appending it (i don't know a thing about manipulating dom elements)
you could try something like this:
var thearray = ["article1", "article2", "article3"];
var thebody = document.getElementsByTagName('body')[0];
var divcontainer = document.createElement("div");
var divpage = document.createElement("div");
var currentarticle
function generatepage(article) {
if(thearray[article]) {
currentarticle = article
var paragraph = document.createElement("p");
var name = document.createTextNode(thearray[article]);
paragraph.appendChild(name);
divpage.innerHTML= paragraph.innerHTML
}else {
return false
}
}
divcontainer.appendChild(divpage);
thebody.appendChild(divcontainer);
generatepage(0); // that would be for the first article
document.getElementById("next").addEventListener("click",function() {
generatepage(currentarticle + 1)
});
document.getElementById("previous").addEventListener("click",function() {
generatepage(currentarticle - 1)
});
document.getElementById("last").addEventListener("click",function() {
generatepage(thearray.length - 1)
});
document.getElementById("first").addEventListener("click",function() {
generatepage(0)
});
​
heres the Fiddle

Text to HTML in SharePoint using Javascript

I have a summary single-line text column in SharePoint 2007 that is a truncation of a multi-line text column. Going through the complicated process to get there, it turns into text which then needs to be converted back to HTML, so that the tags like <div> don't show. The following code works if the multi-line column is rich text, but not if it's enhanced rich text. Does anyone have the code handy to make this work? (Note: I am working on it but haven't really done any javascript up until now, so it's slow going).
<script type="text/javascript">
var theTDs = document.getElementsByTagName("TD");
var i=0;
var TDContent = " ";
while (i < theTDs.length)
{
try
{
TDContent = theTDs[i].innerText || theTDs[i].textContent;
if (TDContent.indexOf("<div") == 0)
{
theTDs[i].innerHTML = TDContent;
}
}
catch(err){}
i=i+1;
}
</script>
The result I'm getting now is nothing visible, because with enhanced rich text the div tag is longer than my 45 character truncation limit.
How about using Christophe's techniques to output HTML using a calculated column.
Specifically he has written javascript that will turn the encoded HTML (which you've now got) into HTML.
Add the following into a Content Editor Web Part (CEWP) on the same page.
<script type="text/javascript">
/*
Text to HTML Lite - version 2.1.1
Questions and comments: Christophe#PathToSharePoint.com
*/
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;
}
}
// Calendar views
var regexpA = new RegExp("\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*");
TextToHTML(document.getElementsByTagName("a"),regexpA);
// List views
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"),regexpTD);
</script>
I have modified the TextToHTML code from below link, source is PathToSharePoint.com and I have added an event listener which works on SharePoint 2016 successfully in IE compatiblity mode which runs as IE10 and Chrome latest version: Text to Html conversion in Sharepoint 2010
<script type="text/javascript">
/*
Text to HTML Lite - version 2.1.1
Questions and comments: Christophe#PathToSharePoint.com
*/
document.addEventListener("DOMContentLoaded", function() {
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;
}
}
// Calendar views
var regexpA = new RegExp("\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*");
TextToHTML(document.getElementsByTagName("a"), regexpA);
// List views
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"), regexpTD);
// This function is call continuesly every 100ms until the length of the main field changes
// after which the convert text to HTML is executed.
var postElemLength = 0;
function PostConvertToHtml() {
if (postElemLength == document.getElementsByTagName("TD").length) {
setTimeout(PostConvertToHtml, 100);
}
else {
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"), regexpTD);
}
}
// Grouped list views
ExpGroupRenderData = (function(old) {
return function(htmlToRender, groupName, isLoaded) {
var result = old(htmlToRender, groupName, isLoaded);
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"), regexpTD);
};
})(ExpGroupRenderData);
// Preview pane views
if (typeof (showpreview1) == "function") {
showpreview1 = (function(old) {
return function(o) {
var result = old(o);
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"), regexpTD);
};
})(showpreview1);
}
});
</script>

Categories