9

I am trying out Backbone.Marionette and I am confused as to why my Layouts and ItemViews keep generating extra divs.

example is in Coffee btw.

AppLayout = Backbone.Marionette.Layout.extend
  template: "#my-layout",

  regions:
    menu: "#menu",
    content: "#content"

MyMenuView = Backbone.Marionette.ItemView.extend
  template: '#project_wiz_nav_template'

MyContentView = Backbone.Marionette.ItemView.extend
  template: '#project_setup_template'

MyApp = new Backbone.Marionette.Application()

MyApp.addRegions
  mainRegion: '#project'

MyApp.addInitializer ->
  layout = new AppLayout()
  MyApp.mainRegion.show(layout)

  layout.menu.show(new MyMenuView())
  layout.content.show(new MyContentView())

MyApp.start()

This is what index.html contains:

<div id='project'></div>
<script type='text/template' id='project_wiz_nav_template'> <h2>HI</h2> </script>
<script type='text/template' id='project_setup_template'> <h2>WORLD</h2> </script>
<script id="my-layout" type="text/template">
  <h2>Hello!</h2>
  <div id="menu"></div>
  <div id="content"></div>
</script>

This is what it produces:

<div id="project">
  <div>
    <h2>Hello!</h2>
    <div id="menu">
      <div> 
        <h2>HI</h2> 
      </div>
    </div>
    <div id="content">
      <div> 
        <h2>WORLD</h2> 
      </div>
    </div>
  </div>
</div>

As you can see, it keeps generating extra divs for the views and the layouts. I've tried adding el: '#menu' and el: '#content' to no avail.

corroded
  • 21,406
  • 19
  • 83
  • 132
  • When `el` or ( `tagName`,`id`,`classname`) are not specified for a view it defaults to **div tag** that's the reason. Might be #menu, #content cannot be found also – Deeptechtons Jun 25 '12 at 03:40
  • possible duplicate of [Backbone js: How to remove extra tag in view?](http://stackoverflow.com/questions/7663895/backbone-js-how-to-remove-extra-tag-in-view) – Derick Bailey Jun 25 '12 at 12:41
  • possible duplicate of http://stackoverflow.com/questions/7096670/stop-backbone-from-adding-surrounding-divs-to-a-view – Derick Bailey Jun 25 '12 at 12:43

3 Answers3

8

This is not because of Marionette. Backbone generates a <div> class for you by default. You can set the tag via the tagName attribute. See comments on the question for duplicates of this.

Drew Dara-Abrams
  • 8,016
  • 11
  • 40
  • 48
Derick Bailey
  • 72,004
  • 22
  • 206
  • 219
  • 4
    Thanks for your reply to this Derick. I'm hitting the same thing -- I'd like the view's el to be the selector defined in the Layout's regions hash. It seems like the definition of the view's tag is coming from both directions: from the layout and from the region's view, with no way to skip an intermediate tag. – Tres Jan 30 '13 at 22:51
  • @Tres: Did you ever figure out a way to change the extra
    behavior when showing regions?
    – Drew Dara-Abrams Mar 19 '13 at 14:40
  • @Derick Bailey, Is there anyway for Tres's comment to work? I've been working on this for hours and would be a lot easier to work with – streetlight Mar 26 '13 at 21:57
  • It can be done via overriding `open` method of `Region` - its a one-line function that makes `$.append` of view's `el` to regions `el', so if remake in way that it will do `append(view.$el.html())` instead - it will solve the problem. – Gill Bates Sep 17 '13 at 08:24
  • @Derick Bailey, we are showing an ItemView to a region which already has a div element. So why do we need the extra nested div? Is there any reason for this? – Konza Nov 11 '13 at 09:38
  • @Konza - this is Backbone.View behavior, not Marionette behavior. Please search StackOverflow and the many blogs out there for info on this. – Derick Bailey Nov 12 '13 at 00:45
  • 2
    Alright, yes, it's Backbone.View behavior. But we use Marionette's Regions to IMPROVE UPON normal Backbone.Views. This behavior is simply unintuitive and makes Regions less useful. – Marco Lazzeri Apr 12 '14 at 08:32
  • I think this is what @GillBates is suggesting - https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.region.md#set-how-views-el-is-attached – Marco Lazzeri Apr 12 '14 at 08:34
  • 1
    You can use `onRender` trigger in you views to do `this.setElement(this.$el.find('selector'));`. The only thing is that you would probably need to create a base class for your ItemView or/and LayoutView... – Denis Ivanov Mar 04 '15 at 23:06
  • actually Marionette could solve it by passing $el: this.getRegionEl implicitly. but it does not do this way. – skyboyer May 05 '16 at 12:21
-1

A hacky workaround, but jQuery's closest() actually did the job for me. Rather than using the returned myView.el directly, I'm using $(myView.el).closest("div").html() -- as I said, hacky, but as a short-term fix it's working.
I was tinkering with this tutorial: http://davidsulc.com/blog/2013/02/03/tutorial-nested-views-using-backbone-marionettes-compositeview/comment-page-1/#comment-3801, which takes a nested model and creates an accordion view using Bootstrap. I wanted to do the same with his starting point, only using the jQueryUI accordion widget, which is the reason I needed an unwrapped view coming back -- hence the filtering with closest().
Other than adding the jqueryUI links and changing the returned HTML as delineated above, it's working pretty well: http://dartsleague.parentleafarm.com/superheroes/

Snowmonkey
  • 3,716
  • 1
  • 16
  • 16
-3

Specify your el property. I think that will fix it:

http://documentcloud.github.com/backbone/#View-el

Rimian
  • 36,864
  • 16
  • 117
  • 117
  • 2
    i tried this and got a `Uncaught Error: HIERARCHY_REQUEST_ERR: DOM Exception 3`. I think this might be more of a marionette thing regarding ItemView, but I'm not sure... – corroded Jun 25 '12 at 05:07
  • that error comes from jQuery. it means you're trying to insert a DOM element in an invalid place. For example, you might be trying to insert a `` tag in to a `
      ` tag, which is not valid.
    – Derick Bailey Jun 25 '12 at 12:40
  • I'm having a really hard time with this issue too. Prior to the 2.x update specifying the el property works. The upgrade breaks this so I'm confused when you say it is a JQuery issue. How does it work in 1.x then? I have a tab control that has stopped functioning with the 2.x update because I'm not able to generate the DOM structure JQuery wants. What has changed in the update to make specifying the el property stop working? – Robert Aug 07 '15 at 15:41