Knockoutjs validation and server validation - html

Hi I'm kind of new to Knockoutjs, I am in the scenario where I want to post a form where I have for example an email address, there is an requirement that the email address needs to be unique.
On the server I check if the email address is unique or not and then returns an validationjson class for example
{
isEmailUnique: false,
isPasswordStrongEnough: true;
}
How can I with knockoutjs validation show these errors in a neat way?

I would use two different server side validators for this, since they affect different observables in the view model.
Originally taken from the knockout validation readme
ko.validation.rules['isEmailUnique'] = {
validator: function(val, param){
var isValid = true;
$.ajax({
async: false,
url: '/validation/isEmailUnique',
type: 'POST',
data: { value: val, param: param },
success: function(response){
isValid = response === true;
},
error: function(){
isValid = false; //however you would like to handle this
}
});
return isValid;
},
message: 'The Email is not unique'
};
Then on the server you need to create an endpoint that accepts POST requests where you perform your lookup and then return true or false depending on the result of the query.
To use the above validator
this.email = ko.observable()
.extend({
isEmailUnique: {
message: 'Something else perhaps? It will override the message in the validator'
}
});
You can use the very same thing for the password strength validation.
Using validators like this will fire validation when the observable changes, which can be a useful way to do validation.

I'm a bit late, but for my 2 cents worth, I would take a more generic approach such as returning a standard JSON serialized AjaxResult class from your server endpoints (such as /Register) with properties such as Data (an arbitrary container used for, for example, an updated model to re-bind with the mapping plugin), and a collection of validation message strings, etc. Then you could have an HTML validation summary which is bound to an ObservableArray and push / map the messages from your Ajax result into there. This is essentially what I've been doing with Knockout and it works nicely.

Related

What Parameter Contact Form 7 using JSON to sent using API

I want create API for contact form 7.
How to send data from front-end to Contact Form 7 using WP rest api?
I mean, what should the data structure be to send it via the POST method?
http://xx.xxx/wp-json/contact-form-7/v1/contact-forms/<id-form>/feedback
I trying different ways, but request always return response “validation_failed”, “One or more fields contain erroneous data. Please check them and try again.”
I did not find anything about this in the documentation.
Were you able to find the solution? I've been working with the Contact Form 7 REST API and there are a few things you need to do to be abled to get a 'success' response, instead of validation_failed.
First, you need to know what form fields you need to submit. This is set up in your CF7's contact form. The field's name is defined in contact form. Most likely, CF7 uses the naming structure your-name and your-email. So you will need to format your post body to match this.
Next, you will need to submit it using FormData() https://developer.mozilla.org/en-US/docs/Web/API/FormData. From personal experience, I found that if I send my request as a normal object by using post, CF7 sends back validation_failed.
Note: I am using Nuxt's http package to submit data, but you are able to use axios here.
// Format your body response
const emailBody = {
"your-name": this.form.name,
"your-email": this.form.email,
"your-message": this.form.message,
};
// Create a FormData object, and append each field to the object
const form = new FormData();
for (const field in emailBody) {
form.append(field, emailBody[field]);
}
// Submit your form body using axios, or any other way you would like
const response = await this.$http.post(this.getEndEndpoint, form);
This is working for me, I am no longer getting the status validation_failed. Instead I now get a spam status. Trying to solve this problem now
Good luck
add_filter( 'wpcf7_mail_components', 'show_cf7_request', 10, 3 );
function show_cf7_request( $components, $wpcf7_get_current_contact_form, $instance ) {
print_r($_REQUEST);
die();
return $components;
};
Don't try on LIVE ;)
// google recaptcha integration v3 with contact form 7 Rest API
let email = $('input.email').val();
let g_recaptcha_response = $('textarea.g-recaptcha-response').val();
let data = new FormData(form);
data.append("email", email);
data.append("_wpcf7_recaptcha_response", g_recaptcha_response);
// _wpcf7_recaptcha_response key is important and should be same
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/wp-json/contact-form-7/v1/contact-forms/783/feedback",
data: data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
}).then((data) => {alert(data.message);});

MVC - returning data via ajax call renders it as page

