__doPostBack trigger on html render from javascript(before real click) - javascript

I'm trying to create some new buttons from js like:
var nextYearList ="";
...
nextYearList += "<button type='button' customparam='" + newCatalogList[l].code + "|" + newBaseName + "' ><span class='catName'>" + newCatalogList[l].name + "</span><span class='catYears'>" + newCatalogList[l].startDate + " - " + newCatalogList[l].endDate + "</span></button>";
...
ok('#YearNavigation .panelNextYear')[0].innerHTML = nextYearList;
var xListYears = ok('.panelNextYear button[customparam]');
for (var f = 0; f < xListYears.length; f++)
{
xListYears[f].addEventListener('click', changeCatalogPostback(xListYears[f].getAttribute('customparam'),true));
}
Where ok is my document.querySelectorAll wrapper;
ok = function (model)
{
return document.querySelectorAll(model);
};
changeCatalogPostback= function (parameter,checker)
{
if(checker)
__doPostBack('changeCatalog',parameter);
};
The main problem is that my __doPostBack is triggered on html rendering... so bye bye current page...
So how can I avoid a __doPostBack trigger on html render from javascript? I really need it to be there but working on click and not on render...

When you are adding an event listener you are actually calling the function which returns undefined and makes a postback. So if you will remove a __doPostBack call from changeCatalogPostback function the line with addEventListener call would evaluate to the end and will be equal to:
xListYears[f].addEventListener('click', undefined);
Instead addEventListener should accept a function as a second parameter. Use a bind call:
xListYears[f].addEventListener(
'click',
changeCatalogPostback.bind(this, xListYears[f].getAttribute('customparam'), true));

Related

Passing string from onclick to a Javascript function

I have this line:
$twizz.html(
'<a class="username" href="#">' + twizz.user + '</a>' + ': ' + twizz.message
)
and a JQuery line that executes a function when clicked:
$('.username').click(function() {displayUserTwizz(); return false; });
For example. JohnDoe (twizz.user) - Hello everyone (twizz.message) (with John Doe calling the displayUserTwizz function when clicked)
How do I dynamic pass the twizz.user string into my displayUserTwizz function. For example if I click JohnDoe, the function will run as
displayUserTwizz = function () {
var index = message.JohnDoe.length;
}
You need to get the content of the <a> element (event.target.innerText), then pass it to the displayUserTwizz() function:
$('.username').click(function() {displayUserTwizz(event.target.innerText); return false; });
Then, you can handle the user in the displayUserTwizz() function:
displayUserTwizz = function (user) {
var index = message[user].length;
}

How to concatenate and pass parameters values in html using jQuery

