Attach DOM handlers in the coach view's load event (the HTML of the view exists then) and scope every query to this.context.element so that a view used twice on a page does not grab its twin's elements:
// Coach view layout (HTML tab)
<div class="cust"><input type="text" class="cust-name"><button class="cust-go">Search</button><ul class="cust-hits"></ul></div>
// load handler
var _this = this, root = this.context.element;
var input = root.querySelector(".cust-name"), button = root.querySelector(".cust-go");
button.addEventListener("click", function () { _this.search(input.value); });
input.addEventListener("change", function (e) { _this.context.binding.set("value", e.target.value); }); // keep the binding in sync
input.addEventListener("keydown", function (e) { if (e.key === "Enter") button.click(); });
this.search = function (term) { /* call the view's Ajax service, then fill root.querySelector(".cust-hits") */ };
// unload handler (BAW 20+): nothing to do for listeners on the view's own elements - they go with the DOM;
// remove listeners you attached to window/document: window.removeEventListener("resize", _this.onResize);Do not use inline onclick="..." attributes in the HTML: the handler would run in the global scope without access to the view. For elements created later (rows rendered by code) use event delegation on the root (root.addEventListener("click", function (e) { if (e.target.matches(".row-delete")) ... })). To fire a boundary event of the view from a DOM click, call _this.context.trigger() - the CSHS then continues its flow.
References