Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ss utils.js JavaScript Client Library

Demis Bellot edited this pageOct 25, 2016 ·11 revisions

This page has moved todocs.servicestack.net/ss-utils-js


An Embedded Resource insideServiceStack.dll is ServiceStack's JavaScript utility library that provides a number of convenience utilities in developing javascript web apps. It enables nicer integration with ServiceStack's Server features includingValidation,Error Handling andServer Events which can be included in any page with:

<scripttype="text/javascript"src="/js/ss-utils.js"></script>

DefinitelyTyped and npm

To make it easier to develop withss-utils in any of the npm-based Single Page Apps templates we're alsomaintaining a copy ofss-utils in npm and have also added it to JSPMand DefinitelyTyped registry so you can now add it to your project like any other external dependency using JSPM:

C:\> jspm install ss-utils

If you're using TypeScript, you can also download the accompanying TypeScript definition from:

C:\>typings install ss-utils --ambient --save

Or if you're using the older tsd package manager:tsd install ss-utils --save.

Usage

To showcase how it simplifies general web development, we'll walkthrough the JavaScript needed to provide all the behavior for theentire UI of Email Contacts that uses just jQuery and bootstrap.js:

Bootstrap Forms

ss-utils.js validation and error handling support works with Bootstrap's standard HTML Form markup, e.g:

<formid="form-addcontact"action="@(new CreateContact().ToPostUrl())"method="POST"><divclass="col-sm-3 form-group"><labelfor="Name">Name</label><inputclass="form-control input-sm"type="text"id="Name"name="Name"value=""><spanclass="help-block"></span></div>    ...</form>

The first thing to notice is theaction url is created with a typed API populated using theReverse RoutingToPostUrl() extension method that looks atCreateContact Request DTO to return the best matching route based on the Route definitions and the fields populated in the Request DTO instance, in this case the empty Request DTO matches[Route("/contacts", "POST")] so returns/contacts.

Other significant parts in this HTML Form is that theINPUT field names match up with the Request DTO it posts to and that it includes Bootstrapsclass="help-block" placeholders adjacent to each INPUT element which is whatss-utils.js uses to bind the field validation errors.

Binding HTML Forms

You can ajaxify a HTML FORM by using ss-utilsbindForm jQuery mixin, e.g:

$("#form-addcontact").bindForm({success:function(contact){addContacts([contact]);$("#form-addcontact input").val('').first().focus();}});

This takes over the handling of this FORM and instead of doing a POST back of the entire page to the server, makes an Ajax request using all the fields in the FORM to POST the data to theCreateContact Service:

publicContactPost(CreateContactrequest){varcontact=request.ConvertTo<Contact>();Db.Save(contact);returncontact;}

Fluent Validation

Normally the Service implementation will be called as-is but as we've added the FluentValidationValidationFeature plugin and there exists a validator forCreateContact below:

publicclassContactsValidator:AbstractValidator<CreateContact>{publicContactsValidator(){RuleFor(x=>x.Name).NotEmpty().WithMessage("A Name is what's needed.");RuleFor(x=>x.Email).NotEmpty().EmailAddress();RuleFor(x=>x.Age).GreaterThan(0);}}

The Request DTO is first validated with the above declarative rules and if it fails returns a structured error response which ss-utils uses to bind the validation errors to all the invalid fieldclass=help-block (orhelp-inline) placeholders:

HTML Validation

Whilst the user goes back and corrects their INPUT, we can provide instant feedback and clear the errors as they update each each field with:

$("input").change($.ss.clearAdjacentError);

Once all is successful we invoke thesuccess: callback with the response of the Service which in this case is the newly createdContact that we dynamically add to the contacts list by calling the existingaddContacts() method. We also clear all form values and put focus back to the first field, ready for a rapid entry of the next Contact:

$("#form-addcontact").bindForm({success:function(contact){addContacts([contact]);$("#form-addcontact input").val('').first().focus();}});

Manual Error Handling

Thevalidate callback can be used to add client side validation logic which can manually set client-side validation errors usingsetFieldError(), e.g:

$("form").bindForm({validate:function(){varparams=$(this).serializeMap();if(params.Password!=params.Confirm){$(this).setFieldError('Password','Passwords to not match');returnfalse;}}});

Declarative Events

An interesting difference in the dynamically generated HTML are the presence ofdata-click=showContact anddata-click=deleteContact attributes:

functionaddContacts(contacts){varhtml=contacts.map(function(c){return"<li data-id='"+c.Id+"' data-click='showContact'>"+"<span class='glyphicon glyphicon-user' style='margin: 0 5px 0 0'></span>"+c.Name+" "+" ("+c.Age+")"+'<span data-click="deleteContact"></span>'+"</li>";});$("#contacts").append(html.join(''));}

This showcases some of the declarative event support in ss-utils which allows you to invoke event handlers without needing to maintain bookkeeping of event handlers when adding or removing elements.You can instead define one set of event handlers for the entire page withbindHandlers, e.g:

$(document).bindHandlers({showContact:function(){varid=$(this).data("id");$.getJSON("/contacts/"+id,function(contact){$("#email-contact").applyValues(contact).show();$("#form-emailcontact .alert-success").hide();});},deleteContact:function(){var$li=$(this).closest("li");$.post("/contacts/"+$li.data("id")+"/delete",function(){$li.remove();});},toggleAction:function(){var$form=$(this).closest("form"),action=$form.attr("action");$form.attr("action",$form.data("action-alt")).data("action-alt",action);}});

The matching event handler will be invoked whenever an element withdata-{event}={handlerName} is clicked, e.g:data-click='showContact'.

In addition toclick, a number of other jQuery events can be declared in this way, as defined in:

$.ss.listenOn='click dblclick change focus blur focusin focusout select keydown keypress keyup hover toggle';

Multiple Arguments

Declarative event handlers can also send multiple arguments:

<ul><lidata-click="single">Foo</li><lidata-click="multiple:arg1,arg2">Bar</li></ul>
$(document).bindHandlers({single:function(){varli=this;},multiple:function(arg1,arg2){varli=this;}});

Data Binding

Diving into the implementation ofshowContact we see ss-utilsapplyValues() jQuery mixin which binds a JS object to the target element, in this case#email-contact:

showContact:function(){varid=$(this).data("id");$.getJSON("/contacts/"+id,function(contact){$("#email-contact").applyValues(contact).show();$("#form-emailcontact .alert-success").hide();});},

The data-binding applied byapplyValues() include:

  • Set thevalue of all elements with matchingid={field} orname={field}
  • Set thevalue of all elements marked withdata-val={field}
  • Set the innerHTML contents of all elements marked withdata-html={field}
  • Set thedata-href anddata-src attributes

Example Usage

$("#email-contact").applyValues(contact);

Which binds the returnedcontact response object to the#email-contact HTML Element, populating all matching elements with data fromcontact:

<divid="email-contact">    ...<adata-href="ProfileUrl"><imgdata-src="ProfileUrl"/></a><h3>        Email<spandata-html="Name"></span></h3><h4>To:<spandata-html="Email"></span></h4><divclass="clearfix"></div><formid="form-emailcontact"method="POST">        ...<inputtype="hidden"name="ContactId"data-val="Id"/>        ...</form></div>

Advanced bindForm usages

Form Loading

Whilst a FORM is being processed all its buttons with[type=submit] (overridable with$.ss.onSubmitDisable) are disabled and aloading class is added whilst a response from the server is pending.This can be used to provide UX feedback to end users with just CSS. E.g. we use.loading CSS rule to show the rotating glyphicon:

#email-contact .loading .rotate {visibility: visible;}

Server initiated actions

Some useful functionality not demonstrated in this example is your Services ability to invoke client behavior by returning a response decorated with custom HTTP Headers.An example is being able to return "Soft Redirects" to navigate to a different page by adding aX-Location HTTP Header, e.g:

returnnewHttpResult(response){Headers={{"X-Location",newLocationUri},}};

When returned to a ajax form, it will instruct the page to automatically redirect to the new url.

You can also trigger an event on the page by returning aX-Trigger header, e.g:

returnnewHttpResult(response){Headers={{"X-Trigger","showLoginPopup"},}};

In this case the page event handler namedshowLoginPopup will be invoked if it exists.

As we expect these features to be popular when developing ajax apps we've provided shorter typed aliases for the above examples:

returnHttpResult.SoftRedirect(newViewContact{Id=newContact.Id}.ToGetUrl(),newContact);returnHttpResult.TriggerEvent(contact,eventName:"showLoginPopup");

$.ajaxSubmit

The$.fn.ajaxSubmit is also available for use independently to submit a HTML form via Ajax on demand.This is used in theconnections.jsxReact Component ofRedis React's Connections Pageto auto submit the form via ajax to the specified/connection url with the populated Form INPUT values. It also disables the#btnConnect submit button and adds a.loading class to the form whilst it's in transit which is used to temporarily show the loading sprite:

