Template button not working with Javascript - javascript

I've been trying to assign a button to my HTML template, that loads a modal with some further description --- buuuut for some reason I can't actually get the button modifying the css display:none to work at all, ever since making it load content dynamically.
The console reports btn is null but I have tried window.onload as well as DOMContentLoaded to no avail. Is this to do with the dynamic loading, and me perhaps needing to assign id's to individual button?
Codepen here for sake of long code
Any help would be greatly appreciated.

Ok, I think I've solved your problem. Honestly, you really should not present your question/code like this, its really hard to understand and troubleshoot (read this).
Anyway...
Several problems:
You're cloning elements, and as such, all the elements are gonna share their attributes (id,name,etc). This is relevant because each one has a different modal box.
You're trying to access elements (append event Listeners) before such elements have been created. So, your event listeners should be created when you clone each element.
Your modal box was initialized with "display:block", but you comment that you require it to be hidden in the beggining.
I've changed your code, so each element creates a new id (each modal box as well) and adds an event listener to it.
The most relevant changes are:
clone.querySelector(".wineWrapper", "#myBtn").id+=count;
clone.querySelector(".wineWrapper", "#myBtn"+count).onclick= function(e) {
this.nextElementSibling.style.display = "block";
}
clone.querySelector(".close").onclick=function(){
this.parentNode.parentNode.style.display = "none";
}
Codepen
Note: I've destroyed your window listener (I thought it might have been the cause of your problem, initially), so if you need it, comment the answer and I'll make an edit.

Related

Fix Hijacked Event Handling of Click-Events

For a few years now I use user-JavaScript to put additional input buttons and clickable span-elements on pages. Usually I manage to make this work, e.g.
span = document.createElement("span");
span.onclick = __oujs.onClickAddPage;
span.appendChild(document.createTextNode("Add page"));
containingDiv.appendChild(span);
Usually __oujs.onClickAddPage() is called when I click on that span-element.
However, yesterday a site made some changes (apparently I have no clue what they were) that causes clicking on my elements to not cause any events. In the example above __oujs.onClickAddPage() is not called any more. The same is true for input-elements of type "button".
As I'm using Opera, DragonFly shows that my span still is the top-most element in that particular area and, therefore, it should handle the click-event. However, I understand that they include jQuery, which might be part of the misery.
Is there a special technique (maybe with a name that Google knows of) they use to able to do such thing? How do I get the control back and have my code called again? Can I remove some object?
I'm sorry for asking in a rather broad style, but I have no clue what I can look for to fix this myself. Please ask if you need to know something.
I would suggest you this steps:
Create the next function:
function stubFn(event){
console.log('event caught', event); // this will log the click event
__oujs.onClickAddPage.call(event.currentTarget, event); // emulate the onclick behavior
}
Use span.addEventListener('click', stubFn) to add the listener to the element in your code.
If it does not work, then you have to reverse-engineer the script and markup.
I'd suggest to check if there is any element with absolute or fixed position overlapping your span. It can prevent the event propagation.
In general, there are no ways to forbid the elements from userscripts to handle events using inlined handlers.
To get this off my open questions I answer this myself rather than waiting for it to be closed:
I'm sorry, it was my fault. I had a stupid mistake in another user-JavaScript file that affected all sites...
I reinstalled my browser and was thinking about reinstalling my OS, but luckily this isn't necessary.

How to make all buttons(even dynamically created) in an application follow jquery button widget without calling .button() multiple times

I am new to stack overflow and this is my first question. Pardon me for any mistakes.
This question is more generic but i tried to search for an answer but could not find it.
Say i have a page and i am using jquery ui button() widget for all the button. What happens is i have a specific class defined for all the buttons on my page. So i can just specify $('.myButtonClass').button(); but whenever i render partial views which has button again i have to do the same thing in the partial views. Is there any way i can globally specify a transition for button or any element for that matter.
Here is a sample Fiddle which adds buttons on click. But the added buttons are not transitions as button widgets(I do not want to use clone).
http://jsfiddle.net/wjxn8/
$('.clsTest').button().click(function(){
$(this).after('<input type="button" value="Added" class="clsTest"/>');
});
Is this possible without:-
1) Adding the css classes for a button widget manually for all the buttons created.
2) Tracking DOM Changes using Javascript and perform transitions for all the button elements.
Thanks for your help!!!
Since you were looking for something else, why not trigger a custom event when you load partials or whatever:
$('.clsTest').button().click(function(){
$(this).after('<input type="button" value="Added" class="clsTest"/>').trigger('addButtonUI');
});
$(document).bind('addButtonUI',function(){
$('.clsTest').button();
});
http://jsfiddle.net/wJXN8/3/
If you trigger your event and have the document listening for it, then you can do whatever you would like. I could have put in there the ability to add more buttons as well, but this should get the point across.
What you are asking for, some event when a button is added.... you would need to come up with that yourself and trigger it when a button is added. There is this: How to detect new element creation in jQuery? which talks about a specific event that is triggered when new elements are added to the DOM. Haven't tested it, and it looks like it may not work on IE.
I'm not a huge fan of this, but you could poll for new buttons. Check out my fork of your fiddle (that sounds funny):
http://jsfiddle.net/lbstr/Hq97H/
Using your example, this would look like:
setInterval(function(){
$('.clsTest').not('.ui-button').button();
}, 1000);
As I said, I'm not a huge fan of this. I understand the desire for something like $.live here, but I still think its better to initialize your new content when you add it. If you are making an ajax call for new content, just initialize it when you add it to the DOM.
My silly polling code and $.live (which is now deprecated) might be convenient, but they perform terribly. Just my two cents. You know your code better than I do!

