3

I'm just starting out with OOP in JavaScript. I want to create a custom "panel." Here is what I have so far:

function ShinyPanel(css, attributes)
{
    this.container = $(document.createElement("div")).addClass("shinyPanel");

    this.titleBar = $(document.createElement("div")).addClass("shinyPanelTitleBar").appendTo(this.container);
    this.topShine = $(document.createElement("div")).addClass("shinyPanelTopShine").appendTo(this.container);
    this.leftShine = $(document.createElement("div")).addClass("shinyPanelLeftShine").appendTo(this.container);
    this.content = $(document.createElement("div")).addClass("shinyPanelContent").appendTo(this.container);

    if (!css) css = {};
    if (!attributes) attributes = {};

    this.css = css;
    $(this.container).css(this.css);

    this.title = attributes["title"];
    $(this.titleBar).html(this.title);
}

Now I can instantiate this object and append it to the body via something like this:

var panel = new ShinyPanel({position:"absolute", top:"25%", width:"300px", height:"200px"}, {title:"Test"});
$("body").append(panel.container);

My question is, is there a way for me to make the object itself a div, thus eliminating the need for a "container" div? Then I could just call $("body").append(panel);.

It's not that its much trouble for me to have the container div there, it's more just for me...wanting to learn the right way to do things.

I tried this = document.createElement("div");, but I got an error: invalid assignment left-hand side.

4
  • Does return this.container; not work? :) Commented Jul 2, 2012 at 18:58
  • I didn't think of that at the time, but after @PaulPhillips suggeted it in his answer, I am trying it and for some reason, appending elements to panel.content isn't working. Still messing around with it to see if I can figure it out, though. Commented Jul 2, 2012 at 19:04
  • I would suggest checking out how jQuery UI works then, since that's roughly what you're trying to do I think. Commented Jul 2, 2012 at 19:10
  • @Jack: I think I am going to use jQuery UI. Thank you for the suggestion. If you want to post an answer, I'll accept it. Commented Jul 2, 2012 at 20:21

4 Answers 4

3

What you're describing is basically what the UI framework is able to accomplish.

Check out the widget factory documentation to get started:

http://wiki.jqueryui.com/w/page/12138135/Widget%20factory

Sign up to request clarification or add additional context in comments.

Comments

2

I would suggest having a ShinyPanel method that handles this. Tell, don't ask.

function ShinyPanel(css, attributes) {
...
   this.appendTo = function (to) {
      $(to).append(this.container);
   }

4 Comments

This would be a better solution than I currently have, but the other issue that I forgot to mention in the original question was setting properties on it also requires me to set them on the container: $(panel.container).attr("id", "myPanel");. Any better suggestion with that in mind?
You could add a attr function that redirected all calls to the container.
Yeah, but it's not just attr, either. I might want to call $(panel).css(...) and a boat-load of other available functions...I don't want to have to override all of them.
+1 Thank you for the suggestions, but it looks like jQuery UI might be a better solution for me.
0

You could return this.container directly from your constructor function, assuming you're not going to use any of the other properties you added to it.

To do this, I think you would have to change it to be a factory method, rather than a constructor (i.e. don't use new anymore - although there is more to it than that).

2 Comments

I'm trying this now, but running into trouble where anything I add to the content div isn't showing up. Perhaps I need to research a bit more and use a different method of creating a custom object.
If you're using anything besides container, what I suggested won't work. Since you're trying to do OOP, I think I've given you a pretty poor answer, honestly. Explosion Pills answer is a much better idea, and there is probably some plugin-way to auto-override all the jquery functions. Though I don't know what it is.
0

When all you want to do is append it to body, instead of returning an object, you could just return a string with your panel.

Something like this:

function shinyPanel(css, attributes) {
    ... all the stuff you did before
    return this.container
}

Furthermore, if you want to achieve some speed in that shinyPanel function of yours, you could try to add strings of your markup and then only use append once.

Also have a look into using an array as a holder for your return string and then use .join('') when you return it.

More info: http://www.learningjquery.com/2009/03/43439-reasons-to-use-append-correctly

1 Comment

I don't think I want it to return a string. I want the panel's properties to be easily modifiable, even after creating the object. For example, I want to be able to do this: var panel = new ShinyPanel(); panel.title = "Test"; I know it won't exactly work that way right now...that's next on my list of things to get working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.