Git Product home page Git Product logo

Comments (33)

timelyportfolio avatar timelyportfolio commented on July 30, 2024

here was my naive unskilled attempt timelyportfolio@8ee84fd. I will be happy to submit a pull, but fear my incompetence will cause widespread damage :)

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

Consider these lines from a very basic widget. spin.js does not allow configuration ex-post like knob anywhere I can see, so I am forced to remove the nodes and rerender with each change. If I could access the already rendered spinner, then I could just change config.

from htmlwidgets.

jjallaire avatar jjallaire commented on July 30, 2024

You can return an arbitrary value from initialize which will then be passed
to you as the last parameter of both resize and renderValue. This is
basically a mechanism for per-widget instance data that you can access from
rendering. See my jjallaire/networkD3 package for an example (there I
return the D3 force layout as the instance data)

Does that help?

On Friday, August 8, 2014, timelyportfolio [email protected] wrote:

Consider these lines
https://github.com/timelyportfolio/htmlwidgets_spin/blob/master/inst/htmlwidgets/spin.js#L4-L13
from a very basic widget. spin.js does not allow configuration ex-post
like knob anywhere I can see, so I am forced to remove the nodes and
rerender with each change. If I could access the already rendered spinner,
then I could just change config.


Reply to this email directly or view it on GitHub
#19 (comment).

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

Not sure it helps in this case, but very good to know. Going to bang my head on keyboard, and I will report back.

from htmlwidgets.

ramnathv avatar ramnathv commented on July 30, 2024

@jjallaire I think @timelyportfolio is looking for a mechanism that will allow him to manipulate the widget directly using javascript, outside of renderValue. I have some use cases for this too. For example, the datamaps js library allows users to define their own plugins. But for the plugin to be activated, it needs to be added to a map instance that was created. Now without access to the map object returned by renderValue, I will not be able to do this.

Note that this feature is more for intermediate-to-advanced users who are going to write javascript to customize widget outputs further.

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

Yes, in a static context so outside of a shiny context, a way to access whatever we created. I will try to assemble a list of potential uses, but this spin.js to stop() is one and in terms of a port of rCharts dimple we will need this for users to configure after creation/render. As far as I now there is no way using spin.js or dimple to get these created objects.

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

Is there an issue, design flaw, or problem adding this to HTMLWidgets.widgets[...] especially in the static context as I have done in the example?

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

I would just attach the object to the element itself using an expando property:

renderValue: function(el, data ) {
  var spin = new Spinner(data);
  // do stuff with spin
  el.spinner = spin; // Attach spinner to element for future use
}

Then later:

var spin = document.getElementById("whatever").spinner;

from htmlwidgets.

ramnathv avatar ramnathv commented on July 30, 2024

That is neat @jcheng5. But since widget id's are randomly generated, how would one know what element to access?

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

also, might be a good idea to use consistent property name such as returnWidget

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

You can get the widget element however you want--by CSS class, dynamically in an event handler, whatever. It really depends on what the scenario is. For example, if you want to stop the spinner on click:

$(document).on("click", ".spinner", function(e) {
  var spin = e.target.spinner;
  spin.stop();
});

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

but say we have three ajax calls each represented by a spinner, how would we know which pairs with which? I guess we could just pass an identifier in config or data.

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

Maybe I'm not understanding something. How would having access to the return value of renderValue help you with that problem either?

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

if in markdown I create a widget and then subsequently create another widget that I would like to bind to the other widget, how might I accomplish that? It seems I need a known identifier and the return value.

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

I'm still not exactly sure we're on the same page, but: If you had two spinners:

var spinners = $(".spinner");
var spinner1 = spinners[0].returnValue;  // or .spinner or whatever
var spinner2 = spinners[1].returnValue;

I have to run to a lunch meeting but will be happy to continue this discussion later. Although at this point I wonder if a vchat on Monday might be more productive?

from htmlwidgets.

ramnathv avatar ramnathv commented on July 30, 2024

@jcheng5 I think a vchat would be good.

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

My Monday is pretty open, anytime during business hours in the Pacific time zone.

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

OK I think I understand what you guys are talking about now--not the widget author, but the user of the widget library wanting to customize the widget further? In that case, I think we certainly need to allow the user to provide the widget's ID, right? (with the default being a randomly generated one, of course)

from htmlwidgets.

ramnathv avatar ramnathv commented on July 30, 2024

@jcheng5 Exactly. Either to do some post rendering manipulation, or say to trigger a link between two widgets.

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

For reference, id is currently set here in htmlwidgets.

I consider charts a very limited subset of htmlwidgets, but as an example with rCharts, I was able to accomplish in one of 2 ways:

1 - Set an id as a parameter in the rCharts configuration; see lines where dom was set in a similar random strategy in initialize
2 - Use afterScript with mustache/whisker to do {{chartId}}. However this does not work as well with multiple widgets, but allows the user a last chance to manipulate, configure, set event handling, etc.

Then to possibly make this idea more tangible, I would love to remake this tags -built website ( code and site ) with all htmlwidgets.

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

A simple test would be

#now do an example with a knob talking to a spin
library(htmltools)
library(htmlwidgets)
#devtools::install_github("timelyportfolio/htmlwidgets_spin")
library(spin)
library(knob)

