Creating a small jQuery plugin - javascript

I created this plugin to make work around an application easier.
Here is the link : http://jsfiddle.net/X5Squ/
My problem it that it always uses just 1 of the elements, please don't edit the data and data5 functions as these work perfectly for other parts but I need my function called jtoggle to work.
Any help much appreciated! Thanks.

$(document).ready(function (){$('.jtoggle').jtoggle(true);});
Have you tried using .each on this? I think the issue is that it isn't passing an array of DOM elements. I lack much experience in creating plugins, but it seems this can be easily averted by doing the following:
$(document).ready(function (){
$('.jtoggle').each(function(){
$(this).jtoggle(true);
});
});
(Which would also mean that you can safely remove the .each you have in jtoggle itself)

In your plugin you should act on each matched element and then return all the matched elements in order to maintain chainability:
$.fn.jtoggle = function (addUnderline) {
return this.each(function () {
// Do what you need on this matched element
});
};
Maintaining chainability means we can do stuff like:
$(".jtoggle").jtoggle(true).addClass("xyz");

Related

Adding event listeners to multiple input elements using plain JS (not jQuery)

I have a code block that works perfectly in jQuery but it's the last bit of a project I am converting to plain vanilla Javascript with the specific aim to remove any and all dependencies on jQuery.
Here is the existing code block at issue:
$("input[data-pattern='comma']").on({
keyup: function() {inputComma($(this));}
});
How do I achieve this same functionality using ONLY plain pure JS?
Note: inputComma is a custom handler that conforms the value for EACH input element instance to a comma-delimited regex pattern as the user is typing.
If it helps, I tried...
document.querySelectorAll("input[data-pattern='comma']").forEach(function(elem) {
elem.addEventListener("keyup", function() {inputComma(elem);});
});
and also...
document.querySelectorAll("input[data-pattern='comma']").forEach(function(elem) {
elem.addEventListener("keyup", () => {inputComma(elem);});
});
I know jQuery's $(this) is different from "this" and that arrow functions also materially affect which "this" is being referenced. I tried to get around that issue by referencing the iterating object but I think that may be part of my problem. Not opposed to using the "this" pointer if there is a way to make it work in pure JS.
Thanks in advance for your help!
I think this can be better done using event delegation. It would look something like:
document.addEventListener(`keyup`, handle);
function handle(evt) {
if (evt.target.dataset?.pattern === `comma`) {
return inputComma(evt.target);
}
}
function inputComma(elem) {...}

Conver current jQuery code to valid vanilla Javascript

I have this jQuery code, but I need to convert it to vanilla Javascript because the project I am working on is not using jQuery
Here is what I have tried, but it is not working. I am unsure for all of these changes that I have made
// My current jQuery code
$('#category-2 ul li').each(function() {
$(this).find("ul.top-menu").parent().remove();
});
$('#category-2>a').html("Produkte");
// Vanilla JS
document.querySelectorAll('#category-2 ul li').forEach(function() {
this.find('ul.top-menu').parentNode().removeChild();
});
document.querySelectorAll('category-2>a').innerHTML="Produkte";
There are several problems in your code. One is that in the function you are using the this keyword as it would be in a class, but in functions the this keyword does not refer to what you would expect it to be. Instead use parameters from the forEach function: item, index, array, thisArg can be used.
The second problem is that in Vanilla JS there is no find() method so I would suggest implementing a ternary operator (one line if statement) to check if the className or the id includes what you are searching for.
I'm not sure what items are you searching for without the html it is hard to tell, but it would look something like this:
// Vanilla JS
document.querySelectorAll("#category-2").forEach(item => {
item.className.includes("top-menu") && item.parentNode.removeChild();
});
document.querySelectorAll("#category-2").forEach(item => {
item.innerHTML = "Produkte";
});

jQuery Multiple ID selectors

