0

I have a json that returns this:

[
    {"home": [
        {"name":"Federico","surname":"","et":"20","citt":"Milano"},
        {"name":"Alberto","surname":"","et":"30","citt":"Milano"},
        {"name":"Mirko","surname":"","et":"30","citt":"Roma"},
        {"name":"Andrea","surname":"","et":"28","citt":"Firenze"}

    ]},
    {"home": [
        {"name":"Brad Pitt"},
        {"name":"Tom Cruise"},
        {"name":"Leonardo DiCaprio"},
        {"name":"Johnny Depp"}

    ]},
    {"home": [
        {"name":"","surname":""},
        {"name":"","surname":""},
        {"name":"","surname":""},
        {"name":"","surname":""}

    ]}

]

When there is a valid value provided for name, for example, I would like to change the background-color of the input box to white. But if the provided value is invalid, I would like to change the background-color back to red.

HTML:

<div class="context">
    <div data-bind="foreach: personList">
        <button data-bind="text: name,click: $root.getInfoPersona($index()), attr: {'id': 'myprefix_' + $index()}"/>
        <button data-bind="text: $index,enable: false"></button>
    </div>

    <form>
        <label>Name: </label>
        <input id="idname" data-bind="value: name, css: { changed: name.isDirty(), notchanged : !name.isDirty() }" />
        <label>Surname: </label>
        <input id="idsurname" data-bind="value: surname, css: { changed: surname.isDirty }" />
        <label>Years: </label>
        <input id="idyears" data-bind="value: years, css: { changed: years.isDirty }" />
        <label>Country: </label>
        <input id="idcountry" data-bind="value: country, css: { changed: country.isDirty }" />
        <button data-bind="click: save">Save Data</button>
        <button data-bind="click: clear">Clear</button>
    </form>
</div>

Javascript:

$(document).ready(function(){
  ko.subscribable.fn.trackDirtyFlag = function() {
    var original = this();

    this.isDirty = ko.computed(function() {
      return this() !== original;
    }, this);

    return this;
  };

  var ViewModel = function() {
    var self=this;
    var pi= (function(){
      var json = null;
      $.ajax({
        'async': false,
        'global': false,
        'url': 'persona.json',
        'dataType': 'json',
        'success': function(data){
          json=data;
        }
      });
      return json;
    })();

    var questionsPerson= pi;
    console.log(questionsPerson);
    self.personList = ko.observableArray(questionsPerson[0].home);
    var n=pi[0].home[0].name;
    var c=pi[0].home[0].surname;
    var e=pi[0].home[0].et;;
    var ci=pi[0].home[0].citt;
    self.name = ko.observable(n).trackDirtyFlag();
    self.surname = ko.observable(c).trackDirtyFlag();
    self.years = ko.observable(e).trackDirtyFlag();
    self.country = ko.observable(ci).trackDirtyFlag();

    self.save = function() {
      alert("Sending changes to server: " + ko.toJSON(self.name));
      alert("Sending changes to server: " + ko.toJSON(this));

    };

    self.clear = function(){
      self.name("");
      self.surname("");
      self.years("");
      self.country("");
    };

    self.getInfoPersona = function(indice){
      var i=indice;
      var ris= pi;
      var n=ris[0].home[indice].name;
      var c=ris[0].home[indice].surname;
      var e=ris[0].home[indice].et;
      var ci=ris[0].home[indice].citt;
      self.name(n);
      self.surname(c);
      self.years(e);
      self.country(ci);
      self.getinfoPersona =     ko.computed( function(){
        return self.name() + " " + self.surname() + " " + self.years() + " " + self.country();
      });

    };
  };
  ko.applyBindings(new ViewModel());
});

First screenshot: the desired effect.

Second screenshot: the wrong effect.

The effect displayed on the second screenshot happens when I click on the second name to change person. The input box becomes "invalid" with background-color=red instead of background-color=white.

2
  • 1
    It's completely predictable result because you do not reset the dirty flags every time you select another person. Commented Mar 12, 2017 at 19:14
  • Can you help me to resolve this problem? Commented Mar 13, 2017 at 8:18

1 Answer 1

1

The quickest way to get it working is to modify your trackDirtyFlag extension:

ko.subscribable.fn.trackDirtyFlag = function() {
    var original = ko.observable(this()); // make original observable

    this.isDirty = ko.computed(function() {
        return this() !== original(); // compare actual and original values
    }, this);

    // this function will reset 'dirty' state by updating original value
    this.resetDirtyFlag = function(){ original(this()); };

    return this;
};

...and call resetDirtyFlag after you reassigned values for editing:

self.name(n);     self.name.resetDirtyFlag();
self.surname(c);  self.surname.resetDirtyFlag();
self.years(e);    self.years.resetDirtyFlag();
self.country(ci); self.country.resetDirtyFlag();

Look at the fiddle to see how it works.

However in general your approach is pretty far from optimal. Maybe this article will be useful for you.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.