New to MVC.
Scenario is. Using a 3rd party upload library for images. When a form is submitted, I want to make a call via ajax to submit the data and return the inserted item id. I then use that id for the 3rd party upload library to build folders where the images will be uploaded to.
I have the ajax call working and inserting the data to the database and getting the inserted id. But when the debug returns from the controller, it renders the id as a whole page.
Missing something fundamental here to MVC I think.
cshtml file:
<div class="col-md-8">
<input type="submit" value="Add Item" id="submitItem" />
<script>
$(document).ready(function () {
$("#submitItem").submit(function () {
event.preventDefault();
insertData();
});
});
function insertData()
{
var requestData = {
userID: $("#hdnUserID").val(),
title: $("#title").val(),
typeID: $("#typeID").val(),
description: $("#description").val()
};
$.ajax({
url: '<%= Url.Action("ItemUserDashBoard", "Home") %>',
type: 'post',
data: JSON.stringify(requestData),
dataType: 'json',
success: function (data) {
// your data could be a View or Json or what ever you returned in your action method
// parse your data here
alert(data);
$("#fine-uploader-gallery").fineUploader("uploadStoredFiles");
},
processData: false
});
}
</script>
</div>
HomeController.cs
[HttpPost]
public JsonResult ItemUserDashBoard(ItemAppraise.Models.iaDashBoardModel objItemUserDashBoard)
{
if(ModelState.IsValid)
{
using (dbContext)
{
ia_items iaItem = new ia_items
{
userID = objItemUserDashBoard.iaItems.userID,
typeID = objItemUserDashBoard.iaItems.typeID,
title = objItemUserDashBoard.iaItems.title,
description = objItemUserDashBoard.iaItems.description,
lastUpdate = DateTime.Now
};
dbContext.ia_items.Add(iaItem);
dbContext.SaveChanges();
//objItemUserDashBoard.iaItems.itemID = iaItem.itemID;
return Json(iaItem.itemID.ToString());
}
}
else{
return null;
}
}
Fiddler shows it as having a header of Content-Type: application/json; charset=utf-8.
But the page renders under the control url 'http://localhost:55689/Home/ItemUserDashBoard' with just the item id showing.
How do I get the data back just to use in the success part of the ajax call and not be rendered? Is this Partial Views or something similar?
Any guidance is appreciated.
In standard MVC. Any call made to a controller is handled just like a web request. So if i understand you correctly - the result of your httpPost is being rendered instead of the desired View? This is because you are returning JSON, so the controller assumes that is what you are trying to render. If you want a View to be rendered instead (and somehow use that response data) you could try setting the return type to ActionResult and returning a View("nameofview"); You can pass your response data to that view in a number of ways.
As a side note I think the problem you are facing could be better solved with Web Api instead of MVC. It works well with MVC and could be a simpler way of implementing your desired functionality. Separating your post requests and database interactions from the logic which decides which View to return.

Backbone model .toJSON() doesn't work after .fetch()

Good day! I need to render a model's attributes to JSON so I can pass them into a template.
Model:
var UserInfo = Backbone.Model.extend({
url: appConfig.baseURL + "users/",
});
Template:
<script type="text/html" class="template" id="profile-form">
<h2 class="ui-li-heading"><%= username %></h2>
<p class="ui-li-desc"><strong><%= phone %></strong></p>
</script>
View:
var ProfilePageView = Backbone.View.extend({
events: {
'click #edit': "edit"
},
initialize: function () {
this.template = $.tpl['profile-form'];
var user = new UserInfo()
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST'
});
console.log(user) //returns correct object with attrs
console.log(user.toJSON()) //returns empty object
},
render: function (eventName) {
$(this.el).html(this.template());
},
edit: function () {
window.workspace.navigate('#account/edit', { trigger: true});
}
});
When i put in console something like this, user.toJSON() returns correct data
var user = new UserInfo();
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST'
});
But when i put it to my view, its returns Object {}.
Where is a mistake or tell me how can differently pass to the template data received from the server in json format? Thanks!
You appear to have two problems. fetch is asyncronous, so you need to use a callback to use the information. But first, an explanation about toJSON. .toJSON() doesn't actually return a JSON string, it returns an object that is what you want JSON to stringify. This allows you to modify the toJSON method to customize what attributes will be taken from your model or collection and added to the JSON string representation of your model. Here is a quotation from the Backbone.js docs:
toJSON collection.toJSON([options])
Return a shallow copy of the model's attributes for JSON
stringification. This can be used for persistence, serialization, or
for augmentation before being sent to the server. The name of this
method is a bit confusing, as it doesn't actually return a JSON string
— but I'm afraid that it's the way that the JavaScript API for
JSON.stringify works.
So you should replace this line in your code
console.log(user.toJSON())
with this one
console.log(JSON.stringify(user))
The object that you saw was returned by toJSON will then be turned into JSON.
Now, even after you do that, it won't work properly, because you will execute the console.log before you get the data for your model from fetch. fetch is asynchronous, so you need to call any code you want to be executed after the fetch is done in the success callback:
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST',
success: function(){
console.log(user);
console.log(JSON.stringify(user));
}
});

