Getting event listener to fire - javascript

I have a script that I am using in conjunction with a PHP form. I am trying to get a counter field that I put on the form to count up by one second after the employee id field is filled out below is my code.
<script type="text/javascript">
var counter = 0;
var timer;
var employee = document.getElementsByName("employeeID")[0];
var employeeVal = document.getElementsByName("employeeID")[0].value;
employee.addEventListener("onchange", startCount);
function countUP () {
counter = counter + 1; //increment the counter by 1
document.getElementsByName("timer_container")[0].value = counter;
}
function startCount () {
timer=setInterval('countUP()', 1000 );
}
function readonly() {
document.getElementsByName("timer_container")[0].readOnly = true;
}
</script>
I have tried different functions to see if the event listener was firing. I also tried using different events, onclick, onblur and have not had any luck. I've taken the timer function and set it to onload in the body tag directly on the HTML and that works. However I need this to be able to run as soon as someone enters info into the employee field.

First, don't use on in the event name when using .addEventListener. The on prefix is only for inline event binding with HTML event attributes (which is why it worked for you in <body onload=...>). Inline event HTML attributes shouldn't be used anymore anyway. So, your line should be:
employee.addEventListener("change", startCount);
And use the input event instead of the change event if you want it to fire as data is being entered.
employee.addEventListener("input", startCount);

Related

Trigger OnChange when field is filed automatically?

