使用 JavaScript/jQuery 更改表单的操作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/979024/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing the action of a form with JavaScript/jQuery
提问by Micah
I'm having an issue that is driving me crazy. I'm trying to modify the openid-selector to support facebook. I'm using RPXNow as my provider so it requires the form to be submitted to a different url than the standard.
我遇到了一个让我发疯的问题。我正在尝试修改 openid-selector 以支持 facebook。我使用 RPXNow 作为我的提供者,因此它要求将表单提交到与标准不同的 url。
For example. RpxNow requires me to setup my form like this:
例如。RpxNow 要求我像这样设置我的表单:
<form action="https://wikipediamaze.rpxnow.com/openid/start?token_url=...">
<form action="https://wikipediamaze.rpxnow.com/openid/start?token_url=...">
This works for every provider except for Facebook and Myspace. Those require the form to be posted to a different url like this:
这适用于除 Facebook 和 Myspace 之外的所有提供商。这些要求将表单发布到不同的网址,如下所示:
<form action="https://wikipediamaze.rpxnow.com/facebook/start?token_url=...">
<form action="https://wikipediamaze.rpxnow.com/facebook/start?token_url=...">
and
和
<form action="https://wikipediamaze.rpxnow.com/myspace/start?token_url=...">
<form action="https://wikipediamaze.rpxnow.com/myspace/start?token_url=...">
The open id selector has a bunch of buttons on the form each representing the openid providers. What I'm trying to do is detect when the Facebook or Myspace button is clicked and changed the action on the form before submitting. However it's not working. Here is my code.
open id 选择器在表单上有一堆按钮,每个按钮代表 openid 提供者。我想要做的是检测何时单击 Facebook 或 Myspace 按钮并在提交之前更改表单上的操作。但是它不起作用。这是我的代码。
I've tried several variations all with the same "not supported" exception
我尝试了几种变体,所有变体都具有相同的“不支持”异常
$("#openid_form").attr("action", form_url)
document.forms[0].action = form_url
Any suggestions?
有什么建议?
Update
更新
Here are more details on the code. I've omitted some for brevity. The only thing i've done is added the Facebook section to the "providers_large" object (which successfully adds the logo to the website), and instead of supply a url identifying the user, I'm creating a property called "form_url" which is what I want to set the action of my form to. If you look at the section title "Provider image click" you'll see where I'm checking for the presence of the property "form_url" and using jQuery to change the action and submit the form. However when I step through the JavaScript in debug mode it tells me it's an invalid operation.
以下是有关代码的更多详细信息。为简洁起见,我省略了一些。我所做的唯一一件事就是将 Facebook 部分添加到“providers_large”对象(它成功地将徽标添加到网站),而不是提供标识用户的 url,我正在创建一个名为“form_url”的属性是我想将表单的操作设置为。如果您查看标题“提供者图像单击”部分,您将看到我正在检查属性“form_url”是否存在并使用 jQuery 更改操作并提交表单的位置。但是,当我在调试模式下单步执行 JavaScript 时,它告诉我这是一个无效操作。
var providers_large = {
google: {
name: 'Google',
url: 'https://www.google.com/accounts/o8/id'
},
facebook: {
name: 'Facebook',
form_url: 'http://wikipediamaze.rpxnow.com/facebook/start?token_url=http://www.wikipediamaze.com/Accounts/Logon'
},
};
var providers_small = {
myopenid: {
name: 'MyOpenID',
label: 'Enter your MyOpenID username.',
url: 'http://{username}.myopenid.com/'
},
livejournal: {
name: 'LiveJournal',
label: 'Enter your Livejournal username.',
url: 'http://{username}.livejournal.com/'
},
flickr: {
name: 'Flickr',
label: 'Enter your Flickr username.',
url: 'http://flickr.com/{username}/'
},
technorati: {
name: 'Technorati',
label: 'Enter your Technorati username.',
url: 'http://technorati.com/people/technorati/{username}/'
},
wordpress: {
name: 'Wordpress',
label: 'Enter your Wordpress.com username.',
url: 'http://{username}.wordpress.com/'
},
blogger: {
name: 'Blogger',
label: 'Your Blogger account',
url: 'http://{username}.blogspot.com/'
},
verisign: {
name: 'Verisign',
label: 'Your Verisign username',
url: 'http://{username}.pip.verisignlabs.com/'
},
vidoop: {
name: 'Vidoop',
label: 'Your Vidoop username',
url: 'http://{username}.myvidoop.com/'
},
verisign: {
name: 'Verisign',
label: 'Your Verisign username',
url: 'http://{username}.pip.verisignlabs.com/'
},
claimid: {
name: 'ClaimID',
label: 'Your ClaimID username',
url: 'http://claimid.com/{username}'
}
};
var providers = $.extend({}, providers_large, providers_small);
var openid = {
cookie_expires: 6*30, // 6 months.
cookie_name: 'openid_provider',
cookie_path: '/',
img_path: 'images/',
input_id: null,
provider_url: null,
init: function(input_id) {
var openid_btns = $('#openid_btns');
this.input_id = input_id;
$('#openid_choice').show();
$('#openid_input_area').empty();
// add box for each provider
for (id in providers_large) {
openid_btns.append(this.getBoxHTML(providers_large[id], 'large', '.gif'));
}
if (providers_small) {
openid_btns.append('<br/>');
for (id in providers_small) {
openid_btns.append(this.getBoxHTML(providers_small[id], 'small', '.ico'));
}
}
$('#openid_form').submit(this.submit);
var box_id = this.readCookie();
if (box_id) {
this.signin(box_id, true);
}
},
getBoxHTML: function(provider, box_size, image_ext) {
var box_id = provider["name"].toLowerCase();
return '<a title="'+provider["name"]+'" href="javascript: openid.signin(\''+ box_id +'\');"' +
' style="background: #FFF url(' + this.img_path + box_id + image_ext+') no-repeat center center" ' +
'class="' + box_id + ' openid_' + box_size + '_btn"></a>';
},
/* Provider image click */
signin: function(box_id, onload) {
var provider = providers[box_id];
if (! provider) {
return;
}
this.highlight(box_id);
this.setCookie(box_id);
// prompt user for input?
if (provider['label']) {
this.useInputBox(provider);
this.provider_url = provider['url'];
}
else if(provider['form_url']) {
$('#openid_form').attr("action", provider['form_url']);
$('#openid_form').submit();
}
else {
this.setOpenIdUrl(provider['url']);
if (! onload) {
$('#openid_form').submit();
}
}
},
/* Sign-in button click */
submit: function() {
var url = openid.provider_url;
if (url) {
url = url.replace('{username}', $('#openid_username').val());
openid.setOpenIdUrl(url);
}
return true;
},
setOpenIdUrl: function (url) {
var hidden = $('#'+this.input_id);
if (hidden.length > 0) {
hidden.value = url;
} else {
$('#openid_form').append('<input type="hidden" id="' + this.input_id + '" name="' + this.input_id + '" value="'+url+'"/>');
}
},
highlight: function (box_id) {
// remove previous highlight.
var highlight = $('#openid_highlight');
if (highlight) {
highlight.replaceWith($('#openid_highlight a')[0]);
}
// add new highlight.
$('.'+box_id).wrap('<div id="openid_highlight"></div>');
},
setCookie: function (value) {
var date = new Date();
date.setTime(date.getTime()+(this.cookie_expires*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
document.cookie = this.cookie_name+"="+value+expires+"; path=" + this.cookie_path;
},
readCookie: function () {
var nameEQ = this.cookie_name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
},
useInputBox: function (provider) {
var input_area = $('#openid_input_area');
var html = '';
var id = 'openid_username';
var value = '';
var label = provider['label'];
var style = '';
if (label) {
html = '<p>' + label + '</p>';
}
if (provider['name'] == 'OpenID') {
id = this.input_id;
value = 'http://';
style = 'background:#FFF url('+this.img_path+'openid-inputicon.gif) no-repeat scroll 0 50%; padding-left:18px;';
}
html += '<input id="'+id+'" type="text" style="'+style+'" name="'+id+'" value="'+value+'" />' +
'<input id="openid_submit" type="submit" value="Sign-In"/>';
input_area.empty();
input_area.append(html);
$('#'+id).focus();
}
};
回答by Tamlyn
jQuery (1.4.2) gets confused if you have any form elements named "action". You can get around this by using the DOM attribute methods or simply avoid having form elements named "action".
如果您有任何名为“action”的表单元素,jQuery (1.4.2) 会感到困惑。您可以通过使用 DOM 属性方法来解决这个问题,或者简单地避免将表单元素命名为“action”。
<form action="foo">
<button name="action" value="bar">Go</button>
</form>
<script type="text/javascript">
$('form').attr('action', 'baz'); //this fails silently
$('form').get(0).setAttribute('action', 'baz'); //this works
</script>
回答by Jose Basilio
I agree with Paolo that we need to see more code. I tested this overly simplified example and it worked. This means that it is able to change the form action on the fly.
我同意 Paolo 的观点,我们需要看到更多的代码。我测试了这个过于简化的例子,它奏效了。这意味着它能够即时更改表单操作。
<script type="text/javascript">
function submitForm(){
var form_url = $("#openid_form").attr("action");
alert("Before - action=" + form_url);
//changing the action to google.com
$("#openid_form").attr("action","http://google.com");
alert("After - action = "+$("#openid_form").attr("action"));
//submit the form
$("#openid_form").submit();
}
</script>
<form id="openid_form" action="test.html">
First Name:<input type="text" name="fname" /><br/>
Last Name: <input type="text" name="lname" /><br/>
<input type="button" onclick="submitForm()" value="Submit Form" />
</form>
EDIT:I tested the updated code you posted and found a syntax error in the declaration of providers_large
. There's an extra comma. Firefox ignores the issue, but IE8 throws an error.
编辑:我测试了您发布的更新代码,并在providers_large
. 还有一个逗号。Firefox 会忽略该问题,但 IE8 会引发错误。
var providers_large = {
google: {
name: 'Google',
url: 'https://www.google.com/accounts/o8/id'
},
facebook: {
name: 'Facebook',
form_url: 'http://wikipediamaze.rpxnow.com/facebook/start?token_url=http://www.wikipediamaze.com/Accounts/Logon'
}, //<-- Here's the problem. Remove that comma
};
回答by yitwail
just to add a detail to what Tamlyn wrote,
instead of$('form').get(0).setAttribute('action', 'baz'); //this works
只是为 Tamlyn 所写的内容添加一个细节,而不是$('form').get(0).setAttribute('action', 'baz'); //this works
$('form')[0].setAttribute('action', 'baz');
works equally well
$('form')[0].setAttribute('action', 'baz');
效果一样好
回答by George
You can actually just use
你实际上可以使用
$("#form").attr("target", "NewAction");
As far as I know, this will NOT fail silently.
据我所知,这不会无声地失败。
If the page is opening in a new target, you may need to make sure the URL is unique each time because Webkit (chrome/safari) will cache the fact you have visited that URL and won't perform the post.
如果页面在新目标中打开,您可能需要确保 URL 每次都是唯一的,因为 Webkit (chrome/safari) 会缓存您访问过该 URL 的事实并且不会执行发布。
For example
例如
$("form").attr("action", "/Pages/GeneratePreview?" + new Date().getMilliseconds());
回答by Daniel
Just an update to this - I've been having a similar problem updating the action attribute of a form with jQuery.
只是对此的更新 - 我在使用 jQuery 更新表单的 action 属性时遇到了类似的问题。
After some testing it turns out that the command: $('#myForm').attr('action','new_url.html');
经过一些测试后发现命令: $('#myForm').attr('action','new_url.html');
silently fails if the action attribute of the form is empty. If i update the action attribute of my form to contain some text, the jquery works.
如果表单的 action 属性为空,则静默失败。如果我更新表单的 action 属性以包含一些文本,jquery 就会工作。
回答by naren
Use Java script to change action url dynamically Works for me well
使用 Java 脚本动态更改操作 url 对我来说效果很好
function chgAction( action_name )
{
{% for data in sidebar_menu_data %}
if( action_name== "ABC"){ document.forms.action = "/ABC/";
}
else if( action_name== "XYZ"){ document.forms.action = "/XYZ/";
}
}
}
<form name="forms" method="post" action="<put default url>" onSubmit="return checkForm(this);">{% csrf_token %}