Onclick button running automatically after $() insertion - javascript

I'm 99% through done writing this code but I'm stuck on the last hurdle.
The main issue here is:
I have 2 HTML buttons which aim to change text based on the function output, successful or not.
Currently, the logic for the functions is working - ie the expected returned values are as expected.
However, when I try to move these functions into my HTML file, they automatically run, which is overwriting the default value and defeating the point of having the button.
Button:
<button id="goldButton" onclick = "${calcGoldTierStatus(exampleCustomer)}">Click me!</button>
<h2 id="goldResult">Gold tier eligibility:${goldTierEligible}</h2>
Function earlier in same script.js:
function calcSilverTierStatus() {
if (
exampleCustomer.previousStays >= silverTier.previousStays &&
exampleCustomer.bookingAgencyId === null || String || Number &&
(exampleCustomer.roomSpend / (exampleCustomer.roomSpend.length+=1)) >= 100 &&
exampleCustomer.reservationNights >= silverTier.previousStays
) {
silverTierEligible = ("Silver Eligibility:Eligible for Silver tier!")
} else {
silverTierEligible= ("Silver Eligibility:Not eligible for Silver Tier")
}
}
What may be noteworthy is that I am passing the values into HTML via declaring a const 'content', then using:
document.body.innerHTML = content;
to write the HTML body.
It seems to be the $(calcGoldTierStatus(exampleCustomer)} that is causing the autorun, but I had no idea how to otherwise move the function into HTML from JS.

I found from some posts that it is bad practice to use template literals inside onclick buttons. Instead, using a combination of event listeners, getElementById, and appending a HTML article object instead of replacing main, solved most my problems.
#me for a look at the exact ways I got around this.

Related

assigning anonymous functions to buttons

When i use if statements to determine whether a user has viewed the form before, it breaks my whole code.Originally, my code just removed a child, and set the display of the next DIV to "block".This worked perfectly fine. all my variables saved properly in the end, etc.
However, since I added these checks to the buttons, everything has gone haywire.
I've tried using different mixes of appendChild, removeChild, and style.display methods. I even booted it up in notepad++ to help me visualize.
document.getElementById("newUser").addEventListener("click", function(parent, start, personal){
parent.removeChild(start);
document.getElementById.style.display="block";
});
document.getElementById("toGeneral").addEventListener("click", function(){
if(reUser === 0){
oPersonal;
document.getElementById("general").style.display="block";
} else if(reUser === 1){
oPersonal;
parent.appendChild(oShowInfo);
} else {
window.alert("Whoops this function is in progress");
}
return oPersonal;
});
I want my forms to be editable at the end of the form.
In one test (not this one). I was able to move back and forth between pages, but it would stop the loops that kept my variables up.
This one is using the oldChild = parent.removeChild() method to fix that, which may also be part of the issue.
**Note: variables such as
oPersonal
reUser
parent
are stored just above this code at the beginning of the page loop.
New code:
document.getElementById("newUser").addEventListener("click", function(){
parent.removeChild(start);
document.getElementById.style.display="block";
});
document.getElementById("toGeneral").addEventListener("click", function(){
if(reUser === 0){
oPersonal;
document.getElementById("general").style.display="block";
} else if(reUser === 1){
oPersonal;
parent.appendChild(oShowInfo);
} else {
window.alert("Whoops this function is in progress");
}
return oPersonal;
});
You have many problems in this code. First, your click event's handler can not take 3 args like this. When an event is triggered, only this event is passed to the function. So your code should looks like :
document.getElementById("newUser").addEventListener("click", function(event) {
let element = event.target;
let parent = element.parentNode;
parent.removeChild(element);
//Next line is wrong since getElementById is a function and should take args
//document.getElementById.style.display="block";
});
Then on your second element's click event handler, it seems like you are trying to use parent which is not in the same scope.
Also the return statement is strange, what are you trying to do ?

how to put an 'if' statement in front of a change function

