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".
Related
I'm just started to work on a new project and I'm not very experienced working with javascript and web programming.
On the website is a form with some checkboxes. My job is to write a javascript file with jquery, which should disable some checkboxes if other checkboxes are checked. The ID, name and other information of the checkbox comes live from a database, so there is no variable for the checkbox in the code directly. I use the ID of the checkboxes to check if a checkbox is checked (is this correct?). I think I already have the right code, because it's working on the web console in the browser.
if ($("#id_865_gen").is(":checked")) {
$("#id_866_gen").prop("disabled", true);
} else {
$("#id_866_gen").prop("disabled", false);
}
I have an index.html file with all the sources for the javascript file. I made a new js file and added it to the index.html (at the bottom of body tag). I think this is working so far because if I make an alert in the js file, I get an alert before the page is loaded. What else I have to consider while including a js file? Of course, my code has to work live. So if a checkbox is checked, another box should be disabled. If the same box is unchecked the other box should be enabled again. Do I have to put the code in a function and start the function in the HTML file?
I don't know what else is important but the project is mainly built with PHP, jquery, backbone (MVC), template library handlebars, and uses ajax. I have never worked with ajax before, but do I have to include some ajax stuff in the code to make it useable live?
I would be very thankful for suggestions or ideas.
Update:
I found the solution for my problem. I added the onchange attribute to the checkbox. Everytime a checkox gets checked or unchecked my function gets triggered.
There's lots to learn when you're coming to javascript from another language. One of the big adjustments is managing when your code will execute.
Generally speaking, for something like this, you want your code to run:
once after the page is ready and
every time the inputs change.
Since you're running your code multiple times, putting it in a method makes sense
function updateBoxes() {
if ($("#id_865_gen").is(":checked")) {
$("#id_866_gen").prop("disabled", true);
} else {
$("#id_866_gen").prop("disabled", false);
}
}
Just putting this function in a script does not execute the function - you still need to make it execute at the right times. To make it execute after page load can be really different depending on the app. It could be as simple as adding updateBoxes() in a script tag, but usually you would need to wait for some sort of rendering. Without knowing more about your app, the following is a good guess:
$(function() {
// this code will execute when jquery thinks your DOM is loaded
updateBoxes(); // do the initial check
$("#id_865_gen").change(updateBoxes); // this will run the check when your input changes value
});
Additional Concerns
If this doesn't work, it's likely because the checkboxes are not in the DOM yet when your code runs. They may be added by a framework. If they are added by backbone, you could look around for the backbone render method that adds your html. Then you'd need to execute updateBoxes after the render.
The jquery selectors you are using to find your inputs look like they might change. It may be safer to find your inputs using the name attribute, or possibly a class or some other way. For example:
$("input[name='blahblah']")
would select the input <input type="checkbox" name="blahblah"> without using any id.
You should put your code inside
$( document ).ready(function() {
// your code
});
Your code will only execute when the page Document Object Model (DOM) is ready
reference: https://learn.jquery.com/using-jquery-core/document-ready/
On a Drupal page a button element gets focused before the page has been loaded completely.
I'm trying to locate where this happens but unfortunately I wasn't able to track down the script. I'm using Chrome and tried to set a break-point but no luck. Further I tried to locate the line where this happens with the profiler. Also no luck so far. Do anyone know how to debug this properly? Any help is much appreciated. Thanks.
When I replace with a div, the issue is gone, so its related to the button element itself (no class nor element id)
What you want to do is right-click on the element you think is going to trigger the event and on the context menu click inspect. The chrome developer bar will open and you should see the html tag for that element you clicked on. On this bar there are two section: one with html tags and the others with tabs named Style, Computed, Event Listeners, DOM Breakpoints and Properties.
The one you want is Event Listeners, so click on that tab. Now we see all the listener for that html element grouped event type. When open a group you should see the list of element on left with a link to that specific line of code for the event handler. If you click on the link, you will be switch to the file where the code is.
Now the hard part. As you will see in some web pages, there are a lot of handlers. Also the use of libraries like JQuery make it harder to find the piece of code that really does something and the code is probably minified.
So let's supposed you found the code that you want to debug. Often it's in a format like
var namespace = {
...
handler: function(event) {
/* Event handler code here */
},
...
In a case like that, this might work
(function () {
var old_handler = namespace.handler;
namespace.handler = function () {
debugger; // this make a breakpoint here and stops
old_handler.apply(this, arguments);
}
})();
When all fails, make a local copy of the file that contains the code and setup an Apache server so that you proxy the web site except for that file which you will reference locally. Then you can modify it however you like. This won't work on https web site.
at the moment I am working on replacing pop-up on a website I inherited. Those pop-ups used modal dialogs, which are on their way out and even were dropped by pop-up blockers on client side.
My approach was loading the HTML of the pop-up into an div on the main site, while hiding the original content, then emptying the div and switch the main content back to visible.
This works so fa, but the loaded content has scripts that run to check if someone is already using that function. The first time you use that function all is fine. The script runs, sees noone is using the function, I go through the stuff, empty the div and return to the main content. When trying to use the function a second time the script to still run (console shows the requests), even though I emptied the div, prompting the eternal "please wait till other user is finished" lines, since the first script is still checking for use, signalling the second script "I'm buisy".
So right now, I am looking for a way to stop the first script, since removing the HTML-content doesn't suffice it seems.
The code so far:
$("#dialog").load("stuffToLoad.htm",function(response, status)
{
if(status=="success"){
$(".fullTable").toggle();
$("#dialog").toggle();
};
})
to get the content. The in-use-check is done with a post-request, that is repeated by a window.setTimeout every second. That part seems to still run.
When everything is done, or the user runs into an error I tried:
function returnToProcVal()
{
$("#dialog").html("");
$("#dialog").toggle();
$(".fullTable").toggle();
}
to delete the function content and scripts, to stop them running. While the DOM says all is gone I can see the post requests being repeated in the console.
I'd be grateful for any pointer or perhaps even better methods to get the function running and returning the user, without the use of pop-ups.
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.
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.