varConnections=React.createClass({//...onSubmit:function(e){e.preventDefault();var$this=this;$(e.target).ajaxSubmit({onSubmitDisable:$("#btnConnect"),success:function(){$this.setState({successMessage:"Connection was changed"});Actions.loadConnection();}});},render:function(){varconn=this.state.connection;return(<divid="connections-page"><divclassName="content"><formid="formConnection"className="form-inline"onSubmit={this.onSubmit}action="/connection"><h2>Redis Connection</h2><divclassName="form-group"><inputname="host"type="text"/><inputname="port"type="text"className="form-control"/><inputname="db"type="text"className="form-control"/></div><pclassName="actions"><imgclassName="loader"src="/img/ajax-loader.gif"/><buttonid="btnConnect"className="btn btn-default btn-primary">Change Connection</button></p><pclassName="bg-success">{this.state.successMessage}</p><pclassName="bg-danger error-summary"></p></form></div></div>);}};

$.ss.parseResponseStatus

Lets you easily parse the raw text of a Ajax Error Response into a responseStatus JavaScript object, example used in Redis React'sConsole Component:

.fail(function(jq,jqStatus,statusDesc){varstatus=$.ss.parseResponseStatus(jq.responseText,statusDesc);Actions.logEntry({cmd:cmd,result:status.message,stackTrace:status.stackTrace,type:'err',});});

$.ss.bindAll

ThebindAll API is a simple helper for creating lightweight JavaScript objects by bindingthis for all functions of an object literal to the object instance, e.g:

varGreeting=$.ss.bindAll({name:"World",sayHello:function(){alert("Hello, "+this.name);}});varfn=Greeting.sayHello;fn();// Hello, World

TypeScript Definition

The TypeScript definitions forss-utils.d.ts is an embedded resource insideServiceStack.dll which is available from/js/ss-utils.d.ts, e.gservicestack.net/js/ss-utils.d.ts.

API Reference

$.ss.onSubmitDisable="[type=submit]"// Disable elements during form submission$.ss.validation={// Customize ValidationoverrideMessages:false,// Whether to override Server Error Messagesmessages:{// List of Server ErrorCodes to overrideNotEmpty:"Required",// Override `NotEmpty` ErrorCode with `Required`},}$.fn.serializeMap()// Return the FORM's INPUT values as a map$.fn.setFieldError(name,msg)// Set the error for field `name` with `msg`$.fn.applyErrors(status,options)// Apply errors in ResponseStatus to Element$.fn.clearErrors()// Clear all errors applied to Element$.ss.clearAdjacentError()// Clear adjacent errors in help-block/inline$.ss.parseResponseStatus// Parse raw JSON Error ResponseStatus$.fn.bindForm(options)// Bind and Ajaxify the HTML Form$.fn.ajaxSubmit()// Submit a HTML Form via Ajax$.fn.applyValues(map)// Databind values in `map` to HTML Element$.fn.bindHandlers(handlers)// Register global declarative JS handlers$.ss.listenOn="click ..."// Specify DOM events for declarative events$.ss.bindAll// Bind all object literal functions to itself$.fn.setActiveLinks()// Add `active` class to links with current url$.ss.todate(string)// Convert String to Date$.ss.todfmt(string)// Convert String to `YYYY-MM-DD` Date Format$.ss.dfmt(date)// Convert Date to `YYYY-MM-DD` Date Format$.ss.dfmthm(date)// Convert Date to `YYYY-MM-DD HH:MM:SS PM`$.ss.tfmt12(date)// Convert Date to `HH:MM:SS PM`$.ss.splitOnFirst(string,needle)// Split on first occurrence of needle$.ss.splitOnLast(string,needle)// Split on last occurrence of needle$.ss.getSelection()// Get currently selected text (if any)$.ss.queryString(url)// Return a map of key value pairs$.fn.handleServerEvents()// Handle ServiceStack ServerEvents$.ss.eventReceivers={}// Specify global receivers for ServerEvents

combinePaths and createUrl

ThecombinePaths andcreateUrl API's help with constructing urls, e.g:

$.ss.combinePaths("path","to","..","join")//= path/join$.ss.createPath("path/{foo}",{foo:1,bar:2})//= path/1$.ss.createUrl("http://host/path/{foo}",{foo:1,bar:2})//= http://host/path/1?bar=2

normalize and normalizeKey

normalizeKey andnormalize APIs helps with normalizing JSON responses with different namingconventions by converting each property into lowercase with any_ separators removed -normalizeKey()converts a single string whilstnormalize() converts an entire object graph, e.g:

$.ss.normalizeKey("THE_KEY")//= thekeyJSON.stringify($.ss.normalize({THE_KEY:"key",Foo:"foo",bar:{A:1}}))//= {"thekey":"key","foo":"foo","bar":{"A":1}}constdeep=true;JSON.stringify($.ss.normalize({THE_KEY:"key",Foo:"foo",bar:{A:1}},deep))//= {"thekey":"key","foo":"foo","bar":{"a":1}}

postJSON

postJSON is jQuery's missing equivalent to$.getJSON, but for POST's, eg:

$.ss.postJSON(url,{data:1},response=> ...,error=> ...);


  1. Getting Started

    1. Creating your first project
    2. Create Service from scratch
    3. Your first webservice explained
    4. Example Projects Overview
    5. Learning Resources
  2. Designing APIs

    1. ServiceStack API Design
    2. Designing a REST-ful service with ServiceStack
    3. Simple Customer REST Example
    4. How to design a Message-Based API
    5. Software complexity and role of DTOs
  3. Reference

    1. Order of Operations
    2. The IoC container
    3. Configuration and AppSettings
    4. Metadata page
    5. Rest, SOAP & default endpoints
    6. SOAP support
    7. Routing
    8. Service return types
    9. Customize HTTP Responses
    10. Customize JSON Responses
    11. Plugins
    12. Validation
    13. Error Handling
    14. Security
    15. Debugging
    16. JavaScript Client Library (ss-utils.js)
  4. Clients

    1. Overview
    2. C#/.NET client
      1. .NET Core Clients
    3. Add ServiceStack Reference
      1. C# Add Reference
      2. F# Add Reference
      3. VB.NET Add Reference
      4. Swift Add Reference
      5. Java Add Reference
    4. Silverlight client
    5. JavaScript client
      1. Add TypeScript Reference
    6. Dart Client
    7. MQ Clients
  5. Formats

    1. Overview
    2. JSON/JSV and XML
    3. HTML5 Report Format
    4. CSV Format
    5. MessagePack Format
    6. ProtoBuf Format
  6. View Engines4.Razor & Markdown Razor

    1. Markdown Razor
  7. Hosts

    1. IIS
    2. Self-hosting
    3. Messaging
    4. Mono
  8. Security

    1. Authentication
    2. Sessions
    3. Restricting Services
    4. Encrypted Messaging
  9. Advanced

    1. Configuration options
    2. Access HTTP specific features in services
    3. Logging
    4. Serialization/deserialization
    5. Request/response filters
    6. Filter attributes
    7. Concurrency Model
    8. Built-in profiling
    9. Form Hijacking Prevention
    10. Auto-Mapping
    11. HTTP Utils
    12. Dump Utils
    13. Virtual File System
    14. Config API
    15. Physical Project Structure
    16. Modularizing Services
    17. MVC Integration
    18. ServiceStack Integration
    19. Embedded Native Desktop Apps
    20. Auto Batched Requests
    21. Versioning
    22. Multitenancy
  10. Caching

  11. Caching Providers

  12. HTTP Caching1.CacheResponse Attribute2.Cache Aware Clients

  13. Auto Query

  14. Overview

  15. Why Not OData

  16. AutoQuery RDBMS

  17. AutoQuery Data1.AutoQuery Memory2.AutoQuery Service3.AutoQuery DynamoDB

  18. Server Events

    1. Overview
    2. JavaScript Client
    3. C# Server Events Client
    4. Redis Server Events
  19. Service Gateway

    1. Overview
    2. Service Discovery
  20. Encrypted Messaging

    1. Overview
    2. Encrypted Client
  21. Plugins

    1. Auto Query
    2. Server Sent Events
    3. Swagger API
    4. Postman
    5. Request logger
    6. Sitemaps
    7. Cancellable Requests
    8. CorsFeature
  22. Tests

    1. Testing
    2. HowTo write unit/integration tests
  23. ServiceStackVS

    1. Install ServiceStackVS
    2. Add ServiceStack Reference
    3. TypeScript React Template
    4. React, Redux Chat App
    5. AngularJS App Template
    6. React Desktop Apps
  24. Other Languages

    1. FSharp
      1. Add ServiceStack Reference
    2. VB.NET
      1. Add ServiceStack Reference
    3. Swift
    4. Swift Add Reference
    5. Java
      1. Add ServiceStack Reference
      2. Android Studio & IntelliJ
      3. Eclipse
  25. Amazon Web Services

  26. ServiceStack.Aws

  27. PocoDynamo

  28. AWS Live Demos

  29. Getting Started with AWS

  30. Deployment

    1. Deploy Multiple Sites to single AWS Instance
      1. Simple Deployments to AWS with WebDeploy
    2. Advanced Deployments with OctopusDeploy
  31. Install 3rd Party Products

    1. Redis on Windows
    2. RabbitMQ on Windows
  32. Use Cases

    1. Single Page Apps
    2. HTML, CSS and JS Minifiers
    3. Azure
    4. Connecting to Azure Redis via SSL
    5. Logging
    6. Bundling and Minification
    7. NHibernate
  33. Performance

    1. Real world performance
  34. Other Products

    1. ServiceStack.Redis
    2. ServiceStack.OrmLite
    3. ServiceStack.Text
  35. Future

    1. Roadmap

Clone this wiki locally


[8]ページ先頭

©2009-2025 Movatter.jp