get JSON with functions from server - javascript

I use JQuery Validate to validate forms on my webapp. I can pass JQuery Validate a list of rules to use to validate my form like this:
$("#myform").validate({
rules: {
age: {
required: true,
min: 3
},
parent: {
required: function(element) {
return $("#age").val() < 13;
}
}
}
});
Now I would like to generate those validation rules on the server instead of coding them in my JavaScript, do an $.ajax request to get them, attach them to the form and be all set.
But this
{
rules: {
age: {
required: true,
min: 3
},
parent: {
required: function(element) {
return $("#age").val() < 13;
}
}
}
}
is not valid JSON, because there is the function declaration. Is there a way to do this?
To elaborate: my application is made of static HTML and JS, and my only interaction with the server is with some REST services that return JSON.
So when I get a person from the server because I want to edit it in a form, I do
$.ajax({url: '/person/1',
success: function(data) {
/* fill form fields */
...
/* get validation rules from server and attach to form
something like */
$.ajax({url: '/person/validation_rules',
success: function(rules) {
/* something like */
$('#myform').validate(rules);
}
}
});
Thanks.

How about simply returning it as a JS literal, instead of as JSON?
Edit:
Your original description included:
{
rules: {
age: {
required: true,
min: 3
},
parent: {
required: function(element) {
return $("#age").val() < 13;
}
}
}
}
That's a JS literal, not a JSON string, and is completely valid to return from the server, in and of itself. No additional changes necessary, and the function declaration is just fine. JSON is simply a subset of the JS literal. (http://www.json.org/js.html).
So, you could easily return that structure from your server, via some AJAX request, exactly as it is.
For more details: http://snook.ca/archives/javascript/json_is_a_subse

If you are already generating Javascript on the server, you don't need to load it as JSON. If you are loading this function from http://myserver.com/validation.js, instead of calling it with ajax, just call it from the script tag, eg.
<script src="http://myserver.com/validation.js"></script>
You will also need to edit slightly generated code:
var validationRule = {
rules: {
age: {
required: true,
min: 3
},
parent: {
required: function(element) {
return $("#age").val() < 13;
}
}
}
}
then your validation will look like
$("#myform").validate(validationRule);
EDIT: if server response must be JSON, you can get it as a string and eval() it. or you can arrange some valid json which you can tweak to desired form, say:
{
...
"minParentAge": 13
}
and then construct function from it.

Create a single global variable as your root namespace - just like third party libraries like jQuery do. Call it for instance MyNamespace.
Then load js files that populate this namespace, that way you get a minimal DOM footprint.
My preferred way is doing it like this:
<myFunctions.js>
MyNamespace = window.MyNamespace || {};
(function(){
function utilityFunction1() {
//....
}
function utilityFunction2() {
//....
}
MyNamespace.UtilityFunctions = {
utilityFunction1: utilityFunction1,
utilityFunction2: utilityFunction2
};
})();
</myFunctions.js>
then include it like always
<script src="myFunctions.js" type="text/javascript"></script>

Related

How to get a value of a function from a javascript file to an ASP.NET MVC view?

i am trying to separate my view from java script,in my view im calling a function in js file to create a chart,
Here is my js file and the function:
function pieChartForInterventions(chartID,pieChartData) {
chartID.kendoChart({
dataSource: {
data: pieChartData
},
series: [{
type: "pie",
field: "list",
categoryField: "mm",
padding: 0,
labels: {
visible: true,
}
}],
seriesClick:onDb,
tooltip: {
visible: true,
template: "${ category }"
}
,
legend: {
position: "bottom"
}
});
}
function onDb(e) {
var _clicked = e.category;
}
here is my view:
pieChartForInterventions($("#pieChart"), result);
now the problem is,as you see in my function i have a onDb() function whick invokes when i click on my chart to get the value of what i clicked,i need this value to send it back with a Ajax call via my view,how should i have this value in my view?
Please elaborate a bit more, where exactly in your view do you require this value? OR what do you want to do with this value after receiving it in the view?
If you have something available in javascript, it means you already have it in your “View”, since the only place your javascript logic is executing is in your view.
From your onDb(e) function, you can:
1) Return the value and use it anywhere you need within the view via javascript logic.
In your sepearated js file you may have a function like:
function onDb(e) {
var _clicked = e.category;
return _clicked;
}
Somewhere in your view (.cshtml) you may do something like:
<script type="text/javascript">
// Get 'e' from wherever you need
var requiredValue = onDb(e);
// Any Javascript / JQuery / Ajax logic ...
</script>
2) If the returned value is required at the server side, you can send an AJAX request etc. See the following on how to send an AJAX request (MVC jquery ajax call with input parameter)
==== UPDATE AFTER COMMENT ====
You can access the onDb function the same way as I mentioned in the second code snippet. However, in that case getting the input parameter “e” would require some scripting.
Alternatively, what’s even easier in this scenario is that you can move the “Ajax Call” inside onDb(e) function. Update the onDb(e) function as follows …
function onDb(e) {
var _clicked = e.category;
$.ajax({
type: "POST",
url: '#Url.Action("ControllerName", "ActionName")',
contentType: "application/json; charset=utf-8",
data: { valueToSend: _clicked },
dataType: "json"
});
}
And on your server side you would have some action like:
public class ControllerName : Controller
{
[HttpPost]
public ActionResult ActionName(string valueToSend)
{
//The value you needed is stored in the input paramater 'valueToSend'
//... process however you want and return any ActionResult ...
return Json("success", JsonRequestBehavior.AllowGet);
}
}

