Don’t you hate it when you have two semi-complex configuration objects, and you need to “mash” them together?
Here is what I mean, is take these objects:
UPDATE: Implemented changes to the code as suggested by Akeru, thanks! UPDATE2: Updated to the newer version of jQuery-jsonp, thanks Julian, the Ugly spinner loading is now gone!
So, whatever happened to comet? Wasn’t it supposed to save the masses from wasteful ajax polling? I certainly appreciate Alex Russel’s work on the matter, but it really seems as though this very useful technology is falling to the wayside. I think this is mainly due to the difficulty and requirements of a successful implementation on the most popular web server, the main problem is Apache’s use of threading, this post explains the problem eloquently. Of course Apache have a whole project that deals with this issue to a degree, but I don’t think that it is easy to implement, once you dig a little into the documentation, you quickly see that this is not really a thing that just works out of the box… You need to read a book on the subject first. That is a bit of a deal-breaker for me; after all, the technique is not that difficult to understand, so why should you need to read a whole book to implement it? Read more
So I created a CSS parser and formatter on the weekend; I think it’s kinda neat as it formats CSS “just the way I like it”.
Why would I do this, when there are so manyCSSformattersavailable? Well, the aim of most formatters is to “optimise” the CSS
(ie: make it as small as possible), whereas the aim of my formatter is to make it as readable as possible. Read more
I attended the free Mozilla booze-up Labs event the other month; it was quite interesting; Ben Galbraith spoke about what Mozilla is up to, and what they are planning in the near future… It was interesting because I got the feeling that whilst they have a few interestingprojects in the pipeline, they don’t really have anywhere specific to take their browser engine; it has gotten to a point where it performs on par with all the other browsers, and all the other browsers perform on par with it.
So where should Mozilla go from here? I think it is blindingly obvious what they could do, though I don’t think they’re gonna like my suggestion… Before I mention what it is, lets take a closer look at Mozilla. Read more
I’m speaking at the WSG about my PAXJS framework next month! You can register at the WSG website! I always enjoy the WSG meetings, there is a great mix of people from different areas and backgrounds, and much discussion anout web development in general. Note that the cost is $10 to attend.
It’s a classic problem: you have a small set of data records that you want your users to interact with at the same time, usually with a need for ordering of the records. I’ve seen this exact problem pop up in just about every project that I’ve every worked on. The most obvious solution to the problem is an inline-editable datagrid-style widget. Often this provides a “good enough” solution, and many UI designers convince their users to integrate this type of widget, as it is relatively easy to do.
This sometimes leads to dis-joined user experiences, inconsistent look & feel, depending on what solution is employed and how much time you spend on integrating it.
When editing a row, the data from other rows is not always accessible
The look and feel is “like a spreadsheet”, and usually doesn’t offer too much in the way of customisation.
This is of course not too bad, as long as it is consistent with the rest of your application, and performs the necessary
tasks for your user. Some datagrids allow you to customise colours and fonts, but that is usually about as far as you can take
it without dwelving deeply into customisation and spending lots of time setting up work arounds for how the
grid is laid out and interacts with your data.
So how do you create a good solution, which easily fits in with your design, and back-end api without spending a
bunch of time customising the datagrid script, and laboriously hacking at the CSS?
The collection manager
The premise is quite simple, it works a little like a datagrid in that there is a concept of data-rows, but
it doesn’t matter what HTML you use for each row; this gives us flexibility to customise exactly how the layout
looks, and at the same time has enough smarts to help you manage the collection of items very easily.
To create a collection, you simply setup a template, a target element, a add button and initialise
the collection using the collections manager script.
Let us start with the most simple of examples.
Example: Hello world
In this example, you can add names – enter a few, and click the “Submit form” button to see how the values map to back-end objects.
We have a div as the target to render the collection manager into, plus an “add” button. The clearing div is optional,
depending on your layout requirements. This HTML is inside a standard form tag that submits to collections.php, which simply
shows you the contents of the submitted form.
The template is where things get interesting; it is plain html, BUT, (and it’s a big BUT), there are no element IDs.
This is because the collections manager script takes the template, and adds IDs to the form elements as needed; it uses
the collection manager’s namePattern to name the field and give it a unique ID. This is a requirement, as we can
have multiple data rows.
The initialisation script simply brings everything together, it uses the template as the query target, specifies the template element, and then the add button.
Let us look at a slightly more useful example, a customer profile – lets assume we have a data structure that maps to this JSON:
The customerType maps to one of the following values: n = new, r = repeat, v = vip; news letter is true or false.
Example 1: Collection manager for customer profiles
In this example, we start with two rows of example data, and use the default settings for everything else. We also include a
delete button, so that you can remove collection items. Change some of the values, or perhaps add a new row, then click the
“Submit form” button to see how the back-end sees your values.
The template is more complex than the hello world example, but it is just plain HTML with no IDs, just names for the form
fields. You will note that there is also a “Delete” button in this template, which allows us to remove items.
The initialisation script now contains some initial data and a reference to the “Delete” button. The use of the deleteButtonName parameter specifes that the script will attach a delete function to that button for each
record.
Example 2: collection manager with order
Here we expand on the previous example by adding ordering and move up / down buttons; this is a unique feature that the collection
manager has, compared to standard data grids: a concept of order.
As you move a field up or down, we persist the value of the order fields, so assuming the fields were in the correct order to start
with, we should have the correct order once we submit the form. Note that usually the order field would be hidden, but we’re showing
it here to make it easier to see what is happening.
Change some of the values, and move the fields around, then click the “Submit form” button to see the values, taking
note of the order field values.
The initialisation script now contains some initial data and a reference to the “Delete” button. The use of the deleteButtonName parameter specifes that the script will attach a delete function to that button for each
record.
Example 3: collection manager for customer profiles with ajax delete
Yet again we expand on the previous example, this time we add ajax delete…
Change some of the values, and move the fields around, then click the “Submit form” button to see the values, taking
note of the order field values. We have also included the “namespace” parameter, which affects how the data is presented
to the back-end, but more about this later.
The initialisation script now also has a deleteFunction parameter, with a function that ensures that we only
access the back-end if we need to; this allows the back-end to only
Back end integration
Of course the collections manager is useless without data from the back-end; it is very
easy to integrate the collection manager, thanks laregly to the namePattern parameter, which allows tight
control of how the fields are named; out of the box, you can quickly integrate with just about any php, python, java
(struts, springBeans), .NET, etc…
The namePattern parameter allows you to specify where the record number and name appears; in the last example,
we use a namePattern like so:
namePattern: "contact{number}[{name}]"
This creates individual objects for each data row, rather than the default of one array of data rows. This can be particularly
convenient if you have a set number of a type of object, for example if you have exactly four contact objects named “contact1″,
…, “contact4″, this will allow you to easliy map directly to those objects.
The default namePattern is:
namePattern: "collection[{number}][{name}]"
Which will map to one array named “collection” of data rows.
API
Here is a list of options, and what you can do with the collections manager
target – The target of the collection manager (defaults to jQuery result)
template – Element to use for cloning. Note: do NOT give any items IDs, they will be removed
data – Optionally include some data, default is 1 record
startCount – What number to start the count from.
minItems – Minimum number of items to show at any time (default 1)
maxItems – Maximum number of items to show (default 10)
namePattern – Pattern for naming the form fields (for mapping to back-end objects)
deleteButtonName – Name for delete button to use in the template