使用 JavaScript/jQuery 更改表单的操作
我遇到了一个让我抓狂的问题。 我正在尝试修改 openid 选择器以支持 facebook。 我使用 RPXNow 作为我的提供程序,因此它要求将表单提交到与标准不同的 url。
例如。 RpxNow 要求我像这样设置我的表单:
这适用于每个提供商Facebook 和 Myspace 除外。 这些要求将表单发布到不同的网址,如下所示:
和
打开的 id 选择器在表单上有一堆按钮,每个按钮代表openid 提供商。 我想做的是检测何时单击 Facebook 或 Myspace 按钮并在提交之前更改表单上的操作。 但是它不起作用。 这是我的代码。
我已经尝试了几种变体,所有变体都有相同的“不支持”异常
$("#openid_form").attr("action", form_url)
document.forms[0].action = form_url
有什么建议吗?
更新
以下是有关代码的更多详细信息。 为了简洁起见,我省略了一些内容。 我所做的唯一一件事是将 Facebook 部分添加到“providers_large”对象(成功将徽标添加到网站),并且我没有提供标识用户的 url,而是创建一个名为“form_url”的属性,其中是我想要将表单的操作设置为的内容。 如果您查看标题“Provider image click”部分,您将看到我在哪里检查属性“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();
}
};
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.
For example. RpxNow requires me to setup my form like this:
<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:
<form action="https://wikipediamaze.rpxnow.com/facebook/start?token_url=...">
and
<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.
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.
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();
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您有任何名为“action”的表单元素,jQuery (1.4.2) 会感到困惑。 您可以通过使用 DOM 属性方法来解决这个问题,或者只是避免使用名为“action”的表单元素。
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".
我同意 Paolo 的观点,我们需要看到更多代码。 我测试了这个过于简化的示例并且它有效。 这意味着它能够动态改变表单动作。
编辑:我测试了您发布的更新代码,发现
providers_large
声明中存在语法错误。 多了一个逗号。 Firefox 会忽略该问题,但 IE8 会抛出错误。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.
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.只是为了在 Tamlyn 所写的内容中添加细节,
而不是
$('form').get(0).setAttribute('action', 'baz'); //这有效
$('form')[0].setAttribute('action', 'baz');
同样有效
just to add a detail to what Tamlyn wrote,
instead of
$('form').get(0).setAttribute('action', 'baz'); //this works
$('form')[0].setAttribute('action', 'baz');
works equally well
实际上,您可以使用
据我所知,这不会默默地失败。
如果页面在新目标中打开,您可能需要确保每次 URL 都是唯一的,因为 Webkit (chrome/safari) 会缓存您访问过该 URL 的事实,并且不会执行发布。
例如
You can actually just use
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.
For example
只是对此的更新 - 我在使用 jQuery 更新表单的操作属性时遇到了类似的问题。
经过一些测试发现该命令:
$('#myForm').attr('action','new_url.html');
如果表单的操作属性为空,则静默失败。
如果我更新表单的操作属性以包含一些文本,则 jquery 可以工作。
Just an update to this - I've been having a similar problem updating the action attribute of a form with jQuery.
After some testing it turns out that the command:
$('#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.
使用Java脚本动态改变action url
对我来说效果很好
}
Use Java script to change action url dynamically
Works for me well
}