Get JavaScript working in a reloaded AJAX box - javascript

When I use AJAX for part of my page, such as a commentbox, in the reloaded box no JavaScript works. e.g. like cutetime or whatever. So I guess I have to reload the cutetime command (in every reload of the commentbox)
It works, but I think I have the cutetime command twice. If I have a confirm box or anything other, I get the confirm box or the add command twice.
I'll try to describe it in one sentence:
I need a way to get JavaScript working in a reloaded AJAX-Box.
P.S.: I think there is a very easy way because everybody uses it :)

If you replace an element anything attached to it is lost.
When using jQuery, you can avoid this issue by using live events. However, this doesn't work for plugins where you don't attach events. In that case you need to call whatever function enables something on your element again when replacing it.

Related

Selenium click event does not trigger angularjs event

I have this page where an angularjs modal-content popup, in there i fill up some fields and click save. After save is initiated, popup should dissapear an event should happen and so on.
My selenium test does all that perfectly except that when it clicks on the save button, popup dissapears but no event is triggered or saved so when i open up the window again everything is empty. I've tried stuff that i know with selenium and it still doesn't work. Can anyone help me out here?
This is the save button:
<button class="save-button" data-ng-click="onSettingsSave()" ng-hide="readOnlyMode || !canSave()">Save</button>
Stuff i've tried:
var saveButton = driver.FindElement(By.CssSelector("button.save-button"));
saveButton.Click();
var saveButton = driver.FindElement(By.XPath(saveXpath));
saveButton.SendKeys(Keys.Enter);
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].focus();",saveButton);
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click();",saveButton );
Try force clicking the element using pure JS:
driver.execute_script("arguments[0].click();", yourElement)
You can't use $ as a shortcut for document.querySelector in a script like that.
driver.ExecuteScript("document.querySelector('#base_element_id div input').click()");
Also this probably won't trigger an onClick in react / angular
Like the OP I have tried everything I can think of to get Selenium to trigger client side javascript events. I've seen some posts across the web of people having partial success where it randomly works; in my case it never works.
Selenium does successfully trigger the browsers primary click action, be it checking a checkbox or pressing a button, but it does not trigger any attached client side javascript events.
Both the native element.Click() method in selenium, and the abstracted ExecuteScript with arguments method of clicking as suggested by #csaladenes have the same result.
The only solution I have found so far is to use pure JS through that same ExecuteScript method; basically avoid the overload with params selenium can embed.
driver.ExecuteScript("$('#base_element_id div input').click()");
In my case I am using the JQuery that is already on my page to make locating the element easier, but any form of truly pure JS should do the same thing.
EDIT:
After some additional testing, it turns out that my "fix" really did nothing. However, performing the same click more than once did cause the client side events to fire.
In my case I am checking a checkbox, so I needed to perform the click 3 times to leave it in the correct state and still have the client side events run.
This is very odd, and definitely needs some more work to figure out where the issue is at that makes this necessary.
Edit 2:
I think I have finally found a solution, and at least partial answer, that does not make me cringe.
It seems as though Selenium has an issue where sometimes it "loses" the focus of the browser. Considering how consistent and repeatable my issue is I don't think focus is the only problem in my case, however the solution works pretty well.
I was able to get the immediate parent of my checkbox, which was a div element, click that first to return focus to the page, then click the checkbox. After that sequence of events the client side events worked correctly.

How to access the DOM after a previous JQuery call