Here's a snippet of the start of my code:
var myUpload = $("#upload_link").upload({bla bla bla
Basically what I'm trying to do is make the same call with a few different ID's...
I would have assumed this would work but it doesn't:
var myUpload = $("#upload_link,#upload_link2,#upload_link3").upload({
Any ideas?
Try this:
$("#upload_link,#upload_link2,#upload_link3").each(function(){
$(this).upload({
//whateveryouwant
});
});
If you give each of these instances a class you can use
$('.yourClass').upload()
You can use multiple id's the way you wrote:
$('#upload_link, #upload_link2, #upload_link3')
However, that doesn't mean that those ids exist within the DOM when you've executed your code. It also doesn't mean that upload is a legitimate function. It also doesn't mean that upload has been built in a way that allows for multiple elements in a selection.
upload is a custom jQuery plugin, so you'll have to show what's going on with upload for us to be able to help you.
Make sure upload plugin implements this.each in it so that it will execute the logic for all the matching elements. It should ideally work
$("#upload_link,#upload_link2,#upload_link3").upload(function(){ });
If all your elements starting with upload_ in its id have the same purpose or syntax you could try and use the following:
$("*[id^='upload_']").each(function() {
$(this).upload()
});
This way you don't have to specify every single element in the selector.
it should. Typically that's how you do multiple selectors. Otherwise it may not like you trying to assign the return values of three uploads to the same var.
I would suggest using .each or maybe push the returns to an array rather than assigning them to that value.
That should work, you may need a space after the commas.
Also, the function you call afterwards must support an array of objects, and not just a singleton object.

Using jQuery in a JavaScript function

function divlightbox(val)
{
if(val)
{
val=val.replace( /^\s+/g, "" );
var count_js=0;
var big_string='';
document.getElementById("video_lightbox").innerHTML="";
document.getElementById("divlightbox").style.display = "block";
$("#video_lightbox").css({"height":"430px","top":"10%","width":"480px"});
I found out that the error is in the above. My question is can't I use jQuery and traditional JavaScript at same time? I have done coding like this numerous times and never ran into a problem like this. I used to use jQuery methods like .hide() and .css() inside JavaScript functions but this time it doesn't work.
Thanks in advance.
While the other answers fix the specific problems, I don't think the OP's question (in bold) is really answered here, as depending on the specific context, $ may possibly not be defined as a jQuery object yet (having had this problem myself a few times now.)
In which case you would need to do something like:
function divlightbox(val) {
// ...
// just use jQuery instead of $ one time
jQuery("#video_lightbox").css({"height":"430px","top":"10%","width":"480px"});
}
OR
function divlightbox(val) {
// define the $ as jQuery for multiple uses
jQuery(function($) {
// ...
$("#video_lightbox").css("height":"430px");
$("#video_lightbox").css("top":"10%");
$("#video_lightbox").css("width":"480px");
});
}
jQuery is JavaScript so YES. Instead .innerHTML="" just use .empty(). Instead .getElementById() use $('#..') and so on.
to do things like hide(); and css() you need jquery objects. you can't do them to dom elements.
so you could do $('#video_lightbox').html("");
or
$('#video_lightbox').empty();
You must provide error in javascript console.
1) Do you pass a val argument to divlightbox function()? When do you call it?
2) why do you use the same identifier divlightbox both for a function and for a div id? Change name to the function please, maybe the problem could be here.
3) Always check if video_lightbox and divlightbox exist before accessing them.

how to reuse effect instance on jquery

On mootools I'm used to declare once and reuse often. An FX example would go like this:
myEffect1 = new Fx.Slide($('myElement1'));
How should I go on jQuery? Meaning, the docs make it straightfoward to use:
$('myElement1').click(function(e){
this.slideToggle();
});
But if I want to call this effect somewhere else on my code will I have to re-declare it? And isn't this approach more resource hungry than the one above? How would this be properly done on jQuery?
Just manually cache the result set in a variable before calling the function, then reuse the function as needed:
var $el_one = $("#path .to > .selection"), // Stores jQuery object
$el_two = $("#path .to > .second"); // Stores jQuery object
var effect = function(){
$el_one.fadeIn();
$el_two.fadeOut();
}
Now you can call effect any time without reselecting the items. They instead use the cached jQuery selection to animate correctly.
If you need more clarity, let me know.
var slideToggleEffect = function(e){
this.slideToggle();
};
$('myElement1').click(slideToggleEffect);
$('myElement2').click(slideToggleEffect);
...
I'd go with a plugin in this case. For example here's a plugin that I use often - a very simple slide and fade toggle effect.
$.fn.slideFadeToggle = function(easing, callback) {
return this.animate({opacity: 'toggle', height: 'toggle'}, "fast", easing, callback);
};
Now you can call slideFadeToggle on any selector like this:
$("#somedom").slideFadeToggle();
Since every command acts on a jQuery object (the object returned by calling $() on a selector), the example you've given is the nearest comparison to what you're used to in MooTools, as far as I can see.
Is it more resource hungry? Well, that's a complex question to answer as instantiating objects is only one piece of client side code. Some framework methods for performing certain operations are better in some situations and worse in others.

Categories