how to improve the display for a large form in this situation?

I made a large form, which has many elements. I use javascript(jquery) to make this form have a step-by-step effect. The problem is that, when the page is loading and before the javascript behavior is triggered, the form shows in a mess and all of its element are shown. Any ideas of improving this?
A common term for this behavior is "flash of unstyled content" (which will be useful when searching for solutions). Technically your content has been styled (assuming the page is structured and parsed correctly), but your JavaScript is applying additional style rules and it doesn't do that until the page is loaded.
One technique I regularly use is to set elements to display:none until I am ready to work with them. This isn't always practical, as sometimes the element must be visible and/or have a display box for a particular piece of code to work.
See this article for ideas.
Group all the form elements in a hidden div (style would be display:none) and have a "loading" message show.
When the document has finished loading, trigger some kind of "startup" function using
$(document).ready(function() {
//unhide the form here
})

How can I bind a javascript dialog using Knockout?

I've got a list of data in an observableArray and I want to show it in a javascript dialog window (I'm using jQuery.blockUI if it matters). Unfortunately the dialog seems to come unbound after the page is loaded. The dialog initializes correctly (the data is displayed), but it isn't updating with changes.
There are no Javascript errors and I've moved the binding to after the dialog is generated and added to the document (no effect). I've also tried calling ko.applyBinding on the main div that makes up the dialog but that, for some reason, causes part of the main page to hide (the DOM is there, but they are hidden).
EDIT: I've created a project on jsfiddle that reproduces the problem. The main culprit seems to be wrapping the content of the dialog in a div. If I show the content directly it seems to work (of course I can't do that, the wrappers provide a common style for our dialogs).
I'm recovering from the flu and could easily be missing something obvious, but I've been trying all day and nothing is coming to me. Any ideas?
The problem is that the dialog does not exist in the DOM (despite your calling $(document).append(). You cannot append a div as a child of the document itself). Instead, append the dialog to the body and hide it.
$dlg = $('<div></div>').hide();
$('body').append($dlg);
Works here: http://jsfiddle.net/yL6ds/4/

What is the best practice for presenting a modal view and binding events to it?

In a very common scenario, I have an HTML page with an "Add" button that opens a modal dialog (through Facebox) and asks the user to select an item from the list that appears in it.
The modal dialog gets its HTML snippet from the server asynchronously. I want this snippet to be reusable in many parts of my application so it shouldn't assume that I am using Facebox to load it. The only thing it should do is to trigger the item-selected event whenever the user selects an item in it. But since the snippet is loaded asynchronously, I cannot use $(document).ready. That is, I cannot trigger the event like this:
$(document).ready(function() {
$(".item").click(function() {
$(".items-modal-dialog").trigger("item-selected", this);
});
});
Also, I don't really like using the items-modal-dialog class to identify the enclosing DOM element.
I came up with some solutions to this, and I would like to know if there is some superior pattern that I am missing, because I think this is a very common problem.
Put the script after all the HTML so I am sure that the snippet DOM is loaded (I think this is a bad practice)
Creating a JavaScript function that loads the snippet with Facebox and then binds the events. This way I assume that I am using Facebox and also have to create a function for every type of modal dialog that I create. The only positive side I see in this is that I can create the items-modal-dialog DIV programmatically so I don't have to use a class to identify it.
Using jQuery live to bind the events.
Using an iframe and $(document).ready.
Any suggestions would be greatly appreciated.
Using jQuery's live or delegate function would be the best solution in my opinion.

Categories