JQuery Validator plugin validating conditions

I am having a few issues validating my data fully with the validator plugin.
I have 2 fields; fieldOne and fieldTwo. I then have 2 PHP files, process.php and processfailed.php.
Now I have quite a few conditions.
If fieldOne and fieldTwo are both empty, I want the error to display to the user but no PHP file called.
If one of the fields has valid data, and the other has invalid data or is empty, I want it to call process.php (I dont want a validation error event to occur).
Only if both fields have invalid data do I want processfailed.php to be called, from within the validation error event.
The code I have so far is this (removed some sections to shorten it)
var validator = $("#my_form").validate({
rules: {
fieldOne: {
require_from_group: [1, '.datagroup'],
maxlength: 40
},
fieldTwo: {
require_from_group: [1, '.datagroup'],
minlength: 8
}
},
groups: {
datagroup: "fieldOne fieldTwo"
},
submitHandler: function (form) {
$.ajax({
type: "POST",
url: "process.php",
data: {
'fieldOne': $("#fieldOne").val(),
'fieldTwo': $("#fieldTwo").val()
}
})
return false;
},
invalidHandler: function (form, validator) {
/* Submit the form even if validation fails: */
$.ajax({
type: "POST",
url: "processfailed.php",
data: {
'fieldOne': $("#fieldOne").val(),
'fieldTwo': $("#fieldTwo").val()
}
})
return false;
}
});
In regards to them both being empty, at the moment it displays the error to the user, but it also appears to be calling processfailed.php as well (I dont want any php file called in this situation).
If I give valid data to one field and leave the other empty, this seems to work.
If I give valid data to one field and give invalid data to the other, this seems to call processfailed.php when it should call process.php (as long as one field is valid that is ok).
If I give invalid data to both fields (they both fail validation) the processfailed.php seems to be called as it should be.
So how can I handle both fields being empty (not to call any php file) and if one field is valid and the other invalid to call process.php and not processfailed.php.
Any advice appreciated.
For the first condition where both fields are empty, you can just place an if-statement in the invalidHandler method.
In order to not apply the validation to one of the fields when the other is valid, you could use the depends property of the rules.
$("#my_form").validate({
rules: {
fieldOne: {
require_from_group: [1, '.datagroup'],
maxlength: {
param: 2,
depends: function(element) {
var valTwo = $('#fieldTwo').val();
return !valTwo || (valTwo.length < 8);
}
}
},
fieldTwo: {
require_from_group: [1, '.datagroup'],
minlength: {
param: 8,
depends: function(element) {
var valOne = $('#fieldOne').val();
return !valOne || (valOne.length > 2);
}
}
}
},
submitHandler: function (form) {
alert("process");
return false;
},
invalidHandler: function (event, validator) {
if ($('#fieldOne').val() || $('#fieldTwo').val()) {
alert('processfailed');
} else {
alert('empty');
}
return false;
}
});
jsfiddle
I removed the groups property because it causes all messages to get displayed next to the first field, which doesn't seem correct when the message is because the second field violates the minlength rule.
Note: The first parameter to the invalidHandler function is the event object, not the form element, but you can get the form element using event.target.

JavaScript data validator?

Looking for a library that could validate input like, for example:
{ points: array of { x: positive and < 20, y: positive and < 15 } }
Preferably working on both server and client side and returning a boolean or throwing an exception.
What I explicitly don't need is string or form validation, I just want to check if JSON sent by client is safe for processing without a ton of dispersed checks as I go.
You could also try Skematic.
Data structure and rule validation engine. Robust schema for JS objects.
It lets you design data models, then format and validate data against those models. Works in browser (Skematic global) or Node/io.js.
To solve your request, something basic like this should work:
// -- Define a simple data structure
var YourData = {
points: {
type:'array',
default: [],
schema: {
x: { type: 'number', required: true, rules: { min:0, max:20 } },
y: { type: 'number', required: true, rules: { min:0, max:15 } }
}
}
};
// -- Validate an object
Skematic.validate( YourData, {points:[ {x:-1,y:10} ]} );
// {valid:false,
// errors:{
// points: {0:{x:['Failed: min']}}
// }}
Never mind, wrote it myself.
https://bitbucket.org/virtulis/validata/overview
https://www.npmjs.org/package/validata

