web-dev-qa-db-fra.com

Changer l'action d'un formulaire avec JavaScript / jQuery

J'ai un problème qui me rend fou. J'essaye de modifier l'openid-selector pour supporter Facebook. J'utilise RPXNow en tant que fournisseur et le formulaire doit donc être soumis à une autre URL que la norme.

Par exemple. RpxNow nécessite que je configure mon formulaire comme suit:

<form action="https://wikipediamaze.rpxnow.com/openid/start?token_url=...">

Cela fonctionne pour tous les fournisseurs sauf Facebook et Myspace. Ceux-ci exigent que le formulaire soit envoyé dans une autre URL, comme ceci:

<form action="https://wikipediamaze.rpxnow.com/facebook/start?token_url=...">

et

<form action="https://wikipediamaze.rpxnow.com/myspace/start?token_url=...">

Le sélecteur open id comporte un groupe de boutons sur le formulaire, chacun représentant les fournisseurs openid. Ce que j'essaie de faire, c'est de détecter quand on clique sur le bouton Facebook ou Myspace et de modifier l'action sur le formulaire avant de le soumettre. Cependant cela ne fonctionne pas. Voici mon code.

J'ai essayé plusieurs variantes, toutes avec la même exception "non supportée"

$("#openid_form").attr("action", form_url)
document.forms[0].action = form_url

Aucune suggestion?

Mise à jour

Voici plus de détails sur le code. J'ai omis certains pour la brièveté. La seule chose que j'ai faite est d'ajouter la section Facebook à l'objet "providers_large" (qui ajoute le logo au site Web). Au lieu de fournir une URL identifiant l'utilisateur, je crée une propriété appelée "formulaire_url". est ce que je veux définir l'action de ma forme à. Si vous consultez le titre de la section "Image du fournisseur, cliquez sur", vous verrez où je vérifie la présence de la propriété "form_url" et à l'aide de jQuery pour modifier l'action et envoyer le formulaire. Cependant, lorsque je passe en revue le JavaScript en mode débogage, il me dit que l'opération est invalide.

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();
    }
};
62
Micah

jQuery (1.4.2) devient confus si vous avez des éléments de formulaire nommés "action". Vous pouvez contourner ce problème en utilisant les méthodes d'attribut DOM ou simplement éviter d'avoir des éléments de formulaire nommés "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>
125
Tamlyn

Je suis d'accord avec Paolo qu'il faut voir plus de code. J'ai testé cet exemple trop simplifié et cela a fonctionné. Cela signifie qu'il est capable de changer l'action du formulaire à la volée.

<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: J'ai testé le code mis à jour que vous avez posté et trouvé une erreur de syntaxe dans la déclaration de providers_large. Il y a une virgule supplémentaire. Firefox ignore le problème, mais IE8 génère une erreur.

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

};
25
Jose Basilio

juste pour ajouter un détail à ce que Tamlyn a écrit, au lieu de
$('form').get(0).setAttribute('action', 'baz'); //this works

$('form')[0].setAttribute('action', 'baz');
fonctionne aussi bien

6
yitwail

Vous pouvez réellement utiliser

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

Pour autant que je sache, cela n'échouera pas en silence.

Si la page s'ouvre dans une nouvelle cible, vous devrez peut-être vous assurer que l'URL est unique à chaque fois car Webkit (chrome/safari) mettra en cache le fait que vous avez visité cette URL et n'effectuera pas la publication.

Par exemple

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

Juste une mise à jour: j'ai un problème similaire lors de la mise à jour de l'attribut d'action d'un formulaire avec jQuery.

Après quelques tests, il s'avère que la commande: $ ('#MyForm'). Attr ('action', 'new_url.html');

échoue silencieusement si l'attribut d'action du formulaire est vide. Si je mets à jour l'attribut d'action de mon formulaire pour qu'il contienne du texte, jquery fonctionne.

3
Daniel

Utilisez le script Java pour modifier l’URL de l’action de manière dynamique. Fonctionne bien pour moi.

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 %} 
1
naren