OlivierBlanvillain / monadic-html

Tiny DOM binding library for Scala.js
https://olivierblanvillain.github.io/monadic-html/examples/
MIT License
225 stars 24 forks source link

updating just a property instead of generating HTML in the code #84

Closed antonkulaga closed 6 years ago

antonkulaga commented 6 years ago

It is very common to have a nonScala person working on html templates, in such case instead of generating most of the elements in the code it can be useful just to bind a property inside an HTML node and tell your colleague that this property will be connected with your Scala code so (s)he can work independently, without editing your scala code.

bbarker commented 6 years ago

You can effectively do this with a light scala file; the just have to get used to properties being embedded in { }. To take this further, you could probably load the html file as a string, and then have monadic html parse it via scala xml, but IIRC parse isn't implemented yet (on phone, can't check easily).

On Nov 2, 2017 5:02 PM, "Anton Kulaga" notifications@github.com wrote:

It is very common to have a nonScala person working on html templates, in such case instead of generating most of the elements in the code it can be useful just to bind a property inside an HTML node and tell your colleague that this property will be connected with your Scala code.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/OlivierBlanvillain/monadic-html/issues/84, or mute the thread https://github.com/notifications/unsubscribe-auth/AA37jiAnUKILgkOBRGJa4RVxm4wjWLpjks5syi3igaJpZM4QQVr0 .

antonkulaga commented 6 years ago

; the just have to getused to properties being embedded in { }

How can I subscribe a property to Var? Could you giive a code example? For me only tags subscription works

bbarker commented 6 years ago

Hi,

Sorry if I don't completely understand, but do you mean something like this? (Also as I was typing this I was surprised to see you pop up in the invenio software gitter channel :))

If you mean properties exposed from the controller in an MVC app, you would probably need to do something like:

MVC-style Properties

Assuming that myVar is not ultimately used by some Rx that is displayed (including itself), it will need to be run and cancelled:

val cc = myVar.run(someval => mvc.property = someval)
//...
cc.cancel() // Do this as appropriate.

If on the other hand myVar does have a downstream value (or is itself) mounted into the page, then you could add a side effect to your map, e.g.:

val someRxThatIsUltimatelyMounted = myVar.map{someval => mvc.property = someval; someval}

Note that the form of mvc.property = someval depends on the MVC framework being used, I imagine.

This is a good question and what I would try first, though I'll admit I haven't done it myself as yet, so someone else with more experience or insight using mhtml this way may want to chime in.

Note, this isn't true MVC as the properties must be exposed and updated in JS-land, not directly on the server-side, but I think the principle is still the same. I just don't have much experience with such JS frameworks as yet.

HTML Attribute updates

If by properties you just mean HTML attributes e.g., onclick, href;

    def renderField(fieldName: String, fieldValues: List[String]): Node = {

      val glyphClicked: Var[Boolean] = Var(false)
      val glyphClass: Rx[String] = glyphClicked.map {
        case false => "glyphicon-menu-right"
        case true => "glyphicon-menu-down"
      }

      if (collapsibleFields.contains(fieldName))
        <div>
          <h3>
            { glyphClass.map{ gclass =>
              <a class={s"glyphicon $gclass"}
                 href={s"#$fieldName-detail"} data-toggle="collapse"
                 onclick={ (ev: dom.Event) => { glyphClicked.update(click => !click) } }>
                {fieldName}
              </a>
            }}
            <div id={s"$fieldName-detail"} class="collapse">
              <p>{ fieldValues.map(fv => Group(Seq(Text(fv), <br />))) }</p>
            </div>
          </h3>
        </div>
      else
        <div>
          <h3>
            {fieldName}
          </h3>
          <p>
            {fieldValues.mkString("\n")}
          </p>
        </div>
    }
antonkulaga commented 6 years ago

Thank you @bbarker for the comprehensive answer, I close this.

I was surprised to see you pop up in the invenio software gitter channel

I just do not like CKAN (that is currently used in our lab). That is why I watch alternatives from time to time. However, it looks like it will take quite a lot of time before invenio_3 will be able to compete with CKAN.