so I am trying to get the fields in my backbone model being called in the view, editable and validated by the model. How do I go about doing that? I know there is an html way of doing contenteditable="true" but I am looking for a more backbone oriented way or a way to actually make that validate too.
Here is my current code for my main.js file (but I am not trying to .append it I want it to stay in place and also trying to figure out how to get the field to be called specifically depending on which text they clicked on. Ultimately the button should change too (to save changes).
The main.js
App.Models.User = Backbone.Model.extend({
defaults: {
firstName: 'first',
lastName: 'last',
email: 'Email',
phone: '222',
birthday: 'date'
},
validate: function (attrs) {
if (!attrs.firstName) {
return 'You must enter a real first name.';
}
if (!attrs.lastName) {
return 'You must enter a real last name.';
}
if (attrs.email.length < 5) {
return 'You must enter a real email.';
}
if (attrs.phone.length < 10 && attrs.phone === int) {
return 'You must enter a real phone number, if you did please remove the dash and spaces.';
}
if (attrs.city.length < 2) {
return 'You must enter a real city.';
}
}
});
App.Views.UserUpdate = Backbone.View.extend({
model: App.Models.User,
events: {
'click .edit': 'editUserProfile'
},
editUserProfile: function(field) {
var field =
$('#user').append('<input type="text" class="edit" placeholder="' + field+'" /> ' );
},
initialize: function() {
this.model.on('change', function() {
this.render();
}, this);
},
render: function() {
this.$el.html(this.model.get('email'));
}
});
This is the jade file:
extends layout
block content
div.centerContent
script(type="text/javascript", src="/js/main.js")
h4 User goes here with equal before it no space
div(contenteditable="true")
form#user
- var firstName = "John"
- var lastName = "Smith"
label #{firstName} #{lastName}
- var email = "test#test.com"
label.edit #{email}
- var phone = "555-555-5757"
label #{phone}
- var pin = "PIN: LIO20001"
label #{pin}
- var birthday = "07/28/1982"
label #{birthday}
button Post
hr
div.user User
p
button.edit Edit
I have created a fiddle for this: http://jsfiddle.net/LTGjT/18/
You should assign the contenteditable and id for each editable label:
- var firstName = "John"
- var lastName = "Smith"
label #{firstName} #{lastName}
- var email = "test#test.com"
label(contenteditable="true", id="email") #{email}
- var phone = "555-555-5757"
label(contenteditable="true", id="phone") #{phone}
- var birthday = "07/28/1982"
label(contenteditable="true", id="birthday") #{birthday}
The reason is to recognize what label is being edited by getting the event.target, in your old code the event.target will always be the parent div.
Then in backbone listen to the input event for the change of the label then update the model:
App.Models.User = Backbone.Model.extend({
defaults: {
firstName: 'first',
lastName: 'last',
email: 'abc#abc.com',
phone: '222',
birthday: '01/01/2001'
},
initialize: function() {
},
validate: function (attrs) {
if (!attrs.firstName) {
return 'You must enter a real first name.';
}
if (!attrs.lastName) {
return 'You must enter a real last name.';
}
if (attrs.email.length < 5) {
return 'You must enter a real email.';
}
if (attrs.phone.length < 10 && attrs.phone === int) {
return 'You must enter a real phone number, if you did please remove the dash and spaces.';
}
if (attrs.city.length < 2) {
return 'You must enter a real city.';
}
}
});
App.Views.UserUpdate = Backbone.View.extend({
model: App.Models.User,
events: {
'click button' : 'saveHandler'
},
initialize: function() {
var self = this;
self.render();
console.log(this.model);
$('[contenteditable=true]').on('input', function(e){
var field = e.target.id;
var value = e.target.innerText;
self.model.set(field, value);
logUser(self.model);
});
self.model.on('change', function(){
$('button').show();
});
},
saveHandler: function(e) {
//Validate & Save logic
//this.model.save()
e.preventDefault();
$(e.target).hide();
},
render: function() {
var template = _.template($('#user-view').html());
this.$el.html(template({user: this.model.toJSON()}));
$('body').prepend(this.$el);
logUser(this.model);
}
});
Related
Hi all how could I insert a (if) statement to this code that if (element1) value is not blank then (element2) is required before submitting.
I'm already using a list of validated element that needs to be filled before subtitling
I would like to add a few more to that list depending on if some element are not empty.
Here's part of the code I'm not sure how or where to inset the if statement.
function submitBotton() {
var tool1 = document.getElementById("OtherEquipment1").value
if (tool1 !== '') {
toolowner1: "Equipment Owner is required!",
}
var toValidate = {
prefDate: "Date is required!",
Person: "Name is required!",
Loc: "Location is required!",
Time: "Time is required!",
};
var idKeys = Object.keys(toValidate);
var allValid = true;
idKeys.forEach(function(id) {
var isValid = checkIfValid(id, toValidate[id]);
if (!isValid) {
allValid = false;
}
});
if (allValid) {
addRecord();
}
}
Thanks
I wonder how do I get the input value from the form in ExtJS.
I have tried several ways "see comments", but none of them gave me a value, i get an error mostly - "undefined".
Another thing that is unclear is where is form name defined ?
Here's my code:
Ext.onReady(function() {
Ext.create('Ext.form.Panel', {
renderTo: document.body,
title: 'Convert Roman characters to Arabic',
height: 150,
width: 300,
bodyPadding: 10,
defaultType: 'textfield',
items: [
{
fieldLabel: 'Enter Roman Character',
name: 'char'
}
],
buttons: [
{
text: 'Submit',
handler: function() {
//var form = formPanel.getForm();
//var value = form.findField('char');
//var form = this.up('form'); // get the form panel
//var value = Ext.getCmp('char').getValue();
// var field = Ext.getCmp('char');
Ext.Msg.alert('Success', "value");
}
}
]
});
});
In the end the application should alert the inputed value.
Thanks in Advance.
text: 'Submit',
handler: function(btn) {
Ext.Msg.alert('Success',btn.up('form').down('[name=char]').getValue());
//var form = formPanel.getForm();
//var value = form.findField('char');
//var form = this.up('form'); // get the form panel
//var value = Ext.getCmp('char').getValue();
// var field = Ext.getCmp('char');
There are multi ways to get value of char field.
1) To get value like this as you used, you have to give id property for this field :
{
fieldLabel: 'Enter Roman Character',
name: 'char',
id : 'char' // or give any name
}
now used below code to get value
var field = Ext.getCmp('char');
var value = field.getValue();
2) You can also use itemId property same :
{
fieldLabel: 'Enter Roman Character',
name: 'char',
itemId : 'char' // or give any name
}
now used below code to get value
var field = Ext.ComponentQuery.query('#char')[0];
var value = field.getValue();
3) another way, you can get value from form values;
var form = this.up('form'),
formValues = form.getForm().getValues();
charValue = formValues.char;
I have a dynamic table, which each row contains country and numberOfState fields. Currently I am able to add new record and validate the country and numberOfState field separately (e.g. required) after click the "AddNewRecord" button, which is below code that generate dynamic table unique field name, i.e. name="country_0", "numberOfState_0" for 1st row, and ="country_1", "numberOfState_1" for 2nd row and etc.
Would like to check whether can validate the dynamic country and numberOfState fields together (i.e. Country is US and NumberOfState must be 50), using dynamic rule code as per below addRowRule function. Thanks in advance.
$(document).ready(function(e){
var rowindex = 0;
$("#AddNewRecord").click(function(){
var row =
"<tr><td>input name=country_"+rowindex+" type=text class='countryRule'/></td>
<tr><td>input name=numberOfState_"+rowindex+" type=text class='stateRule'/></td></tr>";
$("#table").append(row);
rowindex++;
addRowRule(rowindex);
});
jQuery.validate.addClassRules({
countryRule:{required:true},
stateRule:{required:true}
});
$('form').validate();
function addRowRule(i) {
var country = '#country_' + i,
var numberOfState = '#numberOfState_' + i;
$(country).rules('add', {
required: true,
numberOfState:{
required: {
depend: function(element){
if ($(country).val() == 'US' &&
$(numberOfState).val() !=50){
return false;
}
return true;
}
messages: {
numberOfState: "Number of state not match with country",
}
},
messages: {
required: "Required input",
}
});
});
Updated code to share with all:
$( document ).ready(function() {
$("#myForm").validate(); //sets up the validator
var rowindex = 0;
$("#AddNewRecord").click(function(){
var row = "<tr><td>input name=country_"+rowindex+" type=text /></td>" +
"<tr><td>input name=numberOfState_"+rowindex+" type=text /></td></tr>";
$("#table").append(row);
addRowRule(rowindex);
rowindex++;
});
function addRowRule(row_index) {
var country = '#country_' + row_index;
var numberOfState = '#numberOfState_' + row_index;
$(country).rules('add', {
required: true,
messages: {
required: "Pls input country."
}
});
$(numberOfState).rules('add', {
required: true,
checkCountryAndState: [country, numberOfState],
messages: {
required: "Pls input number of state."
}
});
}
jQuery.validator.addMethod("checkCountryAndState", function(value, element, params){
var varCountry = params[0];
var varNumberOfState = params[1];
if ($(varCountry).val() === 'America' && $(varNumberOfState).val() !== 50){
return false;
}
return true;
}, jQuery.format("Country is not match with Number of State."));
});
You can specify validation rules with the rules property. This should do what you specified in the question as an example:
$(".selector").validate({
rules: {
field2: {
required: true,
field1: {
depends: function(element) {
if ($('#field1').val() === 'A' && $('#field2').val() === 'Z') {
return false;
}
return true;
}
}
}
}
});
After this, you need to assign a message if the validation fails with the messages property.
Part of your problem is putting invalid objects inside of the .rules() method. Since the .rules() method is already attached to a selector (representing a SINGLE field), you cannot declare rules for additional fields inside of it...
function addRowRule(i) {
var country = '#country_' + i,
var numberOfState = '#numberOfState_' + i;
$(country).rules('add', {
required: true,
numberOfState: { // <- you can NOT put this here
required: { ...
The only objects allowed inside of .rules() is a key: value list of various rules/methods and/or the messages object.
You would have to attach other fields to different instances of .rules()....
function addRowRule(i) {
var country = '#country_' + i,
var numberOfState = '#numberOfState_' + i;
$(country).rules('add', {
required: true,
....
});
$(numberOfState).rules('add', {
required: true,
....
});
....
I am using BackboneJS MVC pattern and have a form with 2 fields which the user can select.
I call changeAction whenever there is any change in selection by the user (to call validation);
changeAction: function (event) {
var self = this;
var target = event.target;
target.value = $.trim(target.value);
change[target.name] = target.value;
this.model.set(change);
var check = self.model.validateItem(target.id);
if (check.isValid === false) {
self.addValidationError(target.id, check.message);
} else {
self.removeValidationError(target.id);
}
}
My validation is defined in the Model as below;
this.validators.myDropDownField = function(value) {
return !_.isUndefined(value) && !_.isNull(value) && $.trim(value).length > 0 ? {
isValid: true
} : {
isValid: false,
message: "Select dropdown field"
};
};
validateItem: function(key) {
var result = (this.validators[key]) ? this.validators[key](this.get(key)) : {
isValid: true
};
return result;
}
Now my question is I do not want to do anything to the Model in changeAction.
But if I remove the line this.model.set(change) in changeAction()
the validation does not work correctly. I do not get the value in the function
this.validators.myDropDownField
How do I handle this ?
I have an input form that I'm performing client-sided validation on with the jQuery validator plugin. Basic usage is working great, except for a specific scenario:
The form splits up address input fields, allowing separate fields for street number, name, city, state, and zip. The address itself is an optional input to the form (a user may opt to enter no address), but I want to ensure that if any one of these fields are used, the user is prompted to enter all the fields.
This works, except in the case when someone enters in an address and hits submit, and then decides to enter in no address. The ideal behavior in this case would be that, as soon as the text in the inputs they've entered is removed, for the address group to be unhighlighted.
Here is the current scenario:
User enters information into only one input field, e.g., street name.
The submit button is clicked.
The validator plugin highlights the other address inputs with an error message prompting for the full address.
User decides to enter no address, and removes the prior input, e.g. erases street name
Ideally: All the other highlighted address inputs are unhighlighted and the error message is removed. Actually: The highlighted address inputs and message remain until form submission.
Here is the javascript that demonstrates the problem and the corresponding JSFiddle.
$("form").validate({
errorClass: 'error',
errorElement: 'label',
submitHandler: function() {
alert("Form submitted");
return false;
},
groups: {
address: "streetNumber streetName city state zipcode"
},
rules: {
streetNumber: {
required: {
depends: function(){
return $("#streetName").val() != '' || $("#city").val() != '' || $("#state").val() != '' || $("#zipcode").val() != '';
}
}
},
streetName: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#city").val() != '' || $("#state").val() != '' || $("#zipcode").val() != '';
}
}
},
city: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#streetName").val() != '' || $("#state").val() != '' || $("#zipcode").val() != '';
}
}
},
state: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#streetName").val() != '' || $("#city").val() != '' || $("#zipcode").val() != '';
}
}
},
zipcode: {
required: {
depends: function(){
return $("#streetNumber").val() != '' || $("#streetName").val() != '' || $("#city").val() != '' || $("#state").val() != '';
}
}
}
},
messages: {
streetNumber: {required: "Must provide full address"},
streetName: {required: "Must provide full address"},
city: {required: "Must provide full address"},
state: {required: "Must provide full address"},
zipcode: {required: "Must provide full address"}
},
highlight: function(element, errorClass, validClass) {
$(element).addClass(errorClass).removeClass(validClass);
},
unhighlight: function(element, errorClass, validClass) {
$(element).removeClass(errorClass);
},
errorPlacement: function(error, element) {
var n = element.attr("name");
if (n == "streetNumber" || n == "streetName" || n == "city" || n == "state" || n == "zipCode")
error.insertAfter("#zipcode");
}
});
Besides trying to get the desired functionality of the highlight, I'm also wondering if there is a smarter way to accomplish the "all or nothing" input groups that doesn't involve the mess of conditional statements. Perhaps I can use a form input group?
You need to add a function on the focus event, then when the user leaves the field, the form fields will update.
It's difficult because you are using a plugin, so all the calls are happening inside that but I think something like this will work:
var inputs = $('form').find('input');
inputs.focus(function () {
inputs.each(function () {
$(this).removeClass('error');
});
});
Just stick this in your code outside of the validate initialiser.
It would be even better if you defined your errorCode variable outside of the validator and then used that var in both functions, like this:
var errorClass = 'error';
$('form').validate({
errorClass: errorClass,
...
...
});
var inputs = $('form').find('input');
inputs.focus(function () {
inputs.each(function () {
$(this).removeClass(errorClass);
});
});
you can try to add a method in the
unhighlight:
something like
$('.error').removeClass(errorClass);
or define related inputs and do
$('.relatedInputs').removeClass(errorClass);
you could also add an onChange function like
function(el){
if(el.val() == ''){
$('.relatedInputs').removeClass(errorClass);
}
}
I was able to get desired functionality by using this:
onfocusout: function(element) {
var inputs = $(element).closest('form').find('input, select');
inputs.each(function() {
if ($(this).valid())
$(this).removeClass('error');
});
}
Which was inspired from another post and DoubleA's answer. I haven't tested it thoroughly to see if it regresses anything, but so far it seems to work.