jQuery validate and groups - how to avoid errorPlacement usage? - jquery-validate

Current example of groups usage says that errorPlacement should be defined, where names of fields are hard coded:
$("#myform").validate({
groups: {
username: "fname lname"
},
errorPlacement: function(error, element) {
if (element.attr("name") == "fname"
|| element.attr("name") == "lname" )
error.insertAfter("#lastname");
else
error.insertAfter(element);
},
debug:true
})
Is there any way to get rid of this errorPlacement with field names? The error message should be always places after last element in the group.

I think you're going to have to use errorPlacement, but you can pull out a few tricks to get the error in a consistent place among groups every time:
$("#test-form").validate({
groups: {
username: "fname lname",
range: "min max"
},
errorPlacement: function ($error, $element) {
var elementName = $element.attr("name"),
lastInGroup = $.map(this.groups, function(fields, name) {
var fieldsArr;
if (fields.indexOf(elementName) >= 0) {
fieldsArr = fields.split(" ");
return fieldsArr[fieldsArr.length - 1];
} else {
return null;
}
})[0];
if (lastInGroup) {
$error.insertAfter($("input[name='" + lastInGroup + "']"));
} else {
$error.insertAfter($element);
}
}
});
Basically, access the groups object that you've defined and find the last field in every group. Attach the error after that field.
Example: http://jsbin.com/acenic/

Related

Kendo Grid filter using checkboxes and mutliple selections

I am using custom multi-select code to filter a column. Currently I can get it to filter based on one selection, but am unable to filter based on multiple values. I need the logic to read, if any of the selected checkboxes are checked, then show the selections in the grid. The way I have it written right now, its filtering each one, but if one of the selections is false, it deletes it from the grid even if one of the other selections are true.
var filter = dataSource.filter() || { logic: "or", filters: [] };
var fieldFilters = $.map(element.find(":checkbox:checked"), function (input) {
return {
field: field,
operator: "eq",
value: input.value
};
});
if (fieldFilters.length) {
removeFiltersForField(filter, field);
filter.filters.push({
logic: "or",
filters: fieldFilters
});
var filterType = filter.filters[0].filters;
if (filter.filters[0].filters.length > 1) {
var filterLogic = { logic: "or", filters: filter.filters };
dataSource.filter(filterLogic.filters[0]);
} else {
dataSource.filter(filterType); // This works, but its only one selection
}
}
I need it to return if any selections are true and ignore the ones that are false. Currently, it goes in order, so if the first selection is true, it shows it in the grid, but if the next one is false, then it removes it from the grid.
OK I was able to make it work doing this. If someone has a more efficient way to do it, add it here. For now, this works:
var multipleFilters = [];
if (filterType.length > 1) {
$(filterType).each(function (i, value) {
var simpleFilter = { field: value.field, operator: value.operator, value: value.value };
multipleFilters.push(simpleFilter);
})
if (multipleFilters == 2) {
dataSource.filter(multipleFilters[0] || multipleFilters[1]);
} else if (multipleFilters == 3) {
dataSource.filter(multipleFilters[0] || multipleFilters[1] || multipleFilters[2]);
} else {
dataSource.filter(multipleFilters[1] || multipleFilters[2] || multipleFilters[3]);
}
} else {
dataSource.filter(filterType);
}

Multiple filter in ng-repeat

I need help with filtering data in ng-repeat. I've tried to do few things but I can't find solution that works in my case. I need to to something like this:
sensor in sensors | filter: { group: group.id, (name: search || description: search) }
Search is ng-model (text input) and group.id is ID of group that are genereted in ng-repeat (I have two nested ng-repeat). I've tried to do my filter:
$scope.search = '';
$scope.searchFilter = function() {
return function (p) {
if ($scope.search!='') {
for (var i in p) {
console.log("p.name: "+p.name+", search: "+$scope.search);
if (p.name == $scope.search || p.description == $scope.search) {
return p;
}
}
} else {
return p;
}
}
}
Almost works. It filters my data but only if I write correct name. For example I want to find "engine". If I start writing "en" there is no data but if I write "engine" it will display correct data. So I need to work on that too. I hope you understand what I want to do.
I've found solution!
sensor in sensors filter: { group: group.id } | filter: searchFilter()
And this:
$scope.search = '';
$scope.searchFilter = function() {
return function (p) {
if ($scope.search!='') {
for (var i in p) {
var re = new RegExp($scope.search, 'i'); // This I've add
if (p.name.match(re) || p.description.match(re) ) { // This I've change
return true;
}
}
} else {
return true;
}
}
}

Trouble with d3 force directed graph

