-1
<input type="text" id="txtFirstname" data-bind="value:firstName,valueUpdate:'afterkeydown'" />
<i data-bind="css:RequiredStyle(firstName)"></i>
  var ViewModel = function () {
    var self = this;

    self.firstName = ko.observable("Hello World!");

    self.RequiredFieldStyle=function (controlValue) {
        alert('called');
        var hasValue = controlValue().length;
        if (hasValue > 0) {
            return "fa fa-check-circle";
        } else {
            return "fa fa-exclamation-circle";
        }
    };
};

How does one create the utility method for the RequiredFieldStyle function in knockout.js?

Jeroen
  • 60,696
  • 40
  • 206
  • 339

3 Answers3

1

You should subscribe to your input observable and define another observable variable to set CSS of your icon and then whenever the input gets changed the CSS variable gets set automatically .
Example : http://jsfiddle.net/GSvnh/5102/

var MainViewModel = function () {
        var self = this;
        self.firstName = ko.observable("Hello World!");
        self.CSS = ko.observable(); 
        self.firstName.subscribe(function(controlValue){

         var hasValue = controlValue.length;
            if (hasValue > 0) {
                self.CSS("fa fa-check-circle");
            } else {
                self.CSS("fa fa-exclamation-circle");
            }
        })

  }

View :

<input type="text" id="txtFirstname" data-bind="value:firstName,valueUpdate:'afterkeydown'" />
<i data-bind="css:CSS"></i>
Matin Kajabadi
  • 3,414
  • 1
  • 17
  • 21
  • Thanks matt for the reply.By the way i need this function in all my view to show the required field and also to avoid the code repetition i need this method to call from different view. – Sudhesh Gnanasekaran Mar 28 '16 at 18:33
1

Let me offer an alternative. Though using a manual subscription can be useful, there are IMHO more elegant ways to do this in Knockout. The most basic one is a computed observable:

var MainViewModel = function() {
  var self = this;
  self.firstName = ko.observable('');
  self.validnessCssClass = ko.computed(function() {
    return !self.firstName() ? 'fa-exclamation-circle' : 'fa-check-circle';
  });
}

ko.applyBindings(new MainViewModel());
.fa { color: red; font-weight: bold; }
.fa-check-circle:before { content: " "; }
.fa-exclamation-circle:before { content: "!!!"; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<input type="text" data-bind="value: firstName, valueUpdate: 'afterkeydown'" />
<i class="fa" data-bind="css: validnessCssClass"></i>

A second approach uses extenders that will make the resulting code look a lot like that from knockout-validation. Heck, linked docs even contain an example for a required validation, let me post that here ad verbatim:

ko.extenders.required = function(target, overrideMessage) {
    //add some sub-observables to our observable
    target.hasError = ko.observable();
    target.validationMessage = ko.observable();

    //define a function to do validation
    function validate(newValue) {
       target.hasError(newValue ? false : true);
       target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
    }

    //initial validation
    validate(target());

    //validate whenever the value changes
    target.subscribe(validate);

    //return the original observable
    return target;
};
Jeroen
  • 60,696
  • 40
  • 206
  • 339
0

If you need this to be reusable you could use a custom binding

In your case something like this could work

ko.bindingHandlers.checkIcon = {
            init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                $(element).removeClass('fa-check-circle fa-exclamation-circle');
                var v = ko.utils.unwrapObservable(valueAccessor());
                $(element).addClass(v.length ? 'fa-check-circle' : 'fa-exclamation-circle');
            },
            update: function(element, valueAccessor, allBindings, context, bindingContext) {
                $(element).removeClass('fa-check-circle fa-exclamation-circle');
                var v = ko.utils.unwrapObservable(valueAccessor());
                $(element).addClass(v.length ? 'fa-check-circle' : 'fa-exclamation-circle');
            }
        }
        
 var vm = {
   firstName:ko.observable('')
 }
 
 ko.applyBindings(vm);
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<input type="text" data-bind="textInput:firstName"/>

<span class="fa" data-bind="checkIcon:firstName"></span>
AldoRomo88
  • 2,056
  • 1
  • 17
  • 23