зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1098251 - Allow a contact to be created with either a phone number or an email address. r=MattN
This commit is contained in:
Родитель
888dbec214
Коммит
fcd99471b4
|
@ -52,36 +52,33 @@ loop.contacts = (function(_, mozL10n) {
|
|||
* for the contact. Both fields are optional.
|
||||
* @param {object} contact
|
||||
* The contact object to get the field from.
|
||||
* @param {object} data
|
||||
* An object that has a 'field' property. If the 'optional' field
|
||||
* is defined and true, then the field will only be set if the
|
||||
* 'value' is not empty or if the previous value was defined.
|
||||
* @param {string} field
|
||||
* The field within the contact to set.
|
||||
* @param {string} value
|
||||
* The value that the field should be set to.
|
||||
*/
|
||||
let setPreferred = function(contact, data) {
|
||||
if (data.optional) {
|
||||
// Don't clear the field if it doesn't exist.
|
||||
if (!data.value &&
|
||||
(!contact[data.field] || !contact[data.field].length)) {
|
||||
return;
|
||||
}
|
||||
let setPreferred = function(contact, field, value) {
|
||||
// Don't clear the field if it doesn't exist.
|
||||
if (!value && (!contact[field] || !contact[field].length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!contact[data.field]) {
|
||||
contact[data.field] = [];
|
||||
if (!contact[field]) {
|
||||
contact[field] = [];
|
||||
}
|
||||
|
||||
if (!contact[data.field].length) {
|
||||
contact[data.field][0] = {"value": data.value};
|
||||
if (!contact[field].length) {
|
||||
contact[field][0] = {"value": value};
|
||||
return;
|
||||
}
|
||||
// Set the value in the preferred tuple and return.
|
||||
for (let i in contact[data.field]) {
|
||||
if (contact[data.field][i].pref) {
|
||||
contact[data.field][i].value = data.value;
|
||||
for (let i in contact[field]) {
|
||||
if (contact[field][i].pref) {
|
||||
contact[field][i].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
contact[data.field][0].value = data.value;
|
||||
contact[field][0].value = value;
|
||||
};
|
||||
|
||||
const ContactDropdown = React.createClass({displayName: 'ContactDropdown',
|
||||
|
@ -563,8 +560,11 @@ loop.contacts = (function(_, mozL10n) {
|
|||
pristine: false,
|
||||
});
|
||||
|
||||
let emailInput = this.refs.email.getDOMNode();
|
||||
let telInput = this.refs.tel.getDOMNode();
|
||||
if (!this.refs.name.getDOMNode().checkValidity() ||
|
||||
!this.refs.email.getDOMNode().checkValidity()) {
|
||||
((emailInput.required || emailInput.value) && !emailInput.checkValidity()) ||
|
||||
((telInput.required || telInput.value) && !telInput.checkValidity())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -575,10 +575,8 @@ loop.contacts = (function(_, mozL10n) {
|
|||
switch (this.props.mode) {
|
||||
case "edit":
|
||||
this.state.contact.name[0] = this.state.name.trim();
|
||||
setPreferred(this.state.contact,
|
||||
{field: "email", value: this.state.email.trim()});
|
||||
setPreferred(this.state.contact,
|
||||
{field: "tel", value: this.state.tel.trim(), optional: true});
|
||||
setPreferred(this.state.contact, "email", this.state.email.trim());
|
||||
setPreferred(this.state.contact, "tel", this.state.tel.trim());
|
||||
contactsAPI.update(this.state.contact, err => {
|
||||
if (err) {
|
||||
throw err;
|
||||
|
@ -622,7 +620,8 @@ loop.contacts = (function(_, mozL10n) {
|
|||
|
||||
render: function() {
|
||||
let cx = React.addons.classSet;
|
||||
// XXX do we need the ref="" attributes below?
|
||||
let phoneOrEmailRequired = !this.state.email && !this.state.tel;
|
||||
|
||||
return (
|
||||
React.DOM.div({className: "content-area contact-form"},
|
||||
React.DOM.header(null, this.props.mode == "add"
|
||||
|
@ -633,11 +632,11 @@ loop.contacts = (function(_, mozL10n) {
|
|||
className: cx({pristine: this.state.pristine}),
|
||||
valueLink: this.linkState("name")}),
|
||||
React.DOM.label(null, mozL10n.get("edit_contact_email_label")),
|
||||
React.DOM.input({ref: "email", required: true, type: "email",
|
||||
React.DOM.input({ref: "email", type: "email", required: phoneOrEmailRequired,
|
||||
className: cx({pristine: this.state.pristine}),
|
||||
valueLink: this.linkState("email")}),
|
||||
React.DOM.label(null, mozL10n.get("new_contact_phone_placeholder")),
|
||||
React.DOM.input({ref: "tel", type: "tel",
|
||||
React.DOM.input({ref: "tel", type: "tel", required: phoneOrEmailRequired,
|
||||
className: cx({pristine: this.state.pristine}),
|
||||
valueLink: this.linkState("tel")}),
|
||||
ButtonGroup(null,
|
||||
|
|
|
@ -52,36 +52,33 @@ loop.contacts = (function(_, mozL10n) {
|
|||
* for the contact. Both fields are optional.
|
||||
* @param {object} contact
|
||||
* The contact object to get the field from.
|
||||
* @param {object} data
|
||||
* An object that has a 'field' property. If the 'optional' field
|
||||
* is defined and true, then the field will only be set if the
|
||||
* 'value' is not empty or if the previous value was defined.
|
||||
* @param {string} field
|
||||
* The field within the contact to set.
|
||||
* @param {string} value
|
||||
* The value that the field should be set to.
|
||||
*/
|
||||
let setPreferred = function(contact, data) {
|
||||
if (data.optional) {
|
||||
// Don't clear the field if it doesn't exist.
|
||||
if (!data.value &&
|
||||
(!contact[data.field] || !contact[data.field].length)) {
|
||||
return;
|
||||
}
|
||||
let setPreferred = function(contact, field, value) {
|
||||
// Don't clear the field if it doesn't exist.
|
||||
if (!value && (!contact[field] || !contact[field].length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!contact[data.field]) {
|
||||
contact[data.field] = [];
|
||||
if (!contact[field]) {
|
||||
contact[field] = [];
|
||||
}
|
||||
|
||||
if (!contact[data.field].length) {
|
||||
contact[data.field][0] = {"value": data.value};
|
||||
if (!contact[field].length) {
|
||||
contact[field][0] = {"value": value};
|
||||
return;
|
||||
}
|
||||
// Set the value in the preferred tuple and return.
|
||||
for (let i in contact[data.field]) {
|
||||
if (contact[data.field][i].pref) {
|
||||
contact[data.field][i].value = data.value;
|
||||
for (let i in contact[field]) {
|
||||
if (contact[field][i].pref) {
|
||||
contact[field][i].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
contact[data.field][0].value = data.value;
|
||||
contact[field][0].value = value;
|
||||
};
|
||||
|
||||
const ContactDropdown = React.createClass({
|
||||
|
@ -563,8 +560,11 @@ loop.contacts = (function(_, mozL10n) {
|
|||
pristine: false,
|
||||
});
|
||||
|
||||
let emailInput = this.refs.email.getDOMNode();
|
||||
let telInput = this.refs.tel.getDOMNode();
|
||||
if (!this.refs.name.getDOMNode().checkValidity() ||
|
||||
!this.refs.email.getDOMNode().checkValidity()) {
|
||||
((emailInput.required || emailInput.value) && !emailInput.checkValidity()) ||
|
||||
((telInput.required || telInput.value) && !telInput.checkValidity())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -575,10 +575,8 @@ loop.contacts = (function(_, mozL10n) {
|
|||
switch (this.props.mode) {
|
||||
case "edit":
|
||||
this.state.contact.name[0] = this.state.name.trim();
|
||||
setPreferred(this.state.contact,
|
||||
{field: "email", value: this.state.email.trim()});
|
||||
setPreferred(this.state.contact,
|
||||
{field: "tel", value: this.state.tel.trim(), optional: true});
|
||||
setPreferred(this.state.contact, "email", this.state.email.trim());
|
||||
setPreferred(this.state.contact, "tel", this.state.tel.trim());
|
||||
contactsAPI.update(this.state.contact, err => {
|
||||
if (err) {
|
||||
throw err;
|
||||
|
@ -622,7 +620,8 @@ loop.contacts = (function(_, mozL10n) {
|
|||
|
||||
render: function() {
|
||||
let cx = React.addons.classSet;
|
||||
// XXX do we need the ref="" attributes below?
|
||||
let phoneOrEmailRequired = !this.state.email && !this.state.tel;
|
||||
|
||||
return (
|
||||
<div className="content-area contact-form">
|
||||
<header>{this.props.mode == "add"
|
||||
|
@ -633,11 +632,11 @@ loop.contacts = (function(_, mozL10n) {
|
|||
className={cx({pristine: this.state.pristine})}
|
||||
valueLink={this.linkState("name")} />
|
||||
<label>{mozL10n.get("edit_contact_email_label")}</label>
|
||||
<input ref="email" required type="email"
|
||||
<input ref="email" type="email" required={phoneOrEmailRequired}
|
||||
className={cx({pristine: this.state.pristine})}
|
||||
valueLink={this.linkState("email")} />
|
||||
<label>{mozL10n.get("new_contact_phone_placeholder")}</label>
|
||||
<input ref="tel" type="tel"
|
||||
<input ref="tel" type="tel" required={phoneOrEmailRequired}
|
||||
className={cx({pristine: this.state.pristine})}
|
||||
valueLink={this.linkState("tel")} />
|
||||
<ButtonGroup>
|
||||
|
|
|
@ -75,6 +75,80 @@ describe("loop.contacts", function() {
|
|||
expect(addButton).to.not.equal(null);
|
||||
expect(addButton.textContent).to.eql(fakeAddContactButtonText);
|
||||
});
|
||||
it("should have all fields required by default", function() {
|
||||
var view = TestUtils.renderIntoDocument(
|
||||
loop.contacts.ContactDetailsForm({mode: "add"}));
|
||||
var nameInput = view.getDOMNode().querySelector("input[type='text']");
|
||||
var telInput = view.getDOMNode().querySelector("input[type='tel']");
|
||||
var emailInput = view.getDOMNode().querySelector("input[type='email']");
|
||||
|
||||
expect(nameInput.required).to.equal(true);
|
||||
expect(emailInput.required).to.equal(true);
|
||||
expect(telInput.required).to.equal(true);
|
||||
});
|
||||
it("should have email and tel required after a name is input", function() {
|
||||
var view = TestUtils.renderIntoDocument(
|
||||
loop.contacts.ContactDetailsForm({mode: "add"}));
|
||||
var nameInput = view.getDOMNode().querySelector("input[type='text']");
|
||||
TestUtils.Simulate.change(nameInput, {target: {value: "Jenny"}});
|
||||
var telInput = view.getDOMNode().querySelector("input[type='tel']");
|
||||
var emailInput = view.getDOMNode().querySelector("input[type='email']");
|
||||
|
||||
expect(nameInput.required).to.equal(true);
|
||||
expect(emailInput.required).to.equal(true);
|
||||
expect(telInput.required).to.equal(true);
|
||||
});
|
||||
it("should allow a contact with only a name and a phone number", function() {
|
||||
var view = TestUtils.renderIntoDocument(
|
||||
loop.contacts.ContactDetailsForm({mode: "add"}));
|
||||
var nameInput = view.getDOMNode().querySelector("input[type='text']");
|
||||
TestUtils.Simulate.change(nameInput, {target: {value: "Jenny"}});
|
||||
var telInput = view.getDOMNode().querySelector("input[type='tel']");
|
||||
TestUtils.Simulate.change(telInput, {target: {value: "867-5309"}});
|
||||
var emailInput = view.getDOMNode().querySelector("input[type='email']");
|
||||
|
||||
expect(nameInput.checkValidity()).to.equal(true, "nameInput");
|
||||
expect(emailInput.required).to.equal(false, "emailInput");
|
||||
expect(telInput.checkValidity()).to.equal(true, "telInput");
|
||||
});
|
||||
it("should allow a contact with only a name and email", function() {
|
||||
var view = TestUtils.renderIntoDocument(
|
||||
loop.contacts.ContactDetailsForm({mode: "add"}));
|
||||
var nameInput = view.getDOMNode().querySelector("input[type='text']");
|
||||
TestUtils.Simulate.change(nameInput, {target: {value: "Example"}});
|
||||
var emailInput = view.getDOMNode().querySelector("input[type='email']");
|
||||
TestUtils.Simulate.change(emailInput, {target: {value: "test@example.com"}});
|
||||
var telInput = view.getDOMNode().querySelector("input[type='tel']");
|
||||
|
||||
expect(nameInput.checkValidity()).to.equal(true);
|
||||
expect(emailInput.checkValidity()).to.equal(true);
|
||||
expect(telInput.required).to.equal(false);
|
||||
});
|
||||
it("should not allow a contact with only a name", function() {
|
||||
var view = TestUtils.renderIntoDocument(
|
||||
loop.contacts.ContactDetailsForm({mode: "add"}));
|
||||
var nameInput = view.getDOMNode().querySelector("input[type='text']");
|
||||
TestUtils.Simulate.change(nameInput, {target: {value: "Example"}});
|
||||
var emailInput = view.getDOMNode().querySelector("input[type='email']");
|
||||
var telInput = view.getDOMNode().querySelector("input[type='tel']");
|
||||
|
||||
expect(nameInput.checkValidity()).to.equal(true);
|
||||
expect(emailInput.checkValidity()).to.equal(false);
|
||||
expect(telInput.checkValidity()).to.equal(false);
|
||||
});
|
||||
it("should not allow a contact without name", function() {
|
||||
var view = TestUtils.renderIntoDocument(
|
||||
loop.contacts.ContactDetailsForm({mode: "add"}));
|
||||
var nameInput = view.getDOMNode().querySelector("input[type='text']");
|
||||
var emailInput = view.getDOMNode().querySelector("input[type='email']");
|
||||
TestUtils.Simulate.change(emailInput, {target: {value: "test@example.com"}});
|
||||
var telInput = view.getDOMNode().querySelector("input[type='tel']");
|
||||
TestUtils.Simulate.change(telInput, {target: {value: "867-5309"}});
|
||||
|
||||
expect(nameInput.checkValidity()).to.equal(false);
|
||||
expect(emailInput.checkValidity()).to.equal(true);
|
||||
expect(telInput.checkValidity()).to.equal(true);
|
||||
});
|
||||
});
|
||||
describe("edit mode", function() {
|
||||
it("should render 'edit' header", function() {
|
||||
|
@ -137,28 +211,21 @@ describe("loop.contacts", function() {
|
|||
it("should not set the value on the object if the new value is empty," +
|
||||
" it didn't exist before, and it is optional", function() {
|
||||
var contact = {};
|
||||
loop.contacts._setPreferred(contact, {field: "fakeField", value: "", optional: true});
|
||||
loop.contacts._setPreferred(contact, "fakeField", "");
|
||||
|
||||
expect(contact).to.not.have.property("fakeField");
|
||||
});
|
||||
it("should clear the value on the object if the new value is empty," +
|
||||
" it existed before, and it is optional", function() {
|
||||
var contact = {fakeField: [{value: "foobar"}]};
|
||||
loop.contacts._setPreferred(contact, {field: "fakeField", value: "", optional: true});
|
||||
loop.contacts._setPreferred(contact, "fakeField", "");
|
||||
|
||||
expect(contact["fakeField"][0].value).to.eql("");
|
||||
});
|
||||
it("should set the value on the object if the new value is empty," +
|
||||
" and it did not exist before", function() {
|
||||
var contact = {};
|
||||
loop.contacts._setPreferred(contact, {field: "fakeField", value: ""});
|
||||
|
||||
expect(contact).to.have.property("fakeField");
|
||||
});
|
||||
it("should set the value on the object if the new value is empty," +
|
||||
" and it did not exist before", function() {
|
||||
var contact = {fakeField: [{value: "foobar"}]};
|
||||
loop.contacts._setPreferred(contact, {field: "fakeField", value: "barbaz"});
|
||||
loop.contacts._setPreferred(contact, "fakeField", "barbaz");
|
||||
|
||||
expect(contact["fakeField"][0].value).to.eql("barbaz");
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче