MithrilJS / mithril.js

A JavaScript Framework for Building Brilliant Applications
https://mithril.js.org
MIT License
13.99k stars 926 forks source link

m('option[selected]') not possible? #1651

Closed ChrisGitIt closed 7 years ago

ChrisGitIt commented 7 years ago

Hi all,

i just tried to setup a simple form with some pre selected options ...

m.render(document.body, m('option[selected]');

or

m.render(document.body, m('option[selected=selected]', 'selected!!'));

or

m.render(document.body, m('option[selected=true]', 'selected!!'));

or

m.render(document.body, m('option[selected=1]', 'selected!!'));

does not render the desired result: <option selected>selected!!

Any hints appreciate!

Greets,

Chris

barneycarroll commented 7 years ago

Hi @ChrisGitIt, I'm able to determine whether an option is selected or not using this property: https://jsbin.com/xatavo/edit?html,js,output

You won't see this in the markup because selected, like text inputs' value and checkboxes & radios checked, or event handlers like onclick is a DOM property, not an attribute. When writing HTML, these have to be defined as attributes because you need to encode as text and parse it in the browser. But since Mithril is a DOM library, it can read and manipulate properties directly.

You can see similar things going on if you inspect, for example, the textarea used to comment on Github issues: as you type, the value changes to reflect text input, and the height increases to display the right number of lines on oninput events. In order to communicate this via HTML, you'd expect to see <textarea oninput="function(){this.style.height = this.scrollHeight + 'px'}">The content</textarea> - but attribute is only necessary for representation as static HTML: since this is dynamic behaviour taking place in the browser, there's no change to the HTML representation.

ChrisGitIt commented 7 years ago

Hi and thank you for your feedback! I was looking into this issue for about four hours ... you helped me a lot by providing the info that the "select" attribute does not have to be visible in HTML ... now i just have to figure out why the http://materializecss.com/forms.html#select-initialization does not select ... somehow it boils down to $('select').find("option:selected") ... anyway: Thanks a lot!

Greets,

Chris

barneycarroll commented 7 years ago

It's often tricky getting Mithril to work with jQuery plugins because different jQuery plugins make different assumptions – typically they tend to believe they are in total control of the DOM they mutate, and a Mithril view may mutate, destroy or create that DOM in ways the plugin doesn't expect.

According to the documentation you linked though, this shouldn't be a problem:

If you want to update the items inside the select, just rerun the initialization code from above after editing the original select

This suggests you should be able to make material select integrate with Mithril by using a simple component wrapper:

// Component logic
function update(vnode){
  $('select', vnode.dom).material_select()
}

var MaterialSelect = {
  oncreate : update,
  onupdate : update,
  onremove : function(vnode){
    $('select', vnode.dom).material_select('destroy')
  },
  view : function(vnode){
    return vnode.children
  }
}

// In your application
m(MaterialSelect, 
  m('select',
    options.map(function(option, index){
      return m('option',{
        value: option,
        selected: index === selectedIndex,
        onclick: function(){
          selectedIndex = index
        }
      },
        option
      )
    })
  )
)

By the way, you might be interested in Polythene, a Material Design component library for Mithril (although it doesn't have selects, as far as I can tell)

ChrisGitIt commented 7 years ago

Hi barneycarroll and thanks for your feedback again! Did not know about Polythene. Looks nice but i allready implemented my own material design components with form elements included which i now port to the new mithril version.

About the problem that i had: Looks like i had a function scope issue (made a helper function to init materialize js similar to your provided solution (i might rethink my version due to your input (grrr (-;)

Greets,

Chris

barneycarroll commented 7 years ago

@ChrisGitIt I know a lot of people who'd be interested in seeing your work on this – right now Mithril v1 doesn't have many integrations – please let us know if and when your work is ready :)