I have a simple form with three textboxes and a <canvas> on the same page and I have to validate these three fields and then get the values (if validated) sent to a javascript function to draw a picture and some text inside the <canvas> element. The form and textboxes wouldn't have to disappear after the values were submitted because the user could try out different results with different values. I've done other forms before but never tried using Ajax. I know I could use a client-side validation and get the textbox values with jQuery but I have more server-side code running that would make use of these three values. How can I do this?
in your controller, create a method to handle the results. I assume that this is for logging only, and does not need to actually return data.
public useResults(string value1, string value2)
{
// ... Do something with the results
return Json(true);
}
In your view, work out a way to construct the url to the above action. Perhaps in a hidden field;
#Html.Hidden("useResultsUrl", Url.Action("useResults", "controllerName"))
Then in your javascript, attach a click event to the button, as you probably have already (to trigger your javascript task) and add in an ajax call.
Note that the following uses JQuery, but you could use microsoft AJAX if you preferred;
$(function () {
$("#button").click(function() {
$.ajax({
url: $("input[name='useResultsUrl']").val(), // Get the url from the hidden field
type: "POST",
dataType: "JSON",
data: $("input[type='text']").serialize() // Get the value of the text inputs and serialise them.
});
});
// ... do other stuff
});
Your View can make an ajax call to the server using JQuery - either using JQuery.post
or JQuery.ajax - you give the Url of the controller action to the JQuery method, and it will handle the AJAX call for you.
Then, in your controller action, you return a JsonResult - which serialize the data for you into JSON format:
e.g. return Json( model );
Finally, implement a success function in the JQuery Ajax call in your view - this wil have the data returned by the controller available for you to do whatever you want with.
Related
To allow to make validation of form before submit,
I want to make a simple HTTP POST submit from the Submit method i defined.
Code of the view :
<form data-bind="submit: BaseSubmit" id="FormId">
<!-- Some rows ... -->
<button type="submit">Create</button>
</form>
And of the JS behavior
this.viewModel.BaseSubmit =
function(formElements) {
//Here the code to make the submit redirection
};
Is this possible ?
Thanks by advance.
Upon successful validation, make sure and return true from your binding handler:
this.viewModel.BaseSubmit =
function(formElements) {
if (/* validation is successful */) {
return true;
} else {
/* handle validation errors */
}
};
Example: http://jsfiddle.net/CCNtR/22/
From the documentation:
By default, Knockout will prevent the event from taking any default action. For example if you use the event binding to capture the keypress event of an input tag, the browser will only call your handler function and will not add the value of the key to the input element’s value. A more common example is using the click binding, which internally uses this binding, where your handler function will be called, but the browser will not navigate to the link’s href. This is a useful default because when you use the click binding, it’s normally because you’re using the link as part of a UI that manipulates your view model, not as a regular hyperlink to another web page.
However, if you do want to let the default action proceed, just return true from your event handler function
I have a jQuery.ajax() POST request, that runs on button click and has its data parameter set to $(this).parents('form').serialize().
There is one Textarea in the form that has a default placeholder, which I would like to replace with a blank value just before the AJAX request is sent. Is it possible to achieve this using the beforeSend event of jQuery.ajax?
You could simply manipulate the form data.
$.extend($(this).parents('form').serialize(), { textarea_name: "" });
If you don't want the value being sent at all, delete the property from the object returned by serialize().
I need to use removeAttr on elements that may be loaded via ajax. Is there a way to automatically do this, similar to the way you can bind events automatically with live()?
NOTE: I don't have control over the JavaScript libraries that are doing the ajax calls.
this creates a new event for all elements now and in the future that have your 'undesirable attribute', next we'll trigger it to fire and do its work.
$("mySelector").live("myRemoveAttrEvent", function(event){
$(this).removeAttr("myAttr");
});
on the successfull ajax call's function
// quick jQ ajax, the important part is on success
$("div").load("url", function(data, status, xhr){
..do work..
// this is the important part
$("mySelector").trigger("myRemoveAttrEvent");
});
if you do not have control over all the ajax, you have to piggy back on the user events that Cause the ajax to fire ... this is dirty:
//events you think cause the uncontrollable ajax to fire, e.g change
$("*").change()(function(event){
$("mySelector").trigger("myRemoveAttrEvent");
});
You can use complete option of the $.ajax request like this:
$.ajax({
......
complete:function(){
$('selector').removeAttr('attribute here');
}
});
What you're looking for is to handle this at the time those elements are loaded, which would be in the success callback for your AJAX call:
$.ajax({
// your details
success: function(html){
$('a', html).removeAttr('title');
$('body').append(html);
}
});
Update: If you don't have control of whatever is making the AJAX calls and it doesn't provide any hooks or callbacks, you are going to need to find another event to bind to in order to perform this action. Depending on how these elements are being inserted into the page and exactly what you're doing with them, you might be able to use delegate like this (just a guess):
$('body').delegate('p', 'load', function(){ /* remove attr */ });
I don't know of any events that are triggered when the DOM or a single element is modified. You can try load, but I don't think it gets called in the case of AJAX loaded and inserted elements.
Is it possible to call a controller action that will update (refresh) a partial within the View with the updated model? If so, can someone point me to an example?
I'm making an ajax call. The call sends some json to the controller. The controller extracts the json and formats it into XML that then get's passed on to a SPROC. The results of the SPROC update the model. This is where I need to update the view... with the latest model results.
Yes, you simply need to have the action return the PartialView with its updated model. The calling code might look like this:
<div id="MyDiv"></div>
<%=Ajax.ActionLink("Update", "GetUpdatedPartialView",
new AjaxOptions{UpdateTargetId = "MyDiv"}) %>
When you click on the link, the HTML returned by your action will get placed into the div with ID "MyDiv".
Edit
I don't have my code with me, but if I remember right it's something like this:
var url = '<%=Url.Action("GetUpdatedPartialView")%>';
$.post(url, function(data) {$('#MyDiv').html(data);});
In the controller, you can just do something like:
if (Request.IsAjaxRequest()) {
return View(name_of_partial, updated_model);
}
On the front end, it's just a jQuery load, something like:
$("#target-div").load(url_of_action, data_to_send);
I'm using jQuery Form (http://jquery.malsup.com/form/) to get send data to a form - is there a way I can then, without refresh, put the results page that's generated by the form into a div on the page?
Any advice appreciated!
I would suggest not using that form plugin - it was made back in the days before there was an easy way to serialize form data using jQuery, and serves no real purpose any more. I would suggest something like this:
$("form").submit(function() {
$.post($(this).attr("action"), $(this).serialize(), function(data) {
$("#someDiv").html(data);
});
return false; // prevent normal submit
});
If you insist on using jQuery Form Plugin - which is NOT recommended -, you can set the target option to a selector of the element(s) you would like to fill up:
// prepare Options Object
var options = {
target: '#divToUpdate',
url: 'comment.php',
success: function(data) {
alert('Thanks for your comment!');
}
};
Take a look at http://jquery.malsup.com/form/#options-object for more info.
To prevent refresh, just make sure the form's onsubmit event returns false:
<form method="post" onsubmit="return false">