How to get the node and keyboard reference of TVML

2019-06-04 19:03发布

问题:

Someone asked the same question here How do you get the value from a TVML textField? but didn't explain the full answer and my comment there was edited, suggesting me to ask a brand new question. Here it is...

Can anyone help understand how to best get a reference to the textField node and its keyboard value from TVML? Right now I'm using this code below in Presenter.js to get to the textField once the user clicks the Done button in the template displaying the form & keyboard, but still get

ITML : undefined is not an object (evaluating 'textField.getFeature') - .../js/Presenter.js

when I use getFeature("Keyboard"):

load: function(event) {  
var self = this,  
    ele = event.target,  
    templateURL = ele.getAttribute("template"),  
    presentation = ele.getAttribute("presentation"),  
    videoURL = ele.getAttribute("videoURL");  

if (templateURL && (event.type == "select")) {  
    var formTemplate = ele.parentNode.parentNode; // that should give me <formTemplate> element  
    var children = formTemplate.childNodes;  
    var textField = children[1]; // which is the second element in <formTemplate><banner></banner><textField></textField>...  
    var keyboard = textField.getFeature("Keyboard"); // this raises the ITML Error...  
    ...........................

UPDATE:

I found the solution by looking into accessing elements by traversing XML DOM:

var formTemplate = ele.parentNode.parentNode; // your formTemplate button  
var children = formTemplate.childNodes;  
var textField = children.item(1); // replace "1" with the index of "textField" element in your template  
var keyboard = textField.getFeature("Keyboard"); // get the textField's Keyboard element  
var userValue = keyboard.text; // the value entered by the user on the Apple TV keyboard 

回答1:

How about starting at the document's root? Use getElementsByTagName, getElementByTagName or getElementById to access the textField.

var doc = navigationDocument.documents[navigationDocument.documents.length-1];
var textField = doc.getElementByTagName("textField")

var value = textField.getFeature("Keyboard").text;


回答2:

Assumed the self explained solution, I'm adding to be complete the text on change callback:

var keyboard = textField.getFeature("Keyboard");
keyboard.onTextChange = function () {
  console.log("onTextChange "+keyboard.text)
}

And supposed that the formTemplate is like

<formTemplate>
    <banner>
      <title>${formTitle}</title>
      <description class="longDescriptionLayout">${formDescription}</description>
    </banner>
    <textField>${formPlaceholder}</textField>
    <footer>
      <button id="pairingCodeInput">
        <text>Confirm</text>
      </button>
    </footer>
  </formTemplate>

in the Presenter class I would add to handle more selectors something like:

if ((event.type == "select")) { // item selected
    if (itemId == "pairingCodeInput") { // form input
        var formTemplate = ele.parentNode.parentNode;
        var children = formTemplate.childNodes
        var textField = children.item(1)
        var keyboard = textField.getFeature("Keyboard")
        keyboard.onTextChange = function() {
            console.log("onTextChange " + keyboard.text)
        }
        var userValue = keyboard.text
        console.log("Entered " + userValue)

    }
}


回答3:

You need to use

xmlElem.item(i)

instead of

xmlElem.item[i]