Not all attributes of JavaScript object being mapped into JSON

I'm using Inkfilepicker.io for picture uploading on a project I'm working on. When you upload a picture, it returns a JavaScript object with some data in it. I need more, though. So I query their API using their SDK to get more. I then add this information to each object. Lastly, I post these objects using jQuery to process it on the backend. However, none of the second batch of information goes along for the ride on the backend. I manually used JSON.stringify() to see what the data looked like before it was posted. The new data was not included.
fp.pickAndStore({multiple: true}, {}, function (InkBlobs)
{
InkBlobs = $.map(InkBlobs, function(blobio, index)
{
fp.stat(blobio, {
width: true,
height: true
}, function(meta) {
blobio.width = meta.width;
blobio.height = meta.height;
});
return blobio;
});
console.log(InkBlobs);
console.log(JSON.stringify(InkBlobs));
$.post('/picture', { blobs: InkBlobs }, function(data)
{
console.log(data);
}, 'json');
});
How can I make sure all of the attributes get sent?
UPDATE
The string created by the JSON.stringify() looks like the following:
[{"url":"https://www.filepicker.io/api/file/PinzEEUlRhSCpc4dYa0w","filename":"browserWars.jpeg","mimetype":"image/jpeg","size":34284,"key":"Vx1xEuqHTKKCM4hjR6LL_browserWars.jpeg","container":"kandidlypictures","isWriteable":true},{"url":"https://www.filepicker.io/api/file/wdnWcCUWStiBxbrONeSN","filename":"1440-music-is-the-food.jpg","mimetype":"image/jpeg","size":97814,"key":"0RrSFSQBTCiifZ8ZkuIj_1440-music-is-the-food.jpg","container":"kandidlypictures","isWriteable":true},{"url":"https://www.filepicker.io/api/file/trdKhlORPCJEu3JRbPYf","filename":"any_browser.jpeg","mimetype":"image/jpeg","size":271194,"key":"1aJNE9MSEyEiAJZAacfD_any_browser.jpeg","container":"kandidlypictures","isWriteable":true}]
The expected output should also include a width and height for each object.
Use a separate named function:
var data = {
width: true,
height: true
};
var fn = function fn(meta)
{
blobio.width = meta.width;
blobio.height = meta.height;
$.post('/picture', { blobs: InkBlobs }, function(data)
{
console.log(data);
}, 'json');
};
fp.statSync(blobio, data, fn)
Or use statSync since stat is asynchronous:
fp.statSync(blobio, {
width: true,
height: true
}, function(meta) {
blobio.width = meta.width;
blobio.height = meta.height;
});
References
Fun with Named Functions
statSync

jQuery required( dependency-expression ) is not working properly

I am using jquery validation plugin. When I was using required( dependency-expression ) i noticed that
required( dependency-expression ) are not working properly. as mentioned that i tried for
$("#flight_availability").validate({
rules: {
Trip: { required: true },
DepartDate: { required : "#OneTrip:checked" },
Origin: { required:"#OriginId:blank" }
},
});
In the above mentioned code the code DepartDate: { required : "#OneTrip:checked" }, works fine but Origin: { required:"#OriginId:blank" } does not work.
Whats wrong with the code? I used firebug. It did not show any errors. even used validation debug option too, but :(
As per OP's comments:
"even if OriginId is empty(blank), it validates it as true"
Yes, that is exactly how you programmed it.
Origin: {
required: "#OriginId:blank"
}
The above code is saying that the Origin field is only required when the #OriginId field is left blank. Using #OriginId:filled, this logic is saying that the Origin field must remain empty if the #OriginId is filled in. If that's not exactly correct, then you can use the :blank selector instead.
http://jsfiddle.net/xMAs5/
If you want the opposite behavior then use the :filled selector instead.
Origin: {
required: "#OriginId:filled"
}
http://jsfiddle.net/xMAs5/1/
Otherwise, here is a demo using a custom method called empty that works as per your comment: "So if OriginId is empty means Origin value (anything) is invalid."
$(document).ready(function () {
$.validator.addMethod('empty', function (value, element) {
return (value === '');
}, "This field must remain empty!");
$("#flight_availability").validate({
rules: {
Trip: {
required: true
},
DepartDate: {
required: "#OneTrip:checked"
},
Origin: {
empty: {
depends: function (element) {
return $("#OriginId").is(":blank")
}
}
}
}
});
});
DEMO: http://jsfiddle.net/Ab8bT/
It might be the jQuery puesdo selector try using :empty instead of :blank.

Categories

Resources