1

I've been making my first jQuery plugin and I need to add some CSS in the head via a styles tag as doing inline css on the element which gets injected by the script has some weird bugs in IE8 - 10.

But to add the styles in the head I need to target the actual element that the user binded the plugin to.

For example:

$('input').myPlugin(); // I need to get the text "input"
$('#form .foo').myPlugin(); // I need to get the text "#form .foo"

Is it possible to get this data within the plugin?

Brett
  • 19,449
  • 54
  • 157
  • 290
  • In case you need it you can walk up the parents and create selector strings ... see my solution here http://stackoverflow.com/a/28881979/1175966 – charlietfl Mar 22 '15 at 18:29
  • 1
    Why not do the CSS for a specific class unique to your plugin, then add that class to the elements as you're initialising your plugin for them? – Anthony Grist Mar 23 '15 at 16:34
  • @AnthonyGrist Hmmmmm I guess that's a possible idea. Thanks! – Brett Mar 23 '15 at 17:25

3 Answers3

1

That string is the selector property of the object:

$.fn.myPlugin = function(){
    console.log(this.selector);
}
$('#form .foo').myPlugin(); // logs '#form .foo'

But using it looks like a bad practice (and it's also deprecated, as pointed by charlietfl, for good reasons). You shouldn't need it. To style the elements you can directly do

$.fn.myPlugin = function(){
    this.css('color', 'red');
}
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 1
    `.selector` is deprecated...also removed as of 1.9 – charlietfl Mar 22 '15 at 17:18
  • That's what I am doing to set the inline css, but as I said it causes some strange behaviour in certain IE versions with regards to padding text fields/textareas when they are set to `box-sizing: border-box;`. If you manually set the padding it works fine. – Brett Mar 22 '15 at 17:23
  • @charlietfl Apparently still accessible http://stackoverflow.com/questions/14964760/alternative-to-selector-property-now-that-it-is-removed-in-jquery-1-9 ? See https://github.com/jquery/jquery/blob/0ea8c32863af31fb5cfc184e8d513bbae35583e8/src/core/init.js ; try, at `console` , same page `jQuery().jquery; $("body").selector;` – guest271314 Mar 22 '15 at 18:49
  • 1
    @guest271314 yup but when documentation says it's deprecated you can't expect it to always be available in future releases. I was simply quoting what it says in the docs – charlietfl Mar 22 '15 at 19:02
  • @charlietfl See https://github.com/jquery/jquery/blob/0ea8c32863af31fb5cfc184e8d513bbae35583e8/src/core/init.js – guest271314 Mar 23 '15 at 16:56
1

$.myPlugin

The recommended way to solve your problem is using this and other methods described below. If you require the selector as a string, you can define the function as a child of jQuery ($) and have the function executed in a similar way to jQuery's &.ajax and $.extend. What this is doing is it is making it a child of jQuery, and a child of $.fn so it can still be 'classified' as a regular jQuery plugin, or a prototype of jQuery. When you old set your plugin the $.fn, it is set to jQuery's prototype, making it so you have to run the jQuery function. Here we are doing that, but because functions are also objects, we can set that function to $.myPlugin making it still part of jQuery, but prevents the user from entering the selector twice. Since this.selector s deprecated (and it'll probably be removed soon) it's better than running it through a function to generate a selector.

$.myPlugin = $.fn.myPlugin = function (selector) {
    console.log(selector);
}

$.myPlugin('#selector'); //Logs: '#selector

The $.fn is completely optional and is there just in case a user forgets to execute the function using $.myPlugin(selector) the function will still work when using $().myPlugin(selector)

Other alternative

If you don't require the string, I would recommend using jQuery's .filter() or similar functions (here) along with $(this).

$.fn.myPlugin = function () {
    var $this = this;
    var filteredElements = $this.children('a');//

    console.log(filteredElements);
} 
$('#form .class').myPlugin();
//Logs: children that are <a> of #form .class
Community
  • 1
  • 1
Downgoat
  • 13,771
  • 5
  • 46
  • 69
  • Yes, I'm aware of `$(this)`, but I really do need the string. Don't really want to rely on the user providing it either, was hoping there would be a simple way to get it. – Brett Mar 22 '15 at 17:48
  • @Brett You could also ask the user to provide it as a function of `$.fn` as `$.fn.myPlugin('#selector')` – Downgoat Apr 05 '15 at 22:56
  • You mean instead of calling it like `$('#selector').myPlugin()` you would do it that way? – Brett Apr 06 '15 at 07:53
  • @Brett Yeah pretty much. You could also do `$.myPlugin = $.fn.myPlugin` at the end of your code so it would be just $.myPlugin – Downgoat Apr 06 '15 at 15:16
  • Alright cool - perhaps you can update your answer with this solution? – Brett Apr 07 '15 at 05:39
  • Could you detail it a bit more for the chosen solution and mention the extra optional stuff like `$.myPlugin = $.fn.myPlugin`? – Brett Apr 07 '15 at 15:10
0

Try

$.fn.myPlugin = function(sel) {
  console.log(sel, $(this));
};
var selectors = ["input", "#form .foo"];
$(selectors[0]).myPlugin(selectors[0]); // I need to get the text "input"
$(selectors[1]).myPlugin(selectors[1]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>

<input type="text" />
<form id="form">
  <select class="foo" name="foo">
    <option value="abc">abc</option>
  </select>
</form>
guest271314
  • 1
  • 15
  • 104
  • 177
  • Thanks.... but got a bit too much returned. For an `input` I got this returned: `["input#.form-control", "input#.form-control", "input#.form-control", "input#.form-control", "input#."]` – Brett Mar 22 '15 at 18:00
  • Didn't change the output I got; though my test scenario is over a number of input fields. I checked the console for your one above and the first output `input` but the second output `select.foo` rather than `#form .foo`. – Brett Mar 23 '15 at 08:15
  • @Bret See updated post. See also http://api.jquery.com/selector/ , http://stackoverflow.com/questions/500246/how-do-i-get-a-jquery-selectors-expression-as-text/ , http://stackoverflow.com/questions/535967/destination-div-disappearing-in-simple-jquery-ajax-call – guest271314 Mar 23 '15 at 16:32
  • Thanks for your efforts but as per my comment to @vihan1086 I didn't really want to have to get the user to provide it as a parameter. – Brett Mar 23 '15 at 17:29
  • Tried @dystroy 's answer ? Though `.selector` documented as deprecated , appear to still be accessible; see `$.fn.init` https://github.com/jquery/jquery/blob/0ea8c32863af31fb5cfc184e8d513bbae35583e8/src/core/init.js – guest271314 Mar 23 '15 at 18:12