Multiple event handlers created when reopening fancyBox - fancybox

On the calling page, I bind my fancyBox using an href, like so:
<a id="myId" href="myContent.cfm">Click me</a>
<script>
$(document).ready(function(){
$('a#myId').fancybox({
// my initialization params
});
});
</script>
In myContent.cfm, a default "filter" is built, which has add and delete buttons. Something like this:
<div id="fd_0" class="eachFilter blank">
<select name="filterBy" class="fl filterBy">
<option selected="selected">-- Add a Filter --</option>
<!--- add more options --->
</select>
<button type="button" class="addFilter default" title="Add a filter to the current filter set.">+</button>
<button type="button" class="deleteThisFilter default" title="Delete this filter from the current filter set.">-</button>
</div>
When the addFilter button is clicked, a new "default" filter is added to the dom after the filter that was clicked, using consecutive ids. Conversely, clicking the deleteFilter button causes that filter to be deleted and all remaining filters to have their ids renumbered; with the exception that there must be one filter remaining. My original code used .live() to attach event handlers to the newly created elements, like so:
$('.addFilter).live('click', function(){
// get number of existing filters
// create new blank filter
// add to the dom after the filter whose button was just clicked
});
$('.deleteThisFilter).live('click', function(){
// if there is more than one existing filter, use .remove() to remove the parent .eachFilter div
// renumber the existing filter ids consecutively
});
After the user has created all the "filters" they need, they may either "apply" them, which closes the fancybox and reloads a grid with the new, filtered parameters, or simply cancel and close the fancybox.
This all works fine the first time, and on reopening the fancybox, the initial blank filter's add button works as expected. However, after adding a second filter, any filter that was added to the dom has multiple event handlers added to the addFilter and deleteFilter buttons. If I added one filter the first time, then return to the fancybox the second time, then add a filter by clicking on the default filter's add button, then click on the newly created filters add button, two more filters are added. If I close, reopen the fancybox a second time, add a filter, and click on that filters add button, three more filters are added.
So here's what I've tried so far:
1) Changing the .live() calls to
$(document).on('click', 'addFilter', function(){ // add my filter code});
2) Putting the code to create the filters into a function, which at the end uses .bind() to add the event handlers to the newly created filters; followed by using
$('.addFilter').unbind('click', fnCreateMyFilter())
on closing the fancybox.
3) Using .live() ONLY on the newly created filter elements, and a regular click handler on the default element
4) Upgrading jQuery to 1.8.3 from our current version
5) Calling .remove() on all elements inside the fancybox .onClosed function (although I was under the impression that closing fancybox does actually remove the elements from the dom).
Any thoughts?

As always, it's the most obvious thing which isn't readily apparent. Moving the .js code out of the popup into its own file fixed the problem, which is something that I had intended to do after getting all the code to work.

