npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

knockthru

v0.1.0

Published

Node.js module to allow Knockout based html UI to bind directly to server-side Mongoose (MongoDB) data models

Downloads

8

Readme

knockthru

Node.js module that allows you to databind the Knockout UI in the browser directly against the Mongoose datamodel without having to write glue code.

The data is served up to SCRUD endpoints automatically created by the embedded meanify implementation. The knockthru.js file you include in the browser code looks for data-knockthru attributes on elements and creates/binds viewmodels using Knockout accordingly.

Complete Examples

This is the best way to see knockthru in action and to understand how it works.

After running npm update change to the example folder and run node server

The port on which the example is being served will be written to the console, typically http://localhost:3000

You'll need to have mongoose db running locally on port 27017

Snippets

To list the Tasks in the server-side mongoose database that have done set to 0

	<div data-knockthru='kt.search("Task",{done:0})'>
		<p data-bind='foreach: items'>
		...
		</p>
	</div>

To provide a box for the user to define a new Task

    <tfoot data-knockthru='kt.create("Task")' data-bind='with: item'>
        <tr>
            <td><input type="text" data-bind='textInput: description, onEnterKey: (description ? $parent.submitCreate : null)' ></td>
            <td><button data-bind='enable: description, click:$parent.submitCreate'>Add</input></td>
        </tr>            
    </tfoot>  

To display a specific task identified by ?id= on the querystring and allow the user to edit it

	<div data-knockthru='kt.read("Task",kt.getUrlParameter("id"))'>
		<div data-bind='with: item' >
            ...    
                <input type="text" data-bind='textInput: description'>
            ...
                <input type='checkbox' data-bind='checked: done' id="doneInput">Done</input>
            ...
        </div>
        <button data-bind='enable: item.isDirty(), click:submitUpdate'>Save</button>
        <button data-bind='click: submitDelete'>Delete</button>
	</div>

To run knockthru with server-side filters/predicates that will allow you to ensure url re-writers can't access data they shouldn't be able to, e.g. to ensure all data requests have a filter on a field called user that has a value of req.user.id (if you are using passport, for example)

require('knockthru')(app,
{
    predicates: function(req, model) { return {user:req.user.id} }
});

ViewModel Functions

These methods can be used in the data-knockthru attributes

kt.search(modelname[, filters])

Generates a viewmodel the can display a readonly list of items

|element |description | |-----------|----------------------------------------------------------------------------------------| |items |an observable array of the result of the search | |createItem |an observable 'blank' you can bind to for create functionality (see create) | |errors |an observable list of strings detailing any errors / validation errors from the server | |refresh |event handler to re-run the query |

kt.searchEdit(modelname[, filters])

Generates a viewmodel for an editable list of items

|element | description | |-----------|----------------------------------------------------------------------------------------| |items |an observable array of the result of the search | |items[].delete |handler to delete an item | |createItem |an observable 'blank' you can bind to for create functionality (see create) | |errors |an observable list of strings detailing any errors / validation errors from the server | |isDirty |observable boolean indicating whether changes have been made | |submit |event handler to save all the changes made | |refresh |event handler to re-run the query |

Note on delete: use within the context of one of the items array e.g. data-bind='click:$parent.delete'

    <tbody data-knockthru='kt.searchEdit("Task")' data-bind='foreach: items'>
        <tr>
        ...
            <td><button class='form-control btn-xs'><span class='glyphicon glyphicon-remove' data-bind='click:$parent.delete'></button></td>
        </tr>
    </tbody>

kt.create(modelname[, predicates])

Generates a viewmodel for creating a new item. The default values of the fields are obtained from the server.

|element |description | |-----------|----------------------------------------------------------------------------------------| |blank |an observable blank item with fields populated with default values from the server | |error |an observable string detailing any errors / validation errors from the server | |submitCreate |event handler to write the new item to the server | |addToSearch |event handler to add the item to a search/searchEdit viewmodel on the page. Pass the html element that has the data-knockthru attribute (e.g. document.getElementById('...')) |

kt.read(modelname, id)

Generates a viewmodel for binding to a specific item in the database, identified by the id

|element |description | |-----------|----------------------------------------------------------------------------------------| |item |an observable item representing the object read from the server | |error |an observable string detailing any errors / validation errors from the server | |refresh |event handler to re-run the query | |submitUpdate |event handler to write the new item to the server | |submitDelete |event handler to write the new item to the server |

For the id parameter you typically could use either kt.getUrlParameter('_id') or kt.getUrlPathTail() to grab the id from the url.