I'm using jQuery to get values from ajax rest call, I'm trying to concatenate these values into an 'a' tag in order to create a pagination section for my results (picture attached).
I'm sending the HTML (divHTMLPages) but the result is not well-formed and not working, I've tried with double quotes and single but still not well-formed. So, I wonder if this is a good approach to accomplish what I need to create the pagination. The 'a' tag is going to trigger the onclick event with four parameters (query for rest call, department, row limit and the start row for display)
if (_startRow == 0) {
console.log("First page");
var currentPage = 1;
// Set Next Page
var nextPage = 2;
var startRowNextPage = _startRow + _rowLimit + 1;
var query = $('#queryU').val();
// page Link
divHTMLPages = "<strong>1</strong> ";
divHTMLPages += "<a href='#' onclick='getRESTResults(" + query + "', '" + _reg + "', " + _rowLimit + ", " + _startRow + ")>" + nextPage + "</a> ";
console.log("Next page: " + nextPage);
}
Thanks in advance for any help on this.
Pagination
Rather than trying to type out how the function should be called in an HTML string, it would be much more elegant to attach an event listener to the element in question. For example, assuming the parent element you're inserting elements into is called parent, you could do something like this:
const a = document.createElement('a');
a.href = '#';
a.textContent = nextPage;
a.onclick = () => getRESTResults(query, _reg, _rowLimit, _startRow);
parent.appendChild(a);
Once an event listener is attached, like with the onclick above, make sure not to change the innerHTML of the container (like with innerHTML += <something>), because that will corrupt any existing listeners inside the container - instead, append elements explicitly with methods like createElement and appendChild, as shown above, or use insertAdjacentHTML (which does not re-parse the whole container's contents).
$(function()
{
var query=10;
var _reg="12";
var _rowLimit="test";
var _startRow="aa";
var nextPage="testhref";
//before divHTMLPages+=,must be define divHTMLPages value
var divHTMLPages = "<a href='#' onclick=getRESTResults('"+query + "','" + _reg + "','" + _rowLimit + "','" + _startRow + "')>" + nextPage + "</a>";
///or use es6 `` Template literals
var divHTMLPages1 = `` + nextPage + ``;
$("#test").append("<div>"+divHTMLPages+"</div>");
$("#test").append("<div>"+divHTMLPages1+"</div>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test"></div>

Passing argument to on click event of dynamically generated element

I am trying to pass arguments to onclick event of dynamically generated element. I have already seen the existing stackoveflow questions but it didn't answer my specific need.In this existing question , they are trying to access data using $(this).text(); but I can't use this in my example.
Click event doesn't work on dynamically generated elements
In below code snippet, I am trying to pass program and macroVal to onclick event but it doesn't work.
onClickTest = function(text, type) {
if(text != ""){
// The HTML that will be returned
var program = this.buffer.program;
var out = "<span class=\"";
out += type + " consolas-text";
if (type === "macro" && program) {
var macroVal = text.substring(1, text.length-1);
out += " macro1 program='" + program + "' macroVal='" + macroVal + "'";
}
out += "\">";
out += text;
out += "</span>";
console.log("out " + out);
$("p").on("click" , "span.macro1" , function(e)
{
BqlUtil.myFunction(program, macroVal);
});
}else{
var out = text;
}
return out;
};
console.log of out give me this
<span class="macro consolas-text macro1 program='test1' macroVal='test2'">{TEST}</span>
I have tried both this.program and program but it doesn't work.
Obtain values of span element attributes, since you include them in html:
$("p").on("click" , "span.macro" , function(e)
{
BqlUtil.myFunction(this.getAttribute("program"),
this.getAttribute("macroVal"));
});
There are, however, several things wrong in your code.
you specify class attribute twice in html assigned to out,
single quotes you use are not correct (use ', not ’),
quotes of attribute values are messed up: consistently use either single or double quotes for attribute values
var out = "<span class='";
...
out += "' class='macro' program='" + program + "' macroVal='" + macroVal + ;
...
out += "'>";
depending on how many times you plan to call onClickTest, you may end up with multiple click event handlers for p span.macro.

JavaScript: variable name unresolved

I wrote the following JS code:
function downloadFile(dataItem) {
....
}
....
for (var r = 0; r < dataItems.length ; r++) {
table += '<tr>';
var listOfAttributes = ['CarModel', 'BusMapping', 'Date_', 'Location_', 'Comments', 'AttackTraffic', 'IsTagged']
**table +='<td> <a onclick="downloadFile(dataItems[r])" href="#">' + dataItems[r]['FileName']['S'] +'</a></td>';**
for (var c = 0; c < Object.keys(dataItems[0]).length-1 ; c++) {
table +='<td>' + dataItems[r][listOfAttributes[c]]["S"] +'</td>';
}
table+= '</tr>'
}
I get an error for the line:
table +='<td> <a onclick="downloadFile(dataItems[r])" href="#">' + dataItems[r]['FileName']['S'] +'</a></td>';
It seems that JS can't resolve the variable 'dataItems' inside the -tag:
<a onclick="downloadFile(dataItems[r])" href="#">.
However, later in the same line, JS resolves successfully the same name for the part:
+ dataItems[r]['FileName']['S'] +
What do you think can be the problem? How can I make dataItems be resolved inside the -tag ?
Your variable is inside a string. Try changing the code to:
table +='<td> <a onclick="' + downloadFile(dataItems[r]) + '" href="#">' + dataItems[r]['FileName']['S'] +'</a></td>';**
As you're placing a string inside the element's attribute it is not recognized as a JavaScript code or a JavaScript function so place the JavaScript function itself.
So you can do, var anchor = '';
A sample example illustrating the problem, in this example if you write the function name as a string in the onclick property the function won't be called.
var container = document.getElementById('container');
var element = document.createElement('a');
element.href = '#';
element.text = 'Fire!';
element.onclick = fire; // this invokes the fire function
// element.onclick = 'fire'; // this won't invoke the fire function
container.appendChild(element);
function fire() {
console.log('fired');
}
<div id="container">
</div>
In this line
<a onclick="downloadFile(dataItems[r])" href="#">
unless dataItems is a global variable, it won't be available to the environment which will make this call downloadFile(dataItems[r]), since onclick event will be invoked in a global scope.
You need to bind the event less intrusively this way
//you need to update the selector as per your markup
document.querySelector ( "tr td a" ).addEventListener( "click", function(){
downloadFile(dataItems[r]);
})

Uncaught ReferenceError: function is not defined with onclick

I'm trying to make a userscript for a website to add custom emotes. However, I've been getting a lot of errors.
Here is the function:
function saveEmotes() {
removeLineBreaks();
EmoteNameLines = EmoteName.value.split("\n");
EmoteURLLines = EmoteURL.value.split("\n");
EmoteUsageLines = EmoteUsage.value.split("\n");
if (EmoteNameLines.length == EmoteURLLines.length && EmoteURLLines.length == EmoteUsageLines.length) {
for (i = 0; i < EmoteURLLines.length; i++) {
if (checkIMG(EmoteURLLines[i])) {
localStorage.setItem("nameEmotes", JSON.stringify(EmoteNameLines));
localStorage.setItem("urlEmotes", JSON.stringify(EmoteURLLines));
localStorage.setItem("usageEmotes", JSON.stringify(EmoteUsageLines));
if (i == 0) {
console.log(resetSlot());
}
emoteTab[2].innerHTML += '<span style="cursor:pointer;" onclick="appendEmote(\'' + EmoteUsageLines[i] + '\')"><img src="' + EmoteURLLines[i] + '" /></span>';
} else {
alert("The maximum emote(" + EmoteNameLines[i] + ") size is (36x36)");
}
}
} else {
alert("You have an unbalanced amount of emote parameters.");
}
}
The span tag's onclick calls this function:
function appendEmote(em) {
shoutdata.value += em;
}
Every time I click a button that has an onclick attribute, I get this error:
Uncaught ReferenceError: function is not defined.
Update
I tried using:
emoteTab[2].innerHTML += '<span style="cursor:pointer;" id="'+ EmoteNameLines[i] +'"><img src="' + EmoteURLLines[i] + '" /></span>';
document.getElementById(EmoteNameLines[i]).addEventListener("click", appendEmote(EmoteUsageLines[i]), false);
But I got an undefined error.
Here is the script.
I tried doing this to test if listeners work and they don't for me:
emoteTab[2].innerHTML = '<td class="trow1" width="12%" align="center"><a id="togglemenu" style="cursor: pointer;">Custom Icons</a></br><a style="cursor: pointer;" id="smilies" onclick=\'window.open("misc.php?action=smilies&popup=true&editor=clickableEditor","Smilies","scrollbars=yes, menubar=no,width=460,height=360,toolbar=no");\' original-title="">Smilies</a><br><a style="cursor: pointer;" onclick=\'window.open("shoutbox.php","Shoutbox","scrollbars=yes, menubar=no,width=825,height=449,toolbar=no");\' original-title="">Popup</a></td></br>';
document.getElementById("togglemenu").addEventListener("click", changedisplay,false);
Never use .onclick(), or similar attributes from a userscript! (It's also poor practice in a regular web page).
The reason is that userscripts operate in a sandbox ("isolated world"), and onclick operates in the target-page scope and cannot see any functions your script creates.
Always use addEventListener()Doc (or an equivalent library function, like jQuery .on()).
So instead of code like:
something.outerHTML += '<input onclick="resetEmotes()" id="btnsave" ...>'
You would use:
something.outerHTML += '<input id="btnsave" ...>'
document.getElementById ("btnsave").addEventListener ("click", resetEmotes, false);
For the loop, you can't pass data to an event listener like that See the doc. Plus every time you change innerHTML like that, you destroy the previous event listeners!
Without refactoring your code much, you can pass data with data attributes. So use code like this:
for (i = 0; i < EmoteURLLines.length; i++) {
if (checkIMG (EmoteURLLines[i])) {
localStorage.setItem ("nameEmotes", JSON.stringify (EmoteNameLines));
localStorage.setItem ("urlEmotes", JSON.stringify (EmoteURLLines));
localStorage.setItem ("usageEmotes", JSON.stringify (EmoteUsageLines));
if (i == 0) {
console.log (resetSlot ());
}
emoteTab[2].innerHTML += '<span style="cursor:pointer;" id="'
+ EmoteNameLines[i]
+ '" data-usage="' + EmoteUsageLines[i] + '">'
+ '<img src="' + EmoteURLLines[i] + '" /></span>'
;
} else {
alert ("The maximum emote (" + EmoteNameLines[i] + ") size is (36x36)");
}
}
//-- Only add events when innerHTML overwrites are done.
var targetSpans = emoteTab[2].querySelectorAll ("span[data-usage]");
for (var J in targetSpans) {
targetSpans[J].addEventListener ("click", appendEmote, false);
}
Where appendEmote is like:
function appendEmote (zEvent) {
//-- this and the parameter are special in event handlers. see the linked doc.
var emoteUsage = this.getAttribute ("data-usage");
shoutdata.value += emoteUsage;
}
WARNINGS:
Your code reuses the same id for several elements. Don't do this, it's invalid. A given ID should occur only once per page.
Every time you use .outerHTML or .innerHTML, you trash any event handlers on the affected nodes. If you use this method beware of that fact.
Make sure you are using Javascript module or not?!
if using js6 modules your html events attributes won't work.
in that case you must bring your function from global scope to module scope. Just add this to your javascript file:
window.functionName= functionName;
example:
<h1 onClick="functionName">some thing</h1>
I think you put the function in the $(document).ready.......
The functions are always provided out the $(document).ready.......
I got this resolved in angular with (click) = "someFuncionName()" in the .html file for the specific component.
Check the casing of your functions.
onclick="sillyLongFunctionName"
and
function sillylongFunctionName() { ...
Are not identical. Hard to spot sometimes!
If the function is not defined when using that function in html, such as onclick = ‘function () ', it means function is in a callback, in my case is 'DOMContentLoaded'.
See that your function is not in a callback function if you are using an external js file.
Removing the callback function would do the trick
(function() { //comment this out
//your code
})(); //comment this out

Categories