{"_id":"@didww/best_in_place","_rev":"3-1be2303763b5dc5b005de3e12c9a7e8b","name":"@didww/best_in_place","dist-tags":{"latest":"3.1.1"},"versions":{"3.1.1":{"name":"@didww/best_in_place","version":"3.1.1","keywords":["BestInPlace","editable","inputs"],"author":{"name":"Bernat Farrero","email":"bernat@itnig.net"},"license":"MIT","_id":"@didww/best_in_place@3.1.1","maintainers":[{"name":"senid231","email":"senid231@gmail.com"},{"name":"gigorok","email":"igor.g@didww.com"},{"name":"denis.o","email":"denis.o@didww.com"},{"name":"skumring","email":"denys.m@didww.com"},{"name":"kirillparomonov","email":"kirill.p@didww.com"},{"name":"bogdan.p","email":"bogdan.p@didww.com"},{"name":"vvitto","email":"vvitto123@gmail.com"}],"homepage":"https://github.com/didww/best_in_place#readme","bugs":{"url":"https://github.com/didww/best_in_place/issues"},"dist":{"shasum":"ff430eaed784e4d4bcbc5df71c4b5d7ed39584a6","tarball":"https://registry.npmjs.org/@didww/best_in_place/-/best_in_place-3.1.1.tgz","fileCount":4,"integrity":"sha512-FFDJDH6LCEdVV2qJlMfZzM4fm8sZ+j2Axt6AYOBdJ6ReH6C24nMP+/IzPnjsWbE8Ru29/A1QwEMn4kmxNzaePg==","signatures":[{"sig":"MEUCIAa/BSfNkQCX2/gIslOGmaP+Z4KufTzbVlZLsqZDM1EkAiEAnqHER+lVhkFXr52OsoiU+lDQhaco6G/J7x0Th37Stag=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":50946,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJioLuKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpbfg//dB32ADgdf/ZV+a0itxVnbMdDy2l4LcOshNiiCt6mNXfOoLKw\r\nNSt+H7BIKquyYqoBthWGugP9HS6XGJFSkLQFAM8N3GmEHmoc3aNMCqFx4mOS\r\n3aCET/0dRjnJvaMmfRzRO01KfDEnQRfqWqdHbTWS//dOQVo4Gb2Fb7ttMRXN\r\n4lRCgxi6U7lXw91t54AJzhaXL9lvUxei9cF9oLhteZZvx7S0SQd84yWSa4Jm\r\nbxmMS7Kxqbcvn00lXOBcL+kfFLD8IWcmGSaCSwS6aBUyEZQQ6oa1Co9kiNXD\r\nWysugSOA3gsjhvGRcKAyX8av5jSMsbudd2et1z4MisR54qdO/ge/71z4YUU0\r\nuKMOkIZ5hCoGW0HvOT8JUqZ2hjz6YpQIFYyOqX7sjXR6wkJh/gBLg+d4e7Ma\r\nwB391KA6IqS/OaLzp6bmNhdU5LTdhNnMSEi2q087dcjX14o1XVTLZ/3NuhhJ\r\nJ2nLSZ8nsi1ZWoMIKE5wPnfOoLGvHTGufRmY/xnpuxIXsY1QUdMNOBf2aSwt\r\nIyFN23HUnKiuz5lR4AHFzlOKoUrlvanMD1u/pX36hQd2KDm/+l9ksqNq9F0u\r\nnRVaJTQrAnlDlrB4IhmrXcVaiTxy4LUoz7zWUKZp3y9JYfYuPeCsA71vwWWw\r\neUYQyAxnYmCzLozAyKxjT/MnSo91q18O7Sw=\r\n=ORIY\r\n-----END PGP SIGNATURE-----\r\n"},"main":"src/best_in_place.js","gitHead":"a688dbfad22da5f5f5332a9b764b2516e8a0cd03","private":false,"scripts":{"postpack":"rm -rf src && rm vendor/jquery.purr.js","prepare_src":"rm -rf src && mkdir src && cp lib/assets/javascripts/best_in_place_pack.js src/best_in_place.js","prepare_vendor":"cp vendor/assets/javascripts/jquery.purr.js vendor","prepublishOnly":"npm run prepare_src && npm run prepare_vendor"},"_npmUser":{"name":"skumring","email":"denys.m@didww.com"},"repository":{"url":"git+https://github.com/didww/best_in_place.git","type":"git"},"_npmVersion":"8.10.0","description":"BestInPlace is a jQuery script and a Rails helper that provide the method best_in_place to display any object field easily editable for the user by just clicking on it. It supports input data, text data, boolean data and custom dropdown data. It works wit","directories":{},"_nodeVersion":"16.13.0","dependencies":{"jquery-autosize":"~>1.18.9"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/best_in_place_3.1.1_1654700938693_0.5412896349791163","host":"s3://npm-registry-packages"}}},"time":{"created":"2022-06-08T15:08:58.567Z","modified":"2026-02-23T13:04:08.465Z","3.1.1":"2022-06-08T15:08:58.930Z"},"bugs":{"url":"https://github.com/didww/best_in_place/issues"},"author":{"name":"Bernat Farrero","email":"bernat@itnig.net"},"license":"MIT","homepage":"https://github.com/didww/best_in_place#readme","keywords":["BestInPlace","editable","inputs"],"repository":{"url":"git+https://github.com/didww/best_in_place.git","type":"git"},"description":"BestInPlace is a jQuery script and a Rails helper that provide the method best_in_place to display any object field easily editable for the user by just clicking on it. It supports input data, text data, boolean data and custom dropdown data. It works wit","maintainers":[{"email":"senid231@gmail.com","name":"senid231"},{"email":"igor.g@didww.com","name":"gigorok"},{"email":"denys.m@didww.com","name":"skumring"},{"email":"kirill.p@didww.com","name":"kirillparomonov"},{"email":"bogdan.p@didww.com","name":"bogdan.p"},{"email":"vvitto123@gmail.com","name":"vvitto"},{"email":"igor.f@didww.com","name":"igorfedoronchuk"},{"email":"sergei.i@didww.com","name":"sergei.i"}],"readme":"# Best In Place\n[![Build Status](https://secure.travis-ci.org/bernat/best_in_place.png)](http://travis-ci.org/bernat/best_in_place)\n[![NPM Version](https://badge.fury.io/js/@didww%2Fbest_in_place.svg)](https://badge.fury.io/js/@didww%2Fbest_in_place)\n![npm](https://img.shields.io/npm/dm/@didww/best_in_place)\n\n**The Unobtrusive in Place editing solution**\n\n## Description\n\n**Best in Place** is a jQuery based AJAX Inplace-Editor that takes profit of RESTful server-side controllers to allow users to edit stuff with\nno need of forms. If the server has standard defined REST methods, particularly those to UPDATE your objects (HTTP PUT), then by adding the\nJavascript file to the application it allows all the fields with the proper defined classes to become user in-place editable.\n\nThe editor works by PUTting the updated value to the server and GETting the updated record afterwards to display the updated value.\n\n---\n\n## Installation\n\n### Rails\n\nInstalling *best_in_place* is very easy and straight-forward.\nJust begin including the gem in your Gemfile:\n\n    gem 'best_in_place', '~> 3.0.1'\n\n##### Using assets via Sprockets\nAfter that, specify the use of the jquery and best in place\njavascripts in your application.js, and optionally specify jquery-ui if\nyou want to use jQuery UI datepickers:\n\n    //= require jquery\n    //= require best_in_place\n\n    //= require jquery-ui\n    //= require best_in_place.jquery-ui\n\nIf you want to use jQuery UI datepickers, you should also install and\nload your preferred jquery-ui CSS file and associated assets.\n\n##### Using assets via Webpacker (or any other assets bundler) as a NPM module (Yarn package)\n\nExecute:\n\n    $ npm i @didww/best_in_place\n\nOr\n\n    $ yarn add @didww/best_in_place\n\nOr add manually to `package.json`:\n\n```json\n\"dependencies\": {\n  \"@didww/best_in_place\": \"3.1.1\"\n}\n```\nand execute:\n\n    $ yarn\n\nAdd the following line into `app/javascript/active_admin.js`:\n\n```javascript\nimport '@didww/best_in_place';\n```\n\n#### Initialization\nThen, just add a binding to prepare all best in place fields when the document is ready:\n```javascript\n$(document).ready(function() {\n  /* Activating Best In Place */\n  jQuery(\".best_in_place\").best_in_place();\n});\n```\n\nYou are done!\n\n## Features\n\n- Compatible with text **inputs**\n- Compatible with **textarea**\n- Compatible with **select** dropdown with custom collections\n- Compatible with custom boolean values (same usage of **checkboxes**)\n- Compatible with **jQuery UI Datepickers**\n- Sanitize HTML and trim spaces of user's input on user's choice\n- Displays server-side **validation** errors\n- Allows external activator\n- Allows optional, configurable OK and Cancel buttons for inputs and textareas\n- ESC key destroys changes (requires user confirmation)\n- Autogrowing textarea with **jQuery Autosize**\n- Helper for generating the best_in_place field only if a condition is satisfied\n- Provided test helpers to be used in your integration specs\n- Custom display methods using a method from your model or an existing rails\n  view helper\n\n## Usage of Rails 3 Gem\n\n### best_in_place\n**best_in_place object, field, OPTIONS**\n\nParams:\n\n- **object** (Mandatory): The Object parameter represents the object itself you are about to modify\n- **field** (Mandatory): The field (passed as symbol) is the attribute of the Object you are going to display/edit.\n\nOptions:\n\n- **:as** It can be only [:input, :textarea, :select, :checkbox, :date] or if undefined it defaults to :input.\n- **:collection**: If you are using the :select type then you must specify the collection of values it takes as a hash where values represent the display text and keys are the option's value when selected. If you are using the :checkbox type you can specify the two values it can take, or otherwise they will default to Yes and No.\n- **:url**: URL to which the updating action will be sent. If not defined it defaults to the :object path.\n- **:place_holder**: The nil param defines the content displayed in case no value is defined for that field. It can be something like \"click me to edit\".\n  If not defined it will show *\"-\"*.\n- **:activator**: Is the DOM object that can activate the field. If not defined the user will making editable by clicking on it.\n- **:ok_button**: (Inputs and textareas only) If set to a string, then an OK button will be shown with the string as its label, replacing save on blur.\n- **:ok_button_class**: (Inputs and textareas only) Specifies any extra classes to set on the OK button.\n- **:cancel_button**: (Inputs and textareas only) If set to a string, then a Cancel button will be shown with the string as its label.\n- **:cancel_button_class**: (Inputs and textareas only) Specifies any extra classes to set on the Cancel button.\n- **:sanitize**: True by default. If set to false the input/textarea will accept html tags.\n- **:html_attrs**: Hash of html arguments such as maxlength, default-value, etc. that will be set on the rendered input **not** the best_in_place span.\n- **:inner_class**: Class that is set to the rendered input.\n- **:display_as**: A **model** method which will be called in order to display this field. Cannot be used when using `display_with`.\n- **:display_with**: A **helper** method or proc will be called in order to display this field. Cannot be used with `display_as`.\n- **:helper_options**: A hash of parameters to be sent to the helper method specified by `display_with`.\n- **:data**: Hash of custom data attributes to be added to span. Can be used to provide data to the ajax:success callback.\n- **:class**: Additional classes to apply to the best_in_place span.  Accepts either a string or Array of strings\n- **:value**: Customize the starting value of the inline input (defaults to to the field's value)\n- **:id**: The HTML id of the best_in_place span. If not specified one is automatically generated.\n- **:param**: If you wish to specific the object explicitly use this option.\n- **:confirm**: If set to true displays a confirmation message when abandoning changes (pressing the escape key).\n- **:skip_blur**: If set to true, blurring the input will not cause changes to be abandoned in textareas.\n\nHTML Options:\n\nIf you provide an option that is not explicitly a best_in_place option it will be passed through when creating the best_in_place span.\n\nSo, for instance, if you want to add an HTML tab index to the best_in_place span just add it to your method call:\n\n    <%= best_in_place @user, :name, tabindex: \"1\" %>\n\n### best_in_place_if\n**best_in_place_if condition, object, field, OPTIONS**\nsee also **best_in_place_unless**\n\nIt allows us to use best_in_place only if the first new parameter, a\ncondition, is satisfied. Specifically:\n\n* Will show a normal best_in_place if the condition is satisfied\n* Will only show the attribute from the instance if the condition is not satisfied\n\nSay we have something like\n\n    <%= best_in_place_if condition, @user, :name, :as => :input %>\n\nIn case *condition* is satisfied, the outcome will be just the same as:\n\n    <%= best_in_place @user, :name, :as => :input %>\n\nOtherwise, we will have the same outcome as:\n\n    <%= @user.name %>\n\nIt is a very useful feature to use with, for example, [Ryan Bates](https://github.com/ryanb)' [CanCan](https://github.com/ryanb/cancan), so we only allow BIP edition if the current user has permission to do it.\n\n---\n\n## Examples\n\nExamples (code in the views):\n\n### Input\n\n    <%= best_in_place @user, :name, :as => :input %>\n\n    <%= best_in_place @user, :name, :as => :input, :place_holder => \"Click me to add content!\" %>\n\n### Textarea\n\n    <%= best_in_place @user, :description, :as => :textarea %>\n\n    <%= best_in_place @user, :favorite_books, :as => :textarea, :ok_button => 'Save', :cancel_button => 'Cancel' %>\n\n### Select\n\n    <%= best_in_place @user, :country, :as => :select, :collection => {\"1\" => \"Spain\", \"2\" => \"Italy\", \"3\" => \"Germany\", \"4\" => \"France\"} %>\n    <%= best_in_place @user, :country, :as => :select, :collection => { es: 'Spain', it: 'Italy', de: 'Germany', fr: 'France' } %>\n    <%= best_in_place @user, :country, :as => :select, :collection => %w(Spain Italy Germany France) %>\n    <%= best_in_place @user, :country, :as => :select, :collection => [[1, 'Spain'], [3, 'Germany'], [2, 'Italy'], [4, 'France']] %>\n\nOf course it can take an instance or global variable for the collection, just remember the structure is a hash.\nThe value will always be converted to a string for display.\n\n### Checkbox\n\n    <%= best_in_place @user, :receive_emails, as: :checkbox, collection: [\"No, thanks\", \"Yes, of course!\"] %>\n    <%= best_in_place @user, :receive_emails, as: :checkbox, collection: {false: \"Nope\", true: \"Yep\"} %>\n\nIf you use array as a collection, the first value is always the negative boolean value and the second the positive. Structure: `[\"false value\", \"true value\"]`.\nIf not defined, it will default to *Yes* and *No* options.\nDefault true and false values are stored in locales\n\n    t(:'best_in_place.yes', default: 'Yes')\n    t(:'best_in_place.no', default: 'No')\n\n### Date\n\n    <%= best_in_place @user, :birth_date, :as => :date %>\n\nWith the :date type the input field will be initialized as a datepicker input.\nIn order to provide custom options to the datepicker initialization you must\nprepare a `$.datepicker.setDefaults` call with the preferences of your choice.\n\nMore information about datepicker and setting defaults can be found\n[here](http://docs.jquery.com/UI/Datepicker/$.datepicker.setDefaults)\n\n## Controller response with respond_with_bip\n\nBest in place provides a utility method you should use in your controller in\norder to provide the response that is expected by the javascript side, using\nthe :json format. This is a simple example showing an update action using it:\n\n    def update\n      @user = User.find params[:id]\n\n      respond_to do |format|\n        if @user.update_attributes(params[:user])\n          format.html { redirect_to(@user, :notice => 'User was successfully updated.') }\n          format.json { respond_with_bip(@user) }\n        else\n          format.html { render :action => \"edit\" }\n          format.json { respond_with_bip(@user) }\n        end\n      end\n    end\n\n\n## Custom display methods\n\n### Using `display_as`\n\nAs of best in place 1.0.3 you can use custom methods in your model in order to\ndecide how a certain field has to be displayed. You can write something like:\n\n    = best_in_place @user, :description, :as => :textarea, :display_as => :mk_description\n\nThen instead of using `@user.description` to show the actual value, best in\nplace will call `@user.mk_description`. This can be used for any kind of\ncustom formatting, text with markdown, etc...\n\n### Using `display_with`\n\nIn practice the most common situation is when you want to use an existing\nhelper to render the attribute, like `number_to_currency` or `simple_format`.\nAs of version 1.0.4 best in place provides this feature using the\n`display_with` option. You can use it like this:\n\n    = best_in_place @user, :money, :display_with => :number_to_currency\n\nIf you want to pass further arguments to the helper you can do it providing an\nadditional `helper_options` hash:\n\n    = best_in_place @user, :money, :display_with => :number_to_currency, :helper_options => {:unit => \"€\"}\n\nYou can also pass in a proc or lambda like this:\n\n    = best_in_place @post, :body, :display_with => lambda { |v| textilize(v).html_safe }\n\n## Ajax success callback\n\n### Binding to ajax:success\n\nThe 'ajax:success' event is triggered upon success. Use bind:\n\n    $('.best_in_place').bind(\"ajax:success\", function () {$(this).closest('tr').effect('highlight'); });\n\nTo bind a callback that is specific to a particular field, use the 'classes' option in the helper method and\nthen bind to that class.\n\n    <%= best_in_place @user, :name, :classes => 'highlight_on_success' %>\n    <%= best_in_place @user, :mail, :classes => 'bounce_on_success' %>\n\n    $('.highlight_on_success').bind(\"ajax:success\", function(){$(this).closest('tr').effect('highlight');});\n    $('.bounce_on_success').bind(\"ajax:success\", function(){$(this).closest('tr').effect('bounce');});\n\n### Providing data to the callback\n\nUse the :data option to add HTML5 data attributes to the best_in_place span. For example, in your view:\n\n    <%= best_in_place @user, :name, :data => {:user_name => @user.name} %>\n\nAnd in your javascript:\n\n    $('.best_in_place').bind(\"ajax:success\", function(){ alert('Name updated for '+$(this).data('userName')); });\n\n## Non Active Record environments\nWe are not planning to support other ORMs apart from Active Record, at least for now. So, you can perfectly consider the following workaround as *the right way* until a specific implementation is done for your ORM.\n\nBest In Place automatically assumes that Active Record is the ORM you are using. However, this might not be your case, as you might use another ORM (or not ORM at all for that case!). Good news for you: even in such situation Best In Place can be used!\n\nLet's setup an example so we can illustrate how to use Best In Place too in a non-ORM case. Imagine you have an awesome ice cream shop, and you have a model representing a single type of ice cream. The IceCream model has a name, a description, a... nevermind. The thing is that it also has a stock, which is a combination of flavour and size. A big chocolate ice cream (yummy!), a small paella ice cream (...really?), and so on. Shall we see some code?\n\n    class IceCream < ActiveRecord::Base\n      serialize :stock, Hash\n\n      # consider the get_stock and set_stock methods are already defined\n    end\n\nImagine we want to have a grid showing all the combinations of flavour and size and, for each combination, an editable stock. Since the stock for a flavour and a size is not a single and complete model attribute, we cannot use Best In Place *directly*. But we can set it up with an easy workaround.\n\nIn the view, we'd do:\n\n    // @ice_cream is already available\n    - flavours = ... // get them somewhere\n    - sizes = ... // get them somewhere\n    table\n      tr\n        - flavours.each do |flavour|\n          th= flavour\n      - sizes.each do |size|\n        tr\n          th= size\n          - flavours.each do |flavour|\n            - v = @ice_cream.get_stock(flavour: flavour, size: size)\n            td= best_in_place v, :to_i, as: :input, url: set_stock_ice_cream_path(flavour: flavour, size: size)\n\nNow we need a route to which send the stock updates:\n\n    TheAwesomeIceCreamShop::Application.routes.draw do\n      ...\n\n      resources :ice_creams, :only => :none do\n        member do\n          put :set_stock\n        end\n      end\n\n      ...\n    end\n\nAnd finally we need a controller:\n\n\n    class IceCreamsController < ApplicationController::Base\n      respond_to :html, :json\n\n      ...\n\n      def set_stock\n        flavour = params[:flavour]\n        size = params[:size]\n        new_stock = (params[\"fixnum\"] || {})[\"to_i\"]\n\n        @ice_cream.set_stock(new_stock, { :flavour => flavour, :size => size })\n        if @ice_cream.save\n          head :ok\n        else\n          render :json => @ice_cream.errors.full_messages, :status => :unprocessable_entity\n        end\n      end\n\n      ...\n\n    end\n\nAnd this is how it is done!\n\n## Configuration\n\nYou can configure some global options for best_in_place. Currently these options are available:\n\n    BestInPlace.configure do |config|\n      config.container = :div\n      config.skip_blur = true\n    end\n\n\n## Notification\n\nSometimes your in-place updates will fail due to validation or for some other reason. In such case, you'll want to notify the user somehow. **Best in Place** supports doing so through the best_in_place:error event, and has built-in support for notification via jquery.purr, right out of the box.\n\nTo opt into the jquery.purr error notification, just add best_in_place.purr to your javascripts, as described below.\n\n    //= require jquery.purr\n    //= require best_in_place.purr\n\nIf you'd like to develop your own custom form of error notification, you can use best_in_place.purr as an example to guide you.\n\n## Security\n\nIf the script is used with the Rails Gem no html tags will be allowed unless the sanitize option is set to true, in that case only the tags [*b i u s a strong em p h1 h2 h3 h4 h5 ul li ol hr pre span img*] will be allowed. If the script is used without the gem and with frameworks other than Rails, then you should make sure you are providing the csrf authenticity params as meta tags and you should always escape undesired html tags such as script, object and so forth.\n\n    <meta name=\"csrf-param\" content=\"authenticity_token\"/>\n    <meta name=\"csrf-token\" content=\"YOUR UNIQUE TOKEN HERE\"/>\n\n---\n\n## TODO\n\n- Client Side Validation definitions\n- Accepting more than one handler to activate best_in_place fields\n\n---\n\n## Development\n\nFork the project on [github](https://github.com/bernat/best_in_place 'bernat / best_in_place on Github')\n\n    $ git clone <your fork>\n    $ cd best_in_place\n    $ bundle\n\n### Run the specs\n\n    $ appraisal\n    $ appraisal rspec\n\nYou many need to install appraisal: `gem install appraisal`\n\n---\n\n## Test Helpers\nBest In Place has also some helpers that may be very useful for integration testing. Since it might very common to test some views using Best In Place, some helpers are provided to ease it.\n\nAs of now, a total of four helpers are available. There is one for each of the following BIP types: a plain text input, a textarea, a boolean input and a selector. Its function is to simulate the user's action of filling such fields.\n\nThese four helpers are listed below:\n\n* **bip_area(model, attr, new_value)**\n* **bip_text(model, attr, new_value)**\n* **bip_bool(model, attr)**\n* **bip_select(model, attr, name)**\n\nThe parameters are defined here (some are method-specific):\n\n* **model**: the model to which this action applies.\n* **attr**: the attribute of the model to which this action applies.\n* **new_value** (only **bip_area** and **bip_text**): the new value with which to fill the BIP field.\n* **name** (only **bip_select**): the name to select from the dropdown selector.\n\n---\n\n## Authors, License and Stuff\n\nCode by [Bernat Farrero](http://bernatfarrero.com) from [Itnig Web Services](http://itnig.net) (it was based on the [original project](http://github.com/janv/rest_in_place/) of Jan Varwig) and released under [MIT license](http://www.opensource.org/licenses/mit-license.php).\n\nMany thanks to the contributors: [Roger Campos](http://github.com/rogercampos), [Jack Senechal](https://github.com/jacksenechal) and [Albert Bellonch](https://github.com/albertbellonch).\n","readmeFilename":"README.md"}