Too much recursion in JavaScript - javascript

I have this JavaScript which opens new page:
$(document).ready(function () {
//$('a[id$="lnkHidden"]').trigger("click"); // Not sure if this is actually necessary
$('table[id$="dataTable"]').find("tbody").on("click", "tr", function () {
$(this).find('a[id$="lnkHidden"]').trigger("click");
});
});
This is the button which is called by the JS script:
<h:commandLink id="lnkHidden" action="#{bean.pageRedirect}" style="text-decoration:none; color:white; display:none">
</h:commandLink>
After I click on a table row I get this error message:
too much recursion [Break On This Error] ...,c=l.length;c--;)(f=l[c])&&(v[d[c]]=!(y[d[c]]=f));if(i){if(o||e){if(o){for(l=‌​[],...
Can you help me to fix this?

You can cut the infinite loop with those changes from your original code
add a second argument to trigger. The call becomes .trigger("click", [ true ])
name arguments in the event handler : function(event, simulated)
use the simulated argument which is set to true from the trigger : simulated || $(this).find('a[id$="lnkHidden"]').trigger("click", [ true ]);
However that event triggering and that kind of selectors are not recommended.

Instead of triggering synthetic click events, you could just change the current URL directly:
$(document).ready(function () {
$('table[id$="dataTable"]').find("tbody").on("click", "tr", function () {
var links = $(this).find('a[id$="lnkHidden"]');
if(links.length && links[0].href) {
window.location.href = links[0].href;
}
});
});

Related

IntroJS callback function upon skip or done?

I'm using introjs to build a tour of my application. I've searched in quite a few places online and through the documentation but can't seem to find anywhere a method of how to run a function upon skipping or clicking done on the tour. I'm trying to make it so a cookie is stored and the tour isn't run again until a user requests it or a new user comes to the site. Any help would be great, thanks!
$(function(){
var introguide = introJs();
introguide.setOptions({
showProgress: true,
steps: [
{ hidden }
]
});
introguide.start();
});
This code allows to store the tour info
var introguide = introJs();
window.addEventListener('load', function () {
var doneTour = localStorage.getItem('MyTour') === 'Completed';
if (doneTour) {
return;
}
else {
introguide.start()
introguide.oncomplete(function () {
localStorage.setItem('MyTour', 'Completed');
});
introguide.onexit(function () {
localStorage.setItem('MyTour', 'Completed');
});
}
});
Yes, there is a way but with some caveats.
First, after intro.js is loaded you will have a global called introJs with a property fn (standard jquery plug-in approach).
By setting a function using the oncomplete() function under introJS.fn, you can perform some actions when the user hits the 'Done' button.
Here's an example that just displays a console message:
introJs.fn.oncomplete(function() { console.log("Finished"); });
This works as expected. You can put this in a script anytime after the intro.js library is included.
The 'skip' button functionality, however, will only call the 'oncomplete' handler if you are on the last step. The author of the code views that as not complete and so doesn't run that code as you can see by this extract from the code:
skipTooltipButton.onclick = function() {
if (self._introItems.length - 1 == self._currentStep && typeof (self._introCompleteCallback) === 'function') {
self._introCompleteCallback.call(self);
}
_exitIntro.call(self, self._targetElement);
};
This basically says it must be at the last step for this to consider calling the complete callback.
Of course, you could fork the code and remove the restriction. I would suggest if you are going to do that, create a _introSkipCallback in a fashion similar to _introlCompleteCallback and invoke that unless on last step where you might invoke both functions if present.
Hope this helps.
Use oncomplete for functions after 'Done' is clicked
Use onexit for functions after 'Skip' is clicked
Bonus function: onchange will log each step, this can be used to call functions on a particular step
document.getElementById('startButton').onclick = function() {
// log each step
introJs().onchange(function(targetElement) {
console.log(this._currentStep)
if (this._currentStep === 3){
stepThreeFunc()
}
}).start()
// clicking 'Done'
.oncomplete(function(){
someFunc()
})
// clicking 'Skip'
.onexit(function(){
someOtherFunc()
});
};
I've noticed that onexit will be called when you click the done button (which is skip until the last step). onexit does not appear to bind this to the introjs object, so I was able to solve the issue of having onexit called when the walkthrough was completed like this:
// during setup
introJs.oncomplete(handleOnComplete);
introJs.onexit(() => handleOnExit(introJs));
function handleOnComplete() {
console.log(this._currentStep); // this is bound to the introJs object
}
function handleOnExit(introJs) {
const currentStep = introJs._currentStep;
if (currentStep < introJs._options.steps.length) {
doSomethingOnSkip();
}
};
I was going to add a comment, but my rep is too low. I didn't want to answer because I haven't actually tested this, but in version 2.5.0 (maybe previous versions too), there is the onexit function, which I believe is supposed to handle interrupts as well as clicking done at the end. Did you try that?
if ($(".introjs-skipbutton").is(":visible")) {
$( document ).on('click', '.introjs-skipbutton', function(event) {
event.stopPropagation();
event.stopImmediatePropagation();
self.exitTourguide();
});
}
I am using introJS tool in my application to give tour guide information of my application.
I used some functions for handling it dynamically. Here stepsData sending in an array format.
var intro = introJs();
intro.setOptions( {
'nextLabel': 'Next >',
'prevLabel': '< Back',
'tooltipPosition': 'right',
steps: this.stepsData,
showBullets: false,
showButtons: true,
exitOnOverlayClick: false,
keyboardNavigation: true,
} );
hope it will help for handling skip button action.
var self = this; intro.start().onbeforechange( function() { /* skip action*/
if ( $( ".introjs-skipbutton" ).is( ":visible" ) ) {
$( document ).on( 'click', '.introjs-skipbutton', function( event ) {
self.exitTourguide();
});
}
});
skip and done action handling.
/Done click action/
intro.oncomplete( function(){ if ( $( ".introjs-skipbutton" ).is( ":visible" ) ) { $( document ).on( 'click', '.introjs-skipbutton', function( event ) { event.stopPropagation(); event.stopImmediatePropagation(); self.exitTourguide(); }); } });
/* clicking 'Skip' action */ intro.onexit(function(){ if ( $( ".introjs-skipbutton" ).is( ":visible" ) ) { $( document ).on( 'click', '.introjs-skipbutton', function( event ) { event.stopPropagation(); event.stopImmediatePropagation(); self.exitTourguide(); }); } });

javascript action to trigger an event

I've been working on this for a while. But I think it is going to be difficult for me to simply it for this question.
I have this object. It is a child to an other object.
The child object has an 'action' attribute which executes a fn();
On a mouse click I fire off the action I can see I am executing fn() with no problems.
I want fn() to trigger an event of the parent object.
$('#par).on('trgr.obj', fn(e, dta) { alert('success'); });
$('#par').obj({
chi: { action: fn(dta) {
console.log("doing okay so far");
// Here is where I'm trying to trigger trgr.obj event
// this is what I have so far.
var inst = $.obj.reference(dta.reference);
var objT = inst.get_node(dta.reference);
inst.trgr(
objT, { type: "default" }, "last"
, function (newDta) {
setTimeout(function () { inst.edit(newDta); }, 0);
}
);
}}
});
How does action trigger event 'trgr.obj'?
Any help appreciated.
Are you looking for jQuery to trigger a custom event?
Try $('#par').trigger('trgr.obj')
http://api.jquery.com/on/

Difficulty attaching event handler to dynamically generated modal window elements

This question is an ongoing learning / discovery of these three questions. This issue for me started here:
First Post
Second Post
Now this post is regarding #StephenMuecke post about attaching the event handler dynamically. This was new to me so I had to read up but now I see that it does make sense.
Well after reading documentation and numerous SO posts I still can't seem to get the click event handler to fire??
This time I decided to take a different approach. I created a jsfiddle demonstrating the problem. http://jsfiddle.net/ramjet/93nqs040/17/
However the jsfiddle I had to change somewhat from reality to get it to work within their framework. Below is the actual code.
Parent Window script that launches modal...the alert Bound does fire.
<script>
$(document).ready(function ()
{
$("#new").click(function (e)
{
e.preventDefault();
var ischanging = false;
var financierid = 0;
var detailsWindow = $("#window").data("kendoWindow");
if (!detailsWindow)
{
// create a new window, if there is none on the page
detailsWindow = $("#window")
// set its content to 'loading...' until the partial is loaded
.html("Loading...")
.kendoWindow(
{
modal: true,
width: "800px",
height: "400px",
title: "#T("...")",
actions: ["Close"],
content:
{
url: "#Html.Raw(Url.Action("ActionName", "Controller"))",
data: { financierId: financierid, isChanging: ischanging }
}
})
.data("kendoWindow").bind('refresh', function (e)
{
alert('Bound');
$('document').on("click", "#save", function () { alert("i work");});
}).center();
}
detailsWindow.open();
});
</script>
The modal full html I didn't think was needed but if it is I will update it. This is just the element I am trying to dynamically bind to.
<input type="button" id="save" style="margin-right:10px;" value="Save Record" />
document doesn't need quotes:
$(document).on("click", "#save", function () { alert("i work");});
"document" searches for an element of document, not the actual document
$("document").length; //0
$(document).length; //1

Linking button to jQuery through service

I have a small problem that should be very easy to overcome. For some reason I cant work this out. So the problem is I cannot get a button to link to some jquery. My set-up is as follows (showing the relevant code):
Default.aspx
jQuery:
function getContent() {
var data = {
numberID: 1
};
$.jsonAspNet("ContentService.asmx", "GetContent", data,
function (result) {
$('#content').html(result);
});
}
jQuery(document).ready(function () {
getContent();
});
HTML:
<div id="content"></div>
ContentService.vb
<WebMethod()> _
Public Function GetContent(number As Integer) As String
Dim sb = New StringBuilder
sb.AppendLine("<table>")
sb.AppendLine("<tr>")
sb.AppendLine("<td class='ui-widget-header ui-corner-all'>Number</td>")
sb.AppendLine("</tr>")
sb.AppendLine("<tr>")
sb.AppendLine("<td>" & number & "</td>")
sb.AppendLine("<td><a href='#' id='test' class='fg-button ui-state-default ui-corner-all'><img src='" & Context.Request.ApplicationPath & "/images/spacer.gif' class='ui-icon ui-icon-pencil' /></a></td>")
sb.AppendLine("</tr>")
sb.AppendLine("</table>")
Return sb.ToString
End Function
So that's the basics of what I have everything works but I'm not sure how to get the a button (id='test') to get linked to some jQuery. I want it to be pressed and bring up a popup.
I have tried to put the jQuery on default.aspx but this doesn't seem to work unless the button is place in the HTML on that page.
$('#test').unbind('click').click(function () {
alert('Working');
});
I'm sure this is easy to do, but I have been trying for a while and cannot seem to get it to work.
Is the problem that you're trying to bind to the element that ISN'T in existance yet?
are you calling the $('#test').unbind('click').click(function () {
alert('Working');
}); BEFORE the service has returned?
$('#test').on('click', function () {
alert('Working');
});
This will bind the event to the '#test' element once it has been inserted in to the DOM.
As you load the content via ajax, you have to bind to $('#content'). Like this:
$(function () {
$('#content').on('click', '#test', function () {
e.preventDefault(); // if a default action is not needed needed
alert('Working');
});
});
I guess this is about not preventing the default behaviour of the A href tag. Now it will probably link to '#' instead of firing the onclick event.
$('#test').on('click', function (e) {
alert('Working');
e.preventDefault();
});
You could try to wrap this in a document ready, or eventually use the .on binder from jQuery, since it's dynamic content.
Solved
It was a very small thing that caused this. The code to fix this problem is as follows:
$('#test').unbind('click').click(test);
This needed to go inside the function with the json so:
function getContent() {
var data = {
numberID: 1
};
$.jsonAspNet("ContentService.asmx", "GetContent", data,
function (result) {
$('#content').html(result);
$('#test').unbind('click').click(test);
});
}
Thank you to everyone that has tried to help me.

jQuery simulate click

I want to trigger a function when the page is loaded. There are many ways to do this.
However, when I add $('#button').click in front of my function, then the getType function is not recognized. For example:
$('#button').click(function getType(id) {
//...some code
});
error: getType is not defined
What am I doing wrong?
Just to clarify, in this case I cannot use an anonymous function. Also, it does not matter to me whether I use $(document).ready or $(window).bind("load", function(), but using these I still get the “getType is not defined” error.
You either have to make your function anonymous:
$('#button').click(function() {
//...some code
});
Or pass the function itself:
function getType() {
//...some code
}
$('#button').click(getType);
If you just want to trigger a click, call .click():
$('#button').click();
Also, your id parameter won't be the element's id. It'll be the click event object. To get the element's id, you can refer to the clicked element using this:
$('#button').click(function() {
var id = this.id;
});
I suggest you read a few JavaScript and jQuery tutorials (in that order).
You are using the inline notation so, you should use an anonymous function (no name function)
your code should be:
$('#button').click(function() {
// do your stuff here
}
);
Beside that, as the titles says, you need to simulate a click event, right ? if so you better use something like:
$('#button').on('click', function() {
alert($(this).text());
});
// somewhere when you want to simulate the click you call the trigger function
$('#button').trigger('click');
see documentation here
$('#button').click(function getType(id) {
//...some code
});
Should be:
$('#button').click(function() {
[...] code here
}
);
function() { } is a callback with what code have to do when I click some element.
If you have the getType function, you can pass it as a callback:
$('#button').click(getType);
If you want to trigger a funcion, when page load, you can do this:
$('#button').trigger('click');
Or
function getType() {
[...] code here
}
getType();
Use .trigger( event [, extraParameters ] ) on the element.
extraParameters
Type: Array or PlainObject
Additional parameters to pass along to the event handler.
The added benefit is that you can pass data to the event handler, whereas if you use .click(), you cannot assign data to the object.
$("#target").trigger('click');
If you're looking to use the extraParameters:
$( "#foo" ).on( "custom", function( event, param1, param2 ) {
alert( param1 + "\n" + param2 );
});
$( "#foo").trigger( "custom", [ "Custom", "Event" ] );
The .click() method requires a callback function. So you can do something like this instead:
//Define your function somewhere else
function getType(id) {
//...some code
}
$('#button').click(function() {
getType($(this).attr('id')); //Execute it when its clicked.
});
Try this, the id can not be passed the way you do:
$('#button').click(function() {
var id = this.id;
//...some code
});

Categories