使用 JavaScript/jQuery 更改表单的操作

发布于 2024-07-24 06:05:37 字数 8192 浏览 7 评论 0原文

我遇到了一个让我抓狂的问题。 我正在尝试修改 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

柠檬色的秋千 2024-07-31 06:05:38

如果您有任何名为“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>

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".

<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>
杀お生予夺 2024-07-31 06:05:38

我同意 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>

编辑:我测试了您发布的更新代码,发现 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

};

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.

<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.

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

};
つ可否回来 2024-07-31 06:05:38

只是为了在 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

梦在深巷 2024-07-31 06:05:38

实际上,您可以使用

$("#form").attr("target", "NewAction");

据我所知,这不会默默地失败。

如果页面在新目标中打开,您可能需要确保每次 URL 都是唯一的,因为 Webkit (chrome/safari) 会缓存您访问过该 URL 的事实,并且不会执行发布。

例如

$("form").attr("action", "/Pages/GeneratePreview?" + new Date().getMilliseconds());

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.

For example

$("form").attr("action", "/Pages/GeneratePreview?" + new Date().getMilliseconds());
不念旧人 2024-07-31 06:05:38

只是对此的更新 - 我在使用 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.

勿忘初心 2024-07-31 06:05:38

使用Java脚本动态改变action 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 %} 

Use Java script to change action url dynamically
Works for me well

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 %} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文