The function doesn't work - javascript

I've got a problem with this code. When I wrote the first code everything is ok but after processing it doesn't work. Why is it like that? I sent an event object to function as an argument so what's the problem?
Initial code:
var isOkej = null;
function isNumber(someValue) {
return !isNaN(someValue);
}
window.onload = function () {
var wykonawca = document.getElementById("informations").artist;
var tytul = document.getElementById("informations").title;
var label = document.getElementById("informations").label;
var kindOftxt = document.getElementById("kindOftxt");
var action = function (e) {
//pokazuje unicode wpisanego znaku
var wpisanyZnak = e.which;
if (isNumber(this.value) || wpisanyZnak === 190) {
e.preventDefault();
if (this === wykonawca)
kindOftxt.innerHTML = "Podaj swój Alias";
else if (this === tytul)
kindOftxt.innerHTML = "Podaj tytuł utworu";
else
kindOftxt.innerHTML = "Gdzie utwór został wydany";
this.style.backgroundColor = "red";
isOkej = false;
} else {
this.style.backgroundColor = "green";
kindOftxt.innerHTML = "";
isOkej = true;
}
};
wykonawca.onkeyup = action;
tytul.onkeyup = action;
label.onkeyup = action;
}
Final code:
function isNumber(someValue) {
return !isNaN(someValue);
}
var isOkej = null;
function action (e, wykonawca, tytul,kindOftxt) {
//pokazuje unicode wpisanego znaku
var wpisanyZnak = e.which;
if (isNumber(this.value) || wpisanyZnak === 190) {
e.preventDefault();
if (this === wykonawca)
kindOftxt.innerHTML = "Podaj swój Alias";
else if (this === tytul)
kindOftxt.innerHTML = "Podaj tytuł utworu";
else
kindOftxt.innerHTML = "Gdzie utwór został wydany";
this.style.backgroundColor = "red";
isOkej = false;
} else {
this.style.backgroundColor = "green";
kindOftxt.innerHTML = "";
isOkej = true;
}
};
window.onload = function () {
var wykonawca = document.getElementById("informations").artist;
var tytul = document.getElementById("informations").title;
var label = document.getElementById("informations").label;
var kindOftxt = document.getElementById("kindOftxt");
wykonawca.onkeyup = function (e) {
action(e, wykonawca,tytul,kindOftxt);
};
tytul.onkeyup = function (e) {
action(e, wykonawca,tytul,kindOftxt);
};
label.onkeyup = function (e) {
action(e, wykonawca,tytul,kindOftxt);
}; }
I really don't know what can be the reason. What do you think can be a problem?

When you bind the events with the following code, the this inside action function is bound to the input element.
wykonawca.onkeyup = action;
tytul.onkeyup = action;
label.onkeyup = action;
When you bind the events with the updated code
wykonawca.onkeyup = function (e) {
action(e, wykonawca,tytul,kindOftxt);
};
tytul.onkeyup = function (e) {
action(e, wykonawca,tytul,kindOftxt);
};
label.onkeyup = function (e) {
action(e, wykonawca,tytul,kindOftxt);
};
the this inside the anonymous event handlers is bound to the input element, but in the action function, this would refer to the global object i.e. the window object.
You can pass the this reference from your anonymous handlers to the action function as an additional argument.

Related

How to check if a function has been called before executing another function everytime

