Updating written text to view while typing - javascript

We all know StackOverFlow's system, which basically enables you to see what your written text look like while sending a question.
I'm looking to create this as well on my website, and I would like something to start with.
I obviously don't expect you to write that code for me, but to explain a bit what do I need for that and how would that work.

Edit: Using vanilla js instead of jquery
http://jsfiddle.net/wmjnaj6n/4/
HTML
<input type='text' id='input'>
<div id='update'></div>
Javascript
var element = document.getElementById('input');
var target = document.getElementById('update');
element.addEventListener('keyup', function() {
target.innerHTML = this.value;
});
For completeness, the jquery way would be:
$('#input').keyup(function() {
//do stuff here
$('#update').text( $(this).val() );
});

Related

Get true value of textarea

Recently I encountered an issue with the textarea. If I have a textarea likeso,
<textarea>Hello World</textarea>
And I get the contents of it with JS,
var textareaText = document.getElementsByTagName('textarea')[0].value
The variable textareaText is Hello World. But if I were to change the value of the textarea and re-run the JS. It would still result in Hello World despite the true current value being something else. I've looked this up and seen +5 answers but all of them use jQuery which is something I don't use or know (to translate) and none pure JS. If anyone could help me out it would be greatly appreciated. Also some of the answers seemed to be just for one textarea. In my project I'd have +1,000 so I'd like to avoid that.
This should work, no matter how many <textarea>'s you use, this should work:
<textarea id="textarea1">hello</textarea>
<textarea id="textarea2">goodbye</textarea>
<button id="button">button</button>
<script type="text/javascript">
var button = document.getElementById("button");
button.onclick = function() {
alert(document.getElementById("textarea1").value + "\n" + document.getElementById("textarea2").value);
};
</script>
I just tested it and it works, no matter which values I change, and even if I change both. The trick is to not store the values, as they aren't updated, so you should get the value on-the-spot.
Although it was against the questions guidelines, with "1000+" textareas, setting a JavaScript variable for each one might slow down loading times. May I suggest jQuery, with the same HTML?
<script type="text/javascript">
$("#button").on("click", function () {
alert($("#textarea1").val() + "\n" + $("#textarea2").val());
});
</script>
Of course, feel free to mix up and change up the code provided above. Hope this helps!
It works fine in my computer:
function getText(){
var textareaText = document.getElementsByTagName('textarea')[0].value;
console.log(textareaText);
};
<textarea>Hello World</textarea><br>
<button type="button" onclick="getText();">Get text</button>
May be?
<textarea id="text-area">Hello World</textarea>
var el = document.getElementById("text-area");
var textareaText;
el.addEventListener("input", function(e) {
textareaText = e.target.value;
console.log(e.target.value);
});

Cleaner way to attach event handler function and execute it on ready

When I have a page with button that modifies the layout (let's say checkbox that shows/hides a box) I end up writing following blocks of code:
$(function(){
var advancedOptionsToggle = function() {
var isChecked = $('#advanced-options-checkbox').checked;
$('#advanced-options').toggle(isChecked);
};
advancedOptionsToggle();
$('#advanced-options-checkbox').change(advancedOptionsToggle);
});
The reason is that my page content is dynamically generated on the server side, instead of rendered by JS on the client side, so the checkbox might already come checked.
It looks to like a common problem, so I believe there must be a pattern that solves it cleaner. Is there a jQuery function that can encapsulate it?
Your solution is certainly serviceable, however your question suggests that you may have several of these. May I suggest creating a common pattern for this kind of usage, rather than resort to IDs?
$(function(){
var toggleOptionCheck = function(el){
var isChecked = $(el).is(':checked');
$($(el).data('related')).toggle(isChecked);
}
$('.options-toggle').each(function(idx, el){
toggleOptionCheck(el);
});
// Separate call for illustration/simplicity.
$('.options-toggle').on('change', function(){toggleOptionCheck(this)});
});
<input type="checkbox" checked name="show_advanced"
class="options-toggle" data-related="#advanced-options" />
<div id="advanced-options" class="hidden-at-start"></div>
You can create a simple jQuery plugin like this to clean up the code a bit:
$.fn.advancedOptionsToggle = function(selector) {
return this.each(function() {
var isChecked = $(this).checked;
$(this).unbind('change').change(function(){
$(selector).toggle(isChecked));
});
});
};
$(function(){
$('#advanced-options-checkbox').advancedOptionsToggle('#advanced-options');
});

