Alec
Alec

Reputation: 9078

jQuery/PHP and multilingual confirm/alert boxes

Just when I was about to post this question, I came up with an easy solution kind-of-a solution.

The problem was that I needed confirmation messages in multiple languages, depending on the selected language by the user. Since I always grab certain information from the HTML, I was trying to do it that way, but got stuck around this point:

Here's simple delete-button for the user, using a title attribute with the correct message (in this example it's just text; in the code it's a variable containing the correct translation):

<input type="submit" name="delete" value="Delete me" title="Are you sure?" />

And then I retrieve that line with jQuery and display it in the confirm box, like so:

$("input[type='submit'][name='delete']").click(function() {
  return confirm($(this).attr('title'));
});

However, this would still mean that the input element had a title that's visible with a mouseover, which I don't like. Removing it wasn't really an option, because cancelling the confirm box and clicking the button again would then result in an empty message.

Anyway, this whole approach just wasn't working for me for retrieve a simple line of text. Then I thought of $.get() — and I don't know why I didn't think of that earlier, because I use it all the time in other scenarios.

So I guess this is a pretty good solution in general for directly getting the correct texts into JavaScript, without having to deal with the HTML and reading out titles or other attributes.


$("input[type='submit'][name='delete']").click(function() {
    $.get('something.php', {
            action: 'getText',
            variable: 'confirm_delete'
        }, function(text) {
            return confirm(text); // doesn't return instantly...
      });
    return false; // breaks the form action...
});


UPDATE
Ok, now I turn this back into a question about the last part of the jQuery script. It seems that $.get() needs some time to retrieve the information. It's propably not much time at all, but it's some, and in the mean time, the form is already being submitted. The return false at the bottom solves this in part, because it's the first thing that gets returned. But then, when the return confirm follows, clicking OK won't do much of anything, since return false already stopped the default button action.

So.. my question is: is there a way to retrieve the text using $.get(), and in such a way that the form submission waits until the return confirm is loaded?

Upvotes: 0

Views: 2139

Answers (2)

Josh Leitzel
Josh Leitzel

Reputation: 15209

What I would suggest is something that would cost you a little more time initially but long-term I believe would benefit you.

I have a project that is also set up to be multilingual, so one of the first things I do on the page is load the text that I'll need for that page.

I store my text in a simple XML file (I really don't have that much text right now, but you could obviously do it in a database, txt file, whatever you want), and then I just load it with $.ajax (with async set to false so that you know the text is all loaded before you try to call it) right away. I have this set up as my language object, which takes a language code as a parameter. So by calling language = new language('en-us'); at the beginning of my page, I can easily grab any language-agnostic text whenever I need it. For example, if you applied this to your project, it would be this simple:

$("input[type='submit'][name='delete']").click(function() {
  return confirm(language.text('are_you_sure'));
});

Edit: I'd also just like to say that this works well with PHP too, since you can read the same XML file from PHP and jQuery, thereby keeping all your text in one centralized place.

If you don't like this approach, I'd point out two other HTML approaches similar to those that you've been trying. The first is to simply use an input[type=hidden] field. This way, you won't have the mouseover effect that you dislike. Then you could just do something like this:

<input type="hidden" name="confirm_text" value="Are you sure?" />
$("input[type='submit'][name='delete']").click(function() {
  return confirm($('input[name=confirm_text]').val());
});

However, I think this is pretty crude, to be honest, and not very semantic. The other option is to use a data- attribute, but this is only open to you if you're using HTML5 (which you can easily do—just change your doctype). That would work like this:

<input type="submit" name="delete" value="Delete me" data-confirmtext="Are you sure?" />
$("input[type='submit'][name='delete']").click(function() {
  return confirm($(this).attr('data-confirmtext'));
});

Of all these options, I definitely think the first is the best one, since you're interested in best practices and semantics. Trying to store random data in irrelevant HTML attributes or hidden fields just doesn't strike me as very semantic. Hope this helps!

Upvotes: 1

Justin Johnson
Justin Johnson

Reputation: 31300

I think your solution can use a little more tuning. Doing it this way creates (possible) many ajax requests that aren't really necessary.

You could just use the rel attribute:

<input type="submit" name="delete" value="Delete me" rel="Are you sure?" />

And then

$("input[type='submit'][name='delete']").click(function() {
  return confirm($(this).attr('rel'));
});

Better yet, you could store a key in the rel attribute such as rel='confirmation.delete'. And then have an interpreter such as:

var stringLibrary = {
    prompt: {
        foo: "Enter your foo:",
        bar: "How many bars?"
    },
    confirmation: {
        delete: "Are you sure you want to delete that?"
    },
    error: {
        codes: {
            324: "Oh no!",
            789: "Oh yes!"
        }
    }
};

var trans = function(key) {
    var result = stringLibrary;
    key = key.split(".");

    for ( var i in key ) {
        if ( result[ key[i] ] ) {
            result = result[ key[i] ];
        } else {
            return null;
        }
    }

    return result;
}

Usage:

console.log(trans("prompt.foo"));
console.log(trans("confirmation.delete"));
console.log(trans("error.codes.324"));
console.log(trans("i.dont.exist"));

$("input[type='submit'][name='delete']").click(function() {
  return confirm( trans($(this).attr('rel')) );
});

Upvotes: 0

Related Questions