Alberto Montellano
Alberto Montellano

Reputation: 6246

Href link that calls Javascript function opens a new tab and doesn't work in Firefox

I'm creating a link that calls a javascript function in href attribute:

 <a class="product-link" target="_blank" href='javascript:functionToPostParameters("path", "parameters");'><span class="product-name">My Product Link</span></a>

My function is this:

function functionToPostParameters(path, params) {
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("target", "_blank");
form.setAttribute("action", path);

for (var key in params) {
    if (params.hasOwnProperty(key)) {
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", params[key]);
        form.appendChild(hiddenField);
    }
}

    form.submit();
    return false;
};

When I use this link in Chrome, it calls the function, submit the form with parameters and a new tab is opened.

In Firefox, it opens a new tab and then calls the function, as the new tab doens't contain the function, this error is shown in the console of the new tab:

 ReferenceError: functionToPostParameters is not defined

Is there an error in the href value / js function that makes Firefox behave in that way?

Any approach is welcomed, using href for the link.

Upvotes: 4

Views: 3067

Answers (3)

Alberto Montellano
Alberto Montellano

Reputation: 6246

Ok, I found the cause of the problem.

I want that after the post is done, it gets opened in a new tab.

The problem was that Firefox needs two things:

1. Form needs a submit button.
2. Form needs to be appended to body in order to make submit works.

The new code of my function:

function functionToPostParameters(path, params) {

var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("target", "_blank");
form.setAttribute("action", path);

for (var key in params) {
    if (params.hasOwnProperty(key)) {
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", params[key]);
        form.appendChild(hiddenField);
    }
}

var submitButton = document.createElement("input");// NEW  
submitButton.setAttribute("type", "submit");// NEW  
submitButton.setAttribute("value", "Click");// NEW  
form.appendChild(submitButton);// NEW  
document.body.appendChild(form); // NEW  

form.submit();
};

Link html:

 <a class="product-link" target="_self" href="javascript:void(0);" onclick="javascript:functionToPostParameters('path', 'parameters');"><span class="product-name"> My product Link </span> </a>

Hope it helps to someone else.

Upvotes: 1

AlexisK
AlexisK

Reputation: 111

Problem is your that a:href still works - you open new tab by link, not because of form redirect.

Workaround 1:

<a class="product-link postLink" data-path="about:blank" data-params='{"x":1}' href='#'><span class="product-name">My Product Link</span></a>

And JS

function clearEvents(node) {
    node.onclick = function() { return false; }
    node.onmousedown = function() { return false; }
    node.onmouseup = function() { return false; }
    node.onmousemove = function() { return false; }
    return node;
}

function functionToPostParameters(path, params) {
    var form = document.createElement("form");
    form.setAttribute("method", "post");
    form.setAttribute("target", "_blank");
    form.setAttribute("action", path);

    for (var key in params) {
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", params[key]);
        form.appendChild(hiddenField);
    }

    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);

    return false;
}

function processPostLinks() {
    var nodes = document.getElementsByClassName('postLink');

    for ( var i = 0; i < nodes.length; i++ ) {
        var node = nodes[i];
        clearEvents(node).onclick = function() {
            functionToPostParameters(node.getAttribute('data-path'),JSON.parse(node.getAttribute('data-params')));
            return false;
        }
    }
}
processPostLinks();

Basically - script goes through all .postLink elements, than disables default a-tag behavior and sets functionToPostParameters with data-path and data-params attributes as function params on mouse-click.

Workaround 2 - same as first one, but try not to use a:href (give .postLink css-class, data-path and data-params attributes to styled div for example) - in such case function clearEvents is fully optional

Workaround 3 - use formData https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects and ajax to send your request.

Upvotes: 1

Bud Damyanov
Bud Damyanov

Reputation: 31839

Try to set the href attribute to href="javascript:void(0);" (this will disable the default action of the link) and set the onclick event handler:

<a class="product-link" target="_blank" href="javascript:void(0);" onclick="javascript:functionToPostParameters('path', 'parameters');"><span class="product-name">My Product Link</span></a>

Upvotes: 1

Related Questions