Live update the text content that lies within a DIV

I am creating a basic calculator using css, html and js. I have a function as follows:
document.getElementById('user_radius').onkeyup = function ()
{
document.getElementById('live_update').innerHTML = this.value;
}
Basically, whatever is typed into the user text box is supposed to live update the text that lies within the span tag with the id of "live_update". I have a text box with an id of user_radius. I save changes and can't get the text to live update. Am I missing a basic principle here?
there are multiple ways to do it
1.mix javascript and DOM. This makes it a little difficult to debug your stuff in the future.
<input id='user_radius' onkeypress='doSomething()' />
function doSomething() {
document.getElementById('live_update').innerHTML = this.value;
}
2.standard jquery method:
<script type="text/javascript">
$(document).ready(function(){
$('#live_update').on('keyup', function(){
$('#user_radius').val($('#live_update').val());
});
});
</script>
3.find a front-end framework that does 2-way data binding for you such as Angular
demo: http://www.angularjshub.com/examples/basics/twowaydatabinding/
this should do the job:
<input id="user_radius" onkeypress="doSomething()" />
function doSomething() {
document.getElementById('live_update').innerHTML = this.value;
}

check/uncheck checkbox based on another checkbox

I looked at item 4197593 How to check uncheck a checkbox based on another checkbox and copied the code from the demo to my webpage. When I open the page I get a java error - the yellow triangle bottom left hand corner.
The error only occurs when I add in this javascript:
<script type="text/javascript">
$(document).ready(function(){ //bind event to checkbox
$("input[type='checkbox']").bind('click', function(){
var $t = $(this),
val = $t.val(),
key = val.charAt(val.length-1);
// check if element is checked
if($t.val() == 'la'+key && $t.is(':checked')) {
$("#lists_"+key).attr('checked', true);
}
else if($t.val() == 'la'+key){
$("#lists_"+key).attr('checked', false);
}
});
});
</script>
I am adding this to a php page:
<?php
include('header3.html');
$Fullname = $_SESSION['membername'];
include('connectdb.php');
?>
*the above javascript is added in here*
<style type="text/css">
Hope someone can help me here as I am not too bright on java.
Huh? I do not see any java in your code, only a mix of HTML and javascript.
Moreover, you should learn the basics of javascript rather than copy + paste scripts.
For instance, the code you have looks like it needs the jQuery javascript library...
Doing what you are asking in plain javascript is as trivial as:
<input type="checkbox" id="original" onchange="update()"/>
<input type="checkbox" id="other"/>
<script type="text/javascript">
function update(){
var original = document.getElementById('original');
var other = document.getElementById('other');
original.checked = other.checked;
}
</script>
Caution
You should rename function update better or even better, make use of anonymous function bound to the checkbox's change event.
You are using jQuery, so you need to include the jQuery .js too

Clearing <input type='file' /> using jQuery