I want to trigger a function when one of my field (textbox) changed. The problem is: the content of that textbox is filed automatically by an external script(That I don't have access to), therefore the onChange listener won't trigger.
I've tried a lot of code, but here's the two closest (I think?) result I have:
Here's the script and the field
<script async src="SomeNiceScriptHere.js"></script>
<input type="text" name="wt_embed_output" id="wt_embed_output" class="wt_embed_output"/>
Code 1:
function myFunction() {
var x = document.getElementById("wt_embed_output").value;
alert("The input value has changed. The new value is: " + x);
}
document.getElementById("wt_embed_output").addEventListener("change", myFunction);
Code 2:
$( "#wt_embed_output" ).change(function() {
alert( "Value has been changed" );
});
For now, it doesn't work when the value is updated with the script, it only works when the user manually changes the value.
Does anyone know a way to do it?
Try adding event listener in the input.
var el = document.getElementById('wt_embed_output');
el.value = 'New Value'
el.dispatchEvent(new Event('oninput'));
document.getElementById("wt_embed_output").addEventListener("oninput", myFunction());
function myFunction() {
var x = document.getElementById("wt_embed_output").value;
alert("The input value has changed. The new value is: " + x);
}
<input type="text" name="wt_embed_output" id="wt_embed_output" class="wt_embed_output" />
onchange only occurs when the change to the input element is committed by the user, most of the time this is when the element loses focus.
try using oninput event;
if that doesn't work you can use a solution that works for all cases: set up a timing event using setInterval()
This isn't a perfect solution, but it works. Since I wasn't able to fetch the text in the field right after the script execute, I did a little workaround with myFunction():
<script>
function myFunction() {
if(document.getElementsByClassName('wt_embed__message')[0].getElementsByClassName('main')[0].textContent != 'Upload completed!'){
setTimeout(myFunction, 500);
}
else{
var wt_output = document.getElementById("wt_embed_output").value;
//do something
}
}
window.addEventListener("load", myFunction);
</script>
-> When the page load, my function is called until the external scripts runs. Once I get a specified message, I know the script is done so I get out of the 'if' condition.

How to determine if an Element was created dynamically

I have an existing system built using jQuery, Backbone.js and a REST-ish back-end written in C#. The application is an SPA with forms to fill and navigation. My job is to build a "Navigation Interceptor" to connect on the application so the system detects whether a field was modified in the current view so that when the user navigates, he will be warned that fields were modified and be requested to save or cancel the changes.
The way I designed it is using jQuery. To make it short, I use a selector on input, select, etc.. and bind a change event to it. Then I use a selector on links and buttons, unbind all click events, bind my "interceptor" (if a field has changed, ask before navigating) and then rebind all click events after my interceptor. I use stopImmediatePropagation() to cancel the regular navigation events, resulting in a kind of wrapper around the events.
By doing so, I have 2 problems:
Calling .val() on a field does not trigger the change event which is fine since I populate the fields dynamically. The problem is that the bootstrap date pickers does not seem to be setting the value using .val() resulting in all date fields having the "changed" state when initialized.
Elements dynamically created (e.g.: field in accordion panel created after the page has loaded) don't accept the events resulting in forms not firing the change event of my navigation interceptor.
My question is regarding the 2 above elements:
Is there a way to determine if a specific field is a date picker and bind the change event on that field so that when I populate it, the change event does not fire, but when the users do, it does (I tried binding on the changeDate event but the setDate method seems to be firing the changeDate event also)?
Is there a way to determine if the element was dynamically created (e.g.: $(''))? The problem is that I do not have a specific selector for a single field, so I think I cannot use delegation ($(document).on('change', 'someFieldSelectorICannotKnow', function () {});). All I have is a handle on the jQuery element ($(this) in a .each(fn) iteration).
#2 Solved using event delegation on all fields and skipping the handler if the field is not a form field
Solution of #2:
NavigationInterceptor.prototype.bindChangeEventOnAllEditableFields = function () {
var self = this;
var fieldsSelector = $(this.configuration.selectors.formFields.join(', '));
$(fieldsSelector).each(function () {
var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, $(this));
if (isFormField && self.configuration.debug.highlight.fields.unchanged && $(this).attr('type') === 'radio') {
$(this).parent().css('background-color', self.configuration.debug.highlight.fields.unchanged);
} else if (isFormField && self.configuration.debug.highlight.fields.unchanged) {
$(this).css('background-color', self.configuration.debug.highlight.fields.unchanged);
}
});
$(document).on('change', fieldsSelector, function (event) {
var field = $(event.target);
var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, field);
if (isFormField) {
self.hasFieldChanged = true;
if (self.configuration.debug.highlight.fields.changed) {
if (field.attr('type') === 'radio') {
field.parent().css('background-color', self.configuration.debug.highlight.fields.changed);
} else {
field.css('background-color', self.configuration.debug.highlight.fields.changed);
}
}
}
});
return this;
}
var unchangeable_classes = ['decorative', 'constant'];
$(document).on('change', 'input,select,textarea', function () {
var $this=$(this);
for(var i =0;i<unchangeable_classes.length;++i){
if($this.hasClass(unchangeable_classes[i]))
return;
}
global_changed = true;
});
Why doesn't this work, it should? (Edited in response to comment.)
My thoughts>>
1)A way to stop calling changeDate() after calling setDate(), you could just call event.stopPropogation(), it will prevent the event from bubbling up
2)while creating a dynamic element, you could add any property of your wish. For eg
var iDiv = document.createElement('div');
iDiv.isDynamic = true;
then while iterating through the element, check for isDynamic property
Why not add a benign class tag to the element
$('#foo').addClass('bar');
then you can check for the class to see if it was created
if ($('#foo').hasClass('bar'))
alert('was created');
Note that when you add elements you have to re-attach the events. So if you have a global document event and then add an element, that element won't be included unless you explicitly attach the new element.
I'm posting the answer for my question #1.
What I did is modify bootstrap's source. When calling setDate like so:
$('#myDateInput').datepicker('setDate', new Date());
The code goes through the function setDates which calls update and setValue, the first one resulting in the date being set in the datepicker itself, the second one setting only the value in the input text field. What I did is remove the call to 'change' which triggers the change event on the field and left the custom event 'dateChange'. This results in my code not firing the change event when I call setDate, but calls it when the user sets a date using the picker itself.

How to implement manual click event on dynamically generated element

