What I have is a single textbox. If the user hits the maxlength of it, I want to create a new textbox and then change focus to it so they can continue typing.
To accomplish this, I am trying to dynamically create textboxes that have an onkeyup event tied to them. To do this I am using document.createElement and the creation of the element works. The problem is that I can't get the parameters (the id of the current textbox and the id of the one to be created) to pass correctly and they are simply variables. Before I pass them I can test them and they are fine, but in the method they are null.
Here is my code:
<script type="text/javascript">
var i = 2;
function CreateTextbox() {
var box = document.getElementById(divCreateTextbox);
var curr = 'txt' + i;
var next = 'txt' + (i + 1);
var inp = document.createElement('input')
inp.type = 'text';
inp.name = 'textfield';
inp.maxlength = '10';
inp.id = curr;
inp.setAttribute('onkeyup', 'moveOnMax(inp.id, next)');
inp.onkeyup = function() { moveOnMax(inp.id, next); };
box.appendChild(inp);
box.innerHTML += "<br />";
i++;
return next;
}
function moveOnMax(field, nextFieldID) {
if (field.value.length >= field.maxLength) {
if (document.getElementById(nextFieldID) == null) {
var id = CreateTextbox();
if (document.getElementById(id) != null) {
document.getElementById(id).focus();
}
else
alert("problem...");
}
}
}
</script>
<div id="divCreateTextbox">
I am pretty new to Javascript, so if this is completely fubar'd, I apologize.
Any help is appreciated.
<script type="text/javascript">
getId = function(){
var id = 1;
return function(){
id++;
}
}();
function CreateTextbox() {
var box = document.getElementById("divCreateTextbox");
var curr = 'txt' + getId();
var inp = document.createElement('input');
inp.type = 'text';
inp.name = 'textfield';
inp.setAttribute("maxlength",'10');
inp.setAttribute("id",curr);
box.appendChild(inp);
inp.setAttribute('onkeyup','moveOnMax(this)');
box.appendChild(document.createElement("br"));
inp.focus();
}
function moveOnMax(s){
if(s.value.length >= parseInt(s.getAttribute("maxlength"))-1){
s.blur();
CreateTextbox();
}
}
</script>
<div id="divCreateTextbox"></div>
<script>
window.onload = function(){
CreateTextbox()
}
</script>
</html>
The problem you have is related to the scope of inp. When you use the var keyword you scoped it to that block.
Try this code:
inp.onkeyup = function() {
var local_inp_id = inp.id;
var local_next = next;
return function(){
moveOnMax(inp_id, next);
}
}();
Related
I already have this JavaScript code inside a function called add().
var newinput = document.createElement('div');
newinput.innerHTML = "<br><input type='file' id='" + counter +
"'name='filename[" + counter +
"]' accept='image/jpeg' onchange='add()'>";
document.getElementById('asd').appendChild(newinput);
But instead of this innerHTML I want to do this new function:
var newinput = document.createElement('input');
newinput.id=x;
newinput.type="file";
newinput.name="filename";
newinput.accept="image/jpeg";
newinput.onchange=add();
Thus far, the new function creates an input like the innerHTML one of the first function, but doesn't add the onchange property (and the full created input even disapears, so I have to comment the .onchange();
Is there a way I can add the ".onchange" to the createElement var or create a JavaScript listener for a couple inputs like input.onchange() = function (){}? Thanks.
As it currently is, you are expecting add() to return a function. Do not invoke the function and just do:
newinput.onchange = add;
(function() {
function add() {
console.log("Added.");
}
function createFileInput(x) {
var newinput = document.createElement('input');
newinput.id = x;
newinput.type = "file";
newinput.name = "filename";
newinput.accept = "image/jpeg";
newinput.onchange = add;
return newinput;
}
document.body.appendChild(createFileInput('my-input'));
})();
Here's an example of what you were doing, and how it would work:
(function() {
function add() {
return function() {
console.log("Added.");
}
}
function createFileInput(x) {
var newinput = document.createElement('input');
newinput.id = x;
newinput.type = "file";
newinput.name = "filename";
newinput.accept = "image/jpeg";
newinput.onchange = add();
return newinput;
}
document.body.appendChild(createFileInput('my-input'));
})();
I have this function:
var save = document.getElementById('savethis'+this.parentNode.childNodes[1].id);
save.addEventListener('click', savethis.bind(this), false);
function savethis() {
this.removeEventListener('click', edit);
var a = this.childNodes[0].childNodes[0].id;
console.log(a);
var b = document.getElementById(a);
console.log(document.getElementById(a).id.replace('minedit',''));
console.log(b.value);
this.innerHTML = b.value;
this.parentNode.cells[4].className = 'text-center min-edit';
setTimeout(function() {this.addEventListener('click',edit);},1);
}
In another function:
var minedit = document.getElementsByClassName('min-edit');
for (var m=0;m<minedit.length;m++){
minedit[m].addEventListener('click', edit);
}
function edit(){
var avalue = this.innerHTML;
console.log(avalue);
if (this.className.indexOf('input-open')>=0){
}
else {
this.className += ' input-open';
var content = '';
content += '<div class="input-group editable-input"><input type="text" id="minedit'+this.parentNode.childNodes[1].id+'" value="'+parseFloat(avalue).toFixed(2)+'" class="form-control"><span class="input-group-addon editable-input" id="savethis'+this.parentNode.childNodes[1].id+'"><i class="ion-android-done" ></i></span><span class="input-group-addon editable-input"><i class="ion-android-close" id="close"></i></span></span></div>';
this.innerHTML = content;
valuenow = document.getElementById('minedit'+this.parentNode.childNodes[1].id).value;
id = document.getElementById('minedit'+this.parentNode.childNodes[1].id).id;
var save = document.getElementById('savethis'+this.parentNode.childNodes[1].id);
save.addEventListener('click', savethis.bind(this), false);
}
}
function savethis() {
this.removeEventListener('click', edit);
var a = this.childNodes[0].childNodes[0].id;
var b = document.getElementById(a);
this.innerHTML = b.value;
this.parentNode.cells[4].className = 'text-center min-edit';
setTimeout(function() {this.addEventListener('click',edit);},1);
}
As you can see in the fiddle, the opening and closing of the input box works on the first click, but on the second click I get an error saying
TypeError: this.className is undefined
pointing to this line:
if (this.className.indexOf('input-open')>=0){
I totally don't get why className could possibly be undefined, as I define it's name within the savethis function.
Can someone explain and help?
scope is wrong
setTimeout(function() {this.addEventListener('click',edit);},1);
this is the document when this runs, not the element.
var that = this;
setTimeout(function() {that.addEventListener('click',edit);},1);
or use bind() with modern browsers
setTimeout( (function() {this.addEventListener('click',edit);}).bind(this),1);
I've basic knowledge of JS. I'm trying to make the two functions below to work together but I cannot find a solution. It's either one or the other that work but not the two together.
<script>
function random_string(size){
var str = "";
for (var i = 0; i < size; i++){
str += random_character();
}
return str;
}
function random_character() {
var chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
return chars.substr( Math.floor(Math.random() * 62), 1);
}
window.onload = function () {
var partnerurl = document.getElementById('field1');
uniqueid = document.getElementById('field2');
uniqueid.value = random_string(15);
partnerurl.value = "www.website.com"+uniqueid.value
};
</script>
<script>
var defaultHiddenFieldNameValue = "";
function getQueryStringParamValue(strQStrParam) {
var strURL = document.location.href;
var strQStrParamValue = "";
if (strURL.indexOf('?') != -1)
{
strQStrParamValue = strURL.substr(strURL.indexOf('?') + 1);
if (strQStrParamValue.indexOf(strQStrParam) != -1)
{
strQStrParamValue = strQStrParamValue.substr(strQStrParamValue.indexOf(strQStrParam));
strQStrParamValue = strQStrParamValue.substr(strQStrParamValue.indexOf('=') + 1);
if (strQStrParamValue.indexOf('&') != -1)
strQStrParamValue = strQStrParamValue.substr(0, strQStrParamValue.indexOf('&'));
return strQStrParamValue;
}else{
strQStrParamValue = defaultHiddenFieldNameValue;
return strQStrParamValue;
}
}else{
strQStrParamValue = defaultHiddenFieldNameValue;
return strQStrParamValue;
}
}
// Form name goes here
var form = "formname";
function setCampaign(){
var elqForm = document.forms[form];
//repeat for each field to populate
elqForm.elements['src'].value = getQueryStringParamValue('src');
}
window.onload = setCampaign;
</script>
Many thanks in advance for your help!
Cheers,
FX
In your code sample here you are missing a semicolon on the last line of the onload function.
I also don't see you declaring uniqueid.
Your random string function works fine, its just getting the window.onload to fire that I had problems with.
Here is a demostration of your random string working fine: http://jsfiddle.net/Jimmery/tv87X/
I would suggest loading jQuery with this line in your HTML:
<script src="ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
and then use this:
$(document).ready(function(){
var partnerurl = $('field1');
var uniqueid = $('field2');
uniqueid.val(random_string(15));
partnerurl.val("www.website.com/"+uniqueid.val());
};
I added onkeyup javascript for a dynamically added textbox in javascript... But it doesnt seem to work....
var cell4 = row.insertCell(3);
cell4.setAttribute('align','center')
var e3 = document.createElement('input');
e3.type = 'text';
e3.name = 'txtqt' + iteration;
e3.id = 'txtqt' + iteration;
e3.onkeyup = totalAmount(event,this,'tblsample');//Adding this lines doesnt work
e3.size = 10;
cell4.appendChild(e3);
But when i used
e3.onkeyup = totalAmount;
It worked... Here is my javascript function,
function totalAmount(e,obj,tblid)
{
var tbl = document.getElementById(tblid);
//alert(tbl);
var tblRows = tbl.rows.length;
//alert(tblRows);
var result =0;
var str1;
if (obj != null) {
str1 = obj.id;
} else {
str1 = this.id;
}
var lastChar = str1.substring(5,str1.length);
//alert(lastChar);
if(str1=='txtqt'+lastChar)
{
var str2 = 'txtup'+lastChar;
var str3 = 'txtAmount'+lastChar;
var txtDeduct = document.getElementById(str1).value;
var txtAmt = document.getElementById(str2).value;
var txtTotal = document.getElementById(str3);
var totRes = txtAmt*txtDeduct;
//var res = formatNumber(totRes,2)
txtTotal.value = totRes.toFixed(2)
document.getElementById('txttotAmount').value = totRes.toFixed(2);
for(i=1;i<=tblRows;i++)
{
//alert(tblRows);
txtTotID = 'txtAmount'+i;
if(document.getElementById(txtTotID).value!='')
{
result =parseFloat(result) + parseFloat(document.getElementById(txtTotID).value);
//var res= formatNumber(result,2)
document.getElementById('txtTotalAmount').value = result.toFixed(2);
document.getElementById('txttotAmount').value = result.toFixed(2);
//document.getElementById('txtTotalAmount').value = result;
}
}
}
}
You need to wrap your function call in an anonymous function:
e3.onkeyup = function(event){ totalAmount(event,this,'tblsample'); }
But an even better way to do it, to allow for cross browser compatibility would be to use an addEvent function:
function addEvent(obj,type,fn){
if (obj.addEventListener){
obj.addEventListener(type,fn,false);
} else if(obj.attachEvent){
obj["e"+type+fn]=fn;
obj[type+fn]=function(){
obj["e"+type+fn](window.event);
};
obj.attachEvent("on"+type,obj[type+fn]);
};
};
And then add the event using that function:
addEvent(e3,'keyup',function(event){ totalAmount(event,this,'tblsample'); });
Just a much better way to handle events. I would recommend you switch to this method.
onkeyup is a function. If you pass it the return value of totalAmount(event,this,'tblsample'); it won't work (unless it returns a function).
e3.onkeyup = totalAmount; is probably enough.
then inside totalAmount..
function totalAmount(event) {
alert(this); // this is the e3 object
}
So if you need the this and the 'tblsample' arguments, I suggest you add them to the e3 object so that you can access them through the this keyword inside the totalAmount function:
e3.otherScope = this;
e3.tblid = 'tblsample;
e3.onkeyup = totalAmount;
and..
function totalAmount(event) {
alert(this); // this is the e3 object
alert(this.otherScope); // the `this` object in the other scope
alert(this.tblid); // 'tblsample'
}
Or you can simply just do
var otherScope = this;
e3.onkeyup = function(event) {
totalAmount(event, otherSope, 'tblsample');
};
This is my first attempt at a plugin but I think I'm missing the whole "How to" on this.
Ok here goes:
Trying to write an error popup box for form validation.
I like the look and functionality on this JavaScript code on this page, See demo here and source here.
It's basically what I want to do if the user enters invalid data.
Now I have tried to create a jQuery plugin with this code but it's not working, any help would be great :-)
(function($){
/* Might use the fadein fadeout functions */
var MSGTIMER = 20;
var MSGSPEED = 5;
var MSGOFFSET = 3;
var MSGHIDE = 3;
var errorBox = function(target, string, autohide, options)
{
var ebox = $(ebox);
var eboxcontent = $(eboxcontent);
var target = $(target);
var string = $(string);
var autohide = $(autohide);
var obj = this;
if (!document.getElementById('ebox')) {
ebox = document.createElement('div');
ebox.id = 'ebox';
eboxcontent = document.createElement('div');
eboxcontent.id = 'eboxcontent';
document.body.appendChild(ebox);
ebox.appendChild(eboxcontent);
ebox.style.filter = 'alpha(opacity=0)';
ebox.style.opacity = 0;
ebox.alpha = 0;
}
else {
ebox = document.getElementById('ebox');
eboxcontent = document.getElementById('eboxcontent');
}
eboxcontent.innerHTML = string;
ebox.style.display = 'block';
var msgheight = ebox.offsetHeight;
var targetdiv = document.getElementById(target);
targetdiv.focus();
var targetheight = targetdiv.offsetHeight;
var targetwidth = targetdiv.offsetWidth;
var topposition = topPosition(targetdiv) - ((msgheight - targetheight) / 2);
var leftposition = leftPosition(targetdiv) + targetwidth + MSGOFFSET;
ebox.style.top = topposition + 'px';
ebox.style.left = leftposition + 'px';
clearInterval(ebox.timer);
ebox.timer = setInterval("fadeMsg(1)", MSGTIMER);
if (!autohide) {
autohide = MSGHIDE;
}
window.setTimeout("hideMsg()", (autohide * 1000));
// hide the form alert //
this.hideMsg(msg) = function (){
var msg = document.getElementById('msg');
if (!msg.timer) {
msg.timer = setInterval("fadeMsg(0)", MSGTIMER);
}
};
// face the message box //
this.fadeMsg(flag) = function() {
if (flag == null) {
flag = 1;
}
var msg = document.getElementById('msg');
var value;
if (flag == 1) {
value = msg.alpha + MSGSPEED;
}
else {
value = msg.alpha - MSGSPEED;
}
msg.alpha = value;
msg.style.opacity = (value / 100);
msg.style.filter = 'alpha(opacity=' + value + ')';
if (value >= 99) {
clearInterval(msg.timer);
msg.timer = null;
}
else
if (value <= 1) {
msg.style.display = "none";
clearInterval(msg.timer);
}
};
// calculate the position of the element in relation to the left of the browser //
this.leftPosition(target) = function() {
var left = 0;
if (target.offsetParent) {
while (1) {
left += target.offsetLeft;
if (!target.offsetParent) {
break;
}
target = target.offsetParent;
}
}
else
if (target.x) {
left += target.x;
}
return left;
};
// calculate the position of the element in relation to the top of the browser window //
this.topPosition(target) = function() {
var top = 0;
if (target.offsetParent) {
while (1) {
top += target.offsetTop;
if (!target.offsetParent) {
break;
}
target = target.offsetParent;
}
}
else
if (target.y) {
top += target.y;
}
return top;
};
// preload the arrow //
if (document.images) {
arrow = new Image(7, 80);
arrow.src = "images/msg_arrow.gif";
}
};
$.fn.errorbox = function(options)
{
this.each(function()
{
var element = $(this);
// Return early if this element already has a plugin instance
if (element.data('errorbox')) return;
// pass options to plugin constructor
var errorbox = new errorBox(this, options);
// Store plugin object in this element's data
element.data('errorbox', errorbox);
});
};
})(jQuery);
How Im calling it
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>jQuery Plugin - Error ToolTip</title>
<script type="text/javascript" src="js/jquery.js">
</script>
<script type="text/javascript" src="js/jquery.errorbox.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
var name = document.getElementById('name');
if(name == "") {
$('#name','You must enter your name.',2).errorbox();
alert("Blank");
}
});
</script>
<link rel="stylesheet" type="text/css" href="css/errorbox.css" />
</head>
<body>
<div>
Name: <input type="text" id="name" width="30"></input>
</div>
</body>
Any help on my first plugin would be great, thanks in advance.
--Phill
The var errorBox = function(... needs to change to:
$.errorBox = function(...
then you can call it on the jquery object.
Secondly, for clarity you may want to use $('#eboxcontent') instead of document.getElementById('eboxcontent') . It wont be any faster, but it is "clearer" to other jquery developers.
Lastly, jQuery has many built in functions for fading things over a specified time period, and it appears that you have built your own. I know that jQuery's fading is cross-browser compatible. just use:
$('#someDivId').fadeOut(timeInMilliseconds);
var name = document.getElementById('name');
if(name == "") {
//...
}
should be
var name = document.getElementById('name');
if(name.value == "") {
//...
}
or
var name = $('#name').val();
if(name == "") {
//...
}