selectors for action elements: class vs custom HTML5 attribute - javascript

A kinda of subjective issue I think. I have an action element and want to refer to it in the code for binding event I'm trying to choose between to ways of declaring such things:
1) the first option is more simple and straightforward in declaring and use:
<a class="play">Play</a>
('#menu .play').bind('click',...)
2) but the second option shows explicitly the purpose of the attribute
<a data-action="play">Play</a>
('#menu [data-action="play"]').bind('click',...)
Which should I choose (I'm not going to use selectors in CSS, only in JS code)?

If you're not using it for styles, I'd lean towards data-action="play" because it better describes the purpose (the action is play).
However, if you are planning on getting multiple elements like this and looping over them, I would either use class="play", because then you're treating them like a class of the same kind of thing again.. or use both, class for getting them and data-action to verify, can't go wrong there.

Related

Change hidden value and submit form with onclick for href

I currently have multiple links acting as buttons, and each link has a different form with a hidden value storing the ID. The problem is that I'm using bootstrap and it's messing up the styling, and the only way around it seems to be having a single hidden value that will update with the selected ID once a link is clicked.
I currently have <a href="javascript:;" class="list-group-item list-group-item-default" onclick="parentNode.submit();"> as the link, and I've been looking around for a way to edit a value too. Unfortunately, it appears everyone seriously recommends not going down the javascript route and using jQuery instead, but I'm not quite sure how I'd link the two.
I've found this link which has a good example of how to do the jQuery to change values, though I could do with a bit of help putting it together, since I'm not sure if it's possible to use the jQuery code to submit the form as well, or if I should make a separate javascript function to run the jQuery then submit the form.
If there's actually nothing wrong with the javascript route, it looks like this would do the job, just want to check first.
First of all, jQuery actually IS Javascript, it's merely an extention - if you're using jQuery, you are writing Javascript. jQuery just has become so popular that some people mix this up.
You can pass the form you want to be submitted as a parameter to the function like this:
function handleClickAction(formElement) {
// change values
formElement.submit();
}
With your given markup, you could call it like this:
<a href="javascript:;" class="list-group-item list-group-item-default" onclick="handleClickAction(parentNode);">
Of course, you can add more parameters to the function call if you need to know what value to change and/or how.
In general, the solution you are using isn't very elegant and it's redundant, but if you want to go with inline code, this might be an appropriate way :)
So do it in one line if you are doing inline events
onclick="document.formName.elementName.value='foo';this.form.submit();"
Bootstrap's plugins rely on jQuery to function. That being the case, you'll see greater functionality (beyond just css styling) when you add jQuery to a bootstrap design. That being the case, here is a jQuery version which does what you are asking for:
NOTE: revised to answer subsequent questions in the comments. Now uses the index of the element clicked instead of the id, which is what the original post requested, since there is no id attribute assigned to the links.
jQuery(function($) {
$('#form_of_forms a.list-group-item').click(function(e) {
e.preventDefault();
$('#dynamic_form_id').val($(this).index()+1);
$('#form_of_forms').submit();
});
});
Additionally, replace href="javascript:;" with href="#" and remove the onclick="..." attribute from each link entirely.

Is there any proper way to reuse Id's?

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.

How should I avoid duplicate IDs when writing JS-heavy web apps?

Specifically, I have areas of my (heavily JS) web page that contain lists of HTML elements and for simplicity let's assume there are just two lists: A and B. Let's also say When I click on the first item in list A (A1) something happens to the first item in list B (B1).
I gave each element in list A a common HTML class and an ID (like <li class='listAmember' id='1'>...</li>). I set up elements in list B in a similar way (like <li class='listBmember' id='1'>). Then I attached some click handlers (using jQuery in this case) and ran into problems with duplicate IDs, even if I qualified my jQuery id-based selectors with the class name, like this
$('.listAmember#1').click(function(){});
I've realised that this is bad practice (IDs are supposed to be unique in the document!) but I'm unsure what good alternatives there are.
I don't really want to create IDs like listAmember-1 because if I have, say, a lookup-table in my JS code that is keyed on the numeric ID, I'd need to parse out the 1 from that ID string to get the 'real' ID. (And I would still need to add a class like listAmember for styling purposes and that seems unnecessarily repetitious?) All in all that seems clumsy and I assume there are better ways?
As Florent says, I would try and avoid IDs altogether. One convention is to use class names like js-list-a to signify it's a class intended for JavaScript usage only. Then you're free to start using the index of the li within the list.
Also, you could just set one click handler on the list and use event delegation .
A combination of these ideas means you won't have to touch IDs.
For Unified ID's maybe in a System that has external Libarys in use, you should always attach them with a Namespace. For Example like: "myFancySlider-container"
This helps to keep names Unique for your special application.
If you generate Dynamic Code, you have to Make sure, to only create One of each object. Or you Assemble them With iterations. An alternative to that, could be the unifying with Timestamps.
EDIT
As others already mentioned, you should avoid Using ID's as you can. ID's only make sense, to benefit from the Unique Attributes. For example, you know exactly what element you want, so an ID can be a verry good shortcut for that. Specialy in dynamic Content Applications.

own dojo/dijit Editor Plugin is disabled - why?

I am trying to write my own Dojo/Dijit Editor Plugin. the only Information i found on the topic is this forum post recommending to use the print plugin as a pattern.
So i did build my own plugin, copying the print plugin and not changing anything apart from the name.
Then i included the plugin to an editor instance.
But instead of getting the print buttons functionality and the print button, i get a button with classes "dijitButtonDisabled dijitDisabled" and no functionality.
The Print button does work though.
Anyone any idea why that is?
In JavaScript events are often hooked onto individual objects, which are referenced by things like id, classes, and other parameters. For this to work you need both the selector and the original element to match.
It sounds like you updated some parts of the code (by changing the names) but did not update the corresponding actions. I'd start by looking for any remaining events bound to the previous names (in jQuery, look for bind() or live()) and changing those selectors to the new names if you find them.

Handling events from HTML anchor tags in ExtJS

I have a large application built in ExtJS and am looking for the best way to handle custom events from anywhere in the application. For example I might want to put an anchor tag in some text in the application which will open a custom component in my app. At the moment I listen to clicks on the body and if the target has a css class applied to it in a certain format I use that to perform an action.
For example I might have:
<a class="ACTION-View-Customers">View Customers</a>
My event handler will pull the classname apart and do the action. The problem with this approach is that it's difficult to pass many parameters through to the handler. What I propose is to use JSON inside the anchor's class or href tags, like so:
View Customers
Can you think of any problems with this approach and suggest any alternatives? Thanks.
I personally would not use additional meta in the HTML itself, if it can be helped. I would apply specific IDs to links of specific purpose, and bind a click event to that object. I've also found the DomQuery object (needed to find and reference the anchors) interesting to work with. Since I usually use the JQuery adapter with Ext JS, I'll use JQuery's selectors to locate the specific DOM element, and JQuery's bind functions [.click(fn)], while using Ext internal to the function itself. JQuery and Ext JS make a great combo, especially with the new JQuery 1.3.1, which really speeds things up.
I suggest using HTML5's data- attributes. For example:
View Customers
var eventsource = link.getAttribute("data-event");
HTH
As you might know, HTML tag accepts ANY named attribute. So you may create some specifically called attribute(s) and pass any value(s) to them (f.e. my-bogus-param="something"), By this you can develop any sophisticated parameter passing system. Then you can parse these attributes in event handler.

Categories