Ikke's blog » javascript http://eikke.com 'cause this is what I do Sun, 13 Feb 2011 14:58:55 +0000 en-US hourly 1 http://wordpress.org/?v=3.4.1 Scripting your app http://eikke.com/scripting-your-app/ http://eikke.com/scripting-your-app/#comments Tue, 09 Sep 2008 21:12:28 +0000 Nicolas http://eikke.com/scripting-your-app/ Lots of buzz on adding scripting interfaces to applications on Planet GNOME recently, cool. Looks like Alexander Larsson hacked together a wrapper around SpiderMonkey (the Mozilla Engine) to get JavaScript integrated. Related to the jscore-python thing I blogged about before.

Not sure this is the best way to tackle this cool new opportunity though. JavaScript can be pretty hard to “get” for people not used to it, but more familiar with classical languages (wrt object oriented paradigms). I guess lots of current code contributors are not very familiar with JavaScript, but do have an in-depth knowledge of some other scripting language though (not listing any here, you certainly can name some).

So, wouldn’t it be nice if the GScript interface would be abstract for the application developer, who should just create a script context, put some objects in it, and launch a script, after which the GScript runtime figures out which interpreter to use for this script, so scripting languages become plugable?

Reminds me a little of my old OPluginManager work :-)

]]>
http://eikke.com/scripting-your-app/feed/ 12
Embedding JavaScript in Python http://eikke.com/embedding-javascript-in-python/ http://eikke.com/embedding-javascript-in-python/#comments Mon, 25 Aug 2008 23:05:16 +0000 Nicolas http://eikke.com/embedding-javascript-in-python/ Reading some posts about embedding languages/runtimes in applications on Planet GNOME reminded me I still had to announce some really quick and incomplete code blob I created some days after last GUADEC edition (which was insanely cool, thanks guys).

It takes WebKit‘s JavaScriptCore and allows you to embed it in some Python program, so you, as a Python developer, can allow consumers to write plugins using JavaScript. Don’t ask me whether it’s useful, maybe it’s not, but anyway.

There’s one catch: currently there is no support to expose custom Python objects to the JavaScript runtime: you’re able to use JavaScript objects and functions etc. from within Python, but not the other way around. I started working on this, but the JSCore API lacked some stuff to be able to implement this cleanly (or I missed a part of it, that’s possible as well), maybe it has changed by now… There is transparent translation of JavaScript base types: unicode strings, booleans, null (which becomes None in Python), undefined (which becomes jscore.UNDEFINED) and floats.

I did not work on the code for quite a long time because of too much real-job-work, maybe it no longer compiles, sorry… Anyway, it’s available in git here, patches welcome etc. I guess this is the best sample code around. It’s using Cython for compilation (never tried with Pyrex, although this might work as well). If anyone can use it, great, if not, too bad, I did learn Cython doing this ;-)

]]>
http://eikke.com/embedding-javascript-in-python/feed/ 4
django-validation now includes inheritance support http://eikke.com/django-validation-now-includes-inheritance-support/ http://eikke.com/django-validation-now-includes-inheritance-support/#comments Fri, 18 Jan 2008 03:33:39 +0000 Nicolas http://eikke.com/django-validation-now-includes-inheritance-support/ I’m happy to announce django-validation got field type inheritance support since a couple of minutes. This means your form fields will be validated starting from the most base field type (django.newforms.Field) up to the actual field type (no multiple-inheritance supported though).

In the example I wrote yesterday, when using a TestField field, this field will be validated as a django.newforms.Field (a “required” check will be done), then as a django.newforms.CharField (“min_length” and “max_length” checks), and finally as a TestField. A normal CharField would be validated as a Field first, then as a CharField, etc.

The returned errors will be a list of all errors found, starting with the most basic one (the ones found by the most general class, Field).

Next to this, all generated Javascript code should be namespaced now (based on Python module and class names), although there might be some bad things left, I’m no Javascript guru. The generated code might be somewhat messy.

Current Python code is most certainly ugly and will need more rewrites. Next to this, other field types should be added, and some tests would be nice too.

I made a snapshot of yesterday’s sample (with some changes, the ClientValidator API slightly changed), you can try it here.

]]>
http://eikke.com/django-validation-now-includes-inheritance-support/feed/ 0
django-validation: an introduction http://eikke.com/django-validation-an-introduction/ http://eikke.com/django-validation-an-introduction/#comments Tue, 15 Jan 2008 23:59:58 +0000 Nicolas http://eikke.com/django-validation-an-introduction/ Some time ago I wrote this generic AJAX Django form validation code. Some people didn’t like this, as AJAX should not be used to perform form validation, which is sometimes true, sometimes not, as I pointed out before.

So I’ve been thinking since some time to create a Django templatetag which allows one to generate client-side Javascript form validation code without writing any code himself (unless using custom widgets). Today I got into it.

The resulting project is called django-validation. It basicly allows one to write a Newforms form class, and generate client-side validation code for this form in a template. Currently only CharField validation is implemented, more should follow soon and is easy to add.

Next to validation of built-in field types, one can also add code to validate custom fields. This can be done inside an inner class of the field class.

The current release is very alpha-grade software, a lot of enhancements could be done, and most certainly more standard field type validators should be written. Next to this, field type inheritance isn’t supported for now (so if your field type A inherits CharField, no CharField validation will be done), this should change soon.

Patches are, obviously, very welcome!

