I have same form in different pages. In that I have hidden field that value is got from script, on form submit. I'm trigger that script on submit button on click, all submit button ids are different in different pages. how can I need to reuse same script for all pages?
$('#submit').click(function (e) {
// place content into form hidden field.
// I need this code to be reused.
}
});
If the buttons are across multiple pages, it sounds like the script should be in the asset pipeline.
Have a read up, but generally this will mean your script will sit in a javascript file under app/assets/javascripts, and this code will be available to the views.
Therefore, if you have buttons in different views with the id submit, this code will be applied to them all.
Consider changing the selector to a class prefixed with js- (i.e. js-submit) to clarify the targeting. This will save some pain further down the line.
Have a look at this and see how you get on - any questions, let me know.
Using ID's as selectors is in many ways an anti-pattern as it leads to writing "page specific" javascript which leads to duplication as in the end you will want to enhance the behavior of multiple pages or even multiple elements on the same page.
A better approach is to use classes as selectors and think of your javascript as modules that enhance the behaviour of a specific element.
Some key techniques to make your JS suck less:
Place your javascript in app/assets/javascripts.
Use attributes such as data-attributes on the element to pass input to your handlers.
Use .on to delegate handlers instead non-impotent handlers such as .click etc. This is vital if you want your JS to work properly with Turbolinks.
Ensure that your handlers clean up after themselves and do not have unintended side-effects.
Related
I have a "create" form inside a bootstrap's modal. All my Javascript related with that form uses id's and not classes. Now what i want to do is to create a second form that uses the same Javascript (based on id's as said before). Is there any proper way to achieve that? I know that is a very bad practice to use dublicate id's.
No, there is no proper way to ever duplicate the use of id's. Browser behavior for this is a mixed bag and cannot be relied on.
Use classes instead or create dynamic id's for each form.
Not really, no.
When you use IDs, you're telling the browser that the ID is uniquely available, on the page.
If you have two forms with the same IDs, that means you've broken that guarantee.
An example of where this causes problems is document.getElementById( ).
It will grab the first element it finds.
If there are two, it will only get you the first one.
Another issue:
forms with IDs have a habit of being saved to Window, using that ID (this behaviour isn't 100% standard across every browser with more than 2% usage, globally, today, but it's still pretty common).
Ugly solutions I've seen in this space are things like "my-id-1" "my-id-2", et cetera, where you then access them like: document.getElementById("my-id-" + x);
...really not pretty at all...
...alternatively, you can keep the forms in JS, and just attach them to the page, when you want to switch back and forth.
In this way, they can share IDs, so long as they're never attached to the page at the same time.
document.querySelector("#my-form") === form1; // true
form1.parentNode.replaceChild(form2, form1);
document.querySelector("#my-form") === form2; // true
Again, this isn't going to help you with the built-in form and input namespacing, in any meaningful way, but if that's a feature you are 100% ignoring (not a bad thing to do), this will solve those problems.
Alternatively, you could just move to classes and data-attributes (or just attributes), and life would get easier still...
If you insist on using two forms on one 'page' and share ids between them, you have few options to make it work and be relatively 'clean' about it. Not knowing your technology stack, I can't give a completely relevant answer. However you can do something similar to the below:
HTML
<div id="myFormDiv"></div>
JAVASCRIPT
$("#myFormDiv").load(urlToForm);
You would naturally need your forms to be in separate html files for this to work as there is no way you can reliably use ids on multiple elements in one html file.
I need to use JQuery to call vb function through function
$("[id*=Button1]").click();
I have many Button1 on both sub and master.
My JQuery is on sub content page. I wonder if it actually trigger the button1 on both master and sub content page?
Thanks very much!
JQuery will act on the entire rendered HTML. It makes no difference whether the HTML originated in a "master" or a "content" page on the server. If the HTML shows up on the client as a single page (as opposed to say, an <iframe>), JQuery will act on it.
On a side note, you should do your best to keep the "id" property of each HTML element unique. That's the way it's designed to be, and you should do yourself a long-term favor by observing that basic rule.
JQuery has lots and lots of selector rules, and I'm sure you can find some way of applying those selector rules to select the correct button. See http://api.jquery.com/category/selectors/ to get started. But using selectors creatively is much better than using the same id for different elements.
I have a situation where I am working on a large site and what I have been doing is using one main .js file to store all my bound js code that I want to use on elements such as onclick, onchange etc etc.... these are all held within the one onDomReady method.
Now I'm wondering is it such a good idea to have each page have to go over these and "search" for each element to see if it has to bind anything?
..or should I perhaps use more specificity to prevent this such as the main page ID like #page1, #page2 etc OR should I store these in the specifics pages header (I don't really want to do that as I prefer to keep it all in one place).
Just trying to optimize things and get rid of unnecessary overhead! :)
If I understand correctly, you have one js file with all your event handlers.
This file is included i many pages.
So for example, if there are 100 event handlers in the file, each page may be using only 10 of these.
If thats the case, then its not efficinet, because you have lots of
document.getElementBy... that are not fnding the elements, because they belong to a different page, or worse, finding elements with same selector on multile pages that should not be binded to handlers on a specific page.
also, you are adding script to a page that it does not need.
Best to give each page only what it needs, be it in external js or if very little script, in doucment head.
js that you share across pages should be code that you intend to re-use often.
EDIT:
In response to comment:
regarding reducing http requests, you mean the one file will be in cache, for other pages to use? fair enough, that counts as a benefit. Though there are tradeoffs, such as increased memory usage due to javascript that you dont need in page.
using more specific selector will reduce the risk of attaching event handler to wrong element in a page that you did not mean to target, but there is a safer option:
If you insit on sharing one event handler file across pages,
Group them by wrapping them a function, one for each page. call that function from the page.
This way, you dont have to execute a bunch of code that you dont need, and don't risk adding wrong event handlers to simmilar elements accross pages.
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!
I am using partials in Rails combined with jQuery child field templates to dynamically generate forms with multiple nested child attributes. Within these partials is JavaScript that is fired when various events (e.g. onChange) occur in the form, and the code that executes needs to change the DOM for a related but different form element. In this particular case, I'm using it to add multiple sale transactions in a point-of-sale type solution to a particular group of transactions and control what data is collected for each transaction. So, for example:
User clicks on a link that adds 3 new transaction records to the transaction group.
User sets different values in each of those three transaction records, each of which fires an onChange event that calls a JS function that needs to manipulate the DOM for each of the events in different ways. (Example: transaction 1 may be a return, so it changes the text of the transaction from cost to refund, transaction 2 may be for a service, so it changes the taxable status, etc...)
The JS function has to be able to change the DOM for the correct transaction.
My problem is #3 - the DOM elements being modified are not the same as the element generating the event, so I can't use JS this. They are part of a common parent element (i.e. they share a parent <div>), so it may be possible for me to use jQuery parent/child selectors to navigate to the correct element in the DOM. However, even this requires some uniqueness in the div id attributes, and I'm not sure of the best way in Rails to dynamically generate these.
I suppose I could use random values, but this seems bad because it's not truly guaranteed to be unique and just seems like a hack. I suppose I could try to introduce some kind of counter, but this seems to violate the principles of Rails development.
Any guidance is appreciated. Thanks!
Using the current time is recipe for pain and unexplained bugs. I highly recommend you use something like a GUID generator for generating unique IDs.
you could use Time.now as unique-id when creating a new tag
Time.now.to_i
it's not an hack or something that goes against Rails principles ;-)