My basic requirement is to convert given text anchors into hyperlinks, using HTML or any browser side script. We use Windows10/IE/Edge, FYI.
Example : Given text
ABC
CDE
EFG
Required Output:
www.xyz.com/test/ABC
www.xyz.com/test/CDE
www.xyz.com/test/EFG
I have found a bash to hyperlink query here. My requirement is similar but need a browser based script
How to create html links based on a text document of inputs
Put text in <textarea> and read it's content using js/jQuery.
Create links dynamically in memory and later use where needed (I simply append to DOM)
var urlBase = 'https://example.com';
$(document).ready(function () {
$('#input').change(function () {
var lines = $(this).val().split("\n"); // Split textarea content by new line
var links = $('#links'); // Links container
links.html(''); // Empty container content
$.each(lines, function (i, line) {
links.append($('<a>', {href: urlBase + '/' + line, text: line})); // Append new link element
})
})
})
#links a {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="input"></textarea>
<div id="links"></div>
Get the value of the text input, split it at the new lines and create a string of the a's with teh desired hrefs. I am using a ul to display the results.
Note the advantage of creating a string that is then added to the DOM is that it affects the DOM only once - rather than on each loop of the append option. A small matter for when there is a small list, but if there are millions of lines to be appended - the constant DOM maniulation may cause issues if you use .append().
function convertText(){
var links= document.getElementById('textInput').value;
var linksArr = links.split('\n');
var linkStr = '';
linksArr.forEach(function(link){
linkStr += '<li>'+link+'</li>';
})
document.getElementById('results').innerHTML = linkStr;
}
<textarea id="textInput"></textarea>
<hr/>
<button type="button" onclick="convertText()">Convert text to links</button>
<ul id="results"></ul>
Related
I'm trying to turn google docs file into html file. I gave html tags to the content via google docs (h1, h2, p, etc) and then I downloaded it as HTML file and it works great.
I have one problem - I want to wrap specific contents in my google doc file with divs, a div for each chapter for example. Right now the file is just a list of html tags (h1, p, h2 etc) and I need it to be more correct hierarchically.
Is there a way to do that? I tried to use page break and other similar options but it just adds another element to the list and not wrapping a specific content in a div as I wish.
A javascript solution will be good too.
Would appreciate any help, Thanks!
Nir
You can try this approach on Google Apps Script. This is in no way the only solution. This is only a simple code you can try from many possible solutions available. Feel free to modify if needed depending on your use case.
Code:
function myFunction() {
var doc = DocumentApp.getActiveDocument();
var content = doc.getBody();
var numChildren = content.getNumChildren();
var output = [];
// Send email to this address
var sendTo = "test#gmail.com";
output.push("<html><body>");
for(var i=0; i < numChildren; i++){
var item = content.getChild(i).asText();
var text = item.getText();
// Assuming that a chapter always starts in bold headers, we start the div there
if(item.isBold()) {
// Add opening div tags on every start of header, see doc format below
output.push('<div>');
output.push('<h1>' + text + '</h1>');
}
// If not bold, then that element is assumed as the content of the chapter
else if (text){
output.push('<p>' + text + '</p>');
}
}
output.push("</body></html>");
// Get all indices where div is (except the first) and reverse
var indexes = getAllIndexes(output, "<div>");
// Per div found, insert closing div tag </div> before it
indexes.forEach(function(index){
output.splice(index, 0, "</div>");
});
// Join output array and treat it as html
var html = Utilities.newBlob(output.join(""), 'text/html', 'doc_to_html.html');
// Send to your email (modify email above if needed) the converted file with div tags
MailApp.sendEmail(sendTo, "Attached html-converted document", "file is attached below", {name: 'doc-to-html', attachments: [html], noReply: true});
}
function getAllIndexes(arr, val) {
var indexes = [], i = -1;
while ((i = arr.indexOf(val, i+1)) != -1){
indexes.push(i);
}
// Remove the first index (we don't need to add closing divs before the first div)
indexes.shift();
// Return reversed indices since we will add from the end since we are inserting closing div tags (</div>)
// Inserting from the start will change the indices of those succeeding opening div tags (<div>) we need to close
return indexes.reverse();
}
Email:
HTML Attachment:
Note:
This was assumed that per chapter, there is a single header at the start (we insert the <div> here), and paragraph/s below it. The closing div tags </divs> are inserted every before the next <div> tags found.
In an MVC application I have to use #HTML.TextAreaFor to display some text from a database, the trouble is sometimes that text may have HTML tags within it and I can't see a way to remove those for display only.
Is it possible to do this in the view (maybe with CSS?) without having to strip the tags in the controller first?
EDIT
The data coming from the controller contains html tags which I do not want to remove, I just don't want to display them
Normally I would use #HTML.Raw but it has to work in a #HTML.TextAreaFor control.
If you want to decode Html returned from the Controller you can use the following JavaScript method:
This method decodes "Chris' corner" to "Chris' corner".
var decodeEntities = (function () {
// this prevents any overhead from creating the object each time
var element = document.createElement('div');
function decodeHTMLEntities(str) {
if (str && typeof str === 'string') {
// strip script/html tags
str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
element.innerHTML = str;
str = element.textContent;
element.textContent = '';
}
return str;
}
return decodeHTMLEntities;
})();
You can do this by using a razor code in your view.
#Html.Raw(HttpUtility.HtmlDecode(Model.Content))
if I set Model.Content to this string "<strong>This is me</strong><button>click</button>", the code above will render it like HTML code and will have a strong text next to a button as an output like the image below:
There's some nice rich text editors libraries like CK Editor, Quill, or TinyMCE that can display HTML while still maintaining the editor capabilities of being a text editor. All of these libraries have capabilities of being read-only as well if that's necessary.
Example from Quill -
Sorted this by changing TextAreaFor toTextBoxFor and setting a formatted value.
#Html.TextBoxFor(x => Model.MyItem, new { #class = "form-control", #required = "true", Value = Regex.Replace(Model.MyItem, "<.*?>", String.Empty) })
I have asked kind of a similar question before : how to toggle using multiple buttons and pass info to the output JQuery
It was answered well, but this time I am using a different approach in the code thus a new question.
I am trying to toggle info and append a div using three different buttons.
Here is The code https://jsfiddle.net/YulePale/nruew82j/40/
JavaScript
document.getElementById("brazil").addEventListener('click', function(e){
if(e.currentTarget.dataset.triggered) return;
e.currentTarget.dataset.triggered = true;
AppendFunction();
function AppendFunction() {
var para = document.createElement("p");
var homeTeam = document.getElementById("brazil").value
para.innerHTML = 'This is the national team of ' + `${homeTeam}` + ':'
<br> <input type="text" value="${homeTeam}" id="myInput"><button
onclick="myFunction()">Copy text</button>';
var element = document.getElementById("gugu");
element.appendChild(para)
}
})
document.getElementById("draw").addEventListener('click', function(e){
if(e.currentTarget.dataset.triggered) return;
e.currentTarget.dataset.triggered = true;
AppendFunction();
function AppendFunction() {
var para = document.createElement("p");
var homeTeam = document.getElementById("draw").value
para.innerHTML = 'This two teams have played each other 4 times ' +
`${homeTeam}` + ':' <br> <input type="text" value="${homeTeam}" id="myInput">
<button onclick="myFunction()">Copy text</button>';
var element = document.getElementById("gugu");
element.appendChild(para)
}
})
document.getElementById("russia").addEventListener('click', function(e){
if(e.currentTarget.dataset.triggered) return;
e.currentTarget.dataset.triggered = true;
AppendFunction();
function AppendFunction() {
var para = document.createElement("p");
var homeTeam = document.getElementById("russia").value
para.innerHTML = 'This is the national team of ' + `${homeTeam}` + ':'
<br> <input type="text" value="${homeTeam}" id="myInput"><button
onclick="myFunction()">Copy text</button>';
var element = document.getElementById("gugu");
element.appendChild(para)
}
})
PS: I don't know why the javascript code is not working in fiddle yet it is working on my computer.
If you look at the code I am basically trying to toggle a div with info on various teams. If it is Brazil the div comes with info on Brazil if Russia, info on Russia.
The problem with my current code is that it keep on appending the divs instead of
toggling them. How can I toggle them? like this: https://jsfiddle.net/YulePale/7jkuoc93/
Instead of having them append another div each time I click a different button?
............................................................................................
PS: EDIT & UPDATE:
#Twisty, I forked the code from your fiddle and tried to implement it when working with more than one row of buttons. The code works well but I was unable to append a different and separate element for each row each time I click on a button on that row.
I tried putting the appended element as a class:
Here is the code: https://jsfiddle.net/YulePale/a9L1nqvm/34/
Also tried putting it as an id:
Here is the code: https://jsfiddle.net/YulePale/a9L1nqvm/38/
How can I put it in a way that each row appends it's own separate element and I would also like users to be able to copy using the copy button without the element disappearing. How do I make it in such a way that the element only disappears only when I click outside the respective:
<div class="col.buttonCol " id="buttons-div">
and also disappears when I click another row of buttons?
Also in your answer you said you would have used text boxes instead of appending this way. I checked the modals out and they all appear on the browser like alerts can you please point me to a resource that show how you can use a modal that works like an appending element instead of one that acts as an alert? Thank you.
Here is the link to the modals I saw: https://getbootstrap.com/docs/4.0/components/modal/
I converted all your JavaScript to jQuery since you posted this in the jquery-ui, I am assuming you want to work with jQuery.
I will often organize my functions first and then the interactive actions.
JavaScript
$(function() {
function myFunction() {
//Do Stuff
}
function AppendFunction(id) {
var para = $("<p>");
var home = $("#" + id).val();
para.append("This is the national team of " + home + ":", $("<br>"), $("<input>", {
type: "text",
value: home,
id: "myInput"
}), $("<button>").html("Copy Text").click(myFunction));
$("#gugu").html(para);
}
function emptyOnDocumentClick(event) {
var action = $(".triggered").length;
$(".triggered").removeClass("triggered");
return !action;
}
$("#brazil, #russia").on('click', function(e) {
if ($(this).hasClass("triggered")) {
return;
}
$(this).addClass("triggered");
var myId = $(this).attr("id");
AppendFunction(myId);
});
$(document).on("click", function(e) {
if (emptyOnDocumentClick(e)) {
$("#gugu").html("");
}
});
});
Working Example: https://jsfiddle.net/Twisty/nruew82j/91/
The basic concept here is a dialog and if it were me, I would use a dialog box either from BootStrap or jQuery UI. You're not doing that, so we're create the content and append it to a specific <div>. Then, like in your previous question, you just detect a click on the document and decide what that will do. In this case, I emptied the content of the <div> that we'd previously appended content to.
Hope that helps.
I want to create a PDF file along with the text entered by user in text fields(textarea and input type=text).I have an iframe which renders my template consisting of labels and input text fields.Now, I am able to correctly render this template to a PDF file using jspdf.But I want the template along with the user entered text values to be rendered in the PDF file.Please note that I dont want to change the templates html() permanently.Is there a way I can clone a temporary html and then render it via jspdf.Also note that jspdf will only print text within text nodes, which means that it will not print the values of textareas and the like. Example:
<body>
<ul>
<!-- This is printed as the element contains a textnode -->
<li>Print me!</li>
</ul>
<div>
<!-- This is not printed because jsPDF doesn't deal with the value attribute -->
<input type="textarea" value="Please print me, too!">
</div>
</body>
I use the below code to generate pdf from the iframe...
var body = $("#DispTemp").contents().find('body');
var pdf = new jsPDF('p', 'pt', 'letter');
// source can be HTML-formatted string, or a reference
// to an actual DOM element from which the text will be scraped.
// var content = document.getElementById('DispTemp').contentWindow.document.body.innerHTML;
source = body[0].innerHTML;
// we support special element handlers. Register them with jQuery-style
// ID selector for either ID or node name. ("#iAmID", "div", "span" etc.)
// There is no support for any other type of selectors
// (class, of compound) at this time.
specialElementHandlers = {
// element with id of "bypass" - jQuery style selector
'#bypassme': function (element, renderer) {
// true = "handled elsewhere, bypass text extraction"
return true
}
};
margins = {
top: 80,
bottom: 60,
left: 40,
width: 522
};
// all coords and widths are in jsPDF instance's declared units
// 'inches' in this case
pdf.fromHTML(
source, // HTML string or DOM elem ref.
margins.left, // x coord
margins.top, { // y coord
'width': margins.width, // max width of content on PDF
'elementHandlers': specialElementHandlers
},
function (dispose) {
// dispose: object with X, Y of the last line add to the PDF
// this allow the insertion of new lines after html
pdf.save('Test.pdf');
}, margins);
Besides as an option I have also use html2canvas and casper libraries.But there is a problem of text distortion with them..
HTML has a draft specification for a < template > tag. Details here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
I'm thinking about using Rivets.JS on a new project, I also want to use this new template tag.
Can the two be made to work together nicely?
I imagine I'd want to tell rivets something along the lines of 'get this template, bind it to this data and output the result here'.
You can copy the template as your normally would, and then use Rivets to bind to your new element. demo # jsfiddle
HTML:
<template id="demo">
<p id="tag">{ demo.info }<p>
</template>
Javascript:
var demo = {
info: "Test string"
}
// Copy template data to visible DOM
var el = document.getElementById("demo");
var clone = document.importNode(el.content, true);
document.body.appendChild(clone);
// Bind using Rivets as normal
var tag = document.getElementById("tag");
rivets.bind(tag, { demo: demo });