I'm not too familiar with JQuery so please be patient.
Essentially, I have two hyperlinks on a view that runs some JQuery script:
Delete</td>
.
.
Undo
So, each of these links access different parts of the same .js file. My "Delete" does some processing which does a soft delete in the database. The DOM loads and this works fine. I'm using firebug and, when I insert a console.log in .js I can see the id of the Customer I want to delete and the rest is straight forward.
$(container).find('a.deleteCustomer:first').click(function(e) {
console.log("CustomerId " + $(container).find('input[name=Customer_CustomerId]:first').val());
My "Undo", however, accesses the same .js on a different line and console.log in the 'undo' part of .js reveals that it's not being hit.
$(container).find('a.undoCustomer').click(function(e) {
console.log("CustomerId " + $(container).find('input[name=Customer_CustomerId]:first').val());
So, it appears that the DOM is not ready (?). If this is the case, how do I fix this? Do I have to reload the DOM manually? If so, how?
P.S. When I click 'Undo' first nothing seems to happen i.e. I don't get any console.logs in FireBug. However, if I refresh the browser, it runs as expected i.e. the undo jquery about executes.
Without the full code, it is difficult to tell. From your post, title and comments, I see two possible causes.
First, you might be running your code before the DOM is fully ready, then try to wrap all your javascript initialization script in:
$(function() {
... // your code here
});
Second, are you deleting the "input" when you click on delete? If this is the case, it would be normal that "find" does not recover it. The solution to have an undo in such case would be to hide the "input" and show it back when clicking "undo".

jQuery & Chrome - Finding Button Hooks

Using Chrome's developer tools I am trying to determine what jQuery function is hooking an input button on the page for debugging purposes. I usually just keep searching until I find it, but I figured I'd ask this time.
Is there a way to find a jQuery button hook for a specific button in Chrome? I've tried looking through the Event Listener Breakpoints, but can never seem to find the right thing to pause it.
Basically, I need to know what jQuery / Javascript is being executed after the button is clicked.
The hooks are implemented in the application like so:
$('.button_class').click(function (){
$('#button_id').click(function(){
etc...
try this :
$(yourbutton).data('events');
Depending on the number of events/timers on the page this doesn't always work. But you can try "pausing" before clicking the button you want to debug in the JavaScript debug window. That way the debugger will pause on the next line that executes. The thing that occasionally prevents you from using that is if there is a "hover" or mouse move/in/out event tied on an element you have to pass over to get to the button (including the button itself). In that case I just remove those events (if I can) until I get the one I want. The event listener breakpoints would be more ideal but they're sometimes difficult when using jQuery or another library, I've actually put in a feature request to the Chrome Dev Tools team to address this very issue. (allowing you to specify what files are "yours" and only "breaking" in those specific files)
good luck -ck

Running jQuery code retrieved from ajax request, what should I remember to delete?

I understand that it's possible (and I have done it) to return javascript and jQuery code (which of course is javascript... hehe) when doing a jQuery ajax request and running it once it reaches the browser.
What I'm wondering is if I return data, let's say a form, that I present in a dialogcontainer. What should I delete myself once that container is closed by the user and what does jQuery understand by itself to delete.
My idea is to build a page that require very little page reloads and once a user clicks on a button I present them with a form or some other content fetched from the server. Alongside that content the javascript required by that content should also be retrieved. But if the dialog is closet I don't want tons of javascript to be left eating memory. Any way around that?
You could unbind the click event that does the ajax call. If nothing is going to change if they open the dialog again, then this should be fine. While you unbind it you could then change it more a toggle type of thing (Show/Hide), since the javascript and HTML should already be set now.
But it really depends on what you are trying to do. The ajax call will only happen once they click it. It's not going to continually refresh unless you want to. So there should be nothing in the background running except for binding events like click, which is ok.

Facebook JS (FBJS) event listener

So I have looked through most of the facebook questions here and it has absolutely confirmed my thoughts. Facebook development may be among some of the worst I've ever used. I'll avoid my rant for now, but as a note to where I'm coming from: tried php sdk, worked decently out of the box, found out I need to put the functionality on a pages tab, can't iframe on pages tab, have to use FBML (which they are retiring in two months, yet I can't start testing the iframe approach yet)
Anyway, I run into FBJS at this point. It works "good enough" for most things, but for some reason I can't get an event registered to an object (a select box in particular interest) by adding a listener (as per FBJS documentation). I am able to add it directly to the html object and have it work, but this is not desirable and I would really like to know what I consider the proper way to do it, which involves seperation of logic and display.
What I want to happen: click on the select box, make a selection, display the text of the selection in an empty div (later on adding Ajax but one step at a time here)
Code:
<script>
var obj = document.getElementById('select-id');
obj.addEventListener('onchange',my_func);
function my_func(evt){
var inner = document.getElementById('div-id');
inner.setTextValue('hey'); // for testing purposes
}
</script>
The above code doesn't do anything when I make a change to the select box. However, this behaves as planned:
<select name="find_state" id="find_state" onchange="my_func();">
I will be grudgingly using this method as I develop, but would really love to know what I might be doing wrong or if anyone else has this issue? And if anyone has any opinions on the matter I would love to know of some form of facebook development recommendations as applications, pages, and tabs all appear to behave totally different from eachother, yet it seems that they all should be doing the same thing to me? Is there any unified way to develop across all three of these things, or am I missing something?
Thanks in advance, as well as for the past help!
I think it should be:
obj.addEventListener('change',my_func);
(instead of onchange)
Straight from Facebook documentation:
The third parameter [to addEventListener], boolean useCapture is required (it does not have a default value)
That means that you should have:
obj.addEventListener('change', my_func, false);
Use the following html and your events attached with .addEventListener() start to work. This seems to be undocumented "feature".
<select name="find_state" id="find_state" onmousedown="return true;">
This also enables the event to fire first time the user changes the value of select. Otherwise it would fire only on second onchange event.

Categories