I'm rendering a force directed graph using d3js. The design is such that nodes are added to the graph at run time by querying a database. This works fine.
While the graph is being rendered, node-by-node, if I happen to click anywhere on the screen, at sometimes, the incoming node gets stuck at the top left of the div and the following error is displayed on debugging:
Error: Invalid value for <line> attribute x2="NaN"
Error: Invalid value for <g> attribute transform="translate(NaN,NaN)"
Sometimes, even an already formed link breaks and an old node gets stuck on the top left until the next refresh.
If I don't interfere, the rendering completes smoothly.
I really do not understand this behavior. Does anyone have any idea what must be going wrong here?
Find my code to compute the graph below:
var graph = { "nodes": [], "links": [] };
var nodeMap = [];
var timestamp;
var json_obj;
var newLogs = false;
$(document).ready(function () {
var count = 0;
doPoll();
function doPoll() {
json_obj = "some object";
var uri = 'api/values?id=' + json_obj;
newLogs = false;
$.getJSON(uri)
.done(function doPoll(data) {
$.each(data, function (key, item) {
newLogs = true;
timestamp = item.timestamp;
populateJson();
function populateJson() {
if (nameExistsInNodes(item.entityName) && item.state == "1") {
searchAndRemoveFromGraph(item.entityName);
}
if (item.entityId != null && !idExistsInNodes(item.entityId)) {
graph.nodes.push({
"eId": item.entityId,
"name": item.entityName,
"state": item.state
});
} else if (item.state == "0" && item.entityId == null) {
graph.nodes.push({
"eId": item.entityName,
"name": item.entityName,
"state": item.state
});
} else if (idExistsInNodes(item.entityId)) {
updateEntityInfo(item);
}
if (!existsInMap(item.entityId) && item.entityId != null) {
nodeMap.push({ "id": item.entityId, "index": count++ });
}
if (item.mapsTo != null && !existsInLinks(findIndexForId(item.entityId), findIndexForId(item.mapsTo))
&& findIndexForId(item.entityId) != null && findIndexForId(item.mapsTo) != null) {
graph.links.push({
"source": findIndexForId(item.entityId),
"target": findIndexForId(item.mapsTo)
});
}
}
});
if (newLogs) {
renderUsingD3(graph);
}
}) // end done
.always(function () { setTimeout(doPoll, 3000) })
} // end doPoll
});
Each item that comes in has an id, name and state and my logic plays around with these 3 to get the graph up.

dc.js - pieChart ignore unwanted values

I have a piechart I'm displaying using the following dimension -
var types = facts.dimension(function (d) {
if (d.types === 2)
return "Type 2";
else if (d.types === 3)
return "Type 3";
else
return "Other";
});
I would like to not return, ignore, all other types, so the pie chart would just display Type 2 and Type 3. I cannot seem to get this working though I'm sure it's simple. Can I do something within that dimension or do I need to filter before?
Thanks for any help.
Have you tried creating a new type and then creating a dimension on top of that?
facts.forEach(function(d) {
if (d.types == 2) {
d._type = "Type 2";
} else if (d.types == 3) {
d._type = "Type 3";
} else {
d._type = "Other";
}
});
var types = facts.dimension(dc.pluck('_type'))
You need to (1) Filter your data then (2) remove it from the bin. Run your data through ensure_group_bins(myGroup) you'll get the chart you're after
function remove_empty_bins(source_group) {
return {
all:function () {
return source_group.all().filter(function(d) {
return d.key != "unwanted" ;
});
}
};}
function ensure_group_bins(source_group, bins) {
return {
all:function () {
var result = source_group.all().slice(0), // copy original results (we mustn't modify them)
found = {};
result.forEach(function(d) {
found[d.key] = true;
});
bins.forEach(function(d) {
if(!found[d])
result.push({key: d, value: 0});
});
return result;
}
};};
dc.js Github

Issue in Sorting Integer values In AngularJs Custom Sort function

I am having problem in my custom sorting method. I have a json structure wherein integer values are being passed as String. While sorting I need to sort the list based on the integer value, but it is being sorted as String values.
I have created a JsFiddle for the same:
http://jsfiddle.net/ayan_2587/vjF2D/14/
The angular code is as follows:-
var app = angular.module('myModule', []);
app.controller('ContactListCtrl', function ($scope, $timeout, $filter) {
var sortingOrder = 'price';
$scope.sortingOrder = sortingOrder;
$scope.sortorder = '-sort';
$scope.contacts = [{
"name": "Richard",
"surname": "Stallman",
"price": "7200"
}, {
"name": "Donald",
"surname": "Knuth",
"price": "34565"
}, {
"name": "Linus",
"surname": "Torvalds",
"price": "23454"
}];
$scope.setLoading = function (loading) {
$scope.isLoading = loading;
}
$scope.layoutDone = function (value) {
console.log(value);
$scope.setLoading(true);
$timeout(function() {
// take care of the sorting order
if ($scope.sortingOrder !== '') {
if(value == 'sort'){
$scope.contacts = $filter('orderBy')($scope.contacts, $scope.sortingOrder, false);
}
else if(value == '-sort'){
$scope.contacts = $filter('orderBy')($scope.contacts, $scope.sortingOrder, true);
}
}
$scope.setLoading(false);
}, 1000);
}
$scope.loadFeed = function(url) {
$scope.setLoading(true);
}
$scope.loadFeed();
});
app.directive('repeatDone', function() {
return function(scope, element, attrs) {
if (scope.$last) { // all are rendered
scope.$eval(attrs.repeatDone);
}
}
})
Please help me out !!!
SInce you sort in JS, you can allways use Array.sort() - at least on modern browsers-, passing it a sort function like:
function sortAsc(a,b) {
a = parseInt(a.price);
b = parseInt(b.price);
return a > b ? 1 : (a === b ? 0 : -1);
}
And then execute the sorting like:
if(value == 'sort'){
$scope.contacts.sort(sortAsc);
}
See forked fiddle: http://jsfiddle.net/sRruf/ (the initial state is not sorted)
The sort property (here price) can be parameterized with a little extra work.
And here is a version using the orderBy filter and a custom predicate: http://jsfiddle.net/sRruf/1/

Resources