Ad

How To Programmatically Add Items From A Page In KeystoneJS

- 1 answer

I'm trying out KeystoneJS to build a site in which people can submit words and ask other users for synonyms. So I've build a simple Word model:

var keystone = require('keystone');
var Types = keystone.Field.Types;

var Word = new keystone.List('Word', { 
    map: { name: 'word' }
});

Word.add({
    word: { type: Types.Text, required: true, initial: "New word", index: true }
});

Word.defaultColumns = 'word';

Word.register();

The idea is that a user enters a word in an input box on the homepage, clicks "Submit," and the word gets added as an item in the Word model. But I can't figure out the interplay between the Javascript on the page that handles the event that fires on clicking "Submit" and the code that actually creates a new items in the DB, like so:

var keystone = require('keystone'),
    Word = keystone.list('Word');

var newWord = new Word.model({
    word: newWord // read from the input box on the home page
});

newWord.save(function(err) {
    // post has been saved  
});

I originally naively supposed that I could make Word part of the locals object and create the new item from the JS that lives on the page, but this doesn't work. So I imagine I need to read the word from the input box, then make an AJAX call to a route that saves the word to the DB. Here is where my understanding of KeystoneJS breaks down. Where would I put the code to accept that AJAX call and create the new item?

Ad

Answer

The javascript in the page, and keystone on the server side are indeed two seperate domains. To interact with keystone from your page you have to make HTTP calls. These calls are routed to keystone views.You can find an example in de keystone demo site:

in keystone.js the routes are set:

keystone.set('routes', require('./routes'));

in routes/index.js the routes are defined, ie:

app.get('/blog/:category?', routes.views.blog);

In the example above the url "/blog/news" is handled by the view routes.views.blog, and "news" is an (optional) parameter.

In your case you would end up (if you want you use REST style) with something like:

app.post('/word/:newword?', routes.views.word);

The .post method routes urls to this view if and only if the request is a POST request.

The solution that you suggest, making a AJAX call is one of the possible solutions.You could also use a form and post the whole page.

Within the view you create a handler for the view like this:

view.on('post', function(next){
  if (req.params.newword){
    //store and create answer
    next();
  }
});
Ad
source: stackoverflow.com
Ad