I have a onMouseDownEssence() and onMouseUpEssence() function for an HTML element, how to check if onMouseDownEssence() is called every time before calling onMouseUpEssence() to ensure I get the correct mouse down position?
Here is mousedown function:
var mouseDownIndex = -1;
function onMouseDownEssence(downIndex, e, className) {
dragTarget = e.target;
holdStarter = new Date().valueOf();
mouseDownIndex = downIndex;
}
Here is mouseup function:
function onMouseUpEssence(upIndex, e, className) {
var el = e.target;
var holdActive = (new Date().valueOf() - holdStarter) > holdDelay;
if (holdActive) {
var thisUpTargetIndex = el.getAttribute("name");
if (lastUpTargetIndex != null && thisUpTargetIndex != lastUpTargetIndex) {
// console.log("double drag done");
el.removeAttribute(dbl);
lastUpTargetIndex = null;
var selectedText = clickDragAutoExpand(mouseDownIndex, upIndex,
className);
} else {
// console.log("drag done");
var selectedText = clickDragAutoExpand(mouseDownIndex, upIndex,
className);
}
holdActive = false;
} else if (el.getAttribute(dbl) == null) {
el.setAttribute(dbl, 1);
setTimeout(
function() {
if (el.getAttribute(dbl) == 1 && !dragTarget) {
if (e.button === 0) {
// console.log("single clicked ");
el.removeAttribute(dbl);
var selectedText = clickAutoExpand(upIndex,
className);
}
} else {
if (el.getAttribute(dbl) != null)
lastUpTargetIndex = el.getAttribute("name");
}
}, dblDelay);
} else {
// console.log("double clicked");
el.removeAttribute(dbl);
var selectedText = clickAutoExpand(upIndex, className);
}
dragTarget = null;
}
My approach would be to keep a track of whether mouseDownEssence() was called. And if not, call it before proceeding further. This approach would work somewhat as below. It would work differently for asynchronous functions but mouseDownEssence() seems to be a synchronous function.
let isMouseDownEssenceCalled = false;
function mouseDownEssence() {
isMouseDownEssenceCalled = true;
...
}
function mouseUpEssence() {
if (!isMouseDownEssenceCalled) {
mouseDownEssence()
}
...
isMouseDownEssenceCalled = false;
}

HTML button that's submitting an empty field even though it shouldn't be