h <- tags$html(
  tags$div(id = "spin1", style = "width:25%;height:150px;display:inline-block"
    ,tags$h3("Spin To Adjust")
    ,spin(position = "relative", width = "100px", height = "100px")
  )
  ,tags$div(id = "spin2", style = "width:25%;height:150px;display:inline-block"
    ,tags$h3("Spin Not To Adjust")
    ,spin(position = "relative", width = "100px", height = "100px")
  )
  ,tags$div(
    tags$h3("Adjust # of Lines")
    ,knob('Knob Talks to Spin', 14, 0, 20, angleArc = 250, angleOffset = -125, 
          fgColor = "#66CC66",
    )
  )
  ,tags$script(
"
//override knob render value
//since no way currently to do #! js code !# or use JSONfn
HTMLWidgets.widgets[1].renderValue = function(el,data){
  /*var knobData = $('script[data-for = ' + $('.knob')[0].id + ']')
  var dataObj = JSON.parse(knobData.text());
  */
  data.change = function (v) {
    $('.spin')[0].spin.opts.lines = v;
     HTMLWidgets.widgets[0].renderValue(
       $('.spin')[0], $('.spin')[0].spin.opts
     )
  }
  //knobData.text(JSON.stringify(data));
  $('.knob').trigger('configure',data);
  $('.knob').val(data.value).trigger('change');
};

"
  )
)
html_print(h)

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

changed the code above to actually accomplish the objective but this has the unfortunate effect of overriding renderValue on all the knobs

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

After inspecting the code more closely, it appears we can addEventListener("DOMContentLoaded', function(){ do something after widget render}) as in

#now do an example with a knob talking to a spin
library(htmltools)
library(htmlwidgets)
library(spin)
library(knob)

h <- tags$html(
  tags$div(id = "spin1", style = "width:25%;height:150px;display:inline-block"
    ,tags$h3("Spin To Adjust")
    ,spin(position = "relative", width = "100px", height = "100px")
  )
  ,tags$div(id = "spin2", style = "width:25%;height:150px;display:inline-block"
    ,tags$h3("Spin Not To Adjust")
    ,spin(position = "relative", width = "100px", height = "100px")
  )
  ,tags$div(
    tags$h3("Adjust # of Lines")
    ,knob('Knob Talks to Spin', 14, 0, 20, angleArc = 250, angleOffset = -125, 
          fgColor = "#66CC66",
    )
  )
  ,tags$div(
    tags$h3("Do Nothing")
    ,knob('Knob Talks to Spin', 14, 0, 20, angleArc = 250, angleOffset = -125, 
          fgColor = "#66CC66",
    )
  )
  ,tags$script(
"
document.addEventListener('DOMContentLoaded',function (){
  $('.knob:first').trigger('configure', {
      'change': function (v) {
         $('.spin')[0].spin.opts.lines = v;
         HTMLWidgets.widgets[0].renderValue(
           $('.spin')[0], $('.spin')[0].spin.opts
         )
      }
  });
}
)

"
  )
)
html_print(h)

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

@timelyportfolio That snippet works, but, ugh... it's so fragile. To support this properly it seems like we would want to:

  1. Allow the user to (optionally) specify the widget ID
  2. Provide an easy way for code to run after all the widgets have been loaded
  3. Make it easy to pass new values to be rendered from JS to individual widgets (like HTMLWidgets.renderValue(el, data) and have htmlwidgets figure out the right binding to use); we can do this by attaching the binding to the element at the time it is bound

Does that sound right to everyone?

from htmlwidgets.

ramnathv avatar ramnathv commented on July 30, 2024

I think the elementId argument and the ability to store instance values on the DOM element should close this issue. I will wait till @timelyportfolio can test this with the examples he has been playing with.

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

Not optimal, but I think it works for now. Unfortunately, I don't have any better ideas. I think this insight will come as I do this over and over with different widgets. I am satisfied for now that we can do some amazing things.

from htmlwidgets.

JT85 avatar JT85 commented on July 30, 2024

@jcheng5 Wouldn't it be nice to have a function like knobInput for shiny which can be used as an input controller for a shiny app like for instance the ipod wheel: http://anthonyterrien.com/knob/? Do you think this is even feasible?
This is probably not the right place for these kind of suggestions/questions. Let me know where I can do this in the future please.

from htmlwidgets.

ramnathv avatar ramnathv commented on July 30, 2024

@JT85 input widgets are something that we will be thinking about in the future. Currently, the focus is on output html widgets.

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

@JT85 It's quite straightforward to do this today without help from htmlwidgets--see this article.

For htmlwidgets, input widgets are less of a win than output widgets, because the main advantage htmlwidgets gives you is to author a widget once and use it in static HTML pages, static R Markdown documents, RStudio Viewer, and Shiny. For input widgets, it doesn't make much sense to have an input widget in any of those contexts but Shiny (unless the widget user is going to write some javascript, in which case, it's not that clear why you'd need an R wrapper in the first place).

I'm not saying htmlwidgets wouldn't be helpful at all for input widgets--just that it'd be far, far less helpful than it is for output widgets.

from htmlwidgets.

jcheng5 avatar jcheng5 commented on July 30, 2024

I think we can close this, right? Because we have onRender and onStaticRenderComplete?

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

Would agree can close this. Was a fun discussion.

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

didn't mean to close, I'll let y'all decide. Pushed the wrong button.

from htmlwidgets.

timelyportfolio avatar timelyportfolio commented on July 30, 2024

going to close since no other comments or objections

from htmlwidgets.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.