Here’s a sample how to use it. First we define a very basic form:

class TestForm(forms.Form):
    first_name = forms.CharField(max_length=128)
    test = TestField(required_value=u'I like django-validation')

This form uses a custom class (just for demonstration purposes). This class only performs client-side validation, no clean() function is provided, although in real field types this should obviously be added. More information can be found in the inline comments:

from validation.templatetags.validation import add_error
class TestField(forms.CharField):
    def __init__(self, *args, **kwargs):
        if not 'required_value' in kwargs.keys():
            raise Exception, 'required_value should be provided'
        self.required_value = kwargs['required_value']
        del kwargs['required_value']
        super(TestField, self).__init__(*args, **kwargs)

    class ClientValidator:
        '''
        This inner class knows how to generate Javascript validation code for this field type.
        The code will be pasted inside a function block. There is at least one assigned variable, 'field',
        which is the DOM element we got to validate.

        More parameters can be defined in the 'parameters' attribute. These parameters will be added
        to the Javascript function prototype, and the value of the form field parameter value will be
        assigned.

        We need to define the field class name, so the django-validation code can generate suitable
        function names.
        '''
        parameters = ('required_value', )
        field_class = 'TestField'

        def render(self, output):
            '''
            The render function should output Javascript code to check the value of the 'field' element.
            It is called inside a Javascript function scope.

            output is a StringIO object. Normally only write or writelines calls should be used.
            '''
            output.write('value = field.value;\n')
            output.write('if(value != required_value) {\n')
            # This error message should be internationalized.
            # See the add_error documentation.
            add_error(output, 'error_msg', 'Field value should be %(value)d.', (('%(value)d', 'required_value'), ))
            output.write('    return [error_msg];\n')
            output.write('}\n')

Finally, here’s how to use it inside a template (this must be one of the worse HTML/Javascript snippets I ever wrote):

{% load validation %}
<html>
<body>
    <form>
        {{ form.as_p }}
        <p><input type="submit" onclick="return testform(this.form);" />
    </form>
    <div id="errors"></div>
    {% validation_js form 'validate_testform' %}
    <script type="text/javascript">
        function testform(form) {
            valid = true;
            errors = validate_testform(form);
            err = "<ul>";
            for(field in errors) {
                if(errors[field] != null) {
                    err += '<li>' + field + ': ' + errors[field][0] + '</li>';
                    valid = false;
                }
            }
            err += '</ul>';
            if(valid)
                err = 'Form is valid';
            document.getElementById('errors').innerHTML = err;
            return false;
        }
    </script>
</body>
</html>

The current code is available in a git repository. Enjoy!

]]>
http://eikke.com/django-validation-an-introduction/feed/ 6
Django generic AJAX form validation http://eikke.com/django-generic-ajax-form-validation/ http://eikke.com/django-generic-ajax-form-validation/#comments Mon, 31 Dec 2007 13:20:26 +0000 Nicolas http://eikke.com/django-generic-ajax-form-validation/ I just created a generic view for Django which allows a developer to easily add AJAX-style form validation to a newforms based form.

The system needs one server-side view, and some client-side JavaScript. You can find the view code in my Django snippets Git repository. The view only works with POST requests. It takes a standard HttpRequest and some options:

  • form_class: this parameter defines the newforms class to validate against. It can be specified in the extra args parameter of the view’s urlconf. If you don’t specify it, the ‘form_class’ POST field will be used. If this doesn’t exist either, an exception is raised. The parameter can be a newforms form instance, a string, or a class (which should be a subclass of BaseForm).
  • format: the serialization format to use. Currently only ‘json’ is supported.
  • args: extra argument list to provide to the form constructor (shouldn’t be provided in most cases)
  • kwargs: extra argument dics to provide to the form constructor (shouldn’t be provided in most cases)

Next to the server-side view you’ll need some pretty basic JavaScript code on client side. I use JQuery and the JQuery Form plugin. Here’s some sample code, assuming the form ID is ‘my_form’, and form fields are represented like this:

<p id="{{ form.field.name }}_container"><label for="{{ form.field.auto_id }}">{{ form.field.label|capfirst }}:</label>{{ form.field }}
{% if form.field.errors %}<span id="{{ form.field.name }}_error" class="error">{{ form.field.errors.0 }}</span>{% endif %}
</p>

Here’s the corresponding JavaScript code:

function do_something() {
}
function process_validation(data) {
    if(data['form_valid'] == true) {
        do_something();
        return;
    }
    for(var field in data["errors"]) {
        errors = data["errors"][field]
        if(errors.length > 0) {
            error = errors[0];
            if($("#" + field + "_error").length == 0) {
                s = $("<br /><span style=\"display: none;\" id=\"" + field + "_error\" class=\"error\">" + error + "</span>");
                $("#" + field + "_container").append(s);
            }
            $("#" + field + "_error").html(error).fadeIn("slow");
        }
    }
}
function validate_form(data) {
    data.push({name: 'form_class', value: 'project.application.forms.ApplicationForm'});
    $.post("{% url validate_form %}", data, process_validation, "json");
}
$(document).ready(function() {
    $("#my_form").submit(function() {
        data = $("#my_form").formToArray();
        $(".error").fadeOut("slow");
        validate_form(data);
        return false;
    });
});

Obviously this should be changed to suit your needs.

I hope this code can be useful for someone…

]]>
http://eikke.com/django-generic-ajax-form-validation/feed/ 10