I'm attempting to set up a simple way for a non-tech-savvy person to update a marquee ticker that will appear on a website that would be published to our BrightSign display system. I was think that they could easily type what they want into a text file, save it, and "republish" the website to our display system. All the files (index.html, style.css, tickerText.txt) would be saved locally on a computer for the person in charge to edit the marquee.
Everything works well when I type in the text between my marquee tags, but when I attempt to pull in the info from a text file, it scrolls across with a large amount of "white space" and not as long text. The below script shows when it comes out correctly (shown in picture link -- wouldn't let me embed).
Long Text Marquee
<!-- Bottom Marquee Ticker -->
<div class="3-row-padding w3-center">
<div class="w3-container ocacity75"">
<div class="w3-card-4 w3-white w3-round ticker">
<marquee>This is a test and so is this</marquee>
</div>
</div>
</div>
The below script is when I try to populate the marquee from a text file and then messes up my formatting (shown in picture -- wouldn't let me embed).
Incorrect Formatting Marquee
<!-- Bottom Marquee Ticker -->
<div class="3-row-padding w3-center">
<div class="w3-container ocacity75"">
<div class="w3-card-4 w3-white w3-round ticker">
<marquee><object type="text/html" data="./TickerText.txt"></object></marquee>
</div>
</div>
</div>
I even tried adding in-line styling to the object tag to try to make the marquee not so large and to increase the text size, but nothing seems to work. I may be going about this wrong with trying to read in a text file. I tried some JavaScript, but I couldn't get it to work and though just a marquee tag would do just fine. Any help would be a appreciated.
To confirm, I did not use AJAX as the website doesn't show its changes on the display system until we hit the publish button again. So live updates to the website without refreshing would be overkill.
Well, you could try this:
var input = document.getElementById("myFile");
var output = document.getElementById("output");
input.addEventListener("change", function() {
if (this.files && this.files[0]) {
var myFile = this.files[0];
var reader = new FileReader();
reader.addEventListener('load', function(e) {
output.textContent = e.target.result;
});
reader.readAsBinaryString(myFile);
}
});
#styleTest {
color: green;
}
<input type="file" id="myFile">
<div id="styleTest">
<div id="output"></div>
</div>
This will work for what you want, also the data in the text file would be able to be formated if needed.
As said in the comment by A Haworth,
The <marquee></marquee> tag is now deprecated.
Also, you could bypass even having a text file by doing this:
(Note: this one is better suited to your needs, for now.)
var input = document.getElementById("input");
var output = document.getElementById("output");
var txtInSub = document.getElementById("txtInSub");
function addData() {
output.innerHTML = input.value;
}
window.addEventListener("keydown", checkKeyPressed, false);
function checkKeyPressed(e) {
e = e || window.event;
var key = e.which || e.keyCode;
// key == "13" is the enter key
if (key == "13") {
txtInSub.click();
console.log({keyPressed: "Enter", functionExecution: "Submitted the Text Input Field", contentPosted: input.value});
}
}
#styleTest {
color: green;
}
#inSubFld {
text-align: center;
width: 98.22%;
position: absolute;
left: 0;
top: 60px;
}
#input {
width: 100%;
padding: 10px;
display: block;
}
#txtInSub {
display: none;
}
<div id="styleTest">
<div id="output"></div>
</div>
<div id="inSubFld">
<input id="input" type="text" autofocus> <!-- with autofocus it should force it so that you could type in the input field without needing to click it -->
<button id="txtInSub" onclick="addData()">Submit</button>
<p>Press Enter to Submit the content in the field above.</p>
</div>
Related
I am new to HTML ,JavaScript and jQuery. I am currently doing a search box, when I start to type text on the search input the search list must appear and able to click the search list name and append it to search input, and close the search list and left with search input and current text that I clicked on the search list.
var $block = $('.no-results');
$(".personsMenu").hide();
$(".my-textbox").keyup(function() {
var textbox = document.getElementById("textboxEmp");
var val = $(this).val();
var isMatch = false;
var nameAp = document.getElementsByClassName("name12");
$(".personsMenu").show();
if (textbox.value == 0) {
$(".personsMenu").hide();
}
$(".personsMenu div").each(function() {
var content = $(this).html();
if ((content.toLowerCase().indexOf(val) == -1) && (content.toUpperCase().indexOf(val) == -1)) {
$(this).hide();
} else {
isMatch = true;
$(this).show();
}
});
$block.toggle(!isMatch);
});
function mySelect() {
$(".name12").appendTo($(".my-textbox"));
$(".personsMenu").hide();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="cover">
<div name="selected">
<i class="mdi-account-search mdi"></i><input class="my-textbox" id="textboxEmp" autofocus="autofocus" placeholder="search staff member" />
</div>
<div class="personsMenu">
<ul class="infor">
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Malubane Nyikiwe</li>
<li>nyikiwe.malubane#m-t.co.za</li>
</div>
<div class="no-results">no employee found by that name</div>
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Chamano Sydney</li>
<li>sydney.chamano#m-t.co.za</li>
</div>
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Diphofa Tumelo</li>
<li>tumelo.diphofa#m-t.co.za</li>
</div>
</ul>
</div>
</div>
There's several issues in your code which all need to be addressed:
You're using invalid HTML. ul elements can only contain li, not div. I'd suggest restructuring the HTML to use div containers to hold the information for each item in your list.
Use CSS to hide content which should not be visible when the page loads. This avoids the FOUC which can happen as JS only runs after the DOM is ready.
If you've included jQuery in the page, you may as well use it consistently to make your code more succinct.
Use the input method, not keyup, for listening to user input. input will also fire when the user copies content in to the field using the mouse for example, keyup won't.
Use unobtrusive event handlers, eg. jQuery's on() method, not inline onclick attributes. The latter is outdates and bad practice at it doesn't allow for good separation of concerns.
When searching text, equalise the cases of the search and target strings, don't search for both upper and lower versions.
Use text() to search for the content, not html().
To set the value of an input element use val(), not append(). The latter is for adding HTML/text content to an element, not setting its value property.
With all that said, the working code will look something like this:
var $noResults = $('.no-results');
var $names = $(".name12");
var $personsMenu = $('.personsMenu');
var $searchBox = $(".my-textbox").on('input', function() {
var value = $(this).val().trim().toUpperCase();
if (!value) {
$personsMenu.hide();
return;
}
var matches = $personsMenu.show().find('div').each(function() {
var content = $(this).text().toUpperCase();
$(this).toggle(content.indexOf(value) !== -1);
});
$noResults.toggle(matches.filter(':visible').length == 0);
});
$('.item').on('click', function() {
$searchBox.val($(this).find('.name12').text());
$personsMenu.hide();
});
.personsMenu,
.no-results {
display: none;
}
.item {
padding: 10px;
cursor: pointer;
}
.item:hover {
background-color: #CCC;
}
.item p {
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="cover">
<div name="selected">
<i class="mdi-account-search mdi"></i>
<input class="my-textbox" id="textboxEmp" autofocus="autofocus" placeholder="search staff member" />
</div>
<div class="personsMenu">
<div class="no-results">no employee found by that name</div>
<div class="item">
<p class="name12">Malubane Nyikiwe</p>
<p class="email">nyikiwe.malubane#m-t.co.za</p>
</div>
<div class="item">
<p class="name12">Chamano Sydney</p>
<p class="email">sydney.chamano#m-t.co.za</p>
</div>
<div class="item">
<p class="name12">Diphofa Tumelo</p>
<p class="email">tumelo.diphofa#m-t.co.za</p>
</div>
</div>
</div>
I have a field where a user can input raw HTML. This looks like:
<input type="text" id="editor" value="<p>Hi,</p><p>Here is a <a href='domain.com'>link</a> I'd like you to visit.</p>" />
Now, I need a "copy to clipboard" button that takes the content of this field in such a way that we can paste it as formatted text (without the HTML markup). In the example above, the copy/paste output should be:
Hi,
Here is a [link][1] I'd like you to visit.
I've implemented the "copy to clipboard" button like this:
let answer = document.getElementById("editor");
answer.select();
document.execCommand("copy");
This places the content of the input on the clipboard, however when I paste it elsewhere I get the raw HTML.
I need some way to convert HTML into formatted text, but the only solution I found is this and it doesn't work for links:
enter link description here
Is there a native Javascript way to do this? If not, what is the best solution?
Try with Element.insertAdjacentHTML()
let answer = document.getElementById("editor");
let result = document.getElementById("result");
let button = document.getElementById("button");
button.onclick = function() {
answer.select();
document.execCommand("copy");
};
function conVert(event) {
event.preventDefault();
let val = answer.value
console.log(val)
result.insertAdjacentHTML('afterbegin', val);
// you can use event.target here to past it as formated to targeted element onpaste
}
// on button
buttonpaste.onclick = function(event) {
conVert(event)
}
//on paste
document.onpaste = function(event) {
console.log("Paste")
conVert(event)
};
#result {
min-height: 100px;
background-color: yellow
}
#result2 {
min-height: 100px;
background-color: gray;
}
<input type="text" id="editor" value="<p>Hi,</p><p>Here is a <a href='domain.com'>link</a> I'd like you to visit.</p>" />
<button id="button">COPY</button>
<button id="buttonpaste">PASTE</button>
<div id="result" contentEditable="true"></div>
<div id="result2" contentEditable="true"></div>
I was wondering if I can create a text input where users can type some text and then immediately display them on page, same as twitter. I know about alert window or prompt window but I need something different, a text input on website.
Hope it can be done in JavaScript.
Use .keyup() for the input field then replace the content of the output div.
$(".div-input").keyup(function() {
$(".output").html($(this).val());
});
.output {
margin-top: 20px;
font-size: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="div-input" />
<div class="output">
</div>
If you want to display the input on submit, you could attach a .submit() event on a form tag then use appendTo on the div if you want to insert multiple elements;
$(".form-input").submit(function(e) {
e.preventDefault();
var value = $(".div-input").val();
$("<div class='outputs'>" + value + "</div>").appendTo($(".output"));
});
.output {
margin-top: 20px;
}
.outputs {
padding: 20px;
font-size: 2em;
border: 1px solid black;
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="form-input">
<input class="div-input">
<button type="submit">Submit</button>
</form>
<div class="output"></div>
you can use this to show your text anywhere on page
<input id="input-name" oninput="outputname.value = this.value">
<output id="outputname" name="outputname" for="input-name"></output>
You can test it here
If you add an eventlistener to the input, you can use that to change the text in your output area on the page. Like this:
const input = document.getElementById('input');
const output = document.getElementById('output');
input.addEventListener('input', (e) => {
output.innerHTML = input.value;
});
<div id="output"></div>
<input type="text" id="input">
HTML:
<p>Input:</p><input id="input" type="text">
<p>Output:<span id="output"></span></p>
Javascript:
// Function To Select Element
function $(element) {
return document.querySelector(element);
}
// We will get the input when calling this function
function getInput() {
return $('#input').value;
}
// The output will be displayed
function output() {
$('#output').innerHTML = getInput();
}
// This function will start our code
function init() {
output();
}
// On keyup our code will initiate
$('#input').addEventListener('keyup', init);
You can test it here: https://codepen.io/anon/pen/ReyGaO?editors=1111
People are downvoting you because this can be done with very basic JavaScript, and questions like this are very unusual because anyone doing a basic JavaScipt course will probably be able to do this.
Theoretically speaking: you can put an input element and a button on the html page, plus an empty div. You can set an event for the button or even for the input for live updating while typing, and write an event handler function to change the content of the empty div. You can either set its content or add a new child to it, so that the previous content still remains.
Practical example: (The code below is live at https://codepen.io/bradib0y/pen/YJLGrb )
<!DOCTYPE html>
<html>
<body>
<p>Click the button to add a new post.</p>
<input id="NewPostField" type="text" value="Some text">
<button onclick="myFunction()">Add new post</button>
<div id="Posts"></div>
<script>
function myFunction() {
var NewPostField = document.getElementById("NewPostField");
var newPost = document.createElement("p");
newPost.innerHTML = NewPostField.value;
var Posts = document.getElementById("Posts");
Posts.appendChild(newPost);
}
</script>
</body>
</html>
you can do it by this
<input id="mainInput" oninput="output.value = this.value">
<output id="output" name="output" for="input-name"></output>
click here to view in jsFiddle
I have developed a comments editing system in my blog application.
When a user clicks on the page of a select blog post, a #foreach loop iterates through that post's comments and displays each one in the view underneath the Post's main content.
It is also possible for a user to edit a comment's content. User's click an edit button on the comment and a JavaScript function renders its <textarea> editable as well as unhides a "save" button. Once edited and the user hits save, a second JavaScript function sends the updated content to a Controller method which updates the relevant comment on the database.
The code I've produced works fine when there is one comment under the blog post, however, when there are multiple comments on the page, the JavaScript is not able to distinguish which comment is referenced - for example, pressing the edit button on one comment makes the save button appear for all comments.
Is there a straightforward way I can encapsulate the JavaScript for each comment?
Or is the best approach to produce unique Ids for each Comment? If so, what would be the best approach?
My code for your reference is below, though please note I am still new to web scripting and any pointers are appreciated.
THE VIEW (RAZOR):
#model List<Assignment_3.Models.CommentSubmission
//Blog Post
//Comments
#foreach (var item in Model)
{
//Comment information
//The textarea
<textarea rows="10" readonly class="descriptionForm" id="DescriptionText">#item.Body</textarea>
//The Edit button
<div style="text-align:right">
<img class="edit_icon" src=#Url.Content("~/Images/edit.png") alt='edit' height=15 width=15 />
<br />
//The Save button once editing is complete
<button type="submit"class="btn1" style="visibility: hidden">
<p class="split-btn-name">Save</p>
<span class="separator"></span>
<p><span class="glyphicon glyphicon-ok"></span></p>
</button>
</div>
}
<script>
//Make textarea editable and unhide the edit save button
$(document).ready(function () {
$(".edit_icon ").click(function () {
$(".descriptionForm").removeAttr("readonly");
$(".btn").removeAttr("style");
});
});
//Send updated content to Controller and update database
$(".btn1").click(function () {
$(".btn1").hide();
$(".descriptionForm").setAttribute('readonly');
var text1 = document.getElementById('DescriptionText').value;
var url = "/Comments/EditComment?id=#item.Id&s="+ text1;
$.post(url, null, function (data) {
});
});
</script>
THE CONTROLLER:
public void EditComment(int id, string s)
{
var cS = _context.CommentSubmissions
.Where(c => c.Id == id).
FirstOrDefault();
//The Comment's text body
cS.Body = s;
_context.Entry(cS).State = EntityState.Modified;
_context.SaveChanges();
}
UPDATE
ANSWER (thanks to Greg):
FORM:
<div class="row" style="padding: 15px;">
<div data-rel="#item.Id">
<textarea rows="10" readonly class="textarea">#item.Body</textarea>
<div style="text-align:right">
<p>
Edit <img class="edit_icon" src=#Url.Content("~/Images/edit.png") alt='Edit' height=15 width=15 id="EditIcon" />
</p>
#*The Save button once editing is complete*#
<input type="button" data-input="edit" value="Save" style="visibility: hidden" id="saveButton">
</div>
</div>
</div>
JQUERY:
<script>
$(function () {
$(".edit_icon").click(function () {
var container = $(this).closest('.row');
var id = parent.find('div[data-rel]');
var content = container.find('.textarea');
var button = container.find('#saveButton');
button.removeAttr("style");
content.focus();
content.removeAttr('readonly');
});
$("#saveButton").click(function () {
var container = $(this).closest('.row');
var id = container.find('div[data-rel]');
var content = container.find('.textarea');
var button = container.find('#saveButton');
button.hide();
content.prop('readonly', true);
var text1 = descriptionForm.value;
var url = "/Comments/EditComment?id=" + id + "&s=" + text1;
$.post(url, null, function (data) {
});
});
});
</script>
As denoted in the comment, your JavaScript has nothing unique to anchor on. So it modifies all elements that meet your criteria, to resolve this you can achieve with a unique identifier or structuring your markup better.
In your case, you have a button with a type="submit" which will instantly cause a post back. Not sure if that is indeed your intent, but you could do:
#foreach(var content in Model)
{
<form name="content.Id" action="Blog/Save" method="post">
</form>
}
In this instance, the post back from your submit could directly hit the server. But, post backs aren't cool. To rectify via Ajax, you can do.
#foreach(var content in Model)
{
<div class="container">
<div data-rel="#content.Id">
<!-- Put form data, or whatever here. -->
<input type="button" data-input="edit">Edit</input>
</div>
</div>
}
Now you have a unique value, clean structure, and you can move throughout the hierarchy fairly easy. So, for JavaScript you could do:
function editBlog(element) {
var container = document.querySelector(element).closest('[data-rel]');
}
I believe that is the ideal approach for JavaScript, I'm a custom to jQuery or a framework like Vue. So double check the syntax. But in theory, the JavaScript will scale from the button event to the parent node, then retrieve the child id. Similar mapping or templates can occur, so you can post the data to your action.
Hopefully this helps.
Update: You may get some domain error, but I hope not. Anyways, this is a really simple example.
Container : Simple element to act as a wrapper.
Row : Allow you to create a row for element structure.
Column : Will space around, to fit within window.
The point, is the jQuery will recurse up from the button, to the column, to the row, to the section id, to the container. But, it won't affect any other element on the page. If the jQuery was changed, to not affect a specific element, for instance:
$('button').click(function (e) {
$(this).text('Edit'); // Only this element
$('button').text('Edit'); // All button elements
});
$(function () {
$('button').click(function () {
var container = $(this).parents('.container');
var id = parent.find('div[data-rel]');
var rows = parent.find('.row');
var columns = parent.find('.column');
alert('The section id: ' + id.val());
console.log(container.html());
console.log(id);
console.table(rows);
console.table(columns);
});
});
.container {
width: 100%;
padding: 1rem;
box-shadow: 2px -1px 1px -2px, -1px 2px 1px -2px;
}
.row {
display: flex;
flex-flow: row;
justify-content: space-around;
align-items: center;
}
.column {
width: 33.3%;
}
.column:last-of-type {
width: 10%;
}
.column span {
width: 100%;
padding: .2rem;
display: inline-block;
}
.column label {
width: 95%;
}
.column button {
width: 100px;
}
.column input, .column textarea {
width: 95%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div data-rel="1">
<div class="row">
<div class="column">
<span>
<label>Article Name:</label>
<input type="text" data-rel="txtArticleName" />
</span>
<span>
<label>Article Date:</label>
<input type="text" data-input="txtArticleDate" />
</span>
</div>
<div class="column">
<label>Article Summary:</label>
<textarea data-input="txtArticleSummary" rows="5"></textarea>
</div>
<div class="column">
<button name type="button" onclick="return false;">Save</button>
</div>
</div>
</div>
</div>
<div class="container">
<div data-rel="2">
<div class="row">
<div class="column">
<span>
<label>Article Name:</label>
<input type="text" data-rel="txtArticleName" />
</span>
<span>
<label>Article Date:</label>
<input type="text" data-input="txtArticleDate" />
</span>
</div>
<div class="column">
<label>Article Summary:</label>
<textarea data-input="txtArticleSummary" rows="5"></textarea>
</div>
<div class="column">
<button type="button" onclick="return false;">Save</button>
</div>
</div>
</div>
</div>
The code works, but you may have security enabled that may not allow it to work. But the example is the important part.
I am trying to replace the content of a div with an iframe that allows the user to input a URL to display another page. I will, ideally, add another button next to the Change URL button that links to a specific page.
However, I cannot get this code to work. I can get the div to be replaced with text and some html. But the iframe code won't load when I put this in. I am suspecting it's due to the quotation marks.
I am a bit of a novice at javascript/JQuery so any help with this will be greatly appreciated.
Here is what I have going for the code below.
<style>
#target {
width: 200px;
height: 340px;
}
</style>
<script>
$(function load($){
var $iframe = $('#target'),
$change = $('#change'),
$url = $('#url');
$change.click(function url() {
$iframe.attr('src', $url.val());
});
});
document.getElementById("c_emot").innerHTML = "<iframe id="target" src="/"></iframe><br>
<input id="url" type="text"><br>
<button id="change" type="button">Change URL</button>";
</script>
Your quoted string is all wrong. Try this:
document.getElementById("c_emot").innerHTML = '<iframe id="target" src="/"></iframe><br>
<input id="url" type="text"><br><button id="change" type="button">Change URL</button>';
for reference: http://www.javascripter.net/faq/quotesin.htm
Also, your click event is not being bound to the button after the button is created. You can make it persistent on the button's container like this:
$('#c_emot').on('click', '#change', (function(){
$('#target').attr('src', $('#url').val());
});
And if youre going to mess with the DOM, you have to be sure that the element you want to manipulate has already been created when your code is run:
$(document).ready(function(){
// put all your code here
});
but maybe you should be creating elements instead of dumping markup into the container:
document.onreadystatechange = function () {
if(document.readyState == "complete") {
var container = document.getElementById("c_emot");
var iframe = document.createElement('iframe');
iframe.src = "/";
container.appendChild(iframe);
var input = document.createElement('input');
input.id = "url";
input.type = "text";
container.appendChild(input);
var button = document.createElement('button');
button.id = "change";
button.innerHTML = "Change URL";
button.addEventListener('click', function() {
iframe.src = input.value;
});
container.appendChild(button);
}
}
Not sure if that event listener will work, got to try it and see :)
Have you tried just doing it without messing around with the DOM?...
<iframe name="urlbox"></iframe>
<input type="text" id="urlinput" />
<button onclick="window.open(document.getElementById('urlinput').value, 'urlbox')">Navigate!</button>
Most browsers wont let you navigate the iframe to a different domain for security anyway, so maybe this is all for nothing.
This demo has 2 features:
Using the text input, user can enter a URL to change the src of the iframe.*
This is possible by using this function:
function changeSrc(src) {
var iframe = document.getElementById('site');
site.src = src;
}
*Be aware that not all sites are iframe friendly, so expect some sites that my function will simply not work for.
Notice the links to various sites. Their behavior has been alter--rather than jumping to the site, it opens the site within the iframe.
Each link is a normally constructed anchor element <a> with one exception. It's value for their attribute target is site.
site is the name of the iframe. When an anchor has target="name of iframe"` the anchor opens the site within that targeted iframe.
This must be the iframe's name attribute not the iframe's id.
Snippet
function changeSrc(src) {
var iframe = document.getElementById('site');
site.src = src;
}
body {
width: 100vw;
height: 100vh;
overflow: hidden;
}
section {
height: 100%;
width: 100%;
overflow-y: auto;
}
<form id="form" onchange="changeSrc(url.value);">
<fieldset>
<legend>Enter URL</legend>
<input id="url">
<input type="submit" />
</fieldset>
</form>
ROOT Example W3Scools jsFiddle
jsDelvir JavaScript Tut Plain JS
<section>
<iframe id="site" name="site" src="/" width="100%" height="100%" frameborder="0"></iframe>
</section>