Parsing json request in flask 0.9

(I am a complete beginner when it comes to any back-end development so I apologise if any terms are used wrong)
I have some javascript controlling a canvas game and I have a prolog planner which can solve the game. I am now trying to connect the two and have set up a flask server which can successfully call prolog, get the correct plan and send it back to the javascript. I am really struggling with getting the right inputs from the javascript.
Javascript:
var state = {
state : "[stone(s1),active(s1), stone(s2), in(app2,s2), unlocked(app2)]"
}
stone2.on('click',function(){
$.ajax({
type: 'POST',
contentType: 'application/json',
data: state,
dataType: 'json',
url:'http://localhost:5000/next_move',
success:function(data, textStatus, jqXHR){
console.log(data);
alert(JSON.stringify(state)); //making sure I sent the right thing
}
});
});
Flask server
//variables I use in the query at the moment
state = "[stone(s1),active(s1), stone(s2), in(app2,s2), unlocked(app2)]"
goal = "[in(app1,s1),in(app1,s2)]"
#app.route('/next_move', methods=['POST'])
def get_next_step():
own_state = request.json
r = own_state['state']
output = subprocess.check_output(['sicstus','-l','luger.pl','--goal','go('+state+','+goal+').'])
//I would like to use the string I got from my browser here
stripped = output.split('\n')
return jsonify({"plan": stripped})
//the correct plan is returned
I have seen the other questions regarding this, in fact the attempt I posted is from flask request.json order, but I keep getting 400 (BAD REQUEST). I'm guessing flask changed since then? I know it sends the json correctly because if I don't try to touch it I get the success message in my browser, so it is purely my inability to access its fields or to find any examples.
What you're sending through POST is not JSON. It's just a set of key value pairs and as such you should just send it through as that. And get it out using request.form.
In your case I would also not use jQuery's $.ajax and use $.post instead.
Here is the code:
stone2.on('click',function(){
$.post('http://localhost:5000/next_move',
state,
function(data) {
console.log(data);
alert(JSON.stringify(state));
}
);
#app.route('/next_move', methods=['POST'])
def get_next_step():
own_state = request.form
r = own_state['state']
print r
return jsonify({"plan": "something"})

.NET MVC3 HttpRequestValidation & JSON

I'm new to MVC3 framework (and .NET overall; Java veteran), so bear with me, but here goes:
Input submitted to a Controller as JSON doesn't seem to be subject to the HttpRequestValidation -- Does that sound right?
I realize if you're receiving data input via JSON you're possibly already doing more work with it, but the Controller Action doesn't seem to necessarily know whether it has JSON data at that point; input values are mapped to parameters just as they would be if they were standard POST params.
Example - I'm asynchronously submitting JSON data to my Controller like the following:
var data = { "title": $titleField.val(), "content": $textArea.val(),
"location": $location.val()
};
$.ajax(submitUrl,
{
type: "POST",
contentType: "application/json; charset=utf-8",
complete: function (data) {
//blah blah
},
dataType: 'json',
data: JSON.stringify(data)
});
}
I then receive the input in my Action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult New(string title = "", string content = "", string location = "")
{
//yada yada
}
Doing this, params are mapped and the user can easily send tags, etc. I'm not turning ValidateInput off, and if I submit with a standard POST and remove the Stringify, it throws the error as expected. Any good reason why JSONified data would skip validation?
Edit - More specific question: If JSONified data will pass HttpRequestValidation, how can we protect against the event where someone would intentionally mock a request to send JSON data instead of post params? I haven't found a way to force the Action method to differentiate between params passed as JSON vs. those passed non-encoded.
Got an answer for my question over on asp.net - See 2nd response.
Solution involves replacing the default ModelBinder.
Any good reason why JSONified data would skip validation?
JSON is encoded => so it ensures that what transits over the wire is safe. When you use JSON.stringify all dangerous characters are encoded.