Stuff, and then more
Two applications of SortableJS
I have worked in language teaching for a long number of years, so that when I first came across SortableJS I quickly saw its possible relevance to that area of activity. I also understood that :what I am doing is a fairly trivial application of the software, just something to hang it on if you're developing. I was also attracted by the fact that it's more or less certain to work on mobile devices.
What I built with the help of SortableJS can be seen here and then here.
However, it may be regarded as somewhat inaccurate to say that I will be talking about JavaScript, as much of what follows involves the backend. I always try to build so that a non-technical user – a teacher, for example – can control the contents. A database is thus essential.
You will ideally need:an MVC framework and of course the ability to test in a development environment. Here, I'm using https://koseven.dev/ (so PHP and MySQL) with MySQL Workbench, but I'm sure it would work fine with C# / .NET and MSSQL, which I haven't tested yet.
Below is the setup for the two database tables. For the 'sentences' table the foreign key 'category_id' is not essential. I kept it because i use it for other tables, including the 'compounds' one here.
.CREATE TABLE `sentences` (
`id` int(11) UNSIGNED NOT NULL,
`sentence` varchar(255) NOT NULL,
`user_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `sentences`
ADD PRIMARY KEY (`id`),
ADD KEY `fk_user_id` (`user_id`),
ADD KEY `fk_category_id` (`category_id`);
CREATE TABLE `compounds` (
`id` int(11) UNSIGNED NOT NULL,
`user_id` int(11) UNSIGNED NOT NULL,
`category_id` int(11) NOT NULL,
`first` varchar(200) CHARACTER SET utf8 NOT NULL,
`second` varchar(200) CHARACTER SET utf8 NOT NULL,
`shuffled` varchar(200) CHARACTER SET utf8 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `compounds`
ADD PRIMARY KEY (`id`),
ADD KEY `fk_user_id` (`user_id`),
ADD KEY `fk_category_id` (`category_id`);
Functions in both the Sentence Controller and the Compound Controller follow this pattern: index, new, edit, delete, post, update, with a function called 'myview' at the bottom of each file, permitting loggedin users to review and modify their own work.
The Models are kept as skinny as possible, and looping is done in the views. We'll address the looping by comparing the sentence and compound index files.
Obviously, sentences pulled from the database table were inserted with the correct structure and need to be shuffled on output. This is done by using a foreach loop, inside which we use PHP's explode function to put the sentence properties into an array called $words, then using .shuffle($words), putting the implode function on the array, and running an inner foreach loop to output each word value.
Sentences of about eight relatively short words should display well enough that the exercise can be done even on a small device in portrait mode. Checking answers is done by a button which opens a simple modal window. The sorting is based on the SortableJS grid example to be found here..
Somewhere in the docs, or maybe on another site which references SortableJS there is a piece of code which will prevent a word from one sentence being displaced to another sentence. Good, but a user trying to put a sentence in the right order would have no interest in doing this; it would be self-defeating.
In contrast to the sentence index page, the compound page is simply a list of links to the various categories. Here the different category ids are used, whereas the loggedin user creating the sentences was nstructed to leave the category as 'business' for all the sentences.
The thinking has to be done when it comes to constructing the category pages. As compound nouns consist of only two words, the first on the left, the second on the right, my first instinct was to loop through a left <div> containing the `first` entries from the database table, then do the same with a right <div> for `second`. The problem with this is that a user coming to the page would see the correctly sorted pairs for a few seconds, or as long as they liked, before starting the 'sorting'. Not useful.
The solution was to add the `shuffled` field to the table and to make the loggedin user creating the exercise do a little more work. The default number of rows to be inserted into the table each time is six, and the person creating the exercise is confronted with three form fields on each row: 'first', 'second' and 'shuffled', the last of which will be the second word from one of the other rows.
Six is not such a large number that this is very demanding, and six rows per page seems to fit any size of screen well. The `shuffled` properties now replace `second` in the right-hand <div>, and we take care, of course, to make sure that `second` is displayed when the modal window showing the answers is opened. The SortableJS script used is a slightly modified version of the 'disabling sorting' example from the link above.
And for now, that's it.