GithubHelp home page GithubHelp logo

tableau-mkt-archived / jquery.addressfield Goto Github PK

View Code? Open in Web Editor NEW
66.0 18.0 17.0 4.17 MB

The simple, configurable, dynamic postal address form plugin.

Home Page: https://tableau-mkt.github.io/jquery.addressfield

License: MIT License

JavaScript 95.92% HTML 4.08%

jquery.addressfield's Introduction

jquery.addressfield Build Status Test Coverage Code Climate Dependency Status

The simple, configurable, dynamic postal address field plugin.

Features

This plugin helps you enhance user experience and data quality on your address (shipping/PO) forms by dynamically...

  • Updating field labels (e.g. "ZIP code" vs. "Postcode"),
  • Adding or removing fields that are irrelevant (e.g. countries that do not have a postal code system),
  • Converting fields between select lists and text fields (e.g. US States vs. counties in the UK),
  • Updating select options (e.g. US states vs. Canadian provinces)
  • Updating field order (e.g. city, state, zip for US, different elsewhere),
  • Validating fields on a field-by-field basis (e.g. between various postal code standards--depends on jQuery.validate),
  • Providing placeholder text for configured fields (helpful when validating above).

Installation and usage

Include the script after your jQuery include (unless you're packaging scripts in some other magical way):

<script src="/path/to/jquery.js"></script>
<!-- Optionally, install jquery validation to handle field validation. -->
<script src="/path/to/jquery.validate.js"></script>
<script src="/path/to/jquery.addressfield.js"></script>

Also available on NPM, for browserified builds.

Install into node_modules:

$ npm install jquery.addressfield

In your application module;

var $ = require('jquery');
require('jquery.addressfield');

$(...).addressfield(...);

Basic usage

Using jquery.addressfield is easy! Instantiate the plugin against a form or form wrapper with a few special configuration keys and the plugin takes care of the rest:

// If jquery.validate is in use, instantiate it here with your options:
$('#my-address-form').validate({/* ... */});

// Instantiate jquery.addressfield with your configs:
$('#my-address-form').addressfield({
  json: '/path/to/addressfield.json',
  fields: {
    country: 'select#country-field',
    administrativearea: '.state',
    postalcode: '.zipcode'
  },
});

Where json is a path to addressfield.json (packaged with this plugin) or any endpoint serving JSON in the same configuration schema. And where fields is an object mapping xNAL field names to jQuery selectors of form field elements that correspond. At a bare minimum, the country field is required.

Once instantiated, this plugin binds a change handler to the country element. The change handler will trigger a mutation process on the form that handles all of the features outlined above based on the configuration provided in the json key.

Expected markup

Note that this plugin makes certain assumptions about the structure of your form markup. Please be sure to see the usage and configuration guide for complete details.

Detailed documentation

More detailed, topic-based documentation on usage and configuration options is available here below.

Contributing

Check out the Contributing guidelines

jquery.addressfield's People

Contributors

iameap avatar yangmillstheory avatar jrock2004 avatar jtwalters avatar angrytoast avatar jkopel avatar heathdutton avatar commandlinedesign avatar lesliedoherty avatar svc-scm avatar

Stargazers

jmichas avatar Hector Patino avatar  avatar 4CM Network avatar mikkame avatar Benjamin Thint avatar  avatar John Abela avatar Muhamad Azman avatar Razvan avatar karim avatar Simo Heinonen avatar Rob Marscher avatar Shane Wolf avatar Fern (they/them) avatar Bryan Buchanan avatar Tristan Bendixen avatar Carl Liu avatar  avatar Bibek Sharma Chapagain avatar Pascal Martineau avatar Dustin Metcalf avatar Julian Renard avatar Kyle Ridolfo avatar Blue Fuse Server avatar Nowel Yang avatar Marko Hlebar avatar  avatar Khairi Adnan avatar Alexander Vander Woude avatar Kévin O'NEILL avatar Peter Martin avatar Kevin Kee avatar  avatar David Nuon avatar Artem Diontev avatar  avatar Pascal Lammers avatar Raphael Trindade avatar Joohun, Maeng avatar Vivek Dhar avatar Chris Goering avatar Alex Escalante avatar Wendell Muntslag van Amzink avatar Uros Urosevic avatar  avatar Kisuka avatar Luis Abarca avatar Simon Corless avatar Ghali™ avatar Luke Branch avatar  avatar Ally Dewar avatar Ashar avatar James Moberg avatar Eric Ting avatar  avatar  avatar David Lanier avatar Josh Lind avatar Marco Germani avatar Yueping Qian avatar Jonathan Barratt avatar Winston Ly avatar  avatar Pedro Coutinho avatar

Watchers

 avatar  avatar Josh Lind avatar  avatar  avatar James Cloos avatar Alexander Vander Woude avatar  avatar Thomas Wagner avatar Eric F avatar Rodrigo Porcionato avatar  avatar Laud Tetteh avatar Nowel Yang avatar Angela Wilson avatar Isaac Cheung avatar Blake L. avatar Shannon Dunn avatar

jquery.addressfield's Issues

Tests Fail with qunit

Running a test results in the following:

Running "qunit:all" (qunit) task
Testing test/addressfield.html?jquery=1.3.2 
PhantomJS threw an error:ERROR
>> 0 [ '' ]
Warning: PhantomJS exited unexpectedly with exit code null. Use --force to continue.

Aborted due to warnings.

According to this thread on qunit, the suggestion is to move away from grunt-contrib-qunit and PhantomJS and use another testing framework instead.

You might want to try using Karma to run the tests in a real browser (e.g. Chrome or Firefox). grunt-contrib-qunit and PhantomJS are fairly old and might not give a realistic result for end-users.

Ensuring field config order cross-browser

I noticed you're using for ... in to iterate over the properties in the config object.

A for...in loop iterates over the properties of an object in an arbitrary order (see the delete operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting).

Seems like you might want to refactor or warn users that it's not a guaranteed order.

Add to bower

Currently this plugin doesn't appear on bower search.

Provide a web component

Would be cool to package this up into a web component. If I have time this week, I'll give it a shot.

Docs don't indicate structure of expected markup

I had a great deal of frustration trying to use this plugin, until I realized that I could make my .locality group stop disappearing if I wrapped label-input pairs in a container (e.g. div.form-group). The usage docs could use some explicit detail about the requirements for marking up the form.

Look into simplifying initialization / configuration

Consider packaging addressfield.json and optionally using it by default, but allow override to either another JSON file, or provide the config inline.

Replace this:

$.addressfield(config, enabled_fields);

With something like this:

$.addressfield({
  // Inline configuration, no async JSON fetching.
  config: {}

  // Or, defaults to pulling this async via JSON:
  json: 'addressfield.json',

  // Rather than a simple list of fields, maybe a way to specify selectors for each...
  // Or maybe just maintain the existing structure and save the update for another day.
  fields: {
   'postalcode': '#postfield',
   'locality': '#foo .locality-name'
  },

  // Will maybe need to start providing this too:
  country_field: 'select#country'
});

Add addressfield::isVisible() method

We've abstracted things into addressfield::hideField and addressfield::showField, but we still manually use the :visible selector in the main plugin method.

This will cause the plugin to break In cases where end-users have overridden the hide/show methods to match their markup.

Solution is to add an addressfield::isVisible method that matches the assumptions of our show/hide methods and use it in the main plugin instead of the :visible check.

Multiple addressfields and postal code validation

The plugin attaches a custom method name in the format 'isValid_' + field to each element on the form. This is particularly useful for postal codes, since the regexp validation for each is different per country.

When there are two postal code fields on the same page (in different forms), the second form's postal code validation seems to apply to the first as well. So if I select "Canada" in my second form, and leave the first form as "United Kingdom", the "United Kingdom" postal code will be validated using the "Canada" postal code rules. This is because we use the same method name for the validation rule, hence the conflict. They are both named "isValid_postalcode".

Should probably make this method name depend on the country, or a hash of the config array. Something along those lines.

Adding phone number support

Would be a cool feature enhancement to support phone number formatting. Thoughts? I could look at adding feature if you need someone to do the work.

Name attribute can be dropped during input type conversion in IE8

Looks like IE8 does a stupid thing where, for dynamically created elements, the name attribute on a DOM object is element.propdescname rather than element.name.

"Real" fix would probably be a change to the way we read all attributes off of a given element, but the quick fix is to just add it to the list of properties to check (IIRC, the attribute copy method is written in such an odd way for compatibility anyway).

This affects both 0.2.x and 1.x. Patch should be applied to all.

Multiple fields and jQuery 1.7 ~ 1.10

This issue is occurring for us in Drupal with scale_addressfield, but the root is here.

We cannot use multiple address fields on the same page with jQuery versions 1.7, 1.8, 1.9 or 1.10 (we stopped testing there).

When we have two addressfields on screen, and are using one of the jQuery versions above we get:

Uncaught TypeError: Cannot read property 'fields' of undefined

I traced this back to here.
In this method this.value is 0 because the context is not strict enough. As a result of the error, the State fields never becomes dropdowns because the bindings were never assigned.

jQuery 1.5 is fine, and all versions are fine with only a single address field.

A simple fix, incomming.

Install via npm doesn't seem trustworthy

I'm planning on having a browserified build that includes this as a dependency. There's a package.json in the project root, so it seems like this would work via an NPM install. Looking at package.json, it looks like plugin has been registered on NPM with "jquery-plugin".

npm installing that gives me the package, but I think there are a few issues here:

  1. jquery and addressfield.json aren't listened as runtime dependencies, so I don't get them with the install (unlike if I install this with bower). node will not find these dependencies at runtime, so this will likely break on a browserified build that happens to not include jquery as a separate dependency.
  2. in bower.json, I see the main file as dist/jquery.addressfield.js. I don't have this however:
example $ ls -lh node_modules/jquery-plugin/dist/
total 16
-rw-r--r--  1 valvarez  TSI\Domain Users   842B Sep  7  2012 foo.js
-rw-r--r--  1 valvarez  TSI\Domain Users   435B Sep  7  2012 foo.min.js
  1. this is more of a suggestion, but could we make the package name on NPM a bit more specific, something like "jquery.addressfield" instead of "jquery-plugin"?
  2. I get development files in the distribution:
example $ ls -lh node_modules/jquery-plugin/libs/
total 8
drwxr-xr-x  3 valvarez  TSI\Domain Users   102B Sep  7  2012 jquery
-rw-r--r--  1 valvarez  TSI\Domain Users   506B Sep  7  2012 jquery-loader.js
drwxr-xr-x  4 valvarez  TSI\Domain Users   136B Jan 17 19:33 qunit
example $ ls -lh node_modules/jquery-plugin/src/
total 8
-rw-r--r--  1 valvarez  TSI\Domain Users   851B Sep  7  2012 foo.js
example $ ls -lh node_modules/jquery-plugin/test/
total 16
-rw-r--r--  1 valvarez  TSI\Domain Users   1.1K Sep  7  2012 foo.html
-rw-r--r--  1 valvarez  TSI\Domain Users   1.7K Sep  7  2012 foo_test.js

I also get a foo.jquery.json in my project root. Do I need these on my disk?

Proposed solutions:

  • exclude unneeded files in .npmignore
  • rebuild and republish to npm
  • change npm package name
  • enumerate jquery and addressfield.json in dependencies or peerDependencies

Example config not working.

Cannot get basic config to work. Consider this example(Mostly taken from docs):

<html>
<head></head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="jquery.addressfield.js"></script>
<body>
  <form id="myForm">
    <div class="field-wrapper">
      <div class="field-wrapper">
        <label for="country">Country</label>
        <select id="country"></select>
      </div>
    </div>
    <div id="locality-fields">
      <div class="field-wrapper">
        <label for="city">City</label>
        <input type="text" id="city" />
      </div>
      <div class="field-wrapper">
        <label for="state">Administrative Area</label>
        <input type="text" id="state" />
      </div>
      <div class="field-wrapper">
        <label for="zip">Postal Code</label>
        <input type="text" id="zip" />
      </div>
    </div>
  </form>

  <script type="text/javascript">
  $('#myForm').addressfield({
    json: 'addressfield.json',
    fields: {
      Country: '#country',
      locality: '#locality-fields',
      localityname: '#city',
      administrativearea: '#state',
      postalcode: '#zip'
    }
  });
  </script>
</body>
</html>

addressfield.json is the version which is distributed with addressfield.js. Also note that I needed to capitalize 'Country' in order to avoid the error :

"Uncaught TypeError: Cannot read property 'fields' of undefined"

I have confirmed that addressfield.js and addressfield.json are available and properly accessed. Running this html page results in a form with an unpopulated country dropdown and no functionality.

Localization

Does this plugin support localization of the fields?

Element changes, data attributes are not carried over

I have a field that is converted from an input field to a select and the data attribute is not being carried over.

@Html.TextBox("Address.State", @Model.Address.State, new { @class = "input select-state", @id = "State", data_required = "true", data_selected_state = Model.Address.State })

Set selected country

What is the best way to set which country should be selected on page load? Do I just write my own JS to do this? If I just need to set the selected element after load, is there a method that I can have it redraw the fields?

Trying to implement jquery.addressfield

Hi, when trying to implement this library through NPM, we keep getting an error
Uncaught ReferenceError: jQuery is not defined

We added these fields to our code
const $ = require('jquery') require('jquery.addressfield')

and JQuery is a dependency in our package lock

"jquery": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" }, "jquery.addressfield": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jquery.addressfield/-/jquery.addressfield-1.2.3.tgz", "integrity": "sha1-7SaUISfKOUsbqx6zTJKU7bT9Y6c=", "requires": { "addressfield.json": "github:tableau-mkt/addressfield.json#1.1", "jquery": ">=1.3.2" } },

