My requirement is : Thers's an input field. When user is going to filled it,
on runtime i searched for #tag and make text bold. And wants to separate both groups of #tags
For Example: "I am more #FromSide #FromSide and would like to speak with someone more #ToSide"
Group1: #FromSide #FromSide
Group2: #ToSide
Here's my code:
`$('#custm-field').keyup(function(){`
`let str = $(this).val();`
`let arr = str.split(" ");`
`$(arr).each((i,e)=>{`
`if(e=="#")`
`{ // $(e).css('font-weight','bold');`
`arr[i].replace(e,"<strong>"+e+"</strong>");}
`let newStr = arr.join(" ");`
`$('#custm-field').val(newStr)`
`});`
This can be achieved using RegEx:
$('#custm-field').keyup(function(){
let str = $(this).val();
str = str.replace(/#(.+?)\s/, '<strong>$1</strong>');
$('#custm-field').val(str);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="custm-field"></input>
However, the bold effect won't be displayed in input fields, you need a contenteditable element for this.
I've constructed a solution for you,
First of all, you can't add HTML tags inside the value of an input tag. So you have to make use of contenteditable HTML attribute, by setting it to true contenteditable="true" on any element you can start to edit the content of it (write inside it).
NOTE: I added a background-color to make it visible when its empty
<div contentEditable="true" id="text" style="background-color: #eee;"></div>
Your JavaScript (JQuery) would look like this:
Note that your code had many errors I had to fix.
$('#text').keyup(function(){
// get the div element
let e = document.querySelector('#text');
// get only the text inside the element (without the HTML tags)
let str = e.innerText;
e.innerHTML = '';
// create a new element to contain our text because you cant add HTML text inside a DOM element directly
let tag = document.createElement('div');
let arr = str.split(" ");
// this string will contain our HTML and text
let newStr = ``;
$(arr).each((i,e)=>{
if(e[0]=="#")
{
newStr += `<strong>${e}</strong>`;
}
else{
newStr += `${e}`
}
newStr += ` `;
})
// add the string to the inner HTML of the element we created
tag.innerHTML = newStr;
// append the newly created element inside the div
e.append(tag);
// based on Vito Gentile answer
// this is to move the cursor to the end of the text we added, other wise the cursor would be at start of the text
cursorManager.setEndOfContenteditable(e);
});
I made use of the code of this answer, this is where this line cursorManager.setEndOfContenteditable(e); came from. Here is their code for convenience.
(function( cursorManager ) {
//From: http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
var voidNodeTags = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX'];
//From: https://stackoverflow.com/questions/237104/array-containsobj-in-javascript
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
//Basic idea from: https://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text
function canContainText(node) {
if(node.nodeType == 1) { //is an element node
return !voidNodeTags.contains(node.nodeName);
} else { //is not an element node
return false;
}
};
function getLastChildElement(el){
var lc = el.lastChild;
while(lc && lc.nodeType != 1) {
if(lc.previousSibling)
lc = lc.previousSibling;
else
break;
}
return lc;
}
//Based on Nico Burns's answer
cursorManager.setEndOfContenteditable = function(contentEditableElement)
{
while(getLastChildElement(contentEditableElement) &&
canContainText(getLastChildElement(contentEditableElement))) {
contentEditableElement = getLastChildElement(contentEditableElement);
}
var range,selection;
if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
{
range = document.createRange();//Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
selection = window.getSelection();//get the selection object (allows you to change selection)
selection.removeAllRanges();//remove any selections already made
selection.addRange(range);//make the range you have just created the visible selection
}
else if(document.selection)//IE 8 and lower
{
range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
range.select();//Select the range (make it the visible selection
}
}
}( window.cursorManager = window.cursorManager || {}));
Hopefully this works like what you want.
Related
I am working in a project(online exam, a single page application) using PHP+MySQL+AngularJs which has one very important section i.e. "Add Question". Let us take as a example:
$simple_question = "A train running at the speed of 60 km/hr crosses a pole in 9 seconds. What is the length of the train?";
$programmimg_question = "[code]#include int main(int argc, char **argv) { printf("%c\n", **++argv); return 0; }[/code]";
So you can see that, I am adding [code]....[/code] whenever programming language question is getting inserted so that I can prettify the code while showing the question. I am using twitter bootstrap which has <code> tag to show code between them. So I want to create a directive which will replace the [code] to <code> and render as a HTML in the view.
here is my code in HTML
<div class="question-container">
<code-highlighter> {{questionData.question}} </code-highlighter>
</div>
directive code(which is not working):
app.directive('codeHighlighter', function ($compile) {
return {
restrict: 'E',
scope: {
questions: "="
},
link: function (scope, element, attrs) {
var html = element[0].outerHTML;
var hasCodeElement = false;
if(html.indexOf('[code]')!=-1) hasCodeElement = true;
if(hasCodeElement) html = '<code>'+html+'</code>';
var e = $compile(html)(scope);
element.replaceWith(e);
}
};
})
I am pretty new for creating a directive in angularjs, please give me some resource or link to achieve the above problem, Please help me to out of it.
Thanks, In advance.
You don't need to $compile anything. Just set the elements HTML based on the assigned question-text, optionally replacing [code]...[/code] with <code>...</code>.
You can do it like this:
app.directive('question', function () {
return {
restrict: 'E',
scope: {
text: '='
},
link: function questionPostLink(scope, elem, attrs) {
var html = scope.text.replace(
/\[code\](.*?)\[\/code\]/g,
'<code>$1</code>');
elem.html(html);
}
};
});
Then you can use it like this:
$scope.questions = [
'This is a simple questions (without any [code]).',
'[code]var str = \'This is a programming question.\';[/code]'
];
<question text="txt" ng-repeat="txt in questions"></question>
See, also, this short demo.
UPDATE:
In order to be able to render HTML elements inside [code]...[/code] as is, use the following linking function:
link: function questionPostLink(scope, elem, attrs) {
// Here, I assume that programming questions
// always begin with [code] and end with [/code]
var isProgramming = progRE.test(scope.text);
if (!isProgramming) {
var html = scope.text;
elem.html(html);
} else {
var text = scope.text.replace(progRE, '$1');
elem.html('<code></code>');
elem.children().text(text);
}
}
See, also, this updated demo.
I have a HTML table with text in the cells like so:
<tr><td>HELLO</td></tr>
I then have a text area like so:
<input type="text" id="txt_message" name="txt_message"
I want to make it so that when you click inside the table cell, the data (in this case the word 'HELLO') is inserted into the text area (so the user does not have to type it).
I dont know if this is possible, but I am guessing it is and it is 'probably' something in JavaScript.
If anybody has any advice that would be great, Thank you :)
[Working demo]
var textbox = document.getElementById('textbox');
var table = document.getElementById('table');
// add one event handler to the table
table.onclick = function (e) {
// normalize event
e = e || window.event;
// find out which element was clicked
var el = e.target || e.srcElement;
// check if it's a table cell
if (el.nodeName.toUpperCase() == "TD") {
// append it's content to the textbox
textbox.value += (el.textContent || el.innerText);
}
}
Note: all the conditional assignments with || are for cross-browser compatibility.
Here is Working demo using jquery.
To get the value, use innerhtml and a span, more here: http://www.vbforums.com/showthread.php?t=339864
To update the textarea you should be able to do something like: document.getElementById ("text_message").value = x;
a simple jQuery snippet, assuming you have 1 textarea and multiple td's to click over
(function() {
var ta = $('#txt_message');
$('td').bind('click.addtextarea', function() {
var text = $(this).html();
ta.val([ta.val(), text].join(' ')); /* this add words */
/* ta.val(text); this print one word */
});
})()
How would I go about displaying a tooltip when the user hover overs some text / keywords? This body of text is directly retrieved from the database so I am unable to add any span or div tags or title information to these keywords. Is there a way to automatically create tooltips for certain words that are contained in the page?
Please let me know if there are any good tutorials available on how to solve this problem.
// Create tooltips dictionary
$tooltips = Array("Word1"=>"This word is word number 1",
"Word2"=>"This word is word number 2");
$content = "Here are Word1 and Word2";
foreach ($tooltips as $word=>$tip){
$content = preg_replace("/(".$word.")/", "<span title='".$tip."'>$1</span>", $content);
}
echo $content;
I had to do this a while ago. Actually I answered a similar question here: javascript: find strings in dom and emphasize it (took me a while to search for it).
Here's what I use to do the dynamic tooltip thing:
// keyword : tooltip
keywords = {
'hello world' : 'a common first example program',
'goodbye cruel world' : 'the opposite of hello world'
};
function insertTooltips (domNode) {
if (domNode.nodeType === Node.ELEMENT_NODE) { // We only want to scan html elements
var children = domNode.childNodes;
for (var i=0;i<children.length;i++) {
var child = children[i];
// Filter out unwanted nodes to speed up processing.
// For example, you can ignore 'SCRIPT' nodes etc.
if (
child.nodeName != 'span' ||
child.className != 'tooltip_span'
) {
insertTooltips(child); // Recurse!
}
}
}
else if (domNode.nodeType === Node.TEXT_NODE) { // Process text nodes
var text = domNode.nodeValue;
// This is another place where it might be prudent to add filters
for (var i in keywords) {
if (keywords.hasOwnProperty(i)) {
var match = text.indexOf(i); // you may use search instead
if (match != -1) {
// This is how you wrap the keyword in a span:
// create a span:
var span = document.createElement('SPAN');
// split text into 3 parts: before, mid and after
var mid = domNode.splitText(match);
mid.splitText(i.length);
// then assign mid part to span
mid.parentNode.insertBefore(span,mid);
mid.parentNode.removeChild(mid);
span.appendChild(mid);
// now we can assign a mouseover event handler to the span
span.onmouseover = function(){
showToolTip(keywords[i]);
}
// give the span a class name to prevent accidental
// recursion into it:
span.className = 'tooltip_span';
}
}
}
}
}
The implementation of the showTooltip function is left as an exercise for the reader.
The idea is basically to use DOM manipulation to dynamically search and wrap the keywords in spans and then assign a mouseover (or mouseclick, up to you) handler to the span to show the tooltip. On my website, the keyword/tooltip hash/object is generated from data pulled out of the database.
This is much more robust than trying to do this using regexp since it prevents accidental processing of words matching the keywords in class name, id and script tags.
Actually you can make use of span or whatever.
You have two options, the first is load the tooltip content at the first page request in a 'display: none' div or span, and then just show it up with an onmouseover event.
The second option is to perform an ajax request.
You should take a look at this: http://www.smashingmagazine.com/2007/06/12/tooltips-scripts-ajax-javascript-css-dhtml/
I don't know if it is possible! Maybe my thought is also wrong. I want to invoke a search corresponding to all links in my Wordpress blog.
I am using an Ajax call for my other search in this site. How can I retrieve a linking text from hypertext tag in html.
eg: <a href='www.example.com'>demo</a>.here i want to get 'demo' as input.
Thanks.
Try this:
var links_html_list = [];
var links = document.getElementsByTagName('a');
for(var l in links) {
if(typeof links[i] == undefined) continue;
links_html_list.push(links[i].innerHTML);
}
function search(term) {
var results = [];
for(var l in links_html_list) {
var cur = links_html_list[l];
if(typeof cur == undefined) continue;
if(cur.indexOf(term) != -1) results.push(cur);
}
return (results.length > 0) ? results : null;
}
What the search function does is it loops through the list of strings and if any have the term in it (indexOf), then it will get pushed into an array which is then returned. If there are no matches, it will return null.
You could use
$homePageText = file_get_contents(file.html);
preg_match_all('/<a .*?>(.*?)<\/a>/',$homePageText,$matches);
Then all anchor text elements will be stored in the array $matches.
I'm using ajax to update a textbox once the value in a drop down box has been selected. However, i only update/put text in it if certain conditions are met, so it looks rubbish when there is no message. I was thinking that having a label there would be much better, but is this possible? Can i have an empty label and just update the label text when needed?
Cheers
leddy
Edit:
I'm using php and when the drop down box is selected, I am querying a mysql db (in the reports.php page) - depending on what the result of that is, decides whether i update the textbox or not:
function getHTTPObject(){
if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest) return new XMLHttpRequest();
else {
alert("Your browser does not support AJAX.");
return null;
}
}
// Change the value of the outputText field
function setOutput(){
if(httpObject.readyState == 4){
document.getElementById('outputText').value = httpObject.responseText;
}
}
function checkException()
{
httpObject = getHTTPObject();
if (httpObject != null)
{
httpObject.open("GET", "reports.php?exceptions="
+document.getElementById('exceptionsID').value+"&date1=" + document.getElementById('date1').value, true);
httpObject.send(null);
httpObject.onreadystatechange = setOutput;
}
}
var httpObject = null;
the textbox is 'outputText' and is set in the setOutput() function
Hope this explains a little better
Cheers
Something like this should change the text of the label.
// Change the value of the outputText field
function setOutput(){
if(httpObject.readyState == 4){
document.getElementById('outputText').innerHTML= httpObject.responseText;
}
}
I updated my original post to reflect the code that was provided. This assumes that you are using the <label>, <div>, or <span> tags
Assuming you're using ASP.NET, yes you can. Using the Text property of the label.
Change the textbox into a span, and keep the id the same. Then change the code to set the innerHTML instead of the value:
// Change the value of the outputText field
function setOutput(){
if(httpObject.readyState == 4){
document.getElementById('outputText').innerHTML= httpObject.responseText;
}
}
The simplest way to handle this without a textbox is to create a SPAN tag, give it an id of "outputText", and then change the innerText of the SPAN like this:
function setOutput() {
if(httpObject.readyState == 4) {
document.getElementById('outputText').innerText = httpObject.responseText;
}
}
Inside your HTML, you'll have your label defined like this:
<span id="outputText">Some default text here</span>
Of course, some CSS styling of the SPAN might be a good thing, but that's another matter for another time. Depending on your layout needs, a DIV tag may be better than a SPAN.