I was wondering if there is a clean way in backbone to validate forms as you type without using a plugin. The issue is that if you have say a user model with: name, surname, email...
You can validate the model as a whole but not each model attribute individually.
Example:
var User = Backbone.Model.extend({
validate: function(attrs) {
if(!attrs.name) return "name not set"
}
var UserView = Backbone.View.extend({
events: { 'keyup input' : 'validateInput' },
validateInput: return this.model.isValid()
})
One generic method you can use is :
events: {
'keyup input': 'validateFeild'
},
validateFeild: function (event) {
var value = event.currentTarget.value;
var validator = $(event.currentTarget).attr('validator');
console.log(validator);
// Utils.validate(value, validator); here you can manage the validation in a separate utility class
}
and in your html have something like that :
<input id="label" type="text" validator="required" />
Here's the full example
Related
I have a big form (10+ inputs) which values I want to bind (like v-model) with object I have in vuex store, on submission it needs to send axios request to server (server will handle validation) and respond with error object (this field is required, this value is too short, etc...).
I will provide minimalistic example with just one input field.
Object student is for student itself obviously, and error object will be there to handle errors from server response.
App.vue
<template>
<div>
<input v-model="student.name">
<span>{{error.name}}</span>
</div>
</template>
<script>
import { mapActions } from "vuex";
export default {
name: "App",
computed: {
student.name: {
get () {
return this.$store.state.student.name
},
set (value) {
this.$store.commit('setStudentName', value)
}
},
error.name: {
get () {
return this.$store.state.error.name
},
set (value) {
this.$store.commit('setErrorName', value)
}
}
}
}
</script>
and this is mu vuex store:
export default {
state: {
student: { name: ''},
error: { name: ''}
},
mutations: {
setStudentName: (state, student.name) => (state.student.name = student.name),
setErrorName: (state, error.name) => (state.error.name = error.name)
}
}
So this works perfectly, but imagine having 10+ inputs and having to write setters and getters for 10 inputs x 2 objects (student and error), that is like 40 setters&getters at least.
Is there a easier way to do this?
I have also tried vuex-forms which is great, but package is incomplete and documentation is missing, tried vuex-map-fields, which is good only for handling one object at the time.
All suggestions are welcome, what it the correct way to do this?
Very new to Vue2, so far so good but I hit a little snag and front end is not my forte.
The table(vue-tables-2) displays correctly what's in the database. I am passing an id in a function to determine what particular row to update but I also want to update the value of the checkbox in the database whenever I press it. How can I achieve that? Many thanks.
<v-client-table :data="tableData" :columns="columns" :options="options" >
<input type="checkbox" v-model="props.row.powerOff" #change="powerOff(props.row.id, props.row.powerOff)">
</v-client-table>
export default {
data() {
return {
columns: ['id', 'name', 'location.address', 'status', 'payment', 'powerOff'],
tableData: []
}
},
created() {
HTTP.get('test').then( response => {this.tableData = response.data;})
.catch( error => {});
},
methods: {
powerOff(id, currentPowerOff) {
var testURL = 'test/' + id
HTTP.patch(testURL, {id, currentPowerOff})//
.then( response => {})
.catch( error => {console.log(error); });
}
}
}
It seems that changing from v-click:on to #change fixed my issue. Reading a little bit more about it, click event is run before v-model has updated the value, while #change does it afterwards. Thank you !
User's have accounts and can comment using a Comment Mongoose model.
Is it possible to allow a user to enter a username in an text input and generate all user associated comments?
I've been trying to use db.users.find({"name") but I'm not sure how to pass a username from an input field to search. Any suggestions?
Thanks! The comment model is below. It connects each comment with a user.
var commentSchema = new mongoose.Schema({
body: String,
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
})
You have to take the user name entered by another user from the text box and send it with the request to back end, something like {uName : 'user2'}.
Use the value from the object coming with the request and do find in your data base.
Something like below will be the backend code:-
var uName = req.params.uName
var cursor = db.users.find({username : uName.toString()});
Now cursor will give you record from user2 from your data base.
Front-end
send your GET request with Query String to the Back-end API
<form method="get" action="/comments/user" >
<input type="text" name="username" placeholder="username">
<button type="submit">Search</button>
</form>
Back-end
write a API to deal with GET request and Mongoose Query
var app = express();
var Comment = mongoose.model('Comment', commentSchema);
app.get('/comments/user', function (req, res) {
var query=Comment.find();
//get the Query String here
var filter=req.params.username;
if(filter.length>0){
query.where({author.username:filter});
}
query.exec(function (error, comment) {
//send the result back to front-end
res.json({ Comment: comment });
});
});
So I'm just learning Angular and I have basic routing setup and a partial for setting up a basic page with a form (theoretically any form), and based on the controller I load it loads that form from a fields array in the controller.
One of those forms is a registration form where I want to verify that the passwords match.
So in the partial I have (a mode complicated version of) this
<input ng-repeat="field in fields" ng-model="field.model" mustEqual="fields.mustEqual">
I found a directive which does password comparison:
taskDivApp.directive('mustEqual', function() {
return {
restrict: 'A', // only activate on element attribute
require: '?ngModel', // get a hold of NgModelController
link: function(scope, elem, attrs, ngModel)
{
if(!ngModel) return; // do nothing if no ng-model
// watch own value and re-validate on change
scope.$watch(attrs.ngModel, function()
{
validate();
});
// observe the other value and re-validate on change
attrs.$observe('equals', function (val)
{
validate();
});
var validate = function()
{
// values
var val1 = ngModel.$viewValue;
var val2 = attrs.mustEqual;
// set validity
ngModel.$setValidity('equals', val1 === val2);
};
}
}
});
So basically all I want to do is be able to load a literal string into ng-model from the controller so that I can pair up the model and the must equal, so the data for the form would look like:
$scope.fields = [
{
'type':"Email",
'placeholder':"Email Address",
'req': true,
'focus':true
},
{
'type':"Password",
'placeholder':"Password",
'model': "password",
'mustEqual': "passwordConf"
},
{
'type':"Password",
'placeholder':"Comfirm Password",
'model':"passwordConf",
'mustEqual': "password"
}
];
However what happens now is that the main password field gets bound to the "model" field of its index in the array and similar for passwordConf (ie inital values literally "password" and "passwordConf")
The fact that this isn't easy makes me think I have the wrong mindset - is this not a good way to do forms, should I just have them hard coded?
If this is okay then any ideas on how I could accomplish it would be appreciated!
I am new to AngularJS, but have used Backbone for a while now.
I want to create a reusable restful api that I can pass the model name to so that I can use it for different models.
At the moment I have:
angular.module('healthplanApiServices', ['ngResource'])
.factory('Api', function($resource) {
return $resource(base_url + 'api/:object/:id', {
id : '#id', object : 'actions'
}, {
query : {
method : 'GET',
isArray : true,
callback : "JSON_CALLBACK"
},
save : {
method : '#id' ? 'PUT' : 'POST',
isArray : true,
callback : "JSON_CALLBACK"
}
});
});
... which sets the model as 'actions'. Then in my controller I use:
// get the collection
Api.query(function(r) {
$scope.actions = r;
});
$scope.toggleDone = function(a) {
a.done = !a.done;
//save an item
Api.save(a);
}
That's all fine, but how do I pass the model name ('actions' in this case) for each model type: e.g., instead of putting it in the factory function like so:
id : '#id', object : 'actions'
... but rather something more like:
var ActionApi = Api.setObject('actions');
ActionApi.query(function(r) {
$scope.actions = r;
});
UPDATE:
I just figured out a way. It may not be the best, but it does work. Any other suggestions would be welcome!
Just add the 'object' attribute to the model:
Api.query({object: 'actions'}, function(r) {
$scope.actions = r;
angular.forEach($scope.actions, function(a) {
a.object = 'actions' });
});
Api.save(a);// also works
You may want to try https://github.com/klederson/ModelCore ( ModelCore )
Its easy to model and structure and of course ... to use.
model.$find({ filter : "John" },{},true); //to find all with query parameters
model.$get(1); //to retreive the user with id 1
model.$save()
model.$deelte();
And so on.. checkout the documentation