2017-08-17 2 views
1

J'ai créé un objet simple d'entrée comme ceci:Comment puis-je définir la valeur d'un champ de texte de saisie dans Bokeh à partir de JavaScript?

self.dummy_text = TextInput() 
self.dummy_text.css_classes = ['dummy_text'] 

Et je veux de recouvrer la valeur de ce champ avec autre contrôle. Par exemple, ce bouton:

self.dummy_button = Button(label="Foo", button_type="success") 
self.dummy_button.css_classes = ['dummy_button'] 

Si je change la valeur du champ de saisie de texte à la main, le bouton obtenir la valeur de texte d'entrée bien. Mais si je modifie la valeur par JavaScript (jQuery) comme celui-ci la valeur ne reçoit pas du tout:

$("#bokeh_iframe").contents().find(".dummy_text input").val('text value') 

J'ai ouvert bokeh dans le iframe avec id bokeh_iframe. Je dois utiliser find car avec un sélecteur direct ne fonctionne pas. Enfin, j'invoque le bouton du clic comme ceci:

$("#bokeh_iframe").contents().find(".dummy_button button").get(0).click(); 

La méthode bouton ressemble à ceci:

def dummy_button(self): 
    dummy_text_value = self.dummy_text.value 

Qu'est-ce qui se passe? Ai-je besoin de dire à bokeh de synchroniser les données d'une autre manière? Dois-je trouver un autre moyen de remplir le champ par JavaScript?

Note: Je dois faire cette solution de contournement pour exécuter certaines actions dans le serveur bokeh d'une application externe (électronique, qui est construit avec nœud)

Note2: Un autre élément: prevObject: jQuery.fn.init(1) apparaît avec les objets d'entrée et de bouton , pourrait être que le problème? Voilà pourquoi je dois utiliser get(0)

Répondre

1

Pour les machines BokehJS pour détecter automagiquement et synchroniser les modifications aux propriétés modèle (comme la valeur widget d'entrée), vous devez normalement régler la .value propriété sur le modèle BokehJS objet, pas en modifiant directement l'attribut HTML. Cependant, Bokeh n'a jamais vraiment envisagé la possibilité de manipuler des modèles Bokeh à partir de JavaScript "externe", il n'est donc pas optimisé pour rendre cela facile ou simple. Lorsque Bokeh rend des documents dans une page, il laisse un index des vues de niveau supérieur dans un objet window.Bokeh.index. Donc, une approche vraiment réalisable est de recopier à travers cet arbre d'index pour trouver le modèle Bokeh pour le widget d'entrée qui vous intéresse, puis de mettre à jour le champ .value dessus.

Cependant, il peut fonctionner dans ce cas particulier pour définir la valeur de l'élément HTML, et également déclencher explicitement l'événement change:

$("#bokeh_iframe").contents().find(".dummy_text input") 
    .val('text value') 
    .trigger('change'); 

Ce serait certainement plus facile, mais non testé (je don « t ont la bande passante pour essayer de construire et tester un exemple complet, malheureusement.)


Sinon il y a un moyen de ré-exprimer votre intention à l'aide d'un rappel CustomJS, que w Mal être préférable, puisque les modèles Bokeh peuvent être rendus facilement disponibles pour CustomJS code JavaScript via la propriété args.

+0

J'apprécie toute votre aide. Voulez-vous dire utiliser l'attribut args comme ça? 'CustomJS (args = dict (source = source), code =" "" [...] "" ")." De cette façon, j'enverrais l'argument de Python vers JavsScript En fait, je veux faire le contraire, envoyer un paramètre de JavaScript (de l'application externe, pas du code CustomJS) à une méthode python – ChesuCR

+0

J'ai testé la solution 'trigger ('change')' mais ça ne marche pas :( – ChesuCR

+0

J'ai aussi essayé le ' window.document.Bokeh.index' solution et ça marche Donc, la solution serait celle-ci: 'var models = window.Bokeh.index [Object.keys (window.Bokeh.index) [0]]. model.document. _all_models; var input_dummy_text = models [dummy_text_id]; input_dummy_text.value = 'nouvelle valeur'' – ChesuCR