pumi 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.github/actions/fetch_data/Dockerfile +8 -0
  3. data/.github/actions/fetch_data/action.yml +17 -0
  4. data/.github/actions/fetch_data/entrypoint.sh +16 -0
  5. data/.github/workflows/build.yml +25 -0
  6. data/.github/workflows/bump_version.yml +37 -0
  7. data/.github/workflows/update_data.yml +38 -0
  8. data/.gitignore +14 -0
  9. data/.rspec +2 -0
  10. data/.rubocop.yml +22 -0
  11. data/.tool-versions +2 -0
  12. data/CODE_OF_CONDUCT.md +74 -0
  13. data/Gemfile +4 -0
  14. data/LICENSE.txt +21 -0
  15. data/README.md +177 -0
  16. data/Rakefile +6 -0
  17. data/app/assets/javascripts/pumi.js.coffee +97 -0
  18. data/app/controllers/pumi/communes_controller.rb +7 -0
  19. data/app/controllers/pumi/districts_controller.rb +7 -0
  20. data/app/controllers/pumi/provinces_controller.rb +7 -0
  21. data/app/controllers/pumi/villages_controller.rb +7 -0
  22. data/app/serializers/pumi/response_serializer.rb +15 -0
  23. data/bin/console +14 -0
  24. data/bin/parse_data +66 -0
  25. data/bin/setup +8 -0
  26. data/config/routes.rb +3 -0
  27. data/data/communes.yml +13170 -0
  28. data/data/districts.yml +1626 -0
  29. data/data/provinces.yml +202 -0
  30. data/data/villages.yml +114978 -0
  31. data/lib/pumi/administrative_unit.rb +3 -0
  32. data/lib/pumi/commune.rb +3 -0
  33. data/lib/pumi/data_store.rb +7 -0
  34. data/lib/pumi/district.rb +3 -0
  35. data/lib/pumi/location.rb +42 -0
  36. data/lib/pumi/parser.rb +135 -0
  37. data/lib/pumi/province.rb +3 -0
  38. data/lib/pumi/rails/engine.rb +6 -0
  39. data/lib/pumi/rails.rb +2 -0
  40. data/lib/pumi/store_cache.rb +17 -0
  41. data/lib/pumi/version.rb +3 -0
  42. data/lib/pumi/village.rb +3 -0
  43. data/lib/pumi.rb +25 -0
  44. data/pumi.gemspec +40 -0
  45. data/pumi.jpg +0 -0
  46. data/pumi_ui_en.png +0 -0
  47. data/pumi_ui_km.png +0 -0
  48. data/tmp/.keep +0 -0
  49. metadata +302 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 17f74d68e427a1e24638f6b243057647b4f4d6a73e99f91f16248ff974a41ae2
