Edit in JSFiddle

requirejs.config({
  // Path mappings for the logical module names
  paths: {
    'knockout': '//cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min',
    'jquery': '//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min',
    "jqueryui": "//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui",
    "jqueryui-amd": "//cdn.rawgit.com/jquery/jquery-ui/1-11-stable/ui",

    "promise": "//cdn.rawgit.com/components/es6-promise/c95149ffaa2e8162601c57d4282362eac84f929b/promise.min",
    "hammerjs": "//cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.4/hammer.min",
    "ojdnd": "//cdn.rawgit.com/oracle/oraclejet/master/dist/js/libs/dnd-polyfill/dnd-polyfill-1.0.0.min",
    "ojs": "//cdn.rawgit.com/oracle/oraclejet/master/dist/js/libs/oj/debug",
    "ojL10n": "//cdn.rawgit.com/oracle/oraclejet/master/dist/js/libs/oj/ojL10n",
    "ojtranslations": "//cdn.rawgit.com/oracle/oraclejet/master/dist/js/libs/oj/resources",
    "text": "//cdnjs.cloudflare.com/ajax/libs/require-text/2.0.12/text.min",
    "signals": "//cdnjs.cloudflare.com/ajax/libs/js-signals/1.0.0/js-signals.min",
  },
  // Shim configurations for modules that do not expose AMD
  shim: {
    'jqueryui-amd': {
      exports: "$",
      deps: ['jquery']
    },
    'jquery': {
      exports: ['jQuery', '$']
    }
  },
  config: {
    ojL10n: {
      merge: {
        //'ojtranslations/nls/ojtranslations': 'resources/nls/menu'
        // The following addes en-US to the r.js bundle
        //'ojtranslations/nls/ojtranslations': '../../oj/resources/nls/en-US/localeElements'
      }
    }
  }
});

require(['knockout',
  'ojs/ojcore',
  'jquery',
  'ojs/ojinputtext'
], function(ko, oj, $) {
  'use strict';
  
  // Custom binding handler that wraps ojInputText and provides extra functionality
  ko.bindingHandlers.deleteInputText = {
  		// setup extension to ojInputText as well as register event handlers
      init: function(element, valueAccessor, allBindingsAccessor, ctx) {
        var options = allBindingsAccessor().ojInputTextOptions || {};
        
        // cache clear button state
        var buttonVisible = true;
        
        var getButton = function() {
          return $(element)
            .closest(".delete-ojInputText")
            .find("i");
        }

        var updateButtonState = function(val) {
          if (!!val) {
            if(!buttonVisible) {
              showButton();
            }
          } else {
            if(buttonVisible) {
              hideButton();
            }
          } 
        }
        
        var showButton = function() {
           buttonVisible = true;
           getButton()
              .removeClass("delete-hidden");
        }
        
        var hideButton = function() {
           buttonVisible = false;
           getButton()
             .addClass("delete-hidden");
        }
        
        console.log($(element));
        
        $(element)
          .ojInputText(options)
          .focus(function(evt) {
            var val = valueAccessor()();
            updateButtonState(val);
          })
          .blur(function(evt) {
            hideButton();
          })
          .on({
            'ojoptionchange': function (event, data) {
              //console.log(data)
            	// use option === "value" for final value
              // use option === "rawValue" for each character
            	if(data.option === "rawValue") {
                var val = data.value;
                updateButtonState(val);
                
                var observable = valueAccessor();
                observable(val);
              }
            }
          })
          .closest(".delete-ojInputText")
            // tabindex allows for accessibility
            .append('<i class="fa fa-close" tabindex="0"></i>')
            .find("i")
              .click(function() {
                valueAccessor()("");
              })
              // keydown event for accessibility
              .keydown(function(e) {
                switch(e.keyCode) {
			            case 13: // return
			            case 32: // space
                    // e.target should be the button, so invoke its click handler
                    $(e.target).click();
                    break;
		            }
              }).focus(function() {
                showButton();
              }).blur(function() {
                hideButton();
              });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
          $(element).ojInputText("destroy");
        	console.log("ojInputText destroyed");
        });
        
        //updateButtonState(ko.unwrap(valueAccessor()));
        
      },
      // This is how we update the UI based on observable changes
      update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $(element).ojInputText("option", "value", value);
      }
    };

  var ViewModel = function() {
    var self = this;
    
    self.value = ko.observable();
    
  };

  ko.applyBindings(new ViewModel());
  
});
<div class="content-container">
  <p>
    <label for="text-input">Animated delete button in ojInputText Component</label>
    
    <!-- this is the only important part in the HTML -->
    <input id="text-input" 
           type="text"
           data-bind="deleteInputText: value,
                      ojInputTextOptions: {rootAttributes: {class: 'delete-ojInputText'}}"/>
  </p>
  <!-- output text to demonstrate 2-way data binding -->
  <p>
    You said, "<span data-bind="text: value"></span>"
  </p>
</div>
// Declarations copied from _oj.alta.variables.scss to mimic @import in jsfiddle
$background3Color: #fcfdfe !default;
$border4Color:       #dfe4e7 !default;


@import url('//rawgit.com/oracle/oraclejet/master/dist/css/alta/oj-alta-min.css');
@import url('//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css');
.content-container {
  margin: 10px;
}

.delete-ojInputText i {
  cursor: pointer;
  opacity: 1;
  transition: opacity .25s ease-in-out;
}

.delete-ojInputText i.delete-hidden {
  cursor: auto;
  opacity: 0;
}

.delete-ojInputText i:before {
  margin: 0 10px;
}

.delete-ojInputText input {
  border: none;
  flex: 1;
}

.oj-inputtext.delete-ojInputText {
  align-items: center;
  background-color: $background3Color;
  border: 1px solid $border4Color;
  display: flex;
  flex-flow: row nowrap;
}