Skip to content

Commit

Permalink
Merge e982a89 into 2df2081
Browse files Browse the repository at this point in the history
  • Loading branch information
divdavem committed Apr 23, 2014
2 parents 2df2081 + e982a89 commit d37a73b
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 33 deletions.
60 changes: 27 additions & 33 deletions hsp/rt/eltnode.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ var EltNode = klass({
}
this.gesturesEventHandlers = null;
this.needSubScope = (needSubScope===1);
this.preventRefresh=false; // if true will prevent the field from being refreshed during the typing sequence
this._lastValue = null;
},

$dispose : function () {
Expand Down Expand Up @@ -207,30 +207,27 @@ var EltNode = klass({

// if the element is an input tag we synchronize the value
if (this.isInput && this.inputModelExpIdx) {
this.preventRefresh=false;
var exp = this.eh.getExpr(this.inputModelExpIdx);
if (exp.setValue) {
if (et==="keydown") {
// value is updated on keyup - so we must no refresh the field if the model
// is updated during keydown, otherwise the value is lost
this.preventRefresh=true;
} else if (et==="input" || et==="keyup" || et==="click" || et==="focus") {
if (et==="input" || et==="keyup" || et==="click" || et==="focus") {
// push the field value to the data model
// note: when the input event is properly implemented we don't need to listen to keyup
// but IE8 and IE9 don't implement it completely - thus the need for keyup
var v = this.node.value, tp = this.node.type;
if (tp === "checkbox") {
v = this.node.checked;
}

this._lastValue = v; // to avoid refreshing the field and move the cursor
var currentValue=exp.getValue(this.vscope,this.eh);
//log("[EltNode] handleEvent("+et+"): previous model value:["+currentValue+"] new value (from input):["+v+"]");
// if the value is already set no need to set it again and force a resync
if (v!==currentValue) {
exp.setValue(this.vscope, v);
// force refresh to resync other fields linked to the same data immediately
hsp.refresh();
if (v!==this._lastValue) {
// only set the value in the data model if the value in the field changed
this._lastValue = v;
var currentValue=exp.getValue(this.vscope,this.eh);
//log("[EltNode] handleEvent("+et+"): previous model value:["+currentValue+"] new value (from input):["+v+"]");
// if the value is already set no need to set it again and force a resync
if (v!==currentValue) {
exp.setValue(this.vscope, v);
// force refresh to resync other fields linked to the same data immediately
hsp.refresh();
}
}
}
}
Expand Down Expand Up @@ -330,25 +327,22 @@ var EltNode = klass({
if (this.inputModelExpIdx) {
// update the checked state (must be done at the end as the value attribute may not have been set)
var exp = this.eh.getExpr(this.inputModelExpIdx), v1 = '' + exp.getValue(vs, this.eh, "");
if (nd.type === "radio") {
var v2 = '' + nd.value;
nd.checked = (v1 === v2);
} else if (nd.type === "checkbox") {
var v2 = '' + nd.checked;
if (v1 !== v2) {
nd.checked = !nd.checked;
}
} else {
if (this._lastValue !== v1) {
// value change has not been triggered by typing in this field

if (!this.preventRefresh && v1!=nd.value) {
//only update if value is changing and if we are not between 'onkeydown' and 'onkeyup'
//log("[EltNode] Node value update: current value:["+nd.value+"] new value:["+v1+"]");
nd.value = v1;
if (v1 !== this._lastValue) {
// only set the value if it changed in the model since last sync
this._lastValue = v1;
if (nd.type === "radio") {
var v2 = '' + nd.value;
nd.checked = (v1 === v2);
} else if (nd.type === "checkbox") {
var v2 = '' + nd.checked;
if (v1 !== v2) {
nd.checked = !nd.checked;
}
} else if (v1!=nd.value) {
//only update if value is changing
//log("[EltNode] Node value update: current value:["+nd.value+"] new value:["+v1+"]");
nd.value = v1;
}
this._lastValue = null;
}
}
}
Expand Down
71 changes: 71 additions & 0 deletions public/test/rt/input.spec.hsp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,78 @@ var hsp=require("hsp/rt"),
</div>
# /template

# template enterEmptiesFieldSample(object)
<div class="info section">Please type a command and press enter.</div>
<pre>{object.commandsHistory}</pre>
<input type="text" value="{object.value}" onkeydown="{object.keydown(event)}" placeholder="Your command"><br>
<input type="text" model="{object.value}" onkeydown="{object.keydown(event)}" placeholder="Your command"><br>
# /template

describe("Input Elements", function () {
it("input model sync", function () {
var v1 = "init value";
var enterKeyDownCalled = 0;
var object = {
commandsHistory: "",
value: v1,
keydown: function (event) {
if (event.keyCode == 13) { // enter key
enterKeyDownCalled++;
json.set(this, "commandsHistory", this.commandsHistory + "\n" + this.value);
json.set(this, "value", ""); // this should empty the field
}
}
};
var n = enterEmptiesFieldSample(object);
var input1 = n.childNodes[2];
var input2 = n.childNodes[4];

expect(input1.node.value).to.equal(v1);
expect(input2.node.value).to.equal(v1);

// test with input 1
var v2 = "new value";
input1.node.value = v2;
fireEvent("keydown", input1.node);
fireEvent("keyup", input1.node);
hsp.refresh();

expect(object.value).to.equal(v2);
expect(input1.node.value).to.equal(v2);
expect(input2.node.value).to.equal(v2);

expect(enterKeyDownCalled).to.equal(0);
fireEvent("keydown", input1.node, {keyCode: 13});
fireEvent("keyup", input1.node, {keyCode: 13});
expect(enterKeyDownCalled).to.equal(1);
hsp.refresh();

expect(object.value).to.equal("");
expect(input1.node.value).to.equal("");
expect(input2.node.value).to.equal("");

// test with input 2
var v3 = "other value";
input2.node.value = v3;
fireEvent("keydown", input2.node);
fireEvent("keyup", input2.node);
hsp.refresh();

expect(object.value).to.equal(v3);
expect(input1.node.value).to.equal(v3);
expect(input2.node.value).to.equal(v3);

expect(enterKeyDownCalled).to.equal(1);
fireEvent("keydown", input2.node, {keyCode: 13});
fireEvent("keyup", input2.node, {keyCode: 13});
expect(enterKeyDownCalled).to.equal(2);
hsp.refresh();

expect(object.value).to.equal("");
expect(input1.node.value).to.equal("");
expect(input2.node.value).to.equal("");
});

it("validates text elements", function () {
var v1 = "edit me!";
var d = {
Expand Down

0 comments on commit d37a73b

Please sign in to comment.