Here's the HTML button I'm working with:
<b>Other: </b><input type="number" id="AmntValue" data-target-element-id="SubmitAmnt" data-target-parameter="Amnt" onchange="setValueOnTarget(this);' +/* ' enableButton(SubmitAmnt);' */+ '">
<button class="button2" id="SubmitAmnt" type="button" data-redirect-src="https://hub.deltasigmapi.org/donations/donations.aspx?appealid=1989&NumberOfPaymentsDisplay=0&GiftRecurrenceDisplay=0&GiftRecurrence=onetime&GiftAmount=" onclick="disableButton(this); addValueToQueryString(this); redirectPage(this);">Continue To Payment</button>
When someone hits the button but the "Other" text field is blank, it's supposed to not redirect and instead show an error message. Right now the error message displays, but only for a quick moment before it redirects anyway.
Here is my complete JavaScript code:
function setValueOnTarget(sourceElem) {
var targetId = sourceElem.getAttribute('data-target-element-id');
if (targetId) {
var targetElem = document.getElementById(targetId);
if (targetElem) {
var valueToSet;
var parameterToSet;
if (sourceElem.nodeName.toUpperCase() == 'SELECT') {
valueToSet = sourceElem.options[sourceElem.selectedIndex].value;
}
if (sourceElem.nodeName.toUpperCase() == 'INPUT') {
if (sourceElem.type.toUpperCase() == 'NUMBER' || sourceElem.type.toUpperCase() == 'TEXT') {
valueToSet = sourceElem.value;
}
}
targetElem.setAttribute('data-value-set-by-other-element', valueToSet);
parameterToSet = sourceElem.getAttribute('data-target-parameter');
targetElem.setAttribute('data-target-parameter', parameterToSet);
EnableButton(targetElem)
}
}
}
function disableButton(btn) {
btn.disabled = true;
}
function EnableButton(btn) {
btn.disabled = false;
}
function addValueToQueryString(elem) {
var src = elem.getAttribute('data-redirect-src');
var newValue = elem.getAttribute('data-value-set-by-other-element');
var parameter = elem.getAttribute('data-target-parameter');
if (newValue && parameter) {
if (src && newValue && parameter) {
var newSrc;
newSrc = src + newValue;
elem.setAttribute('data-redirect-src', newSrc);
} else {
displayError('Could not find the URL to redirect to');
}
} else {
displayError('No value or parameter has been set. Please set a proper value.');
}
}
function redirectPage(elem) {
var src = elem.getAttribute('data-redirect-src');
window.location = src;
}
function displayError(message) {
var userMessage = document.getElementById('userMessage');
userMessage.innerHTML = message;
userMessage.style.backgroundColor = 'red';
userMessage.style.color = 'white';
userMessage.style.display = 'block';
}
function displaySuccess(message) {
var userMessage = document.getElementById('userMessage1');
userMessage.innerHTML = message;
userMessage.style.backgroundColor = 'green';
userMessage.style.color = 'white';
userMessage.style.display = 'block';
}
I'm not sure if something's wrong with the code I put in the button or in the JavaScript.
Disable button by default
The button should be disabled by default, and should only be enabled when the expected input value is detected. It appears you already have a mechanism for this in your example, but you have some impediments to overcome first:
button should be disabled by default. Do this in the HTML:<button disabled …>Continue To Payment</button>
input's onchange handler should just call setValueOnTarget(), because this function already calls EnableButton(). In the HTML:<input onchange="setValueOnTarget(this);" … >
Remove the call to redirectPage() from the button's onclick handler and move it into addValueToQueryString() after you have assigned a value to newSrc.
Add a call to EnableButton() after you call displayError() in cases where you want to allow the user to modify the input and try again.
For example:
function setValueOnTarget(sourceElem) {
var targetId = sourceElem.getAttribute('data-target-element-id');
if (targetId) {
var targetElem = document.getElementById(targetId);
console.log(targetElem);
if (targetElem) {
var valueToSet;
var parameterToSet;
if (sourceElem.nodeName.toUpperCase() == 'SELECT') {
valueToSet = sourceElem.options[sourceElem.selectedIndex].value;
}
if (sourceElem.nodeName.toUpperCase() == 'INPUT') {
if (sourceElem.type.toUpperCase() == 'NUMBER' || sourceElem.type.toUpperCase() == 'TEXT') {
valueToSet = sourceElem.value;
}
}
targetElem.setAttribute('data-value-set-by-other-element', valueToSet);
parameterToSet = sourceElem.getAttribute('data-target-parameter');
targetElem.setAttribute('data-target-parameter', parameterToSet);
EnableButton(targetElem);
}
}
}
function disableButton(btn) {
btn.disabled = true;
}
function EnableButton(btn) {
btn.disabled = false;
}
function addValueToQueryString(elem) {
var src = elem.getAttribute('data-redirect-src');
var newValue = elem.getAttribute('data-value-set-by-other-element');
var parameter = elem.getAttribute('data-target-parameter');
if (newValue && parameter) {
if (src && newValue && parameter) {
var newSrc;
newSrc = src + newValue;
elem.setAttribute('data-redirect-src', newSrc);
redirectPage(elem);
} else {
displayError('Could not find the URL to redirect to');
}
} else {
displayError('No value or parameter has been set. Please set a proper value.');
EnableButton(elem);
}
}
function redirectPage(elem) {
var src = elem.getAttribute('data-redirect-src');
window.location = src;
}
function displayError(message) {
var userMessage = document.getElementById('userMessage');
userMessage.innerHTML = message;
userMessage.style.backgroundColor = 'red';
userMessage.style.color = 'white';
userMessage.style.display = 'block';
}
<b>Other: </b>
<input
type="number"
id="AmntValue"
data-target-element-id="SubmitAmnt"
data-target-parameter="Amnt"
onchange="setValueOnTarget(this);">
<button
disabled
class="button2"
id="SubmitAmnt"
type="button"
data-redirect-src="https://hub.deltasigmapi.org/donations/donations.aspx?appealid=1989&NumberOfPaymentsDisplay=0&GiftRecurrenceDisplay=0&GiftRecurrence=onetime&GiftAmount="
onclick="disableButton(this); addValueToQueryString(this);">Continue To Payment</button>
<div id="userMessage"></div>

… is not a function in javascript {custom code}