Is it possible to clear an <input type='file' /> control value with jQuery? I've tried the following:
$('#control').attr({ value: '' });
But it's not working.
Easy: you wrap a <form> around the element, call reset on the form, then remove the form using .unwrap(). Unlike the .clone() solutions otherwise in this thread, you end up with the same element at the end (including custom properties that were set on it).
Tested and working in Opera, Firefox, Safari, Chrome and IE6+. Also works on other types of form elements, with the exception of type="hidden".
window.reset = function(e) {
e.wrap('<form>').closest('form').get(0).reset();
e.unwrap();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<input id="file" type="file">
<br>
<input id="text" type="text" value="Original">
</form>
<button onclick="reset($('#file'))">Reset file</button>
<button onclick="reset($('#text'))">Reset text</button>
JSFiddle
As Timo notes below, if you have the buttons to trigger the reset of the field inside of the <form>, you must call .preventDefault() on the event to prevent the <button> from triggering a submit.
EDIT
Does not work in IE 11 due to an unfixed bug. The text (file name) is cleared on the input, but its File list remains populated.
Quick answer: replace it.
In the code below I use the replaceWith jQuery method to replace the control with a clone of itself. In the event you have any handlers bound to events on this control, we'll want to preserve those as well. To do this we pass in true as the first parameter of the clone method.
<input type="file" id="control"/>
<button id="clear">Clear</button>
var control = $("#control");
$("#clear").on("click", function () {
control.replaceWith( control = control.clone( true ) );
});
Fiddle: http://jsfiddle.net/jonathansampson/dAQVM/
If cloning, while preserving event handlers, presents any issues you could consider using event delegation to handle clicks on this control from a parent element:
$("form").on("focus", "#control", doStuff);
This prevents the need for any handlers to be cloned along with the element when the control is being refreshed.
Jquery is supposed to take care of the cross-browser/older browser issues for you.
This works on modern browsers that I tested: Chromium v25, Firefox v20, Opera v12.14
Using jquery 1.9.1
HTML
<input id="fileopen" type="file" value="" />
<button id="clear">Clear</button>
Jquery
$("#clear").click(function () {
$("#fileopen").val("");
});
On jsfiddle
The following javascript solution also worked for me on the browsers mention above.
document.getElementById("clear").addEventListener("click", function () {
document.getElementById("fileopen").value = "";
}, false);
On jsfiddle
I have no way to test with IE, but theoretically this should work. If IE is different enough that the Javascript version does not work because MS have done it in a different way, the jquery method should in my opinion deal with it for you, else it would be worth pointing it out to the jquery team along with the method that IE requires. (I see people saying "this won't work on IE", but no vanilla javascript to show how it does work on IE (supposedly a "security feature"?), perhaps report it as a bug to MS too (if they would count it as such), so that it gets fixed in any newer release)
Like mentioned in another answer, a post on the jquery forum
if ($.browser.msie) {
$('#file').replaceWith($('#file').clone());
} else {
$('#file').val('');
}
But jquery have now removed support for browser testing, jquery.browser.
This javascript solution also worked for me, it is the vanilla equivalent of the jquery.replaceWith method.
document.getElementById("clear").addEventListener("click", function () {
var fileopen = document.getElementById("fileopen"),
clone = fileopen.cloneNode(true);
fileopen.parentNode.replaceChild(clone, fileopen);
}, false);
On jsfiddle
The important thing to note is that the cloneNode method does not preserve associated event handlers.
See this example.
document.getElementById("fileopen").addEventListener("change", function () {
alert("change");
}, false);
document.getElementById("clear").addEventListener("click", function () {
var fileopen = document.getElementById("fileopen"),
clone = fileopen.cloneNode(true);
fileopen.parentNode.replaceChild(clone, fileopen);
}, false);
On jsfiddle
But jquery.clone offers this [*1]
$("#fileopen").change(function () {
alert("change");
});
$("#clear").click(function () {
var fileopen = $("#fileopen"),
clone = fileopen.clone(true);
fileopen.replaceWith(clone);
});
On jsfiddle
[*1] jquery is able to do this if the events were added by jquery's methods as it keeps a copy in jquery.data, it does not work otherwise, so it's a bit of a cheat/work-around and means things are not compatible between different methods or libraries.
document.getElementById("fileopen").addEventListener("change", function () {
alert("change");
}, false);
$("#clear").click(function () {
var fileopen = $("#fileopen"),
clone = fileopen.clone(true);
fileopen.replaceWith(clone);
});
On jsfiddle
You can not get the attached event handler direct from the element itself.
Here is the general principle in vanilla javascript, this is how jquery an all other libraries do it (roughly).
(function () {
var listeners = [];
function getListeners(node) {
var length = listeners.length,
i = 0,
result = [],
listener;
while (i < length) {
listener = listeners[i];
if (listener.node === node) {
result.push(listener);
}
i += 1;
}
return result;
}
function addEventListener(node, type, handler) {
listeners.push({
"node": node,
"type": type,
"handler": handler
});
node.addEventListener(type, handler, false);
}
function cloneNode(node, deep, withEvents) {
var clone = node.cloneNode(deep),
attached,
length,
evt,
i = 0;
if (withEvents) {
attached = getListeners(node);
if (attached) {
length = attached.length;
while (i < length) {
evt = attached[i];
addEventListener(clone, evt.type, evt.handler);
i += 1;
}
}
}
return clone;
}
addEventListener(document.getElementById("fileopen"), "change", function () {
alert("change");
});
addEventListener(document.getElementById("clear"), "click", function () {
var fileopen = document.getElementById("fileopen"),
clone = cloneNode(fileopen, true, true);
fileopen.parentNode.replaceChild(clone, fileopen);
});
}());
On jsfiddle
Of course jquery and other libraries have all the other support methods required for maintaining such a list, this is just a demonstration.
For obvious security reasons you can't set the value of a file input, even to an empty string.
All you have to do is reset the form where the field or if you only want to reset the file input of a form containing other fields, use this:
function reset_field (e) {
e.wrap('<form>').parent('form').trigger('reset');
e.unwrap();
}​
Here is an exemple: http://jsfiddle.net/v2SZJ/1/
This works for me.
$("#file").replaceWith($("#file").clone());
http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie
Hope it helps.
In IE8 they made the File Upload field read-only for security. See the IE team blog post:
Historically, the HTML File Upload Control () has been the source of a significant number of information disclosure vulnerabilities. To resolve these issues, two changes were made to the behavior of the control.
To block attacks that rely on “stealing” keystrokes to surreptitiously trick the user into typing a local file path into the control, the File Path edit box is now read-only. The user must explicitly select a file for upload using the File Browse dialog.
Additionally, the “Include local directory path when uploading files” URLAction has been set to "Disable" for the Internet Zone. This change prevents leakage of potentially sensitive local file-system information to the Internet. For instance, rather than submitting the full path C:\users\ericlaw\documents\secret\image.png, Internet Explorer 8 will now submit only the filename image.png.
$("#control").val('') is all you need! Tested on Chrome using JQuery 1.11
Other users have tested in Firefox as well.
I got stuck with all the options here. Here's a hack that I made which worked:
<form>
<input type="file">
<button type="reset" id="file_reset" style="display:none">
</form>
and you can trigger the reset using jQuery with a code similar to this:
$('#file_reset').trigger('click');
(jsfiddle: http://jsfiddle.net/eCbd6/)
I ended up with this:
if($.browser.msie || $.browser.webkit){
// doesn't work with opera and FF
$(this).after($(this).clone(true)).remove();
}else{
this.setAttribute('type', 'text');
this.setAttribute('type', 'file');
}
may not be the most elegant solution, but it work as far as I can tell.
I have used https://github.com/malsup/form/blob/master/jquery.form.js, which has a function called clearInputs(), which is crossbrowser, well tested, easy to use and handles also IE issue and hidden fields clearing if needed. Maybe a little long solution to only clear file input, but if you are dealing with crossbrowser file uploads, then this solution is recommended.
The usage is easy:
// Clear all file fields:
$("input:file").clearInputs();
// Clear also hidden fields:
$("input:file").clearInputs(true);
// Clear specific fields:
$("#myfilefield1,#myfilefield2").clearInputs();
/**
* Clears the selected form elements.
*/
$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
return this.each(function() {
var t = this.type, tag = this.tagName.toLowerCase();
if (re.test(t) || tag == 'textarea') {
this.value = '';
}
else if (t == 'checkbox' || t == 'radio') {
this.checked = false;
}
else if (tag == 'select') {
this.selectedIndex = -1;
}
else if (t == "file") {
if (/MSIE/.test(navigator.userAgent)) {
$(this).replaceWith($(this).clone(true));
} else {
$(this).val('');
}
}
else if (includeHidden) {
// includeHidden can be the value true, or it can be a selector string
// indicating a special test; for example:
// $('#myForm').clearForm('.special:hidden')
// the above would clean hidden inputs that have the class of 'special'
if ( (includeHidden === true && /hidden/.test(t)) ||
(typeof includeHidden == 'string' && $(this).is(includeHidden)) )
this.value = '';
}
});
};
The value of file inputs is read only (for security reasons). You can't blank it programatically (other than by calling the reset() method of the form, which has a broader scope than just that field).
I was able to get mine working with the following code:
var input = $("#control");
input.replaceWith(input.val('').clone(true));
I have been looking for simple and clean way to clear HTML file input, the above answers are great, but none of them really answers what i'm looking for, until i came across on the web with simple an elegant way to do it :
var $input = $("#control");
$input.replaceWith($input.val('').clone(true));
all the credit go's to Chris Coyier.
// Referneces
var control = $("#control"),
clearBn = $("#clear");
// Setup the clear functionality
clearBn.on("click", function(){
control.replaceWith( control.val('').clone( true ) );
});
// Some bound handlers to preserve when cloning
control.on({
change: function(){ console.log( "Changed" ) },
focus: function(){ console.log( "Focus" ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="control">
<br><br>
Clear
The .clone() thing does not work in Opera (and possibly others). It keeps the content.
The closest method here for me was Jonathan's earlier, however ensuring that the field preserved its name, classes, etc made for messy code in my case.
Something like this might work well (thanks to Quentin too):
function clearInput($source) {
var $form = $('<form>')
var $targ = $source.clone().appendTo($form)
$form[0].reset()
$source.replaceWith($targ)
}
I have managed to get this to work using the following...
function resetFileElement(ele)
{
ele.val('');
ele.wrap('<form>').parent('form').trigger('reset');
ele.unwrap();
ele.prop('files')[0] = null;
ele.replaceWith(ele.clone());
}
This has been tested in IE10, FF, Chrome & Opera.
There are two caveats...
Still doesn't work properly in FF, if you refresh the page, the file element gets re-populated with the selected file. Where it is getting this info from is beyond me. What else related to a file input element could I possible try to clear?
Remember to use delegation on any events you had attached to the file input element, so they still work when the clone is made.
What I don't understand is who on earth thought not allowing you to clear an input field from an invalid unacceptable file selection was a good idea?
OK, don't let me dynamically set it with a value so I can't leach files from a user's OS, but let me clear an invalid selection without resetting an entire form.
It's not like 'accept' does anything other than a filter anyhow and in IE10, it doesn't even understand MS Word mime types, it's a joke!
On my Firefox 40.0.3 only work with this
$('input[type=file]').val('');
$('input[type=file]').replaceWith($('input[type=file]').clone(true));
its works for me in every browser.
var input = $(this);
var next = this.nextSibling;
var parent = input.parent();
var form = $("<form></form>");
form.append(input);
form[0].reset();
if (next) {
$(next).before(input);
} else {
parent.append(input);
}
I tried with the most of the techniques the users mentioned, but none of they worked in all browsers. i.e: clone() doesn't work in FF for file inputs.
I ended up copying manually the file input, and then replacing the original with the copied one. It works in all browsers.
<input type="file" id="fileID" class="aClass" name="aName"/>
var $fileInput=$("#fileID");
var $fileCopy=$("<input type='file' class='"+$fileInput.attr("class")+" id='fileID' name='"+$fileInput.attr("name")+"'/>");
$fileInput.replaceWith($fileCopy);
$("input[type=file]").wrap("<div id='fileWrapper'/>");
$("#fileWrapper").append("<div id='duplicateFile' style='display:none'>"+$("#fileWrapper").html()+"</div>");
$("#fileWrapper").html($("#duplicateFile").html());
This works with Chrome, FF, and Safari
$("#control").val("")
May not work with IE or Opera
Make it asynchronous, and reset it after the button's desired actions have been done.
<!-- Html Markup --->
<input id="btn" type="file" value="Button" onchange="function()" />
<script>
//Function
function function(e) {
//input your coding here
//Reset
var controlInput = $("#btn");
controlInput.replaceWith(controlInput = controlInput.val('').clone(true));
}
</script>
function clear() {
var input = document.createElement("input");
input.setAttribute('type', 'file');
input.setAttribute('value', '');
input.setAttribute('id', 'email_attach');
$('#email_attach').replaceWith( input.cloneNode() );
}
it does not work for me:
$('#Attachment').replaceWith($(this).clone());
or
$('#Attachment').replaceWith($('#Attachment').clone());
so in asp mvc I use razor features for replacing file input.
at first create a variable for input string with Id and Name and then use it for showing in page and replacing on reset button click:
#{
var attachmentInput = Html.TextBoxFor(c => c.Attachment, new { type = "file" });
}
#attachmentInput
<button type="button" onclick="$('##(Html.IdFor(p => p.Attachment))').replaceWith('#(attachmentInput)');">--</button>
An easy way is changing the input type and change it back again.
Something like this:
var input = $('#attachments');
input.prop('type', 'text');
input.prop('type', 'file')
You can replace it with its clone like so
var clone = $('#control').clone();
$('#control').replacewith(clone);
But this clones with its value too so you had better like so
var emtyValue = $('#control').val('');
var clone = emptyValue.clone();
$('#control').replacewith(clone);
It's easy lol (works in all browsers [except opera]):
$('input[type=file]').each(function(){
$(this).after($(this).clone(true)).remove();
});
JS Fiddle: http://jsfiddle.net/cw84x/1/
What?
In your validation function, just put
document.onlyform.upload.value="";
Assuming upload is the name:
<input type="file" name="upload" id="csv_doc"/>
I'm using JSP, not sure if that makes a difference...
Works for me, and I think it's way easier.

Categories