This question is for using javascript in Caspio Cloud's platform, so a few things might look different than normal. But basically, I need to put an 'if' statement that references a variable 'above' a change function that runs some other code and I can't figure it out.
The problem is that in Caspio's form the Virtual9 field will 'change' on the form's load, and so it runs the change js. I need to not run the change js onload and also only if the variable 'item' is null.
<script>
var item = document.getElementsByName("InsertRecordItemID")[0].value;
<!-- right here I need an if (item !== null) to then run the change function but that if it's not null to not run the change function{ -->
$("[name='cbParamVirtual9']").change(function(){
var itid = document.getElementsByName("cbParamVirtual9")[0].value;
document.getElementsByName("InsertRecordItemID")[0].value = itid;
}
);
</script>
I've tested the variables using alert windows and they are gotten correctly. I just need to make sure the change function doesn't run if the variable 'item' is null.
EDIT: To clarify, when the form loads the ItemID field may or may not be null (based on parameters that pass over).
If it is not null then the Virtual9 field (where the user makes a selection) will be hidden- because the ItemID already had a value and needs to not change.
However, if ItemID is null then Virtual9 will be visible and the user can make a change, thereby updating the ItemID field. The user may update Virtual9 multiple times (looking for the right record) so it needs to keep updating ItemID (even after it is no longer null in this case).
That's why I think the best solution is to disable the code ONLY for onload, if possible. So that the code runs on change of Virtual9 but not onload.

Why is the existing content removed when I appendChild to an element?

I'm trying to create an implementation of "infinite scrolling". Here is my relevant code:
var postsIndex = 0;
var chunk = 5;
function getNextChunk() {
for (i=0; i<chunk; i++) {
postsIndex++;
document.write(getTimeLineElement(posts[postsIndex]));
}
}
if (postsIndex === 0) { // initial chunk.
var contentDiv = document.createElement("DIV"); // Create the div container.
var divTextNode = document.createTextNode(getNextChunk()); // Create a text node with the initial chunk.
contentDiv.appendChild(divTextNode); // Append the text node to the div container.
contentDiv.style.border="solid";
}
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
alert("near bottom!");
contentDiv.appendChild(getNextChunk());
}
});
The initial chunk loads just fine and the loading of the 2nd chunk is triggered just fine. However, when the 2nd chunk gets loaded the original content is lost leaving only what was appended. As you can see I have placed a border around the div for testing purposes. I'm not seeing that border. I'm not sure why. This may be an indication that somehow this whole thing is not in the div element like I think that it is. Can anyone please tell me what I'm missing? Thanks for any input.
... doug
Your function, getNextChunk, which is called at various times after the document has loaded, itself calls document.write. As described in the notes in MDN's document.write documentation, when called against a document that has loaded, document.write makes an implicit call to document.open. The Notes in the MDN documentation for document.open state that when called against an existing document, document.open clears that document.
As such, your function is wiping out the document before inserting your content.
I don't know what you expect any of this to do anyway...you're calling appendChild while passing in a function call. This means that function's return value would be passed in--but it doesn't return anything...and it calls document.write in a loop...it's really all over the map.
We will start with the line that is not behaving the way you expect.
contentDiv.appendChild(getNextChunk());
What does this mean?
It means, execute the getNextChunk function and whatever it returns, add it to the DOM as a child of contentDiv.
So, what does getNextChunk return?
function getNextChunk() {
for (i=0; i<chunk; i++) {
postsIndex++;
document.write(getTimeLineElement(posts[postsIndex]));
}
}
As far as I can tell from that code, it does not actually return anything. Therefore, you are adding nothing as a child of your content div.
So what is getting added to the DOM?
You are calling getTimeLineElement, but adding its return value (assuming it is a string) directly to the HTML content of the page. This does not go into the div, but just gets appended to the document.
What did I do wrong?
Returns: You are passing the return value of a function which does not return anything.
Side effects: You have a function named get*, which suggests it exclusively reads data, but actually mutates the page (called a side effect).
Data types: The result of a function named getTimeLineElement, which suggests it returns a DOM element, actually returns a string.
Always understand what data types you are working with and how they move around from function to function.

Is it possible to run two MutationObservers at the same time?