I was using a combination of Fancybox2 http://fancyapps.com/fancybox/ and Noty popups http://needim.github.com/noty/ and having a similar problem.
I loaded a product edit form into a fancybox via ajax using class='fancybox.ajax' in the href link.
Everything saved fine when I clicked my save button until I reloaded another (or the same) product in fancybox.
I was using this code to trigger my save buttons:
$(document).on("click",".save_product_button",function(){
... post to ajax file to save info
});
Using that triggered multiple noty popups and saves (once for each time I'd loaded a fancybox since refreshing), because the save button was already loaded in the document model that many times. (I guess??)
But when I changed my on() to the save button's immediate parent, all my problems went away.
$("#productBox").on("click",".save_product_button",function(){
... post to ajax file to save info
});
Everything saved once from then on.
Plus, that should make the code a tad quicker.
Hope this helps someone not waste half a day like I just did.

Related

Onclick is triggered twice after changing the value manually in jquery

I have changed the onclick(for li element) using the inspect element. In onClick I have called a function it was invoked twice.
Here is my sample code
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
function a(val)
{
alert(val);
}
</script>
</head>
<body>
<ul>
<li onClick="a(1)"> 1 </li>
</ul>
</body>
</html>
I assume you are using Google Chrome. This is a bug/problem with the Inspect Element feature.
If you use Inspect Element to change or remove the onclick handler of an element, it doesn't work as expected. The new Javascript code is ADDED as a new handler to the existing list of the onclick handlers, rather than replacing the existing handler of the old code.
This is incorrect and a bug, because Inspect Element allows user to replace the code, and it looks like it's replaced - but hidden from the user, it's actually appended as a new handler - so the result is not what it would seem like.
If the code or the onclick attribute is deleted, the JS code is still executed as it remains registered as a handler.
This is highly misleading and makes the Inspect Element nearly useless for debugging event handler JS bugs.
To try it out:
Right-click any element and click Inspect element (or Inspect).
Add or modify its onclick handler to alert('stack');.
Again, modify the onclick handler to alert('overflow');.
Now, click the element to fire the handler.
You may think that you will just get one alert with the word overflow. But you will actually get two alerts, one with stack and another with overflow. This means the code alert('stack'); is still in the handler, even though it's not visible on the DOM tree.
There is no permanent fix for this problem. The following workarounds may help. Reporting it to Google may encourage them to fix it in a future version of the browser.
Workarounds
Use Mozilla Firefox. The behavior of Inspect Element in Firefox is as expected - the browser really replaces the old handler instead of adding a new handler to the list.
If you need to use Google Chrome, do the following:
With the element selected in the Developer Tools window's Elements tab, click the Event Listeners tab (this is on the other pane which may appear below or on the right side).
Make sure that the Ancestors checkbox is unchecked.
If your element already has an onclick handler, you should be able to see a click event handler listed. If you don't see anything, try clicking Refresh button (next to Ancestors checkbox).
If you still don't see it, close the Developer Tools and right-click the element in the page and click Inspect to open it again.
Click the rightward arrow next to the click event handler. It will open and you will get a list of all the registered handlers (listed with the tag#id.class notation).
In the DOM tree (top pane or left pane), double-click and edit the onclick handler code and confirm it by pressing Enter.
In the Event Listeners tab, click Refresh button again. You will see that a new handler has been added.
Hover over the handlers and you will see a Remove button appearing on each of them. Click this button on each handler until only one remains.
The order doesn't matter - you can start at the bottom, the top or even go randomly - internally, the Remove button removes handlers in the order they were added.
If there's only one handler left, you can be sure that's your latest code - it doesn't matter which handler was left.
To change the onclick code again, repeat steps 5 to 7.
I notice this bug as well. While working on my project this week with ajax calls.
Having a button like this:
<button id="mybutton" type="button" onclick="sendMessage('12345')"></button>
If you go into the inspector and edit '12345' to 'abcde'. Then clicking the button will cause the button to fire twice. Once as '12345' and once as 'abcde'.
To solve the double sending you can attach the event listener with an ID rather than using html's onclick. So instead use something like:
$("#mybutton").click(function(){
sendMessage('12345');
});
This will not suffer the same double sending bug.
However, anything you edit on the inspector will not do anything now, it will be disregarded.

Enabling button on any value change in JSF form

I have multiple fields including text,checkbok box, drop-down etc in jsf form, which is showing values from DB.I would like the submit button to be disabled by default and to only be clickable if the user made changes to any of the fields in the form. Please help !!
For a simple form you can use this jQuery plugin that a user mentioned here.
Edit:
The plugin is quite simple to use, and powerful, because for example you will have your buttons disabled again if you revert changes inside an input field.
Just make sure that you include the js file:
<h:outputScript name="path/jquery.are-you-sure.js"/>
And for using it, you have to add the line:
$('#idofyourform').areYouSure();
After that, for enabling and disabling submit buttons you have to add:
//All disabled by default
$('#idofyourform').find('button[type="submit"]').attr('disabled', 'disabled');
//Enabled all when there are changes
$('#idofyourform').bind('dirty.areYouSure', function () {
$(this).find('button[type="submit"]').removeAttr('disabled');
});
//Disable all when there aren't changes
$('#idofyourform').bind('clean.areYouSure', function () {
$(this).find('button[type="submit"]').attr('disabled', 'disabled');
});
Both codes inside your document ready function.
Note that I used button[type="submit"], which is what p:commandButton renders by default. You can use input if it's your case.
NOTE: This plugin also adds an extra functionality the OP didn't ask for (the dialog check when you navigate without saving changes). You can disable this if you want by doing:
$('#idofyourform').areYouSure( {'silent':true} );
Not tested, but I would simply use something like this :
$(document).ready(function() {
$('#formId input[type="submit"]').attr('disabled','disabled');
$('#formId').change(function(){ $('#formId input[type="submit"]').removeAttr('disabled'); });
});
If you don't use any jQuery functions already in the view (any PrimeFaces ajax buttons for example), you might need to add :
<h:outputScript library="primefaces" name="jquery/jquery.js" />

How to reset form after form submitting?

I have one search form with search button and some field, when I put value in form field and click on search button then come back on form by clicking on link(modify search form) then form value does not reset...Please check it here(http://dev.viawebgroup.com/search/)
Thanks
Try this:
<script>
function test(){
var input = document.getElementById('search');
input.value = '';
};
</script>
Add onload to the body:
<button onclick="test()">Clear</button>
Add id to input field:
<input type="text" id="search">
Fatal flaw rests form befor data is sent
The simplest way I found is
onsubmit="this.reset()"
Just put this in the form tag and all's well, simple yet efective.
I someone wanted a button excluesivly for form reset I would use onclick and write the reset in a function like this.
function clform()
{
documentgetElementById('myform').reset();
}
The first is tried and true, the second I just wrote but should work.
The function works well used in a onbeforeunload event in the body.
I have been working on this problem my self because the page I wrote is dynamically updated and was keeping form data when back button of browser was used. I also used PHP to reload the page after submission and onfocus to reload the page when form is selected so input is on a fresh page and not the dynamically updated page.

CKEditor - Inserts Blank Content into the Database on First Click on the Save Button

Since this morning am trying to make this work, but failed. The CKEditor appears perfectly into the textarea, but when I try to save the content on the first mouse click on the save button, it doesn't inserts the content into the database. When I trigger my second click on save button again on the same content then its does insert into the database.
Textarea
<textarea class="txtPageContent" name="pageContent" id="pageContent"></textarea>
JavaScript Included
<script type="text/javascript" src="plugins/ckeditor/ckeditor.js"></script>
<script type="text/javascript">
CKEDITOR.replace( 'pageContent' );
</script>
Plead do let me know for more informations.
Call CKEDITOR.instances.pageContent.updateElement() first (see docs).
This will synchronize your textarea and your editor in terms of the content. Then, your AJAX request should serialize correct data. Just make sure that updateElement() call is before you gather data.
i have tried this. it works.
function returnToSubmit() {
$('#ckeditor').val(CKEDITOR.instances['ckeditor'].getData();
}
Also take a look into this SO

rails 3 - Add a Button that won't submit a form

I am trying to add a few "next" and "back" buttons to a form. The Idea is to divide the filling-out process into several steps and with these buttons, the div of the current step gets hidden and the next resp. previous step is displayed.
My Problem is that when I add buttons in the following way...
<button class="proceed_button" id="loan_information">Proceed</button>
<button class="cancel_button" id="loan_information">Cancel</button>
... they submit the form.
Is every button inside a form-tag considered to be a submit-button?
If so, how can I change this behavior?
If not, why are they doing it then?
Ok, the solution is that the button needs a type.
<button type="button" class="proceed_button" id="loan_information">Proceed</button>
<button type="button" class="cancel_button" id="loan_information">Cancel</button>
Like this, it won't submit the form anymore.
According to http://w3schools.com/html5/att_button_type.asp the default type is depending on the browser, so you should always specify the type.
I'm not sure that you want a button, maybe you want it to look like a button. Either way, refer to this post: rails 3: display link as button?
Once you have your button, you'll need to update your javascript to prevent anything from happening when it's clicked (assuming you have jquery). It's still nice to provide a real fallback for those dinosaurs without js, so assuming your proceed button submits for users without js, for those with js you'd do something like:
$('#proceed_button').click(function(e) { e.preventDefault(); // Show and hide your divs here });
Also note that in your posted code you should not have two buttons with the same id, your ids and classes look swapped.