We of course thought it might be our own setup, but when running the library through the RunKit link on the npm page (https://npm.runkit.com/jquery.addressfield), we experience exactly the same error at the same spot in the code.

ReferenceError: jQuery is not defined

jquery.addressfield/dist/jquery.addressfield.js — line 19

Is this library still maintained and useable?

Thank you,

Terry Fox

Not compatible with IE8

The addressfield.orderfields method uses .class, which is a protected property in IE8.

We can work around this by accessing it using array notation.

// From...
$element.find('.' + order[i].class).val(order[i].value).change();

// To...
$element.find('.' + order[i]['class']).val(order[i].value).change();

Provide more detailed documentation

Should keep the README lean, just keep the features highlights + installation + basic usage. Then, in a "docs" folder, create topic-based documentation, linked to from the README:

  • Detailed usage: goes into detail about format of config and expected structure of the form.
  • Overridding functionality: goes into the methods in the plugin that can be overridden.

Add a way to specify form element attribute maintenance

Both the convertToSelect and convertToText methods make assumptions about the form element attributes that should be maintained when converting element types.

They're sensible defaults, but we should allow others to add their own (or get rid of the defaults, if need be).

A configuration layer is beyond a 0.2.x release, so maybe we should just abstract it into an override-able method.

Cannot read property 'settings' of undefined

Trying to use jQuery validate with the plugin and getting an error

Uncaught TypeError: Cannot read property 'settings' of undefined

Error is starting here

// Account for nested fields. if (config.fields[fieldPos][field] instanceof Array) { return $.fn.addressfield.apply.call($element, {fields: config.fields[fieldPos][field]}, fieldMap); }

Here is how I am instantiating addressfield

$('#contact-form').addressfield({ json: 'bower_components/addressfield.json/src/addressfield.json', fields: { country: '#Country', locality: '#locality-fields', administrativearea: '#State', postalcode: '#Zip' }, });

Thoughts

Add a way to find a form element's container

Some methods are extremely opinionated in finding form element containers, and they aren't even all necessarily of the same opinion.

The showField/hideField methods assume the parent element. The orderFields method assumes the parent, but specifically a div or section...

We should probably introduce a generic elementContainer method that finds a form elements containing element. The definition of which is something along the lines of... "The closest element that contains both this form element and its label"

We should then update showField, hideField, and orderFields to use this new method.

Remove GitHub Releases Deploy

The releases are triggering weird things on the jQuery plugin page... Better to just do it manually. Not that hard.

Make addressfield::updateLabel less opinionated

The updateLabel method is extremely opinionated about the location of the label relative to the form element.

Rather than assuming that the previous element is a form element's label, we should explicitly check the label's for attribute matching the form element's name.

For API compatibility reasons, we may want to keep the existing prev check in an elseif.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.