I'm trying to make a script with Greasemonkey for the Facebook's Timeline log page.
I need to catch two kind of events :
1)The URL change (Since the changes are made with AJAX on Facebook and therefore the page isn't fully reloaded, and neither the script).
2)The appearance of some elements.
I tried to make two MutationObservers, one to catch URL changes, and the other to catche the elements appearance.
But it seems to trigger only one (the url_mutation_observer).
Here is some of my code :
function handling_url_change(mutations){
mutations.forEach(function (mutation){
if (check_timeline()){
if (!buttons_added){
var element = $(document).find(button_location);
if (element && element.length > 0){
add_buttons();
}
}
}else if (set){
reset();
}
});
}
function handle_deletion(mutations){
mutations.forEach(function (mutation){
if (mutation.addedNodes){
for (var i = 0; i < mutation.addedNodes.length; i++){
if (isheader(mutation.addedNodes[i])){
mutation.addedNodes[i].remove()
}else if (isactivity(mutation.addedNodes[i])){
delete_activity(mutation.addedNodes[i]);
}
return true;
}
}
});
return true;
}
/*
** Mutation observers :
*/
var url_mutation_observer = new MutationObserver(handling_url_change);
var delete_mutation_observer = new MutationObserver(handle_deletion);
I have some questions :
1) Isn't each MutationObserver catching every mutation?
2) Is the addition of a button (like my script does) counted as a mutation?
3) If I add an element with a callback function triggered by the addition of such element. Isn't there a risk of recursion and infinite loop?
4) Is that possible to catch only the URL change with a MutationObserver, and to catch the appearance of only some kinds of elements with the other one?
(To be sure that each one catches only what he needs to catch, I didn't know how to do and I checked the url with a function inspecting the page, and not with a function checking if the mutation is a "UrlChangeMutation" or something like that).
5) What could I do?
NB:
If you want too, here is the full script with console.log() calls for debugging.
http://dpaste.com/3NWV08J
NB2:
If you also want this script without the console.log() calls :
http://dpaste.com/3AH8YF5
First off, note that your for loop is broken, because it contains an unconditional return true.
1) Isn't each MutationObserver catching every mutation?
Yes, because you're observing document.
2) Is the addition of a button (like my script does) counted as a mutation?
Of course.
3) If I add an element with a callback function triggered by the addition of such element. Isn't there a risk of recursion and infinite loop?
Absolutely.
(It will be a non-blocking loop though, meaning the page might not freeze.)
4) Is that possible to catch only the URL change with a MutationObserver [...]?
No, that's not what MutationObservers do. From MDN:
MutationObserver provides developers a way to react to changes in a DOM.
Note that "UrlChangeMutation or something like that" does not exist.
4) [...] and to catch the appearance of only some kinds of elements with the other one?
You cannot specify a filter, but you can check whether the affected elements meet your criteria in your callback function.
Hell, you have access to all methods and attributes of every node, what more could you need?
5) What could I do?
My suggestion? Google more.
For example, the first result for "javascript on url change" is:
How to detect url change
And I suggest you read up on the DOM, because it seems that you are simply unaware of many things that exist there.
I had an error : observer.observer() isn't a function. observer.observe() is : http://dpaste.com/3AH8YF5#line-254

Using "if" inside an "onclick

Please before posting or commenting ... read and understand that this is inside an application that generates the web page and I cannot create a function I can only edit with will happen inside the onclick
Is it possible to use a "if" function inside an "onclick".
The reason why I have to do this is because this "onclick" is used inside an application that I do not control the code, the only thing I can control is what happens inside the "onclick"
For example:
onclick="document.getElementById('REF_DOC_1_NUMBER').value = '';"
I can write the:
document.getElementById('REF_DOC_1_NUMBER').value = '';
I cannot declare any function in the webpage... cause it's an application that compiles the pages... I can only write what is written in the tag onclick...
But not a function. The page is generated by the application itself so I do not control the header.
What I need, a IF that checks an other ID and to change the value ONLY if the value of the other ID (REF_DOC_1_CHOICE) is NA (not applicable)
Any thoughts?
Yes, you can use any inline statement you want. The onclick event is a function by itself. As you can define one in JS in the header:
document.getElementById('mydiv').onclick = function() {
var a = 2;
if (a > 1) {
// do stuff
}
};
You can also do so inline:
onclick="var a=2;if(a>1){a=3}else{a=-1}"
onclick="a == 12 && b = true || b = false"
Here's a JSFiddle
though it is not a good practice to use inline javascript but you can use an if in onclick
onclick="document.getElementById('REF_DOC_1_NUMBER').value = '';if(condition){dosomething}else{dosomething else}"
You may use ternary operator. Somehow like this:
onclick="document.getElementById('REF_DOC_1_CHOICE') == 'some_value'? (document.getElementById('REF_DOC_1_NUMBER').value = '') : 0"
Define a function like this :
onclick="function(text){
// My stuffs
if(text==='test')
document.getElementById('REF_DOC_1_NUMBER').value = '';
}";

Categories

Resources