In my page I have a form:
<form method="post" id="confirm-order-form" name="confirm-order-form">
Inside the form I have written some scripts to make a JSON call:
<script type="text/javascript"><xsl:text disable-output-escaping="yes"><![CDATA[
$(function() {
$('#submit').click(function() {
if ($('#nlapproved').attr('checked')) {
newsletter();
}
});
function newsletter()
{
$form = $('<form action="http://mydomain.createsend.com/t/j/s/jtes/" method="post" id="subForm" />');
$form.append('<input type="hidden" name="cm-name" id="hidName" />');
$form.append('<input type="hidden" name="cm-jtes-jtes" id="hidEmail" />');
$form.append('<input type="hidden" name="cm-fo-pikty" id="hidPrivateBusiness" />');
$form
.find("#hidName")
.val(']]></xsl:text><xsl:value-of select="$context//checkoutinformation/info[key='name']/value" disable-output-escaping="yes"/><xsl:text disable-output-escaping="yes"><![CDATA[');
$form
.find("#hidEmail")
.val(']]></xsl:text><xsl:value-of select="$context//checkoutinformation/info[key='email']/value" disable-output-escaping="yes"/><xsl:text disable-output-escaping="yes"><![CDATA[');
$form
.find("#hidPrivateBusiness")
.val(']]></xsl:text><xsl:value-of select="$acctype"/><xsl:text disable-output-escaping="yes"><![CDATA[');
$.getJSON(
$($form).get(0).action + "?callback=?",
$($form).serialize(),
function (data) {
if (data.Status === 400) {
alert("Error: " + data.Message);
} else {
// 200
alert("Success: " + data.Message);
}
}
);
}
});
]]>
</xsl:text>
</script>
My problem is that this thing does not work when the outer form is there--the code works fine otherwise.
Note: I am redirecting this page to another physical server in the post back of my outer form and i have a lot of other controls in my first form so i cant simply avoid that.
Can anyone help?
The actual form is being submitted. Stop that:
$("#confirm-order-form").on('submit', function (e) { e.preventDefault(); });
EDIT: to submit ajax, then normal form:
...ajax.done(function () {
$("#confirm-order-form").off('submit').trigger('submit');
});
After successful ajax completion, unbind the prevention of the form submission and trigger a submission.
1) Add a div outside the form that has the runat="server" attribute.
<form runat="server">
<!-- stuff here -->
</form>
<div id="target"></div>
2) Write your jQuery selector to target that div.
$('#target').append('<form id="newform"></form>');
// add your controls...
$.post(
'your_action',
$('#newform').serialize(),
function(result){
// handle result...
},
'json');
3) Do whatever you need to do with the server form...
Related
I'm trying to display sum value in template page using meteor.js.
Here is my html code:
<head>
<title>Sum</title>
</head>
<body>
<h1>Sum of two values</h1>
{{> sumForm}}
</body>
<template name="sumForm">
<form>
<input type="text" name="value1"> + <input type="text" name="value2"><p>Total: {{totalSum}}</p>
<input type="submit" value="Sum">
</form>
</template>
and my js code:
if(Meteor.isClient){
Template.sumForm.events({
'submit form': function(event){
event.preventDefault();
value1Var = parseInt(event.target.value1.value);
value2Var = parseInt(event.target.value2.value);
Template.sumForm.totalSum = value1Var + value2Var;
return Template.sumForm.totalSum;
}
});
}
But this does not work.
Can any one help?
You can user reactive-var to achive what you want
First you have to add the lightweight reactive-var package
meteor add reactive-var
Then at your Template file add:
if (Meteor.isClient) {
Template.sumForm.created = function () {
//We set default value
this.counter = new ReactiveVar(0);
}
Template.sumForm.helpers({
totalSum: function () {
return Template.instance().counter.get();
}
});
Template.sumForm.events({
'submit form': function(event, template){
event.preventDefault();
value1Var = parseInt(event.target.value1.value);
value2Var = parseInt(event.target.value2.value);
var sum = value1Var + value2Var;
return template.counter.set(sum);;
}
});
}
Template.sumForm.helpers({
totalSum: function(){
return Session.get("sum");
}
});
And at the end of your submit event
Session.set("sum", value1Var + value2Var);
For a cleaner solution also consider using reactive-var instead of session variables.
Inside a view, I have the following:
#using (Html.BeginForm())
{
<input type="submit" id="savebtn" value="Save" onclick="saveLayout()"/>
}
<script type="text/javascript">
function saveLayout() {
$.ajax({
url: '/Page/SaveFaces/',
data: {
/* layout data of the page, irrelevant */
},
type: 'post',
success: function () {
}
});
return false;
}
</script>
The above hits the following action, which simply redirects the user back to the URL they came from (it's also supposed to save the data, but I've removed that part for simplicity, as it doesn't affect the problem):
[HttpPost]
public ActionResult SaveFaces(string items)
{
return Redirect(Request.UrlReferrer.AbsoluteUri);
}
Then, due to the redirect, we go back to this pretty standard model-fetching action:
public ActionResult Index(int id = 0)
{
var page = db.Pages.Find(id);
if (page == null) return HttpNotFound();
return View(page);
}
The problem is that this last action is called twice.
I have tried removing the AJAX call and doing a normal POST operation and the problem goes away. However, the data I'm trying to send is obtainable only through the a jQuery script and I can't put them in a form. I'm constrained to work with the AJAX method.
Is there anything I can do to prevent the action from being hit twice?
I see you are using jQuery. Can you try this instead? (Note you may have to bind the the form submit event rather than the input button, or both)
#using (Html.BeginForm())
{
<input type="submit" id="savebtn" value="Save" >
}
<script type="text/javascript">
$("#savebtn").submit(function saveLayout(event) {
// The magic that prevents post.
event.preventDefault();
$.ajax({
url: '/Page/SaveFaces/',
data: {
/* layout data of the page, irrelevant */
},
type: 'post',
success: function () {
}
});
return false;
}
</script>
Also if you have access to form element, another way:
<form onsubmit="javascript: return false;">
Though it might be a bit specific to my scenario, I just found an acceptable solution. Since all the data is provided through jQuery, I removed the form completely and replaced the submit button with a simple link.
So, this goes away:
#using (Html.BeginForm())
{
<input type="submit" id="savebtn" value="Save" />
}
And this is put in place instead:
<a onclick="saveLayout()" id="saveLink">Click to save.</a>
Now the [HttpPost] action is hit, the data is saved and the redirected-to action is also hit, once.
Is there a standard practice for localizing the JQuery Validation messages?
I've been able to hack something together by declaring my own ClassRules and referencing them instead of the default ones.
My code.
<input class="localized-required" id="myTextInput" name="myTextInput" type="text" value="" />
<script language="javascript" type="text/javascript">
jQuery(document).ready(function () {
$.validator.addMethod("localized-required", $.validator.methods.required, '<%: Resources.Strings_ValidationMessages.SelectionRequired %>');
$.validator.addClassRules(
{
"localized-required": { "localized-required": true }
});
jQuery("#myForm").validate();
})
</script>
I'm just looking to see if there is a better way.
You could overwrite the messages object in the validator object.
$.validator.messages = {
required: '<%: Resources.Strings_ValidationMessages.SelectionRequired %>'
};
Or you could potentially use your own defaultMessage function.
$.validator.prototype.defaultMessage = function(element, method) {
var locale = magicFunctionToGetLocale();
var message = $.validator.localizedMessages[locale][method];
return this.findDefined(
this.customMessage( element.name, method ),
this.customMetaMessage( element, method ),
// title is never undefined, so handle empty string as undefined
!this.settings.ignoreTitle && element.title || undefined,
message,
"<strong>Warning: No message defined for " + element.name + "</strong>"
);
};
In the above example, $.validator.localizedMessages is an object created elsewhere in your code. The standard validation plugin does not have a localizedMessages object.
There are validation files available if you want:
https://github.com/jzaefferer/jquery-validation/tree/master/src/localization
Just get the ones you need and reference the .js file(s) in your page.
<script type="text/javascript" src="localization/messages_XX.js"></script>
function postForm()
{
$.ajax({
type: "POST",
data: $("#myForm").serialize(),
dataType: "json",
url: '<%= Url.Action("JSONRequest","Home") %>',
success: function(result)
{
window.alert(result.name);
},
error : function()
{
window.alert('error');
}
});
}
Html.BeginForm("JSONRequest", "Home", FormMethod.Post, new { id = "myForm" });
Html.TextBox("mazhar")
<input type="submit" onclick="postForm" />
Html.EndForm();
public ActionResult JSONRequest(FormCollection form)
{
string a = form["mazhar"];
var data = new { name = "aaaa", Success = "Record is Succesfully Saved", ErrorMessages = "abc" };
return Json(data);
}
Ok the problem is that the dialog box is opening after running this code which is asking to save file.
Can someone tell me how to resolve this issue? Why does this box comes afterall?
You need to cancel the default form submission by returning false inside the button onclick handler:
<input type="submit" onclick="postForm(); return false;" />
That being said, I would suggest you a better solution. Use the jquery.form plugin which enables you to ajaxify an HTML form. This way much of the duplication in your code could be simplified:
Html.BeginForm("JSONRequest", "Home", FormMethod.Post, new { id = "myForm" });
Html.TextBox("mazhar")
<input type="submit" value="OK" />
Html.EndForm();
And in javascript:
$(function() {
$('#myForm').ajaxForm({
success: function(result) {
window.alert(result.name);
},
error : function() {
window.alert('error');
}
});
});
This way you no longer need to specify url, method, manually serialize form fields, etc... You also don't need to pollute your HTML markup with javascript functions. This is unobtrusive javascript. Another advantage of this approach is that now you will be able to externalize this javascript into a separate static .js file as it no longer relies on server side code (<%= Url.Action("JSONRequest","Home") %>) and this you will benefit from reducing the bandwidth and caching static resources.
I think you are posting the form twice. You should use Ajax.BeginForm instead of normal form. And remove the jQuery Ajax call.
Here is a very good example of using Ajax Form.
http://davidhayden.com/blog/dave/archive/2009/05/19/ASPNETMVCAjaxBeginForm.aspx
Or you can also try by replacing
<input type="submit" onclick="postForm" />
with
<input type="button" onclick="postForm" />
I am using the .alphanumeric plugin for jQuery which is certainly doing what I would expect as users type directly into the textbox. But, if a user were to copy and paste a value into the text box, all bets are off.
$("#<%= txtNumber.ClientID %>").alphanumeric({allow:"-"});
I can certainly do this:
$(document).ready(function() {
$("#<%= txtNumber.ClientID %>").blur(function() {
$("#<%= txtNumber.ClientID %>").val(
RemoveInvalidCharacters(
$("#<%= txtNumber.ClientID %>").val()
)
);
});
});
//FUNCTION REMOVES ANY ; IN TEXT TO PREVENT SQL INJECTION
function RemoveInvalidCharacters(text) {
return text.replace(';', '');
}
But... I'd rather not have to kluge up my code even further with .blur() functions. Are there any other ways around this?
Handling the paste event is fairly straightforward. I'm using this technique in my masked input plugin with good results. Feel free to browse the source to see it in use.
Here is the relevant bits modified for your example above.
var pasteEventName = $.browser.msie ? 'paste' : 'input';
$("#<%= txtNumber.ClientID %>").bind(pasteEventName, function() {
setTimeout(function() {
RemoveInvalidCharacters(
$("#<%= txtNumber.ClientID %>").val()
);
}, 0);
});
I found this solution here:
http://www.devcurry.com/2009/10/allow-only-alphanumeric-characters-in.html
<script type="text/javascript">
$(function() {
$('input.alpha').keyup(function() {
if (this.value.match(/[^a-zA-Z0-9 ]/g)) {
this.value = this.value.replace(/[^a-zA-Z0-9 ]/g, '');
}
});
});
</script>
<input type="text" name="test" value="" class="alpha">
I too was needing a solution to the paste problem, and I figured out something that will work for me. A person can still use the Edit > Paste in the browsers menu, but Ctrl-V, as well as right click paste is handled. Tested in FF,IE,Opera,Safari,Chrome:
<!DOCTYPE html>
<html>
<head>
<title>Only Allow Certain Characters</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
<body>
<br>
<form id="myform" action="">
<input id="element1" name="mytext1" type="text">
<input id="element2" name="mytext2" type="text">
</form>
<script>
/* removes evil chars while typing */
(function($){
$.fn.disableChars = function(a) {
a = $.extend({
allow: ''
}, a);
b = a.allow.split('');
for ( i=0; i<b.length; i++) b[i] = "\\" + b[i];
a.allow = b.join('');
var regex = new RegExp('[^a-z0-9' + a.allow + ']', 'ig');
$(this)
.bind('keyup blur', function() {
if (this.value.search(regex) != '-1') {
this.value = this.value.replace(regex, '');
}
})
.bind('contextmenu',function () {return false});
}
})(jQuery);
$("#element1").disableChars();
$("#element2").disableChars({allow:".,:-() "});
</script>
</body>
</html>
Copy and Paste is definitely a challenge for masked inputs.
Have you considered "encoding" special characters when the form is submitted as opposed to when the user enters values? We do the same thing to allow users to enter the < and > characters in TextBoxes (we convert them to < and > via javascript and then back in to < and > in the code behind.
This way you will not prevent an SQL injection. I’m not required to use your form, I can make mine and POST it to your script. Even easier: I can disable javascript and go drop your database.
Instead, check the input validity on server side.
The easiest ways are escaping it or using parametrised queries.