4
+ data.tar.gz: fb80152d500f3f83d36ff6c9b3a551269dea4d298127c5c293fe2876b0ceb64a
5
+ SHA512:
6
+ metadata.gz: '038bb2cb0ec0c7308ce96bf4df841de3c1fb696b5a9bb90d944a098abf1b17928f9f7bc501624ed88069a0d194ae576ad06a3a7690c7442e5702b1ada81f28db'
7
+ data.tar.gz: e7a0cec8036bbccfc7c69c2f50aac41ccd3a8fa2c8f4576b4d16436941d9933789b89d0076db6751245c86cbac40709ac48deb0c19737e83732dd83235e2f9c1
@@ -0,0 +1,8 @@
1
+ FROM alpine:latest
2
+
3
+ RUN apk update && apk upgrade && apk add --update --no-cache curl gnumeric font-noto-khmer ttf-opensans
4
+
5
+ COPY entrypoint.sh /entrypoint.sh
6
+
7
+ # Code file to execute when the docker container starts up (`entrypoint.sh`)
8
+ ENTRYPOINT ["/entrypoint.sh"]
@@ -0,0 +1,17 @@
1
+ name: Fetch Data
2
+ description: Fetches the latest data
3
+ inputs:
4
+ num_provinces:
5
+ description: Number of provinces to fetch
6
+ required: true
7
+ default: 25
8
+ url:
9
+ description: URL to fetch the data
10
+ required: true
11
+ default: 'http://db.ncdd.gov.kh/gazetteer/province/downloadprovince.castle?pv=${province_code}'
12
+ runs:
13
+ using: docker
14
+ image: Dockerfile
15
+ args:
16
+ - ${{ inputs.num_provinces }}
17
+ - ${{ inputs.url }}
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+ set -o pipefail
5
+
6
+ PLACEHOLDER='${province_code}'
7
+
8
+ num_provinces=$1
9
+ url=$2
10
+
11
+ for province_code in `seq 1 $num_provinces`
12
+ do
13
+ province_url=$(echo $url | sed -e s/$PLACEHOLDER/$province_code/g)
14
+ curl -s $province_url > "tmp/p$province_code.xls"
15
+ ssconvert "tmp/p$province_code.xls" "tmp/p$province_code.csv"
16
+ done
@@ -0,0 +1,25 @@
1
+ name: Build
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - uses: actions/checkout@v2
12
+
13
+ - name: Set up Ruby
14
+ uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: 2.6.x
17
+
18
+ - name: Install Dependencies
19
+ run: |
20
+ gem install bundler
21
+ bundle install --jobs 4 --retry 3
22
+
23
+ - name: Run Specs
24
+ run: |
25
+ bundle exec rake
@@ -0,0 +1,37 @@
1
+ name: Create Release
2
+ on:
3
+ push:
4
+ branches:
5
+ - release_new_gems
6
+ jobs:
7
+ release:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+
12
+ - name: Set up Ruby
13
+ uses: actions/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.6.x
16
+
17
+ - name: Install Dependencies
18
+ run: |
19
+ gem install bundler
20
+ bundle install --jobs 4 --retry 3
21
+
22
+ - name: Set up Git
23
+ run: |
24
+ git config --global user.email "dwilkie@gmail.com"
25
+ git config --global user.name "David Wilkie"
26
+
27
+ - name: Bump version and publish release
28
+ env:
29
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30
+ GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }}
31
+ run: |
32
+ mkdir -p ~/.gem
33
+ echo -e "---\r\n:rubygems_api_key: $GEM_HOST_API_KEY" > ~/.gem/credentials
34
+ chmod 0600 ~/.gem/credentials
35
+ bundle exec bump patch --tag
36
+ git push --tags
37
+ bundle exec rake release
@@ -0,0 +1,38 @@
1
+ name: Update Data
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 0 * * 0'
6
+
7
+ jobs:
8
+ fetch_data:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v1
13
+
14
+ - name: Setup Ruby
15
+ uses: actions/setup-ruby@v1
16
+ with:
17
+ ruby-version: '2.x'
18
+
19
+ - name: Fetch Data
20
+ uses: ./.github/actions/fetch_data
21
+
22
+ - name: Parse Data
23
+ run: ./bin/parse_data
24
+
25
+ - name: Create Pull Request
26
+ uses: peter-evans/create-pull-request@v1
27
+ with:
28
+ token: ${{ secrets.REPO_TOKEN }}
29
+ commit-message: "Update pumi data"
30
+ title: "Update pumi data"
31
+ labels: "update_data"
32
+ base: "master"
33
+
34
+ - name: Upload Data
35
+ uses: actions/upload-artifact@v1
36
+ with:
37
+ name: data_files
38
+ path: tmp
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ spec/dummy/tmp
10
+ spec/dummy/log
11
+ /tmp/*
12
+ !/tmp/.keep
13
+ vendor/ruby
14
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,22 @@
1
+ require: rubocop-rspec
2
+
3
+ Style/FrozenStringLiteralComment:
4
+ Enabled: false
5
+
6
+ Style/StringLiterals:
7
+ EnforcedStyle: double_quotes
8
+
9
+ Layout/LineLength:
10
+ Max: 100
11
+
12
+ Style/Documentation:
13
+ Enabled: false
14
+
15
+ MultipleExpectations:
16
+ Enabled: false
17
+
18
+ ExampleLength:
19
+ Max: 10
20
+
21
+ RSpec/DescribedClass:
22
+ Enabled: false
data/.tool-versions ADDED
@@ -0,0 +1,2 @@
1
+ ruby 2.6.5
2
+ nodejs 10.16.3
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at dwilkie@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in pumi.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 David Wilkie
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # Pumi
2
+
3
+ ![](https://github.com/dwilkie/pumi/workflows/Build/badge.svg)
4
+
5
+ Pumi (ភូមិ pronounced Poom, which means Village in Khmer) is an Open Source library containing Geodata for administrative regions in Cambodia including Provinces, Districts, Communes and Villages.
6
+
7
+ ![Khmer Village](https://raw.githubusercontent.com/dwilkie/pumi/master/pumi.jpg)
8
+
9
+ ## Demo and API
10
+
11
+ A [JSON API](https://pumiapp.herokuapp.com) is available to if you're not using Ruby or if you just don't want to install a local copy of the data. The [API Start Page](https://pumiapp.herokuapp.com) also shows a Demo of a UI for for entering any location in Cambodia.
12
+
13
+ ## Usage
14
+
15
+ ### Rails
16
+
17
+ Using Pumi with Rails gives you some javascript helpers as well as an API to filter and select Provinces (ខេត្ត), Districts (ស្រុក / ខណ្ឌ), Communes (ឃុំ / សង្កាត់) and Villages (ភូមិ) in both latin and Khmer as seen below and in the [Pumi API Start Page](https://pumiapp.herokuapp.com)
18
+
19
+ ![Pumi UI Latin](https://raw.githubusercontent.com/dwilkie/pumi/master/pumi_ui_en.png)
20
+ ![Pumi UI Khmer](https://raw.githubusercontent.com/dwilkie/pumi/master/pumi_ui_km.png)
21
+
22
+ To use Pumi with Rails first, require `"pumi/rails"` in your Gemfile:
23
+
24
+ ```ruby
25
+ gem 'pumi', github: "dwilkie/pumi", require: "pumi/rails"
26
+ ```
27
+
28
+ Next, mount the Pumi routes in `config/routes`
29
+
30
+ ```ruby
31
+ # config/routes.rb
32
+
33
+ mount Pumi::Engine => "/pumi"
34
+ ```
35
+
36
+ Then require the pumi javascript in `app/assets/javascripts/application.js`
37
+
38
+ ```js
39
+ //= require jquery
40
+ //= require pumi
41
+ ```
42
+
43
+ Note: `jquery` is a dependency of pumi and must be required before `pumi`
44
+
45
+ Finally setup your view with selects for the province, district, commune and village. See the [dummy application](https://github.com/dwilkie/pumi/blob/master/spec/dummy/app/views/addresses/new.html.erb) for an example and refer to the [configuration](#configuration) below.
46
+
47
+ ### Plain Ol' Ruby
48
+
49
+ Rails is not a dependency of Pumi so you can use it with Plain Ol' Ruby if you don't need the javascript and route helpers.
50
+
51
+ Add this line to your application's Gemfile:
52
+
53
+ ```ruby
54
+ gem 'pumi', :github => "dwilkie/pumi"
55
+ ```
56
+
57
+ And then execute:
58
+
59
+ $ bundle
60
+
61
+ ```ruby
62
+ require 'pumi'
63
+
64
+ # Working with Provinces (ខេត្ត)
65
+
66
+ # Get all provinces
67
+ Pumi::Province.all
68
+
69
+ # Find a province by id
70
+ Pumi::Province.find_by_id("12")
71
+
72
+ # Find a province by its latin name
73
+ Pumi::Province.where(name_latin: "Phnom Penh")
74
+
75
+ # Find a province by its Khmer name
76
+ Pumi::Province.where(name_km: "បន្ទាយមានជ័យ")
77
+
78
+ # Working with Districts (ស្រុក / ខណ្ឌ)
79
+
80
+ # Get all districts
81
+ Pumi::District.all
82
+
83
+ # Get all districts by province_id
84
+ Pumi::District.where(province_id: "12")
85
+
86
+ # Find district by its Khmer name and Province ID
87
+ district = Pumi::District.where(province_id: "12", name_km: "ចំការមន").first
88
+
89
+ # Return the district's province name in latin
90
+ district.province.name_latin
91
+ # => Phnom Penh
92
+
93
+ # Working with Communes (ឃុំ / សង្កាត់)
94
+
95
+ # Get all communes by district_id
96
+ Pumi::Commune.where(district_id: "1201")
97
+
98
+ # Find a commune by its latin name and District ID
99
+ commune = Pumi::Commune.where(district_id: "1201", name_latin: "Tonle Basak").first
100
+
101
+ # Return the commune's district name in Khmer
102
+ commune.district.name_km
103
+ # => "ចំការមន"
104
+
105
+ # Return the commune's province name in Khmer
106
+ commune.province.name_km
107
+ # => "ភ្នំពេញ"
108
+
109
+ # Working with Villages (ភូមិ)
110
+
111
+ # Get all villages by commune_id
112
+ Pumi::Village.where(commune_id: "010201")
113
+
114
+ # Find a village by it's Khmer name and Commune ID
115
+ village = Pumi::Village.where(commune_id: "010201", name_km: "អូរធំ").first
116
+
117
+ # Return the village's commune name in latin
118
+ village.commune.name_latin
119
+ # => "Banteay Neang"
120
+
121
+ # Return the village's district name in Khmer
122
+ village.district.name_km
123
+ => "មង្គលបូរី"
124
+
125
+ # Return the village's province name in Khmer
126
+ village.province.name_km
127
+ # => "បន្ទាយមានជ័យ"
128
+
129
+ # Get the villages address in Latin
130
+ village.address_latin
131
+ # => "Phum Ou Thum, Khum Banteay Neang, Srok Mongkol Borei, Khaet Banteay Meanchey"
132
+
133
+ # In English
134
+ village.address_en
135
+ # => "Ou Thum Village, Banteay Neang Commune, Mongkol Borei District, Banteay Meanchey Province"
136
+
137
+ # In Khmer
138
+ village.address_en
139
+ # => "ភូមិអូរធំ ឃុំបន្ទាយនាង ស្រុកមង្គលបូរី ខេត្តបន្ទាយមានជ័យ"
140
+ ```
141
+
142
+ ## Configuration
143
+
144
+ The following html5 data-attributes can be used to configure Pumi.
145
+
146
+ <dl>
147
+ <dt><code>data-pumi-select-id</code></dt>
148
+ <dd>A unique id of the select input which is looked up by <code>data-pumi-select-target</code></dd>
149
+ <dt><code>data-pumi-select-target</code></dt>
150
+ <dd>The <code>data-pumi-select-id</code> of the select input in which to update the options when this input is changed</dd>
151
+ <dt><code>data-pumi-select-collection-url</code></dt>
152
+ <dd>The url in which to lookup the values for this select input. If this option is not given then no ajax request will be made. Hint: You can use the Rails url helpers here e.g. <code>pumi.districts_path(:province_id => "FILTER")</code></dd>
153
+ <dt><code>data-pumi-select-collection-url-filter-interpolation-key</code></dt>
154
+ <dd>The key value to interpolate for filtering via the collection url. E.g. if you set <code>data-pumi-select-collection-url="/pumi/districts?province_id=FILTER"</code>, then a value of <code>"FILTER"</code> here will replace the collection URL with the value of the select input which this select input is the target of</dd>
155
+ <dt><code>data-pumi-select-collection-label-method</code></dt>
156
+ <dd>The name of the label method. E.g. <code>data-pumi-select-collection-label-method="name_en"</code> will display the labels in Latin or <code>data-pumi-select-collection-label-method="name_km"</code> will display the labels in Khmer</dd>
157
+ <dt><code>data-pumi-select-collection-value-method</code></dt>
158
+ <dd>The name of the value method. E.g. <code>data-pumi-select-collection-value-method="id"</code> will set the value of the select input to the Pumi of the location</dd>
159
+ <dt><code>data-pumi-select-disabled-target</code></dt>
160
+ <dd>The target of a parent selector in which to apply the class <code>data-pumi-select-disabled-class</code> to when the input is disabled</dd>
161
+ <dt><code>data-pumi-select-disabled-class</code></dt>
162
+ <dd>When the input is disabled this class will be applied to <code>data-pumi-select-disabled-target</code></dd>
163
+ <dt><code>data-pumi-select-populate-on-load</code></dt>
164
+ <dd>Set to true to populate the select input with options on load. Default: false</dd>
165
+ <dt><code>data-pumi-select-has-hidden-value</code></dt>
166
+ <dd>Set to true if you also have a hidden field for this input with the same name. Useful for remembering the selection across page reloads. Default: false</dd>
167
+ </dl>
168
+
169
+ ## Development
170
+
171
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
172
+
173
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
174
+
175
+ ## Contributing
176
+
177
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dwilkie/pumi.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,97 @@
1
+ $(document).ready ->
2
+ pumi.setup()
3
+
4
+ pumi =
5
+ dataAttributeTag: (attribute, selector) ->
6
+ tag = "pumi-select-#{attribute}"
7
+ tag = if !!selector then "[data-#{tag}]" else tag
8
+
9
+ setDataAttribute: (element, attribute, value) ->
10
+ element.data(pumi.dataAttributeTag(attribute), value)
11
+
12
+ getDataAttribute: (element, attribute, value) ->
13
+ element.data(pumi.dataAttributeTag(attribute))
14
+
15
+ removeDataAttribute: (element, attribute) ->
16
+ element.removeData(pumi.dataAttributeTag(attribute))
17
+
18
+ toggleEnableSelect: (select, enable) ->
19
+ wrapperTarget = select.closest(pumi.getDataAttribute(select, 'disabled-target'))
20
+ disabledClass = pumi.getDataAttribute(select, 'disabled-class')
21
+
22
+ if !!enable
23
+ wrapperTarget.removeClass(disabledClass)
24
+ select.removeAttr("disabled")
25
+ else
26
+ wrapperTarget.addClass(disabledClass)
27
+ select.attr("disabled", "disabled")
28
+
29
+ selectPopulateOnLoad: ->
30
+ $(pumi.dataAttributeTag('populate-on-load', true))
31
+
32
+ selectTargets: ->
33
+ $(pumi.dataAttributeTag('id', true))
34
+
35
+ selectHasTarget: ->
36
+ $(pumi.dataAttributeTag('target', true))
37
+
38
+ selectTarget: (id) ->
39
+ $(pumi.dataAttributeTag("id=#{id}", true))
40
+
41
+ selectHasHiddenValue: =>
42
+ $(pumi.dataAttributeTag('has-hidden-value', true))
43
+
44
+ setupOnLoad: ->
45
+ pumi.selectPopulateOnLoad().each ->
46
+ pumi.populateFromAjax($(this))
47
+
48
+ pumi.selectHasHiddenValue().each ->
49
+ select = $(this)
50
+ pumi.setDataAttribute(select, 'default-value', $($.find("[name='#{select.attr('name')}']")).val())
51
+
52
+ populateFromAjax: (select, filterValue) ->
53
+ collectionUrl = pumi.getDataAttribute(select, 'collection-url')
54
+ if !!collectionUrl
55
+ filterInterpolationKey = pumi.getDataAttribute(select, 'collection-url-filter-interpolation-key')
56
+ labelMethod = pumi.getDataAttribute(select, 'collection-label-method')
57
+ valueMethod = pumi.getDataAttribute(select, 'collection-value-method')
58
+ $.getJSON collectionUrl.replace(filterInterpolationKey, filterValue), (data) ->
59
+ $.each data, (index, item) ->
60
+ select.append($('<option>').text(item[labelMethod]).val(item[valueMethod]))
61
+ defaultValue = pumi.getDataAttribute(select, 'default-value')
62
+ if !!defaultValue
63
+ select.val(defaultValue)
64
+ pumi.removeDataAttribute(select, 'default-value')
65
+ select.trigger("change")
66
+
67
+ setupTargets: (selects) ->
68
+ selects.each ->
69
+ select = $(this)
70
+ options = []
71
+ select.find('option').each ->
72
+ options.push
73
+ value: @value
74
+ text: @text
75
+
76
+ pumi.setDataAttribute(select, 'options', options)
77
+ pumi.toggleEnableSelect(select, false)
78
+
79
+ filterSelectByValue: (select, filterValue) ->
80
+ staticPumiOptions = pumi.getDataAttribute(select, 'options')
81
+ select.empty()
82
+
83
+ pumi.toggleEnableSelect(select, !!filterValue)
84
+ select.trigger("change")
85
+
86
+ $.each staticPumiOptions, (i) ->
87
+ pumiOption = staticPumiOptions[i]
88
+ select.append($('<option>').text(pumiOption.text).val(pumiOption.value)) if !pumiOption.value || pumiOption.value.match(///^#{filterValue}///)
89
+
90
+ pumi.populateFromAjax(select, filterValue) if !!filterValue
91
+
92
+ setup: ->
93
+ pumi.setupOnLoad()
94
+ pumi.setupTargets(pumi.selectTargets())
95
+
96
+ pumi.selectHasTarget().change ->
97
+ pumi.filterSelectByValue(pumi.selectTarget(pumi.getDataAttribute($(this), 'target')), @value)
@@ -0,0 +1,7 @@
1
+ module Pumi
2
+ class CommunesController < ActionController::Base
3
+ def index
4
+ render(json: ResponseSerializer.new(Commune.where(request.query_parameters)))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Pumi
2
+ class DistrictsController < ActionController::Base
3
+ def index
4
+ render(json: ResponseSerializer.new(District.where(request.query_parameters)))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Pumi
2
+ class ProvincesController < ActionController::Base
3
+ def index
4
+ render(json: ResponseSerializer.new(Province.where(request.query_parameters)))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Pumi
2
+ class VillagesController < ActionController::Base
3
+ def index
4
+ render(json: ResponseSerializer.new(Village.where(request.query_parameters)))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module Pumi
2
+ class ResponseSerializer
3
+ attr_reader :data
4
+
5
+ def initialize(data)
6
+ @data = data
7
+ end
8
+
9
+ def as_json(*)
10
+ data.map do |location|
11
+ location.attributes.except(:province, :district, :commune, :village)
12
+ end
13
+ end
14
+ end
15
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "pumi"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)