i have a mainbox inside which some more boxes are dynamically generated.
// first time retrive
$.post("dataretrive.php", {
}, function(data, status) {
document.getElementById('mainbox').innerHTML = data;
timer();
});
then on click on these subboxes some i am implementing some functionality
$('.boxes-main').unbind('click').on('click', '.subbox', function(e){
var value1 = $(this).attr('data');
var value2 = $(this).attr('data2');
var value3 = $(this).attr('data3');
var value11 = $(this).attr('data4');
var value12 = $(this).attr('data5');
var value13 = $(this).attr('data6');
...... // some more functionality with these data which i think doesn't matter for this question for this question
});
As i want to implement shortcuts to these subbox like when user press 1 it trigger a click event on that box. I also have ID's associated with that. like box1 , box2, box3 and so on. and i am trying to put a click event of that box when key 1 is pressed.
$(document).keypress(function(e) {
if(e.charCode == 49) {
$('#box1').click();
}
});
I had also tried trigger function , $("boxes-main #box1').click(); but nothing works because contents are dynamically generated. someone tell me please how to implement manual click event on dynamically generated element.
and don't get confused between boxes-main and mainbox both are class and id of same div element.
Based on your comment:
and don't get confused between boxes-main and mainbox both are class
and id of same div element.
It is not the click generation that is broken, but you are targeting the wrong ancestor in your delegated click event handler. Go higher up the ancestors to a non-changing element. document is the best default if nothing else is closer.
$(document).on('click', '.subbox', function(e){
Notes:
Don't mix bind with on. Use off instead
You don't need off/unbind at all in this example

javascript getting a variable from a child to a parent

I shortened my code dramatically but below relays the point pretty efficiently, I'm trying to get the variable "Monitor" to update if the buttons pressed. I can get the variable through to my code if I put all of my code inside of the "button.onclick" function. However, my code won't run until I press the button. I need my code to run and if a button is pressed it updates my code.
<form name="form1">
<span id="buttons">
<input type="button" name="button1" value="funny1"/>
<input type="button" name="button2" value="funny2"/>
</span>
</form>
<script type="text/javascript">
var Monitor, buttonsDiv=document.getElementById("buttons");
Monitor = "funny1"
for (var i=1; i<=2; i++) {
var button = document.form1["button" + i];
button.onclick = function() {
buttons.Monitor = this.value;
};
/*lots of my own code that runs
inside of my for loop waiting
to reference monitor for an update*/
</script>
Hopefully the following code will get you going in the right direction. Instead of wiring up all the events per button, I think you were trying to get it so each button would then call into a function that would set the value of Monitor.
var Monitor = "funny1";
//selecting all elements named button
var buttons = document.querySelectorAll('input[type="button"]');
//For each of the buttons wire up an event listener
for(var i=0, length=buttons.length; i < length;i++)
{
//create a reference shorthand
var button = buttons[i];
//add the event listener for a click
button.addEventListener('click', function(event)
{
//on the event look at the event's target property to find the element that invoked the click
Monitor = event.target.value;
console.log(Monitor); //Output the value of monitor the the console
});
}
This code first finds all the inputs with type=button. I suggest you perhaps give the inputs a class instead to make the selector clearer, your choice. Secondly, I loop through the buttons and wire an event up for each one. The event then sets the value of the Monitor variable.
http://jsfiddle.net/wcf4c/

Dispatching Custom Event and listening for it somewhere else (Bubbling) in IE

I can't seem to get this to work in JavaScript. I've tried using plain old JavaScript and also JQuery but nothing seems to work.
Here's my situation:
I have this PopUp "Panel" and in it I have a Button. The button has an event listener for click and I want that handler to fire off a custom event that the Panel will listen for. This is because I need to handle all the logic of the button click in the Panel.
Here's what I'm doing:
Before I launch the Panel I call a constructor for my "Class":
function PopUpStageAsssignmentTaker(content) {
PopUpStage.call(this);
this.allPagesAdded = false;
this.questionsCreated = [];// will be an array of pages that will be submitted
this.listLabel = null;
addAssignmentTakerParts.call(this);
this.popUpDiv.addEventListener("assignmentTakingSubmitEvent", handleAssignmentSubmit, true);
function handleAssignmentSubmit(event) {
alert("YESSS!");
}
}
This does quite a bit but just know that in the call to PopUpStage it creates the div that represents the Panel and saves that in this.popUpDiv. So I add a event listener to this.popUpDiv listening for some custom event that I'm making up.
Later on I have code that creates the content in the Panel and we have something like this:
SubmitQuestionTakingPage.prototype.makeContent = function(question) {
var questionWrapper = getQuestionWrapper();
var submitDiv = document.createElement("section");
submitDiv.innerHTML = "Pressing Submit will cause this Assignment to be submitted and you will be unable to make any changes after that. If this " +
"Assignment is automatically graded you will receive a Grade upon clicking submit. If this Assignment is not automatically submitted you must wait" +
" for the creator of this Assignment to assign you a Grade. To continue, please press Submit.";
submitDiv.setAttribute("class", "separatedSmaller");
questionWrapper.appendChild(submitDiv);
var submitButton = document.createElement("input");
submitButton.setAttribute("type", "submit");
submitButton.setAttribute("class", "fancyButton");
submitButton.addEventListener("click", handleSubmitButtonClick);
questionWrapper.appendChild(submitButton);
return questionWrapper;
};
function handleSubmitButtonClick(event) {
var event = document.createEvent("Event");
event.initEvent("assignmentTakingSubmitEvent", true, true);
window.dispatchEvent(event);
// $(this).trigger("assignmentTakingSubmitEvent");
}
So we create some content and in it we create a button that has a listener for click. In the click handler you can see how I fire off the event.
Problem: I'm reading that this does not work in IE under version 9+. What can I do in to make it work in all browsers? Is there a way?

Categories

Resources