I have a user log table, which inserts a record to every user action, but sometimes it duplicates the inserted records.
my code is very simple
<script>
db.transaction(function(tx) {
tx.executeSql('INSERT INTO tab_log (date_occurrence,hour_occurrence,number_user,occurrence,obs_occurrence) VALUES (?,?,?,?,?)', [var_date, var_hour, var_number_user, var_occurrence, var_obs_occurrence]);
});
</script>
<input type="button" name="btn_finish" id="btn_finish" value="Finish" onclick="this.blur();salvar();">
EDIT I have post full code. This code works perfectly, but sometimes doubles in the row of the log table
Has this ever happened to anyone? Does anyone have any idea what it might be?
You are adding a click listener twice so to speak. There is a function carregado() which is called on window load event that binds an event listener to the finish button.
function carregado() {
document.getElementById('btn_finish').addEventListener('click', salvar);
}
However, further on the html side, you are setting the onclick attribute of that button, making it call salvar() twice as onclick and addEventListener('click') both binds a different listeners to the button.
<input ... id="btn_finish" value="Finish" onclick="this.blur();salvar();">
What you can do to sort this out, is to remove the onlick attribute call to salvar() as it breaks your logic to bind the event only after finishing loading the page with carregado(), so the onclick part seems useless this case. Nevertheless, it will prevent the salvar() to be called twice.
Related
I have some working code that I'm now using in slightly different context. The working part is that I use objects onclick event to bring up a form to send an e-mail. When this in an HTML page, it works fine. I would have a lot of buttons that look like this:
<button id="mail-c1" onclick="initMailFormButton(this.id, 'someone','somedomain.com','a subject')">Someone's Name</button>
The entire form is created in javascript and has its own submit and cancel buttons but is within the button element. In order to be able to enter data into the form, I need to kill the onclick event then restore it after I've submitted or cancelled the e-mail. The onclick handler starts out with:
function initMailFormButton(mailId, eName, eDomain, eSubject) {
myFormLocation = document.getElementById(mailId);
stopFormClick(myFormLocation);
where the stopFormClick function is:
function stopFormClick(myFormLocation) {
saveOnclick = myFormLocation.onclick;
myFormLocation.onclick = null;
}
This has the bug that it doesn't handle someone opening multiple forms at once, but that's not my immediate concern. I'll fix it outside of this discussion.
The submit and cancel buttons in the generated form both restore the onclick event handler so you can open and close the form multiple times quite happily.
My new case is that I'm generating HTML page from a database. I'm using HTML datasets to store the previously hard-coded information like so:
emailButton.setAttribute("data-mailname", emailName);
emailButton.setAttribute("data-maildomain", emailDomain);
emailButton.addEventListener("click", function() { initMailFormButton(this.id, this.dataset.mailname, this.dataset.maildomain, ""); }, false);
The information being retrieved is correct and the form appears in the correct location. However, I can't enter information because the original onclick handler kicks in when I click in the first form field and generates another form...
The only clue I have is that when I look at the value of the onclick event being saved in the static HTML pages, it has the expected value but it is null in the generated pages. I find this confusing because I am passing the (unique) element id to the routine so it should be getting to the correct element.
Can anyone help me on this one. Meanwhile, I'll fix the event handler bug I mentioned above.
OK. So it's that there is a difference between click and onclick. The onclick event handler wasn't set so it is null. I changed setting the click event listener to setting the onclick attribute as:
emailButton.onclick =
function() { initMailFormButton(this.id, this.dataset.mailname, this.dataset.maildomain, ""); };
and everything works nicely.
To handle the limitation I'd noted earlier, I made the saveOnclick variable into an associative array keyed by the button id. Now people can have as many buttons clicked as they want - although wanting to have more than one is probably rare.
This is my startQuiz() function which is bounded to the start button.
I click the start button to set the display of my quiz to flex. The issue here is with the submit button.
When I click the submit button and run submit(), everything works out and 1 is logged into the console.
The issue arises when I run closeQuiz() which simply changes the quiz display back to none. After running startQuiz() to reset the display to flex, running the submit() causes the console to log twice.
This pattern continues in where each time I run closeQuiz() and reopen the quiz, submit() ends up running more and more times.
Please help me to run submit() only once and thank you.
function startQuiz(){
quizBox.classList.remove("hide");
populateAnswers();
}
function closeQuiz(){
quizBox.classList.add("hide");
}
function populateAnswers(){
document.getElementById("submit").addEventListener("click" , () => {
submit();}
)
}
function submit(){
console.log(1)
}
Everytime you run startQuiz(), an event listener is being added to submit button. First time when startQuiz() is invoked, you add an event listener. After closeQuiz() when you call startQuiz() to reset display to flex, an event listener is added to submit button for second time which causes the console to be logged twice with 1 and so on.
Add event listener to submit button only once initially or remove event listener when you call closeQuiz().
The issue is because in your code whenever populateAnswers is being called a new Event listener for click is being added to the element with id submit since the listener is being added as an anonymous function. Because anonymous functions are not identical even if defined using the SAME unchanging source-code simply called repeatedly, even if in a loop. So every time one more function is being added as a new listener.
In order to resolve the issue send submit method reference itself as a listener, which will not add multiple listeners even though the function gets called multiple times. Because If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice, and they do not need to be removed manually with the removeEventListener() method.
By changing the code with the below implementation will resolve the issue that you are facing.
function populateAnswers(){
document.getElementById("submit").addEventListener("click" , submit)
}
Hope this helps.
How do you selectize.addItem("value") without triggering item_add?
I have a tags field that’s dependent on another selection. I need to automatically fill in tags whenever that other selection is changed, and then I need to have a listener run code whenever the user adds or removes a tag. I can’t figure out how to add the tags programmatically without triggering the item_add event, but I don’t want it triggering before the user’s even touched the tags.
(There is addItem(…, silent), but unless I’m mistaken, that only stops it from triggering the change event.)
Sample code:
$('#input-tags').selectize({
onItemAdd: function() {
alert("This should only appear by user action");
}
});
$tags = $('#input-tags')[0].selectize;
$tags.addItem("awesome");
$tags.addItem("neat");
JSFiddle
One solution (and the only one I know of) is to remove the event listeners before the addItems and add them back afterwards. That hardly seems ideal, though, especially if it needs to be done more than once.
You can convert your code to register the add callback after adding all initial values:
$('#input-tags').selectize();
$tags = $('#input-tags')[0].selectize;
$tags.addItem("awesome");
$tags.addItem("neat");
// Register the listener once you have initialized the selectize component.
$tags.on('item_add', function() {
alert("This should only appear by user action");
});
I am using a simplified example to describe the issue I am facing.
I have the following HTML markup:
<input ng-model="something" style="margin-top:8px;"/>
And, I have two HTML buttons:
<button id='submit'>Save</button>
<button id='btnGetAnalyzerInput'>Generate Analyzer File </button>
I used jQuery's change event on my input (to track whether any changes have been made to the input - by maintaining a simple JS variable).
When the user clicks "Generate Analyzer file button", what I want to is this:
Look up the JS variable to find out whether any changes have been made.
If yes, then prompt the user to save changes (window.dialog)
However, I find that when the focus is still on the input element, and when the button is clicked, the click event runs before the OnChange event. In all other cases, it is the OnChange event which gets fired before the click event (and so my code works as expected).
Is there any way to ensure that for such a scenario, the click event runs after the onChange event?
I am using Google Chrome to test my application.
Note :
Both events work as expected - the OnChange event gets fired when the textbox loses focus.
I can't use the keypress event since I want to track changes.
You could have the click event call the same function as the OnChange event. Something like this:
function OnChange(){
//Do stuff for on change;
}
function ClickEvent(){
OnChange();
//continue with generate stuff
}
You you may need to set up and pass in arguments to the OnChange function, depending on how you are accessing the data you need. If you need more guidance, post more of your code.
Most of the stuff I see on this site refers to adding information to a div from php. I just want to take a user's input, add it to a table dynamically and have it displayed in the div as the click the submit button.
I'm not doing anything where the data gets posted to a database, no php, etc, at this point.
I have the JQuery to run the dynamic add to the database as well. It works, but I have to use a breakpoint in the javascript to step through and see the entered data added to the row....issue is when that function is done, the page refreshes, and all data is gone.
I need a way to add the data to the table in the div without the page refreshing and clearing all of the other data each time.
Imagine parent information in one div, and child information being added in another div. As I add each child piece, I don't want the parent information to be removed, and in fact want it to remain as "editable" information.
------------------------------------------ Edit ----------------------------------------------
Below is the code I'm now using based on suggestions, but I obviously don't understand completely, because it hits the event handler for the click, but then doesn't get inside the function, just jumps back out, and never hits my other breakpoints inside there.
---------------------------------------Final Edit ----------------------------------------------
I finally pulled my head out of my backside and paid attention to what Charlie was telling me, and got this...and it works when I call the function from the onClick event. I couldn't get the event to bind to the button click, but that may be because I was using the tag instead of the setup.
function(addNoteRow){
event.prevent.Default();
var noteTxt = $('#noteEntry').val();
var noteEntBy = 'BGM'
noteEntDate = (Date());
if (!document.getElementsByTagName) return;
tabBody=document.getElementsByTagName("TBODY").item(0);
row=document.createElement("TR");
cell1=document.createElement("TD");
cell2=document.createElement("TD");
cell3=document.createElement("TD");
textnode1=document.createTextNode(noteEntDate);
textnode2=document.createTextNode(noteEntBy);
textnode3=document.createTextNode(noteTxt);
cell1.appendChild(textnode1);
cell2.appendChild(textnode2);
cell3.appendChild(textnode3);
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
tabBody.appendChild(row);
}
You mentioned you're using jQuery, so I will in my example to make this easier.
$('#submit_button').click( // Bind an event handler to the submit button
function(event){
event.preventDefualt(); //This is necessary if you are using a an submit button input element as normal behavior is to submit the form without ajax causing the page location to change. Event is automatically passed in, and we can call preventDefault() on this object to stop the browser from navigating away from our page.
$.ajax({
url:'http://youserver.com/script_that_will_respond.php', //Give the ajax call a target url
data: $('#user_input').val(), //Supply some data to send with the request,
success: function(data){ //Supply an anonymous function to execute on success. The parameter will be the response text.
$('#your_result_div').html(data); //On success of the ajax call, put the response text into an html element on your page
}
});
}
);
jQuery's ajax method has a lot of settings. This is a pretty bare-bones example.
You can read more about the various options here: http://api.jquery.com/jQuery.ajax/
Edit: I may have misunderstood. If you do not need to reach a server, and want to do this all locally, it is simpler.
$('#submit_button').click( // Bind an event handler to the submit button
function(event){
event.preventDefault();
/*
We have to call this method on the event object bacause deafult behavior
of a subnmit button is to submit the form, causing the browser to go to a new page.
*/
var text = $('#some_input_element').val(); //Store the value of a text input in the variable text
$('#your_div').html(text); //put the contents of the variable text into the "your_div" elemnt.
}
);
try AJAX for partially refreshing portions of page like div etc.
http://api.jquery.com/jQuery.ajax/