please, could somebody tell me, what he heck I am doing wrong in my syntax?
The problem starts in the statement this.form.onsubmit, where I get this.initData is not a function.
Thanks.
var Contact_Form = function(element){
this.form = element;
this.errors = new Array();
this.invalid = new Array();
this.inSent = false;
this.name = new String();
this.email = new String();
this.message = new String();
this.initData = function()
{
this.name = this.getElementValue('contact-name');
this.email = this.getElementValue('contact-email');
this.message = this.getElementValue('contact-message');
}
this.form.onsubmit = function(event)
{
event.preventDefault();
this.initData();
if(this.verifyData())
this.send();
}
this.verifyData = function()
{
if(!this.isNameLength())
this.setError('name', 'Zadejte, prosím, jméno dlouhé maximálně 30 znaků.');
if(this.isProperEmail())
{
if(!this.isEmailLength())
this.setError('email', 'Váš e-mail smí obsahovat maximálně 50 znaků.');
}
else
this.setError('email', 'Zadejte, prosím, email v korektním formátu.');
if(!this.isMessageLength())
this.setError('name', 'Zadejte, prosím, zprávu v rozsahu 1-999 znaků.');
this.doInvalidFields();
if(0 == this.errors.length)
return true;
return false;
}
this.doInvalidFields = function()
{
if(this.invalid.length > 0)
{
for(var invalid in this.invalid)
this.getElement(invalid).setAttribute('aria-invalid', true);
}
}
this.setError = function(field, message)
{
this.errors.push(message);
this.invalid.push(field);
}
this.getElementValue = function(element) {
return this.getElement(element).value;
}
this.getElement = function(element) {
return document.getElementById(element);
}
this.getElementName = function() {
return this.getElement('contact-name');
}
this.getElementEmail = function() {
return this.getElement('contact-email');
}
this.getElementMessage = function() {
return this.getElement('contact-message');
}
this.isNameLength = function(){
return this.isLength(this.name, 1, 30);
}
this.isEmailLength = function(){
return this.isLength(this.email, 1, 50);
}
this.isMessageLength = function(){
return this.isLength(this.email, 1, 999);
}
this.isProperEmail = function() {
return this.email.match(/^(?:\w){1,100}#{1}(?:\w){1,100}(?:.){1}(?:\w){1,10}$/ig);
}
this.isLength = function isLength(string, _min, _max) {
if(string.length >= _min && string.length <= _max)
return true;
return false;
}
}
window.onload = function()
{
new Contact_Form(document.forms[0]);
}
The problem is that this is not inherited, and has a different value inside each function.
Then, use
var Contact_Form = function(element){
/* ... */
var that = this;
/* Here this===that */
this.form.onsubmit = function(event)
{
/* Here this===that.form */
event.preventDefault();
that.initData();
if(that.verifyData())
this.send();
}
/* ... */
}
this is referring to the form in the onsubmit handler. You could assign this to a local variable, or bind the handler to the correct this with Function.prototype.bind, ie:
this.form.onsubmit = function(event) {
event.preventDefault();
this.initData();
if(this.verifyData())
this.send();
}.bind(this)
or with jQuery.proxy
this.form.onsubmit = $.proxy(function(event) {
event.preventDefault();
this.initData();
if(this.verifyData())
this.send();
}, this);
Both examples are forcing the this context of the function to be the instance of a Contact_Form whenever the handler is called

Javascript - Object not a collection

i try to create an video object with activex but i take this error : "Object not a collection". This is my code and error begins on line "this.parts = null;". There may be other things which causes error before this line. I search on the Net about this error but there is no example to solve it.
function detailKeyPress(evt) {
var evtobj=window.event? event : evt;
switch (evtobj.keyCode) {
case KEYS.OK:
if (player.isFullScreen == false)
player.makeFullScreen();
else
player.makeWindowed();
break;
case KEYS.PLAY:
player.isPlaying = true;
player.object.play(1);
break;
case KEYS.PAUSE:
player.pause();
break;
case KEYS.STOP:
player.makeWindowed();
player.stop();
break;
}
}
function Player(id) {
this.id = id;
this.object = document.getElementById(id);
this.isFullScreen = false;
this.isPlaying = false;
this.parts = null;
return this;
}
Player.prototype.play = function () {
this.isPlaying = true;
return this.object.play(1);
}
Player.prototype.playByUrl = function (url) {
this.object.data = url;
return this.play();
}
document.onkeydown = function (evt) {
detailKeyPress(evt);
}
window.onload = function () {
player = new Player('playerObject');
player.playByUrl($mp4Link);
}
Player.prototype.makeFullScreen = function () {
try {
this.object.setFullScreen(true);
this.isFullScreen = true;
}
catch (ex) {//If philips
this.object.fullScreen = true;
this.isFullScreen = true;
}
}
Player.prototype.makeWindowed = function () {
try {
this.object.setFullScreen(false);
this.isFullScreen = false;
}
catch (ex) { //If philips
this.object.fullScreen = false;
this.isFullScreen = false;
}
}
Player.prototype.pause = function () {
this.isPlaying = false;
this.object.play(0);
}
Player.prototype.stop = function () {
this.isPlaying = false;
this.object.stop();
}
This may caused by your registry. If you clean it, you can solve or probably a bug. I have searched also a lot about this error. There is no another thing to say.

attach event in loop, javascript

I know this is a "classic" and I already tried to read different explanatory articles on this subject, but I still manage to do it wrong somehow. I am talking about adding event handlers and functions in a javascript loop.
Here is my code with problems (it's a suggest-box / auto complete)
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
document.getElementById('autocom').style.display = 'none';
} else {
document.getElementById('autocom').style.display = 'block';
var divholders = [];
for (var i = 0; i < results.length; i++) {
divholders[i] = document.createElement('div');
divholders[i].style.width = '350px';
var divrestext = document.createElement('div');
divrestext.className = 'autocom0';
divrestext.innerHTML = results[i][0];
divholders[i].appendChild(divrestext);
var divrestype = document.createElement('div');
divrestype.className = 'autocom1' + results[i][1];
divrestype.innerHTML = results[i][1];
divholders[i].appendChild(divrestype);
divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i));
divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i));
document.getElementById('autocom').appendChild(divholders[i]);
}
}
}
It is (of course) the attachevent lines that do not work. This part of javascript is so weird/tricky :) Can a kind expert help me fix those two lines?
This is a half-way fix (I think(:
function bindEvent(element, type, listener) {
if (element.addEventListener) {
element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, listener);
}
}
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
document.getElementById('autocom').style.display = 'none';
} else {
document.getElementById('autocom').style.display = 'block';
var divholders = [];
for (var i = 0; i < results.length; i++) {
divholders[i] = document.createElement('div');
divholders[i].style.width = '350px';
var divrestext = document.createElement('div');
divrestext.className = 'autocom0';
divrestext.innerHTML = results[i][0];
divholders[i].appendChild(divrestext);
var divrestype = document.createElement('div');
divrestype.className = 'autocom1' + results[i][1];
divrestype.innerHTML = results[i][1];
// BIND THE EVENTS
divholders[i].appendChild(divrestype);
document.getElementById('autocom').appendChild(divholders[i]);
}
}
}
It looks like this now, but still no "action"
function autoComplete() {
var ss = document.getElementById('txbkeyword').value;
if (ss.length > 0) { CSearch.SearchAutoComplete(ss, 3, autoCompleteCB); }
else { document.getElementById('autocom').style.display = 'none'; }
}
function bindEvent(element, type, listener) {
if (element.addEventListener) {
element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, listener);
}
}
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
document.getElementById('autocom').style.display = 'none';
} else {
document.getElementById('autocom').style.display = 'block';
var divholders = [];
for (var i = 0; i < results.length; i++) {
divholders[i] = document.createElement('div');
divholders[i].style.width = '350px';
var divrestext = document.createElement('div');
divrestext.className = 'autocom0';
divrestext.innerHTML = results[i][0];
divholders[i].appendChild(divrestext);
var divrestype = document.createElement('div');
divrestype.className = 'autocom1' + results[i][1];
divrestype.innerHTML = results[i][1];
(function (i) {
bindEvent(divholders[i], 'mouseover', function () {
divholders[i].style.backgroundColor = '#266699';
});
bindEvent(divholders[i], 'mouseout', function () {
divholders[i].style.backgroundColor = '#F5F5F5';
});
})(i);
divholders[i].appendChild(divrestype);
document.getElementById('autocom').appendChild(divholders[i]);
}
}
}
One possibility is because attachEvent is IE-specific. You'll have to use attachEventListener in many other browsers.
And, to use the "proper" method for the current browser, you'll need to feature-detect them (snippet from MDN):
if (el.addEventListener){
el.addEventListener('click', modifyText, false);
} else if (el.attachEvent){
el.attachEvent('onclick', modifyText);
}
You can also create a function to aid in this:
function bindEvent(element, type, listener) {
if (element.addEventListener) {
element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, listener);
}
}
Then, in place of these 2 lines:
divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i));
divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i));
...use the function to bind your handlers (skipping the on in the event type argument):
(function (i) {
bindEvent(divholders[i], 'mouseover', function () {
divholders[i].style.backgroundColor = '#266699';
});
bindEvent(divholders[i], 'mouseout', function () {
divholders[i].style.backgroundColor = '#F5F5F5';
});
})(i);
You could also just enclose the <div>:
(function (div, i) {
bindEvent(div, 'mouseover', function () {
div.style.backgroundColor = '#266699';
});
bindEvent(div, 'mouseout', function () {
div.style.backgroundColor = '#F5F5F5';
});
})(divholders[i], i);
Try this:
divholders[i].attachEvent('onmouseover', this.style.backgroundColor='#266699');

Categories

Resources