├── .gitignore ├── LICENSE ├── README.md ├── README.rst ├── build.sh ├── django_jsoneditor ├── __init__.py ├── settings.py ├── settings_testapp1.py ├── settings_testapp2.py ├── urls.py └── wsgi.py ├── jsoneditor ├── __init__.py ├── fields │ ├── __init__.py │ ├── django3_jsonfield.py │ ├── django_extensions_jsonfield.py │ ├── django_json_field.py │ ├── django_jsonfield.py │ ├── jsonfield.py │ └── postgres_jsonfield.py ├── forms.py └── static │ ├── django-jsoneditor │ ├── ace_options.js │ ├── django-jsoneditor.css │ ├── django-jsoneditor.js │ └── init.js │ └── jsoneditor │ ├── img │ ├── jsoneditor-icons.png │ └── jsoneditor-icons.svg │ ├── jsoneditor.css │ └── jsoneditor.js ├── manage.py ├── setup.cfg ├── setup.py ├── testapp ├── __init__.py ├── admin.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── tests.py └── views.py └── testapp2 ├── __init__.py ├── admin.py ├── migrations ├── 0001_initial.py └── __init__.py ├── models.py ├── tests.py └── views.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # Database 60 | *.sqlite3 61 | 62 | # IntelliJ 63 | *.idea 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django-JSONEditor 2 | 3 | Django-JSONEditor is an online structured JSON input widget for Django appropriate for various JSONField's provided for Django. 4 | 5 | Code of the javascript JSONEditor online editor has been got from the http://jsoneditoronline.org/. 6 | 7 | See the latest versions of the javascript online JSON Editor here: https://github.com/josdejong/jsoneditor 8 | 9 | Sample views: 10 | 11 | json editor 12 | 13 | ## Installation 14 | 15 | ### Latest version from the GIT repository:: 16 | 17 | pip install "git+git://github.com/nnseva/django-jsoneditor.git" 18 | 19 | ### Stable version from the PyPi repository:: 20 | 21 | pip install django-jsoneditor 22 | 23 | Note that you should use one of original JSONField packages to provide the JSONField itself. 24 | 25 | ## Configuration 26 | 27 | You **should** append `jsoneditor` into the `INSTALLED_APPS` of your `settings.py` file: 28 | ```python 29 | INSTALLED_APPS = ( 30 | # ... 31 | 'jsoneditor', 32 | # ... 33 | ) 34 | ``` 35 | 36 | You **can** use CDN repositories to get JSONEditor javascript code, or host it yourself, instead of the packaged one using the following two settings in your `settings.py` file: 37 | ```python 38 | JSON_EDITOR_JS = 'whatever-your-want.js' 39 | JSON_EDITOR_CSS = 'whatever-your-want.css' 40 | ``` 41 | 42 | Just look to the http://cdnjs.com/libraries/jsoneditor and select the preferred one, like: 43 | ```python 44 | JSON_EDITOR_JS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/8.6.4/jsoneditor.js' 45 | JSON_EDITOR_CSS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/8.6.4/jsoneditor.css' 46 | ``` 47 | 48 | ### Custom JSONEditor initialization 49 | You **can** change initial parameters for the `jsoneditor.JSONEditor` 50 | *javascript* constructor initial call for your own purposes using 51 | `JSON_EDITOR_INIT_JS` settings. Copy the `jsoneditor/static/django-jsoneditor/init.js` 52 | file to your own static storage, change initial values of the 53 | `django_jsoneditor_init` object and setup the `JSON_EDITOR_INIT_JS` 54 | variable of the `settings` file to point your own modified copy of the 55 | file. 56 | 57 | **Note** that the django original static file subsystem is used to 58 | refer to the init file. 59 | 60 | For example, let's say your project has a `myapp` application, 61 | and you would like to init all available modes of the JSONEditor 62 | instead of two allowed by default. 63 | 64 | * copy the `jsoneditor/static/django-jsoneditor/init.js` to `myapp/static/jsoneditor-init.js` file 65 | * change content of the `myapp/static/jsoneditor-init.js` to: 66 | ```javascript 67 | django_jsoneditor_init = { 68 | mode: 'tree', 69 | modes: ['code', 'form', 'text', 'tree', 'view'] // all modes 70 | } 71 | ``` 72 | * insert into your `settings.py` file the following code: 73 | ```python 74 | JSON_EDITOR_INIT_JS = "jsoneditor-init.js" 75 | ``` 76 | (**note** that the static file subsystem refers to static files without `static` prefix) 77 | 78 | You can extend the `JSON_EDITOR_INIT_JS` file as you wish; it will be used on every 79 | page where the `JSONEditor` widget is used just before the `django-jsonfield.js` file. 80 | 81 | ### Custom Ace initialization 82 | In the same fashion, you can also set options for the Ace editor that is initialized when either 83 | starting with or switching to 'code' mode. These options can be found here: 84 | https://github.com/ajaxorg/ace/wiki/Configuring-Ace. This can for example come in handy when 85 | wanting to customize for example the height or looks of the editor. The default of this file can be 86 | found in `jsoneditor/static/django-jsoneditor/ace_options.js`, which is empty. A custom one can be 87 | pointed to by adding the following line to your `settings.py`: 88 | ```python 89 | JSON_EDITOR_ACE_OPTIONS_JS = "[your_ace_options_file].js" 90 | ``` 91 | 92 | ### Per-field customization 93 | You can also override JSONEditor and Ace initialization on a per-field basis. To do this, pass the 94 | desired `init_options` and/or `ace_option` to the widget's initializer. For example, let's 95 | say you want to make a certain field read-only: 96 | 97 | ```python 98 | from django.contrib import admin 99 | from django.db.models.fields.json import JSONField 100 | from jsoneditor.forms import JSONEditor 101 | 102 | 103 | class MyAdmin(admin.ModelAdmin): 104 | formfield_overrides = { 105 | JSONField: { 106 | "widget": JSONEditor( 107 | init_options={"mode": "view", "modes": ["view", "code", "tree"]}, 108 | ace_options={"readOnly": True}, 109 | ) 110 | } 111 | } 112 | ``` 113 | 114 | These values will override any project-level options in the custom javascript files described above. 115 | 116 | 117 | ## Use 118 | 119 | You can use the JSONEditor widget for fields in selected Admin classes like: 120 | 121 | admin.py: 122 | ```python 123 | from django.contrib import admin 124 | from django.db.models.fields.json import JSONField 125 | from jsoneditor.forms import JSONEditor 126 | 127 | 128 | class MyAdmin(admin.ModelAdmin): 129 | formfield_overrides = { 130 | JSONField: {'widget': JSONEditor}, 131 | } 132 | ``` 133 | 134 | Or use the original JSONField implementation fixed by the package. 135 | 136 | Right now there are the following fixed implementations: 137 | 138 | * `jsoneditor.fields.django_json_field.JSONField` replaces a `JSONField` from https://github.com/derek-schaefer/django-json-field (**NOTE** the package is not compatible with django v.1.9) 139 | * `jsoneditor.fields.django_jsonfield.JSONField` replaces a `JSONField` from https://launchpad.net/django-jsonfield package 140 | * `jsoneditor.fields.postgres_jsonfield.JSONField` replaces `django.contrib.postgres.fields.JSONField` (**NOTE** this field type appears only from django v.1.9) 141 | * `jsoneditor.fields.django_extensions_jsonfield.JSONField` replaces `django_extensions.db.fields.json.JSONField` 142 | * `jsoneditor.fields.jsonfield` has been added for people using https://github.com/rpkilby/jsonfield (the https://github.com/bradjasper/django-jsonfield now redirects there) 143 | * `jsoneditor.fields.django3_jsonfield` uses the standard JSONField and JSONFormField provided by Django 3+ 144 | 145 | To use the fixed implementation instead of the original one, just replace your import with the desired one. For example, for Django 3.0 and above: 146 | 147 | models.py: 148 | ```python 149 | from django.db import models 150 | 151 | # from json_field import JSONField replaced by: 152 | from jsoneditor.fields.django3_jsonfield import JSONField 153 | # Create your models here. 154 | 155 | class TestModel(models.Model): 156 | my_field = JSONField() 157 | ``` 158 | 159 | You can access the underlying ``JSONEditor`` JS objects in your JavaScript via dictionary named ``jsonEditors``. This dictionary's keys are the IDs of the fields generated by this component in the form: ``"id"+[your form field name]+"_json_jsoneditor"``, e.g. ``id_template_parameters_json_jsoneditor``. The values in the dictionary are the instances of the correspondent JSONEditor objects. 160 | 161 | 162 | ## Jsonschema 163 | 164 | You can pass a jsonschema as an arguement to `JSONEditor` widget so that 165 | jsoneditor can validate user inputs. Example: 166 | 167 | ``` python 168 | from django import forms 169 | from jsoneditor.forms import JSONEditor 170 | 171 | class MyAdmin(admin.ModelAdmin): 172 | def formfield_for_dbfield(self, db_field, request, **kwargs): 173 | field = super().formfield_for_dbfield(db_field, request, **kwargs) 174 | if isinstance(field, forms.fields.JSONField): 175 | field.widget = JSONEditor(jsonschema={ 176 | "type": "array", 177 | "items": { 178 | "type": "string" 179 | } 180 | }) 181 | return field 182 | 183 | ``` 184 | 185 | ## Custom Style 186 | 187 | You can pass the style in attrs params for `JSONEditor` widget so that 188 | jsoneditor render with the style what you setup. Example: 189 | 190 | ``` python 191 | from json_field import JSONField 192 | from jsoneditor.forms import JSONEditor 193 | 194 | class MyAdmin(admin.ModelAdmin): 195 | formfield_overrides = { 196 | JSONField: {'widget': JSONEditor(attrs={'style': 'width: 620px;'})} 197 | } 198 | ``` 199 | ## Custom Encoders 200 | 201 | There are situations where you may prefer to use a custom [JSONEncoder](https://docs.python.org/3/library/json.html#json.JSONEncoder) class. For example, you may want to use Django's [DjangoJSONEncoder](https://docs.djangoproject.com/en/4.1/topics/serialization/#djangojsonencoder) to handle timestamps in a Django-friendly way. You can do this by passing the `encoder` param as an initialization argument. 202 | 203 | ``` python 204 | from django.core.serializers.json import DjangoJSONEncoder 205 | 206 | class MyAdmin(admin.ModelAdmin): 207 | formfield_overrides = { 208 | JSONField: {'widget': JSONEditor(encoder=DjangoJSONEncoder)} # will now encode/decode python datetime and timestamp objects! 209 | } 210 | ``` 211 | 212 | ## Collecting bounties 213 | 214 | You are free to give some bounties on https://www.bountysource.com/ to force solving existent or new issues 215 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Django-JSONEditor 2 | =================== 3 | 4 | Django-JSONEditor is an online structured JSON input widget for Django appropriate for various JSONField's provided for Django. 5 | 6 | Code of the javascript JSONEditor online editor has been got from the http://jsoneditoronline.org/. 7 | 8 | See the latest versions of the javascript online JSON Editor here: https://github.com/josdejong/jsoneditor 9 | 10 | Sample views: 11 | 12 | .. image:: https://raw.github.com/josdejong/jsoneditor/master/misc/jsoneditor.png 13 | 14 | Installation 15 | ------------ 16 | Latest version from the GIT repository:: 17 | 18 | pip install "git+git://github.com/nnseva/django-jsoneditor.git" 19 | 20 | Stable version from the PyPi repository:: 21 | 22 | pip install django-jsoneditor 23 | 24 | See all details on https://github.com/nnseva/django-jsoneditor 25 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -r dist/* 4 | python setup.py sdist bdist_wheel 5 | twine upload dist/* 6 | -------------------------------------------------------------------------------- /django_jsoneditor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnseva/django-jsoneditor/dfc1ad59ef7da77c754a1beb31f07417e2a3a334/django_jsoneditor/__init__.py -------------------------------------------------------------------------------- /django_jsoneditor/settings.py: -------------------------------------------------------------------------------- 1 | settings_testapp1.py -------------------------------------------------------------------------------- /django_jsoneditor/settings_testapp1.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for django_jsoneditor project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.8.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.8/ref/settings/ 11 | """ 12 | 13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 14 | import os 15 | 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '1@5n@*f2ng(+il*9im)f$ie8lpc)c3an!3-3z2f9cwn*=6pzvc' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [ 29 | 'django-jsoneditor-nnseva.c9users.io', 30 | '127.0.0.1', 31 | ] 32 | SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') 33 | 34 | 35 | # Application definition 36 | 37 | INSTALLED_APPS = ( 38 | 'testapp', 39 | 40 | 'jsoneditor', 41 | 42 | 'django.contrib.admin', 43 | 'django.contrib.auth', 44 | 'django.contrib.contenttypes', 45 | 'django.contrib.sessions', 46 | 'django.contrib.messages', 47 | 'django.contrib.staticfiles', 48 | ) 49 | 50 | MIDDLEWARE_CLASSES = ( 51 | 'django.contrib.sessions.middleware.SessionMiddleware', 52 | 'django.middleware.common.CommonMiddleware', 53 | 'django.middleware.csrf.CsrfViewMiddleware', 54 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 55 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 56 | 'django.contrib.messages.middleware.MessageMiddleware', 57 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 58 | 'django.middleware.security.SecurityMiddleware', 59 | ) 60 | 61 | MIDDLEWARE = ( 62 | 'django.middleware.security.SecurityMiddleware', 63 | 'django.contrib.sessions.middleware.SessionMiddleware', 64 | 'django.middleware.common.CommonMiddleware', 65 | 'django.middleware.csrf.CsrfViewMiddleware', 66 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 67 | 'django.contrib.messages.middleware.MessageMiddleware', 68 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 69 | ) 70 | 71 | ROOT_URLCONF = 'django_jsoneditor.urls' 72 | 73 | TEMPLATES = [ 74 | { 75 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 76 | 'DIRS': [], 77 | 'APP_DIRS': True, 78 | 'OPTIONS': { 79 | 'context_processors': [ 80 | 'django.template.context_processors.debug', 81 | 'django.template.context_processors.request', 82 | 'django.contrib.auth.context_processors.auth', 83 | 'django.contrib.messages.context_processors.messages', 84 | ], 85 | }, 86 | }, 87 | ] 88 | 89 | WSGI_APPLICATION = 'django_jsoneditor.wsgi.application' 90 | 91 | 92 | # Database 93 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 94 | 95 | DATABASES = { 96 | 'default': { 97 | 'ENGINE': 'django.db.backends.sqlite3', 98 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 99 | } 100 | } 101 | 102 | # Internationalization 103 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 104 | 105 | LANGUAGE_CODE = 'en-us' 106 | 107 | TIME_ZONE = 'UTC' 108 | 109 | USE_I18N = True 110 | 111 | USE_L10N = True 112 | 113 | USE_TZ = True 114 | 115 | 116 | # Static files (CSS, JavaScript, Images) 117 | # https://docs.djangoproject.com/en/1.8/howto/static-files/ 118 | 119 | STATIC_URL = '/static/' 120 | 121 | #JSON_EDITOR_JS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/5.26.2/jsoneditor.js' 122 | #JSON_EDITOR_CSS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/5.26.2/jsoneditor.css' 123 | 124 | #JSON_EDITOR_JS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/5.13.3/jsoneditor.js' 125 | #JSON_EDITOR_CSS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/5.13.3/jsoneditor.css' 126 | -------------------------------------------------------------------------------- /django_jsoneditor/settings_testapp2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for django_jsoneditor project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.8.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.8/ref/settings/ 11 | """ 12 | 13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 14 | import os 15 | 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '1@5n@*f2ng(+il*9im)f$ie8lpc)c3an!3-3z2f9cwn*=6pzvc' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [ 29 | 'django-jsoneditor-nnseva.c9users.io', 30 | '127.0.0.1', 31 | ] 32 | SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') 33 | 34 | 35 | # Application definition 36 | 37 | INSTALLED_APPS = ( 38 | 'testapp2', 39 | 40 | 'jsoneditor', 41 | 42 | 'django.contrib.admin', 43 | 'django.contrib.auth', 44 | 'django.contrib.contenttypes', 45 | 'django.contrib.sessions', 46 | 'django.contrib.messages', 47 | 'django.contrib.staticfiles', 48 | ) 49 | 50 | MIDDLEWARE = ( 51 | 'django.contrib.sessions.middleware.SessionMiddleware', 52 | 'django.middleware.common.CommonMiddleware', 53 | 'django.middleware.csrf.CsrfViewMiddleware', 54 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 55 | 'django.contrib.messages.middleware.MessageMiddleware', 56 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 57 | 'django.middleware.security.SecurityMiddleware', 58 | ) 59 | 60 | ROOT_URLCONF = 'django_jsoneditor.urls' 61 | 62 | TEMPLATES = [ 63 | { 64 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 65 | 'DIRS': [], 66 | 'APP_DIRS': True, 67 | 'OPTIONS': { 68 | 'context_processors': [ 69 | 'django.template.context_processors.debug', 70 | 'django.template.context_processors.request', 71 | 'django.contrib.auth.context_processors.auth', 72 | 'django.contrib.messages.context_processors.messages', 73 | ], 74 | }, 75 | }, 76 | ] 77 | 78 | WSGI_APPLICATION = 'django_jsoneditor.wsgi.application' 79 | 80 | 81 | # Database 82 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 83 | 84 | DATABASES = { 85 | 'default': { 86 | 'ENGINE': 'django.db.backends.sqlite3', 87 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 88 | } 89 | } 90 | 91 | # Internationalization 92 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 93 | 94 | LANGUAGE_CODE = 'en-us' 95 | 96 | TIME_ZONE = 'UTC' 97 | 98 | USE_I18N = True 99 | 100 | USE_L10N = True 101 | 102 | USE_TZ = True 103 | 104 | 105 | # Static files (CSS, JavaScript, Images) 106 | # https://docs.djangoproject.com/en/1.8/howto/static-files/ 107 | 108 | STATIC_URL = '/static/' 109 | -------------------------------------------------------------------------------- /django_jsoneditor/urls.py: -------------------------------------------------------------------------------- 1 | """django_jsoninput URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.8/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Add an import: from blog import urls as blog_urls 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 15 | """ 16 | from django.urls import include, re_path 17 | from django.contrib import admin 18 | 19 | urlpatterns = [ 20 | re_path(r'^admin/', admin.site.urls), 21 | ] 22 | -------------------------------------------------------------------------------- /django_jsoneditor/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for django_jsoninput project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_jsoneditor.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /jsoneditor/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.2.4" 2 | -------------------------------------------------------------------------------- /jsoneditor/fields/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnseva/django-jsoneditor/dfc1ad59ef7da77c754a1beb31f07417e2a3a334/jsoneditor/fields/__init__.py -------------------------------------------------------------------------------- /jsoneditor/fields/django3_jsonfield.py: -------------------------------------------------------------------------------- 1 | from django.db.models import JSONField as _JSONField 2 | from django.forms import JSONField as _JSONFormField 3 | 4 | from jsoneditor.forms import JSONEditor 5 | 6 | class JSONFormField(_JSONFormField): 7 | widget = JSONEditor 8 | def __init__(self,*av,**kw): 9 | kw['widget'] = self.widget # force avoiding widget override 10 | super(JSONFormField,self).__init__(*av,**kw) 11 | 12 | class JSONField(_JSONField): 13 | def formfield(self, **kwargs): 14 | defaults = { 15 | 'form_class': kwargs.get('form_class', JSONFormField), 16 | } 17 | defaults.update(kwargs) 18 | return super(JSONField, self).formfield(**defaults) 19 | -------------------------------------------------------------------------------- /jsoneditor/fields/django_extensions_jsonfield.py: -------------------------------------------------------------------------------- 1 | from django_extensions.db.fields.json import JSONField as _JSONField 2 | from django import forms 3 | from django.core.exceptions import ValidationError 4 | 5 | from jsoneditor.forms import JSONEditor 6 | 7 | import json 8 | import six 9 | 10 | class JSONFormField(forms.CharField): 11 | widget = JSONEditor 12 | def __init__(self,*av,**kw): 13 | kw['widget'] = self.widget # force avoiding widget override 14 | super(JSONFormField,self).__init__(*av,**kw) 15 | 16 | class JSONField(_JSONField): 17 | def formfield(self, **kwargs): 18 | defaults = { 19 | 'form_class': kwargs.get('form_class', JSONFormField), 20 | } 21 | defaults.update(kwargs) 22 | return super(JSONField, self).formfield(**defaults) 23 | 24 | def to_python(self, value): 25 | if isinstance(value, six.string_types): 26 | try: 27 | json.loads(value) 28 | except json.decoder.JSONDecodeError as ex: 29 | raise ValidationError(ex) 30 | return super(JSONField, self).to_python(value) 31 | -------------------------------------------------------------------------------- /jsoneditor/fields/django_json_field.py: -------------------------------------------------------------------------------- 1 | from json_field import JSONField as _JSONField 2 | from json_field.forms import JSONFormField as _JSONFormField 3 | 4 | from jsoneditor.forms import JSONEditor 5 | 6 | class JSONFormField(_JSONFormField): 7 | widget = JSONEditor 8 | def __init__(self,*av,**kw): 9 | kw['widget'] = self.widget # force avoiding widget override 10 | super(JSONFormField,self).__init__(*av,**kw) 11 | 12 | class JSONField(_JSONField): 13 | def formfield(self, **kwargs): 14 | defaults = { 15 | 'form_class': kwargs.get('form_class', JSONFormField), 16 | } 17 | defaults.update(kwargs) 18 | return super(JSONField, self).formfield(**defaults) 19 | -------------------------------------------------------------------------------- /jsoneditor/fields/django_jsonfield.py: -------------------------------------------------------------------------------- 1 | from jsonfield import JSONField as _JSONField 2 | from jsonfield.fields import JSONFormField as _JSONFormField 3 | 4 | from jsoneditor.forms import JSONEditor 5 | 6 | class JSONFormField(_JSONFormField): 7 | widget = JSONEditor 8 | def __init__(self,*av,**kw): 9 | kw['widget'] = self.widget # force avoiding widget override 10 | super(JSONFormField,self).__init__(*av,**kw) 11 | 12 | class JSONField(_JSONField): 13 | def formfield(self, **kwargs): 14 | defaults = { 15 | 'form_class': kwargs.get('form_class', JSONFormField), 16 | } 17 | defaults.update(kwargs) 18 | return super(JSONField, self).formfield(**defaults) 19 | -------------------------------------------------------------------------------- /jsoneditor/fields/jsonfield.py: -------------------------------------------------------------------------------- 1 | from jsonfield import JSONField as _JSONField 2 | from jsonfield.forms import JSONField as _JSONFormField 3 | 4 | from jsoneditor.forms import JSONEditor 5 | 6 | class JSONFormField(_JSONFormField): 7 | widget = JSONEditor 8 | def __init__(self,*av,**kw): 9 | kw['widget'] = self.widget # force avoiding widget override 10 | super(JSONFormField,self).__init__(*av,**kw) 11 | 12 | class JSONField(_JSONField): 13 | def formfield(self, **kwargs): 14 | defaults = { 15 | 'form_class': kwargs.get('form_class', JSONFormField), 16 | } 17 | defaults.update(kwargs) 18 | return super(JSONField, self).formfield(**defaults) 19 | -------------------------------------------------------------------------------- /jsoneditor/fields/postgres_jsonfield.py: -------------------------------------------------------------------------------- 1 | from django.contrib.postgres.fields import JSONField as _JSONField 2 | from django.contrib.postgres.forms import JSONField as _JSONFormField 3 | 4 | from jsoneditor.forms import JSONEditor 5 | 6 | class JSONFormField(_JSONFormField): 7 | widget = JSONEditor 8 | def __init__(self,*av,**kw): 9 | kw['widget'] = self.widget # force avoiding widget override 10 | super(JSONFormField,self).__init__(*av,**kw) 11 | 12 | class JSONField(_JSONField): 13 | def formfield(self, **kwargs): 14 | defaults = { 15 | 'form_class': kwargs.get('form_class', JSONFormField), 16 | } 17 | defaults.update(kwargs) 18 | return super(JSONField, self).formfield(**defaults) 19 | -------------------------------------------------------------------------------- /jsoneditor/forms.py: -------------------------------------------------------------------------------- 1 | import json 2 | from packaging import version 3 | 4 | import django 5 | from django.conf import settings 6 | from django.forms.widgets import Textarea 7 | from django.utils.safestring import mark_safe 8 | from django.core.serializers.json import DjangoJSONEncoder 9 | 10 | 11 | try: 12 | from django.forms.util import flatatt 13 | except ImportError: 14 | from django.forms.utils import flatatt 15 | 16 | try: 17 | unicode = unicode 18 | except NameError: 19 | # 'unicode' is undefined, must be Python 3 20 | str = str 21 | unicode = str 22 | bytes = bytes 23 | basestring = (str, bytes) 24 | else: 25 | # 'unicode' exists, must be Python 2 26 | str = str 27 | unicode = unicode 28 | bytes = str 29 | basestring = basestring 30 | 31 | 32 | class JSONEditor(Textarea): 33 | class Media: 34 | js = ( 35 | 'admin/js/vendor/jquery/jquery.js', 36 | 'admin/js/jquery.init.js', 37 | getattr(settings, "JSON_EDITOR_JS", 'jsoneditor/jsoneditor.js'), 38 | getattr(settings, "JSON_EDITOR_ACE_OPTIONS_JS", 'django-jsoneditor/ace_options.js'), 39 | getattr(settings, "JSON_EDITOR_INIT_JS", 'django-jsoneditor/init.js'), 40 | 'django-jsoneditor/django-jsoneditor.js', 41 | ) 42 | css = { 43 | 'all': ( 44 | getattr(settings, "JSON_EDITOR_CSS", 'jsoneditor/jsoneditor.css'), 45 | 'django-jsoneditor/django-jsoneditor.css', 46 | ) 47 | } 48 | 49 | def __init__(self, *args, **kwargs): 50 | self.jsonschema = kwargs.pop('jsonschema', None) 51 | self.init_options = kwargs.pop('init_options', None) 52 | self.ace_options = kwargs.pop('ace_options', None) 53 | self.encoder = kwargs.pop("encoder", None) 54 | super().__init__(*args, **kwargs) 55 | 56 | def render(self, name, value, attrs=None, renderer=None): 57 | attrs['jsonschema'] = json.dumps(self.jsonschema) 58 | attrs['init_options'] = json.dumps(self.init_options) 59 | attrs['ace_options'] = json.dumps(self.ace_options) 60 | 61 | if not isinstance(value, basestring): 62 | value = json.dumps(value, cls=self.encoder) 63 | 64 | input_attrs = {'hidden': True} 65 | input_attrs.update(attrs) 66 | if 'class' not in input_attrs: 67 | input_attrs['class'] = 'for_jsoneditor' 68 | else: 69 | input_attrs['class'] += ' for_jsoneditor' 70 | r = super(JSONEditor, self).render(name, value, input_attrs) 71 | div_attrs = {} 72 | div_attrs.update(attrs) 73 | div_attrs.update({'id': (attrs['id'] + '_jsoneditor')}) 74 | if version.parse(django.get_version()) >= version.parse("1.11"): 75 | final_attrs = self.build_attrs(div_attrs, extra_attrs={'name': name}) 76 | else: 77 | final_attrs = self.build_attrs(div_attrs, name=name) 78 | r += ''' 79 |
80 | ''' % { 81 | 'attrs': flatatt(final_attrs), 82 | } 83 | return mark_safe(r) 84 | -------------------------------------------------------------------------------- /jsoneditor/static/django-jsoneditor/ace_options.js: -------------------------------------------------------------------------------- 1 | django_jsoneditor_ace_options = { 2 | }; -------------------------------------------------------------------------------- /jsoneditor/static/django-jsoneditor/django-jsoneditor.css: -------------------------------------------------------------------------------- 1 | div .outer_jsoneditor { 2 | float: left; 3 | width: 100%; 4 | resize: both; 5 | overflow: auto; 6 | max-width: 100%; 7 | } 8 | -------------------------------------------------------------------------------- /jsoneditor/static/django-jsoneditor/django-jsoneditor.js: -------------------------------------------------------------------------------- 1 | var jsonEditors = {}; 2 | 3 | django.jQuery(function () { 4 | if (typeof(jsoneditor) == "undefined") 5 | jsoneditor = {JSONEditor: JSONEditor}; 6 | setInterval(function () { 7 | var fields = django.jQuery(".for_jsoneditor"); 8 | for (var i = 0; i < fields.length; i++) { 9 | var $f = django.jQuery(fields[i]); 10 | var id = $f.attr("id") + "_jsoneditor"; 11 | var name = $f.attr("name") + "_jsoneditor"; 12 | var $nxt = $f.parent().find('#' + id); 13 | if ($nxt.attr("name") == name) { 14 | continue; 15 | } 16 | var value = $f[0].value; 17 | var style = $f.attr("style"); 18 | var disabled = $f.is(':disabled'); 19 | var jsonschema = JSON.parse($f.attr("jsonschema")); 20 | var initOverrides = JSON.parse($f.attr("init_options")); 21 | var aceOverrides = JSON.parse($f.attr("ace_options")); 22 | 23 | $nxt.detach(); 24 | if (style) { 25 | $nxt = django.jQuery('
'); 26 | } else { 27 | $nxt = django.jQuery('
'); 28 | } 29 | $f.parent().append($nxt); 30 | var fnc = function (f, nxt, value) { 31 | var initOptions = Object.assign({}, initOverrides ? initOverrides : django_jsoneditor_init); 32 | initOptions['schema'] = jsonschema; 33 | 34 | var editor = new jsoneditor.JSONEditor(nxt, Object.assign({ 35 | onChange: function () { 36 | f.value = editor.getText(); 37 | }, 38 | // If switching to code mode, properly initialize with ace options 39 | onModeChange: function(endMode, startMode) { 40 | if (endMode == 'code') { 41 | editor.aceEditor.setOptions(aceOverrides ? aceOverrides : django_jsoneditor_ace_options); 42 | } 43 | }, 44 | onEditable: function() { 45 | return !disabled; 46 | } 47 | }, initOptions)); 48 | 49 | // Load the editor. 50 | try { 51 | editor.set(JSON.parse(value)); 52 | } catch (e) { 53 | // Force editor mode to "code" if there are JSON parse errors. 54 | editor.setMode('code'); 55 | 56 | // Initialise contents of form even on unparseable JSON on load 57 | editor.setText(value); 58 | } 59 | 60 | // If initialized in code mode, set ace options right away 61 | if (editor.mode == 'code') { 62 | editor.aceEditor.setOptions(django_jsoneditor_ace_options); 63 | 64 | // Format the code on first load 65 | editor.format(); 66 | } 67 | 68 | return editor; 69 | }; 70 | jsonEditors[id] = fnc($f[0], $nxt[0], value); 71 | } 72 | }, 10); 73 | }); 74 | -------------------------------------------------------------------------------- /jsoneditor/static/django-jsoneditor/init.js: -------------------------------------------------------------------------------- 1 | django_jsoneditor_init = { 2 | mode: 'tree', 3 | // modes: ['code', 'form', 'text', 'tree', 'view'], // all modes 4 | modes: ['code', 'tree'], // allowed modes 5 | } -------------------------------------------------------------------------------- /jsoneditor/static/jsoneditor/img/jsoneditor-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnseva/django-jsoneditor/dfc1ad59ef7da77c754a1beb31f07417e2a3a334/jsoneditor/static/jsoneditor/img/jsoneditor-icons.png -------------------------------------------------------------------------------- /jsoneditor/static/jsoneditor/img/jsoneditor-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | JSON Editor Icons 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | JSON Editor Icons 27 | 28 | 29 | 30 | 32 | 56 | 60 | 61 | 62 | 69 | 76 | 83 | 90 | 97 | 100 | 107 | 114 | 115 | 119 | 126 | 133 | 134 | 141 | 148 | 155 | 157 | 164 | 171 | 178 | 179 | 182 | 189 | 196 | 203 | 204 | 211 | 217 | 223 | 230 | 235 | 240 | 247 | 253 | 258 | 265 | 271 | 277 | 284 | 291 | 298 | 305 | 312 | 319 | 326 | 332 | 340 | 346 | 352 | 359 | 367 | 375 | 382 | 389 | 396 | 403 | 410 | 417 | 424 | 431 | 437 | 445 | 451 | 457 | 464 | 472 | 480 | 487 | 494 | 501 | 508 | 515 | 522 | 529 | 536 | 541 | 546 | 551 | 557 | 563 | 568 | 573 | 578 | 583 | 588 | 604 | 621 | 638 | 655 | 661 | 667 | 673 | 679 | 686 | 692 | 695 | 702 | 709 | 716 | 723 | 729 | 730 | 736 | 737 | -------------------------------------------------------------------------------- /jsoneditor/static/jsoneditor/jsoneditor.css: -------------------------------------------------------------------------------- 1 | /* reset styling (prevent conflicts with bootstrap, materialize.css, etc.) */ 2 | 3 | div.jsoneditor .jsoneditor-search input { 4 | height: auto; 5 | border: inherit; 6 | } 7 | 8 | div.jsoneditor .jsoneditor-search input:focus { 9 | border: none !important; 10 | box-shadow: none !important; 11 | } 12 | 13 | div.jsoneditor table { 14 | border-collapse: collapse; 15 | width: auto; 16 | } 17 | 18 | div.jsoneditor td, 19 | div.jsoneditor th { 20 | padding: 0; 21 | display: table-cell; 22 | text-align: left; 23 | vertical-align: inherit; 24 | border-radius: inherit; 25 | } 26 | 27 | 28 | div.jsoneditor-field, 29 | div.jsoneditor-value, 30 | div.jsoneditor-readonly, 31 | div.jsoneditor-default { 32 | border: 1px solid transparent; 33 | min-height: 16px; 34 | min-width: 32px; 35 | padding: 2px; 36 | margin: 1px; 37 | word-wrap: break-word; 38 | float: left; 39 | } 40 | 41 | /* adjust margin of p elements inside editable divs, needed for Opera, IE */ 42 | 43 | div.jsoneditor-field p, 44 | div.jsoneditor-value p { 45 | margin: 0; 46 | } 47 | 48 | div.jsoneditor-value { 49 | word-break: break-word; 50 | } 51 | 52 | div.jsoneditor-readonly { 53 | min-width: 16px; 54 | color: #808080; 55 | } 56 | 57 | div.jsoneditor-empty { 58 | border-color: #d3d3d3; 59 | border-style: dashed; 60 | border-radius: 2px; 61 | } 62 | 63 | div.jsoneditor-field.jsoneditor-empty::after, 64 | div.jsoneditor-value.jsoneditor-empty::after { 65 | pointer-events: none; 66 | color: #d3d3d3; 67 | font-size: 8pt; 68 | } 69 | 70 | div.jsoneditor-field.jsoneditor-empty::after { 71 | content: "field"; 72 | } 73 | 74 | div.jsoneditor-value.jsoneditor-empty::after { 75 | content: "value"; 76 | } 77 | 78 | div.jsoneditor-value.jsoneditor-url, 79 | a.jsoneditor-value.jsoneditor-url { 80 | color: green; 81 | text-decoration: underline; 82 | } 83 | 84 | a.jsoneditor-value.jsoneditor-url { 85 | display: inline-block; 86 | padding: 2px; 87 | margin: 2px; 88 | } 89 | 90 | a.jsoneditor-value.jsoneditor-url:hover, 91 | a.jsoneditor-value.jsoneditor-url:focus { 92 | color: #ee422e; 93 | } 94 | 95 | div.jsoneditor td.jsoneditor-separator { 96 | padding: 3px 0; 97 | vertical-align: top; 98 | color: #808080; 99 | } 100 | 101 | div.jsoneditor-field[contenteditable=true]:focus, 102 | div.jsoneditor-field[contenteditable=true]:hover, 103 | div.jsoneditor-value[contenteditable=true]:focus, 104 | div.jsoneditor-value[contenteditable=true]:hover, 105 | div.jsoneditor-field.jsoneditor-highlight, 106 | div.jsoneditor-value.jsoneditor-highlight { 107 | background-color: #FFFFAB; 108 | border: 1px solid yellow; 109 | border-radius: 2px; 110 | } 111 | 112 | div.jsoneditor-field.jsoneditor-highlight-active, 113 | div.jsoneditor-field.jsoneditor-highlight-active:focus, 114 | div.jsoneditor-field.jsoneditor-highlight-active:hover, 115 | div.jsoneditor-value.jsoneditor-highlight-active, 116 | div.jsoneditor-value.jsoneditor-highlight-active:focus, 117 | div.jsoneditor-value.jsoneditor-highlight-active:hover { 118 | background-color: #ffee00; 119 | border: 1px solid #ffc700; 120 | border-radius: 2px; 121 | } 122 | 123 | div.jsoneditor-value.jsoneditor-string { 124 | color: #006000; 125 | } 126 | 127 | div.jsoneditor-value.jsoneditor-object, 128 | div.jsoneditor-value.jsoneditor-array { 129 | min-width: 16px; 130 | } 131 | 132 | div.jsoneditor-value.jsoneditor-number { 133 | color: #ee422e; 134 | } 135 | 136 | div.jsoneditor-value.jsoneditor-boolean { 137 | color: #ff8c00; 138 | } 139 | 140 | div.jsoneditor-value.jsoneditor-null { 141 | color: #004ED0; 142 | } 143 | 144 | div.jsoneditor-value.jsoneditor-invalid { 145 | color: #000000; 146 | } 147 | 148 | div.jsoneditor-default { 149 | color: #808080; 150 | padding-left: 10px; 151 | } 152 | 153 | div.jsoneditor-tree button.jsoneditor-button { 154 | width: 24px; 155 | height: 24px; 156 | padding: 0; 157 | margin: 0; 158 | border: none; 159 | cursor: pointer; 160 | background: transparent url("img/jsoneditor-icons.svg"); 161 | } 162 | 163 | div.jsoneditor-mode-view tr.jsoneditor-expandable td.jsoneditor-tree, 164 | div.jsoneditor-mode-form tr.jsoneditor-expandable td.jsoneditor-tree { 165 | cursor: pointer; 166 | } 167 | 168 | div.jsoneditor-tree button.jsoneditor-collapsed { 169 | background-position: 0 -48px; 170 | } 171 | 172 | div.jsoneditor-tree button.jsoneditor-expanded { 173 | background-position: 0 -72px; 174 | } 175 | 176 | div.jsoneditor-tree button.jsoneditor-contextmenu { 177 | background-position: -48px -72px; 178 | } 179 | 180 | div.jsoneditor-tree button.jsoneditor-contextmenu:hover, 181 | div.jsoneditor-tree button.jsoneditor-contextmenu:focus, 182 | div.jsoneditor-tree button.jsoneditor-contextmenu.jsoneditor-selected, 183 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu { 184 | background-position: -48px -48px; 185 | } 186 | 187 | div.jsoneditor-tree *:focus { 188 | outline: none; 189 | } 190 | 191 | div.jsoneditor-tree button.jsoneditor-button:focus { 192 | /* TODO: nice outline for buttons with focus 193 | outline: #97B0F8 solid 2px; 194 | box-shadow: 0 0 8px #97B0F8; 195 | */ 196 | background-color: #f5f5f5; 197 | outline: #e5e5e5 solid 1px; 198 | } 199 | 200 | div.jsoneditor-tree button.jsoneditor-invisible { 201 | visibility: hidden; 202 | background: none; 203 | } 204 | 205 | div.jsoneditor-tree div.jsoneditor-show-more { 206 | display: inline-block; 207 | padding: 3px 4px; 208 | margin: 2px 0; 209 | background-color: #e5e5e5; 210 | border-radius: 3px; 211 | color: #808080; 212 | font-family: arial, sans-serif; 213 | font-size: 10pt; 214 | } 215 | 216 | div.jsoneditor-tree div.jsoneditor-show-more a { 217 | display: inline-block; 218 | color: #808080; 219 | } 220 | 221 | div.jsoneditor-tree div.jsoneditor-show-more a:hover, 222 | div.jsoneditor-tree div.jsoneditor-show-more a:focus { 223 | color: #ee422e; 224 | } 225 | 226 | div.jsoneditor-tree div.jsoneditor-color { 227 | display: inline-block; 228 | width: 12px; 229 | height: 12px; 230 | margin: 4px; 231 | border: 1px solid #808080; 232 | cursor: pointer; 233 | } 234 | 235 | div.jsoneditor div.jsoneditor-anchor .picker_wrapper.popup.popup_bottom { 236 | top: 28px; 237 | left: -10px; 238 | } 239 | 240 | div.jsoneditor-tree div.jsoneditor-date { 241 | background: #a1a1a1; 242 | color: white; 243 | font-family: arial, sans-serif; 244 | border-radius: 3px; 245 | display: inline-block; 246 | padding: 3px; 247 | margin: 0 3px; 248 | } 249 | 250 | div.jsoneditor { 251 | color: #1A1A1A; 252 | border: thin solid #3883fa; 253 | /* we use thin and not 1px to work around an issue in Chrome/IE, see #637 */ 254 | -moz-box-sizing: border-box; 255 | -webkit-box-sizing: border-box; 256 | box-sizing: border-box; 257 | width: 100%; 258 | height: 100%; 259 | position: relative; 260 | padding: 0; 261 | line-height: 100%; 262 | } 263 | 264 | div.jsoneditor-tree table.jsoneditor-tree { 265 | border-collapse: collapse; 266 | border-spacing: 0; 267 | width: 100%; 268 | } 269 | 270 | div.jsoneditor-outer { 271 | position: static; 272 | width: 100%; 273 | height: 100%; 274 | margin: 0; 275 | padding: 0; 276 | -moz-box-sizing: border-box; 277 | -webkit-box-sizing: border-box; 278 | box-sizing: border-box; 279 | } 280 | 281 | div.jsoneditor-outer.has-nav-bar { 282 | margin-top: -26px; 283 | padding-top: 26px; 284 | } 285 | 286 | div.jsoneditor-outer.has-status-bar { 287 | margin-bottom: -26px; 288 | padding-bottom: 26px; 289 | } 290 | 291 | div.jsoneditor-outer.has-main-menu-bar { 292 | margin-top: -35px; 293 | padding-top: 35px; 294 | } 295 | 296 | div.jsoneditor-outer.has-nav-bar.has-main-menu-bar { 297 | margin-top: -61px; 298 | padding-top: 61px; 299 | } 300 | 301 | textarea.jsoneditor-text, 302 | .ace-jsoneditor { 303 | min-height: 150px; 304 | } 305 | 306 | div.jsoneditor-tree { 307 | width: 100%; 308 | height: 100%; 309 | position: relative; 310 | overflow: auto; 311 | } 312 | 313 | textarea.jsoneditor-text { 314 | width: 100%; 315 | height: 100%; 316 | margin: 0; 317 | -moz-box-sizing: border-box; 318 | -webkit-box-sizing: border-box; 319 | box-sizing: border-box; 320 | outline-width: 0; 321 | border: none; 322 | background-color: white; 323 | resize: none; 324 | } 325 | 326 | tr.jsoneditor-highlight, 327 | tr.jsoneditor-selected { 328 | background-color: #d3d3d3; 329 | } 330 | 331 | tr.jsoneditor-selected button.jsoneditor-dragarea, 332 | tr.jsoneditor-selected button.jsoneditor-contextmenu { 333 | visibility: hidden; 334 | } 335 | 336 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea, 337 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu { 338 | visibility: visible; 339 | } 340 | 341 | div.jsoneditor-tree button.jsoneditor-dragarea { 342 | background: url("img/jsoneditor-icons.svg") -72px -72px; 343 | cursor: move; 344 | } 345 | 346 | div.jsoneditor-tree button.jsoneditor-dragarea:hover, 347 | div.jsoneditor-tree button.jsoneditor-dragarea:focus, 348 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea { 349 | background-position: -72px -48px; 350 | } 351 | 352 | div.jsoneditor tr, 353 | div.jsoneditor th, 354 | div.jsoneditor td { 355 | padding: 0; 356 | margin: 0; 357 | } 358 | 359 | div.jsoneditor td { 360 | vertical-align: top; 361 | } 362 | 363 | div.jsoneditor td.jsoneditor-tree { 364 | vertical-align: top; 365 | } 366 | 367 | div.jsoneditor-field, 368 | div.jsoneditor-value, 369 | div.jsoneditor td, 370 | div.jsoneditor th, 371 | div.jsoneditor textarea, 372 | .jsoneditor-schema-error { 373 | font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif; 374 | font-size: 10pt; 375 | color: #1A1A1A; 376 | } 377 | 378 | /* popover */ 379 | 380 | .jsoneditor-schema-error { 381 | cursor: default; 382 | display: inline-block; 383 | /*font-family: arial, sans-serif;*/ 384 | height: 24px; 385 | line-height: 24px; 386 | position: relative; 387 | text-align: center; 388 | width: 24px; 389 | } 390 | 391 | div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error { 392 | width: 24px; 393 | height: 24px; 394 | padding: 0; 395 | margin: 0 4px 0 0; 396 | background: url("img/jsoneditor-icons.svg") -168px -48px; 397 | } 398 | 399 | .jsoneditor-text-errors tr.jump-to-line:hover { 400 | text-decoration: underline; 401 | cursor: pointer; 402 | } 403 | 404 | .jsoneditor-schema-error .jsoneditor-popover { 405 | background-color: #4c4c4c; 406 | border-radius: 3px; 407 | box-shadow: 0 0 5px rgba(0,0,0,0.4); 408 | color: #fff; 409 | display: none; 410 | padding: 7px 10px; 411 | position: absolute; 412 | width: 200px; 413 | z-index: 4; 414 | } 415 | 416 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-above { 417 | bottom: 32px; 418 | left: -98px; 419 | } 420 | 421 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-below { 422 | top: 32px; 423 | left: -98px; 424 | } 425 | 426 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-left { 427 | top: -7px; 428 | right: 32px; 429 | } 430 | 431 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-right { 432 | top: -7px; 433 | left: 32px; 434 | } 435 | 436 | .jsoneditor-schema-error .jsoneditor-popover:before { 437 | border-right: 7px solid transparent; 438 | border-left: 7px solid transparent; 439 | content: ''; 440 | display: block; 441 | left: 50%; 442 | margin-left: -7px; 443 | position: absolute; 444 | } 445 | 446 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-above:before { 447 | border-top: 7px solid #4c4c4c; 448 | bottom: -7px; 449 | } 450 | 451 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-below:before { 452 | border-bottom: 7px solid #4c4c4c; 453 | top: -7px; 454 | } 455 | 456 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-left:before { 457 | border-left: 7px solid #4c4c4c; 458 | border-top: 7px solid transparent; 459 | border-bottom: 7px solid transparent; 460 | content: ''; 461 | top: 19px; 462 | right: -14px; 463 | left: inherit; 464 | margin-left: inherit; 465 | margin-top: -7px; 466 | position: absolute; 467 | } 468 | 469 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-right:before { 470 | border-right: 7px solid #4c4c4c; 471 | border-top: 7px solid transparent; 472 | border-bottom: 7px solid transparent; 473 | content: ''; 474 | top: 19px; 475 | left: -14px; 476 | margin-left: inherit; 477 | margin-top: -7px; 478 | position: absolute; 479 | } 480 | 481 | .jsoneditor-schema-error:hover .jsoneditor-popover, 482 | .jsoneditor-schema-error:focus .jsoneditor-popover { 483 | display: block; 484 | -webkit-animation: fade-in .3s linear 1, move-up .3s linear 1; 485 | -moz-animation: fade-in .3s linear 1, move-up .3s linear 1; 486 | -ms-animation: fade-in .3s linear 1, move-up .3s linear 1; 487 | } 488 | 489 | @-webkit-keyframes fade-in { 490 | from { 491 | opacity: 0; 492 | } 493 | 494 | to { 495 | opacity: 1; 496 | } 497 | } 498 | 499 | @-moz-keyframes fade-in { 500 | from { 501 | opacity: 0; 502 | } 503 | 504 | to { 505 | opacity: 1; 506 | } 507 | } 508 | 509 | @-ms-keyframes fade-in { 510 | from { 511 | opacity: 0; 512 | } 513 | 514 | to { 515 | opacity: 1; 516 | } 517 | } 518 | 519 | /*@-webkit-keyframes move-up {*/ 520 | 521 | /*from { bottom: 24px; }*/ 522 | 523 | /*to { bottom: 32px; }*/ 524 | 525 | /*}*/ 526 | 527 | /*@-moz-keyframes move-up {*/ 528 | 529 | /*from { bottom: 24px; }*/ 530 | 531 | /*to { bottom: 32px; }*/ 532 | 533 | /*}*/ 534 | 535 | /*@-ms-keyframes move-up {*/ 536 | 537 | /*from { bottom: 24px; }*/ 538 | 539 | /*to { bottom: 32px; }*/ 540 | 541 | /*}*/ 542 | 543 | /* JSON schema errors displayed at the bottom of the editor in mode text and code */ 544 | 545 | .jsoneditor .jsoneditor-validation-errors-container { 546 | max-height: 130px; 547 | overflow-y: auto; 548 | } 549 | 550 | .jsoneditor .jsoneditor-additional-errors { 551 | position: absolute; 552 | margin: auto; 553 | bottom: 31px; 554 | left: calc(50% - 92px); 555 | color: #808080; 556 | background-color: #ebebeb; 557 | padding: 7px 15px; 558 | border-radius: 8px; 559 | } 560 | 561 | .jsoneditor .jsoneditor-additional-errors.visible { 562 | visibility: visible; 563 | opacity: 1; 564 | transition: opacity 2s linear; 565 | } 566 | 567 | .jsoneditor .jsoneditor-additional-errors.hidden { 568 | visibility: hidden; 569 | opacity: 0; 570 | transition: visibility 0s 2s, opacity 2s linear; 571 | } 572 | 573 | .jsoneditor .jsoneditor-text-errors { 574 | width: 100%; 575 | border-collapse: collapse; 576 | border-top: 1px solid #ffd700; 577 | } 578 | 579 | .jsoneditor .jsoneditor-text-errors td { 580 | padding: 3px 6px; 581 | vertical-align: middle; 582 | } 583 | 584 | .jsoneditor .jsoneditor-text-errors tr { 585 | background-color: #ffef8b; 586 | } 587 | 588 | .jsoneditor .jsoneditor-text-errors tr.parse-error { 589 | background-color: #ee2e2e70; 590 | } 591 | 592 | .jsoneditor-text-errors .jsoneditor-schema-error { 593 | border: none; 594 | width: 24px; 595 | height: 24px; 596 | padding: 0; 597 | margin: 0 4px 0 0; 598 | cursor: pointer; 599 | } 600 | 601 | .jsoneditor-text-errors tr .jsoneditor-schema-error { 602 | background: url("img/jsoneditor-icons.svg") -168px -48px; 603 | } 604 | 605 | .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error { 606 | background: url("img/jsoneditor-icons.svg") -25px 0px; 607 | } 608 | 609 | .fadein { 610 | -webkit-animation: fadein .3s; 611 | animation: fadein .3s; 612 | -moz-animation: fadein .3s; 613 | -o-animation: fadein .3s; 614 | } 615 | 616 | @-webkit-keyframes fadein { 617 | 0% { 618 | opacity: 0; 619 | } 620 | 621 | 100% { 622 | opacity: 1; 623 | } 624 | } 625 | 626 | @-moz-keyframes fadein { 627 | 0% { 628 | opacity: 0; 629 | } 630 | 631 | 100% { 632 | opacity: 1; 633 | } 634 | } 635 | 636 | @keyframes fadein { 637 | 0% { 638 | opacity: 0; 639 | } 640 | 641 | 100% { 642 | opacity: 1; 643 | } 644 | } 645 | 646 | @-o-keyframes fadein { 647 | 0% { 648 | opacity: 0; 649 | } 650 | 651 | 100% { 652 | opacity: 1; 653 | } 654 | } 655 | /* ContextMenu - main menu */ 656 | 657 | div.jsoneditor-contextmenu-root { 658 | position: relative; 659 | width: 0; 660 | height: 0; 661 | } 662 | 663 | div.jsoneditor-contextmenu { 664 | position: absolute; 665 | box-sizing: content-box; 666 | z-index: 99999; 667 | } 668 | 669 | div.jsoneditor-contextmenu ul, 670 | div.jsoneditor-contextmenu li { 671 | box-sizing: content-box; 672 | position: relative; 673 | } 674 | 675 | div.jsoneditor-contextmenu ul { 676 | position: relative; 677 | left: 0; 678 | top: 0; 679 | width: 128px; 680 | background: white; 681 | border: 1px solid #d3d3d3; 682 | box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); 683 | list-style: none; 684 | margin: 0; 685 | padding: 0; 686 | } 687 | 688 | div.jsoneditor-contextmenu ul li button { 689 | position: relative; 690 | padding: 0 4px 0 0; 691 | margin: 0; 692 | width: 128px; 693 | height: auto; 694 | border: none; 695 | cursor: pointer; 696 | color: #4d4d4d; 697 | background: transparent; 698 | font-size: 10pt; 699 | font-family: arial, sans-serif; 700 | box-sizing: border-box; 701 | text-align: left; 702 | } 703 | 704 | /* Fix button padding in firefox */ 705 | 706 | div.jsoneditor-contextmenu ul li button::-moz-focus-inner { 707 | padding: 0; 708 | border: 0; 709 | } 710 | 711 | div.jsoneditor-contextmenu ul li button:hover, 712 | div.jsoneditor-contextmenu ul li button:focus { 713 | color: #1a1a1a; 714 | background-color: #f5f5f5; 715 | outline: none; 716 | } 717 | 718 | div.jsoneditor-contextmenu ul li button.jsoneditor-default { 719 | width: 96px; 720 | /* 128px - 32px */ 721 | } 722 | 723 | div.jsoneditor-contextmenu ul li button.jsoneditor-expand { 724 | float: right; 725 | width: 32px; 726 | height: 24px; 727 | border-left: 1px solid #e5e5e5; 728 | } 729 | 730 | div.jsoneditor-contextmenu div.jsoneditor-icon { 731 | position: absolute; 732 | top: 0; 733 | left: 0; 734 | width: 24px; 735 | height: 24px; 736 | border: none; 737 | padding: 0; 738 | margin: 0; 739 | background-image: url("img/jsoneditor-icons.svg"); 740 | } 741 | 742 | div.jsoneditor-contextmenu ul li ul div.jsoneditor-icon { 743 | margin-left: 24px; 744 | } 745 | 746 | div.jsoneditor-contextmenu div.jsoneditor-text { 747 | padding: 4px 0 4px 24px; 748 | word-wrap: break-word; 749 | } 750 | 751 | div.jsoneditor-contextmenu div.jsoneditor-text.jsoneditor-right-margin { 752 | padding-right: 24px; 753 | } 754 | 755 | div.jsoneditor-contextmenu ul li button div.jsoneditor-expand { 756 | position: absolute; 757 | top: 0; 758 | right: 0; 759 | width: 24px; 760 | height: 24px; 761 | padding: 0; 762 | margin: 0 4px 0 0; 763 | background: url("img/jsoneditor-icons.svg") 0 -72px; 764 | } 765 | 766 | div.jsoneditor-contextmenu div.jsoneditor-separator { 767 | height: 0; 768 | border-top: 1px solid #e5e5e5; 769 | padding-top: 5px; 770 | margin-top: 5px; 771 | } 772 | 773 | div.jsoneditor-contextmenu button.jsoneditor-remove > div.jsoneditor-icon { 774 | background-position: -24px 0; 775 | } 776 | 777 | div.jsoneditor-contextmenu button.jsoneditor-append > div.jsoneditor-icon { 778 | background-position: 0 0; 779 | } 780 | 781 | div.jsoneditor-contextmenu button.jsoneditor-insert > div.jsoneditor-icon { 782 | background-position: 0 0; 783 | } 784 | 785 | div.jsoneditor-contextmenu button.jsoneditor-duplicate > div.jsoneditor-icon { 786 | background-position: -48px 0; 787 | } 788 | 789 | div.jsoneditor-contextmenu button.jsoneditor-sort-asc > div.jsoneditor-icon { 790 | background-position: -168px 0; 791 | } 792 | 793 | div.jsoneditor-contextmenu button.jsoneditor-sort-desc > div.jsoneditor-icon { 794 | background-position: -192px 0; 795 | } 796 | 797 | div.jsoneditor-contextmenu button.jsoneditor-transform > div.jsoneditor-icon { 798 | background-position: -216px 0; 799 | } 800 | 801 | /* ContextMenu - sub menu */ 802 | 803 | div.jsoneditor-contextmenu ul li button.jsoneditor-selected, 804 | div.jsoneditor-contextmenu ul li button.jsoneditor-selected:hover, 805 | div.jsoneditor-contextmenu ul li button.jsoneditor-selected:focus { 806 | color: white; 807 | background-color: #ee422e; 808 | } 809 | 810 | div.jsoneditor-contextmenu ul li { 811 | overflow: hidden; 812 | } 813 | 814 | div.jsoneditor-contextmenu ul li ul { 815 | display: none; 816 | position: relative; 817 | left: -10px; 818 | top: 0; 819 | border: none; 820 | box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5); 821 | padding: 0 10px; 822 | /* TODO: transition is not supported on IE8-9 */ 823 | -webkit-transition: all 0.3s ease-out; 824 | -moz-transition: all 0.3s ease-out; 825 | -o-transition: all 0.3s ease-out; 826 | transition: all 0.3s ease-out; 827 | } 828 | 829 | 830 | 831 | div.jsoneditor-contextmenu ul li ul li button { 832 | padding-left: 24px; 833 | animation: all ease-in-out 1s; 834 | } 835 | 836 | div.jsoneditor-contextmenu ul li ul li button:hover, 837 | div.jsoneditor-contextmenu ul li ul li button:focus { 838 | background-color: #f5f5f5; 839 | } 840 | 841 | div.jsoneditor-contextmenu button.jsoneditor-type-string > div.jsoneditor-icon { 842 | background-position: -144px 0; 843 | } 844 | 845 | div.jsoneditor-contextmenu button.jsoneditor-type-auto > div.jsoneditor-icon { 846 | background-position: -120px 0; 847 | } 848 | 849 | div.jsoneditor-contextmenu button.jsoneditor-type-object > div.jsoneditor-icon { 850 | background-position: -72px 0; 851 | } 852 | 853 | div.jsoneditor-contextmenu button.jsoneditor-type-array > div.jsoneditor-icon { 854 | background-position: -96px 0; 855 | } 856 | 857 | div.jsoneditor-contextmenu button.jsoneditor-type-modes > div.jsoneditor-icon { 858 | background-image: none; 859 | width: 6px; 860 | } 861 | 862 | /* pico modal styling */ 863 | 864 | .jsoneditor-modal-overlay { 865 | position: absolute !important; 866 | background: rgb(1,1,1) !important; 867 | opacity: 0.3 !important; 868 | } 869 | 870 | .jsoneditor-modal { 871 | position: absolute !important; 872 | max-width: 95% !important; 873 | width: auto !important; 874 | border-radius: 2px !important; 875 | padding: 45px 15px 15px 15px !important; 876 | box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3) !important; 877 | color: #4d4d4d; 878 | line-height: 1.3em; 879 | } 880 | 881 | .jsoneditor-modal.jsoneditor-modal-transform { 882 | width: 600px !important; 883 | } 884 | 885 | .jsoneditor-modal .pico-modal-header { 886 | position: absolute; 887 | box-sizing: border-box; 888 | top: 0; 889 | left: 0; 890 | width: 100%; 891 | padding: 0 10px; 892 | height: 30px; 893 | line-height: 30px; 894 | font-family: arial, sans-serif; 895 | font-size: 11pt; 896 | background: #3883fa; 897 | color: white; 898 | } 899 | 900 | .jsoneditor-modal table { 901 | width: 100%; 902 | } 903 | 904 | .jsoneditor-modal table th, 905 | .jsoneditor-modal table td { 906 | text-align: left; 907 | vertical-align: top; 908 | font-weight: normal; 909 | color: #4d4d4d; 910 | border-spacing: 0; 911 | border-collapse: collapse; 912 | } 913 | 914 | .jsoneditor-modal table td { 915 | padding: 3px 0; 916 | } 917 | 918 | .jsoneditor-modal p:first-child { 919 | margin-top: 0; 920 | } 921 | 922 | .jsoneditor-modal a { 923 | color: #3883fa; 924 | } 925 | 926 | 927 | 928 | .jsoneditor-modal .jsoneditor-jmespath-block { 929 | margin-bottom: 10px; 930 | } 931 | 932 | .jsoneditor-modal table td.jsoneditor-modal-input { 933 | text-align: right; 934 | padding-right: 0; 935 | white-space: nowrap; 936 | } 937 | 938 | .jsoneditor-modal table td.jsoneditor-modal-actions { 939 | padding-top: 15px; 940 | } 941 | 942 | .jsoneditor-modal .pico-close { 943 | background: none !important; 944 | font-size: 24px !important; 945 | top: 7px !important; 946 | right: 7px !important; 947 | color: white; 948 | } 949 | 950 | .jsoneditor-modal select, 951 | .jsoneditor-modal textarea, 952 | .jsoneditor-modal input, 953 | .jsoneditor-modal #query { 954 | background: #ffffff; 955 | border: 1px solid #d3d3d3; 956 | color: #4d4d4d; 957 | border-radius: 3px; 958 | padding: 4px; 959 | } 960 | 961 | .jsoneditor-modal, 962 | .jsoneditor-modal table td, 963 | .jsoneditor-modal table th, 964 | .jsoneditor-modal select, 965 | .jsoneditor-modal option, 966 | .jsoneditor-modal textarea, 967 | .jsoneditor-modal input, 968 | .jsoneditor-modal #query { 969 | font-size: 10.5pt; 970 | font-family: arial, sans-serif; 971 | } 972 | 973 | .jsoneditor-modal table th { 974 | vertical-align: middle; 975 | } 976 | 977 | .jsoneditor-modal #query, 978 | .jsoneditor-modal .jsoneditor-transform-preview { 979 | font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif; 980 | font-size: 10pt; 981 | } 982 | 983 | .jsoneditor-modal input[type="button"], 984 | .jsoneditor-modal input[type="submit"] { 985 | background: #f5f5f5; 986 | padding: 4px 20px; 987 | } 988 | 989 | .jsoneditor-modal select, 990 | .jsoneditor-modal input { 991 | cursor: pointer; 992 | } 993 | 994 | .jsoneditor-modal input { 995 | padding: 4px; 996 | } 997 | 998 | .jsoneditor-modal input[type="text"] { 999 | cursor: inherit; 1000 | } 1001 | 1002 | .jsoneditor-modal input[disabled] { 1003 | background: #d3d3d3; 1004 | color: #808080; 1005 | } 1006 | 1007 | .jsoneditor-modal .jsoneditor-select-wrapper { 1008 | position: relative; 1009 | display: inline-block; 1010 | } 1011 | 1012 | .jsoneditor-modal .jsoneditor-select-wrapper:after { 1013 | content: ""; 1014 | width: 0; 1015 | height: 0; 1016 | border-left: 5px solid transparent; 1017 | border-right: 5px solid transparent; 1018 | border-top: 6px solid #666; 1019 | position: absolute; 1020 | right: 8px; 1021 | top: 14px; 1022 | pointer-events: none; 1023 | } 1024 | 1025 | .jsoneditor-modal select { 1026 | padding: 3px 24px 3px 10px; 1027 | min-width: 180px; 1028 | max-width: 350px; 1029 | -webkit-appearance: none; 1030 | -moz-appearance: none; 1031 | appearance: none; 1032 | text-indent: 0; 1033 | text-overflow: ""; 1034 | font-size: 10pt; 1035 | line-height: 1.5em; 1036 | } 1037 | 1038 | .jsoneditor-modal select::-ms-expand { 1039 | display: none; 1040 | } 1041 | 1042 | .jsoneditor-modal .jsoneditor-button-group input { 1043 | padding: 4px 10px; 1044 | margin: 0; 1045 | border-radius: 0; 1046 | border-left-style: none; 1047 | } 1048 | 1049 | .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first { 1050 | border-top-left-radius: 3px; 1051 | border-bottom-left-radius: 3px; 1052 | border-left-style: solid; 1053 | } 1054 | 1055 | .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last { 1056 | border-top-right-radius: 3px; 1057 | border-bottom-right-radius: 3px; 1058 | } 1059 | 1060 | .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc, 1061 | .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc { 1062 | background: #3883fa; 1063 | border-color: #3883fa; 1064 | color: white; 1065 | } 1066 | 1067 | .jsoneditor-modal #query, 1068 | .jsoneditor-modal .jsoneditor-transform-preview { 1069 | width: 100%; 1070 | box-sizing: border-box; 1071 | } 1072 | 1073 | .jsoneditor-modal .jsoneditor-transform-preview { 1074 | background: #f5f5f5; 1075 | height: 200px; 1076 | } 1077 | 1078 | .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error { 1079 | color: #ee422e; 1080 | } 1081 | 1082 | .jsoneditor-modal .jsoneditor-jmespath-wizard { 1083 | line-height: 1.2em; 1084 | width: 100%; 1085 | padding: 0; 1086 | border-radius: 3px; 1087 | } 1088 | 1089 | .jsoneditor-modal .jsoneditor-jmespath-label { 1090 | font-weight: bold; 1091 | color: dodgerblue; 1092 | margin-top: 20px; 1093 | margin-bottom: 5px; 1094 | } 1095 | 1096 | .jsoneditor-modal .jsoneditor-jmespath-wizard-table { 1097 | width: 100%; 1098 | } 1099 | 1100 | .jsoneditor-modal .jsoneditor-jmespath-wizard-label { 1101 | font-style: italic; 1102 | margin: 4px 0 2px 0; 1103 | } 1104 | 1105 | .jsoneditor-modal .jsoneditor-inline { 1106 | position: relative; 1107 | display: inline-block; 1108 | width: 100%; 1109 | padding-top: 2px; 1110 | padding-bottom: 2px; 1111 | } 1112 | 1113 | .jsoneditor-modal .jsoneditor-inline:not(:last-child) { 1114 | padding-right: 2px; 1115 | } 1116 | 1117 | .jsoneditor-modal .jsoneditor-jmespath-filter { 1118 | display: flex; 1119 | flex-wrap: wrap; 1120 | } 1121 | 1122 | .jsoneditor-modal .jsoneditor-jmespath-filter-field { 1123 | width: 180px; 1124 | } 1125 | 1126 | .jsoneditor-modal .jsoneditor-jmespath-filter-relation { 1127 | width: 100px; 1128 | } 1129 | 1130 | .jsoneditor-modal .jsoneditor-jmespath-filter-value { 1131 | min-width: 180px; 1132 | flex: 1; 1133 | } 1134 | 1135 | .jsoneditor-modal .jsoneditor-jmespath-sort-field { 1136 | width: 170px; 1137 | } 1138 | 1139 | .jsoneditor-modal .jsoneditor-jmespath-sort-order { 1140 | width: 150px; 1141 | } 1142 | 1143 | .jsoneditor-modal .jsoneditor-jmespath-select-fields { 1144 | width: 100%; 1145 | } 1146 | 1147 | .jsoneditor-modal .selectr-selected { 1148 | border-color: #d3d3d3; 1149 | padding: 4px 28px 4px 8px; 1150 | } 1151 | 1152 | .jsoneditor-modal .selectr-selected .selectr-tag { 1153 | background-color: #3883fa; 1154 | border-radius: 5px; 1155 | } 1156 | div.jsoneditor-menu { 1157 | width: 100%; 1158 | height: 35px; 1159 | padding: 2px; 1160 | margin: 0; 1161 | -moz-box-sizing: border-box; 1162 | -webkit-box-sizing: border-box; 1163 | box-sizing: border-box; 1164 | color: white; 1165 | background-color: #3883fa; 1166 | border-bottom: 1px solid #3883fa; 1167 | } 1168 | 1169 | div.jsoneditor-menu > button, 1170 | div.jsoneditor-menu > div.jsoneditor-modes > button { 1171 | width: 26px; 1172 | height: 26px; 1173 | margin: 2px; 1174 | padding: 0; 1175 | border-radius: 2px; 1176 | border: 1px solid transparent; 1177 | background: transparent url("img/jsoneditor-icons.svg"); 1178 | color: white; 1179 | opacity: 0.8; 1180 | font-family: arial, sans-serif; 1181 | font-size: 10pt; 1182 | float: left; 1183 | } 1184 | 1185 | div.jsoneditor-menu > button:hover, 1186 | div.jsoneditor-menu > div.jsoneditor-modes > button:hover { 1187 | background-color: rgba(255,255,255,0.2); 1188 | border: 1px solid rgba(255,255,255,0.4); 1189 | } 1190 | 1191 | div.jsoneditor-menu > button:focus, 1192 | div.jsoneditor-menu > button:active, 1193 | div.jsoneditor-menu > div.jsoneditor-modes > button:focus, 1194 | div.jsoneditor-menu > div.jsoneditor-modes > button:active { 1195 | background-color: rgba(255,255,255,0.3); 1196 | } 1197 | 1198 | div.jsoneditor-menu > button:disabled, 1199 | div.jsoneditor-menu > div.jsoneditor-modes > button:disabled { 1200 | opacity: 0.5; 1201 | } 1202 | 1203 | div.jsoneditor-menu > button.jsoneditor-collapse-all { 1204 | background-position: 0 -96px; 1205 | } 1206 | 1207 | div.jsoneditor-menu > button.jsoneditor-expand-all { 1208 | background-position: 0 -120px; 1209 | } 1210 | 1211 | div.jsoneditor-menu > button.jsoneditor-sort { 1212 | background-position: -120px -96px; 1213 | } 1214 | 1215 | div.jsoneditor-menu > button.jsoneditor-transform { 1216 | background-position: -144px -96px; 1217 | } 1218 | 1219 | div.jsoneditor.jsoneditor-mode-view > div.jsoneditor-menu > button.jsoneditor-sort, 1220 | div.jsoneditor.jsoneditor-mode-form > div.jsoneditor-menu > button.jsoneditor-sort, 1221 | div.jsoneditor.jsoneditor-mode-view > div.jsoneditor-menu > button.jsoneditor-transform, 1222 | div.jsoneditor.jsoneditor-mode-form > div.jsoneditor-menu > button.jsoneditor-transform { 1223 | display: none; 1224 | } 1225 | 1226 | div.jsoneditor-menu > button.jsoneditor-undo { 1227 | background-position: -24px -96px; 1228 | } 1229 | 1230 | div.jsoneditor-menu > button.jsoneditor-undo:disabled { 1231 | background-position: -24px -120px; 1232 | } 1233 | 1234 | div.jsoneditor-menu > button.jsoneditor-redo { 1235 | background-position: -48px -96px; 1236 | } 1237 | 1238 | div.jsoneditor-menu > button.jsoneditor-redo:disabled { 1239 | background-position: -48px -120px; 1240 | } 1241 | 1242 | div.jsoneditor-menu > button.jsoneditor-compact { 1243 | background-position: -72px -96px; 1244 | } 1245 | 1246 | div.jsoneditor-menu > button.jsoneditor-format { 1247 | background-position: -72px -120px; 1248 | } 1249 | 1250 | div.jsoneditor-menu > button.jsoneditor-repair { 1251 | background-position: -96px -96px; 1252 | } 1253 | 1254 | div.jsoneditor-menu > div.jsoneditor-modes { 1255 | display: inline-block; 1256 | float: left; 1257 | } 1258 | 1259 | div.jsoneditor-menu > div.jsoneditor-modes > button { 1260 | background-image: none; 1261 | width: auto; 1262 | padding-left: 6px; 1263 | padding-right: 6px; 1264 | } 1265 | 1266 | div.jsoneditor-menu > button.jsoneditor-separator, 1267 | div.jsoneditor-menu > div.jsoneditor-modes > button.jsoneditor-separator { 1268 | margin-left: 10px; 1269 | } 1270 | 1271 | div.jsoneditor-menu a { 1272 | font-family: arial, sans-serif; 1273 | font-size: 10pt; 1274 | color: white; 1275 | opacity: 0.8; 1276 | vertical-align: middle; 1277 | } 1278 | 1279 | div.jsoneditor-menu a:hover { 1280 | opacity: 1; 1281 | } 1282 | 1283 | div.jsoneditor-menu a.jsoneditor-poweredBy { 1284 | font-size: 8pt; 1285 | position: absolute; 1286 | right: 0; 1287 | top: 0; 1288 | padding: 10px; 1289 | } 1290 | table.jsoneditor-search input, 1291 | table.jsoneditor-search div.jsoneditor-results { 1292 | font-family: arial, sans-serif; 1293 | font-size: 10pt; 1294 | color: #1A1A1A; 1295 | background: transparent; 1296 | /* For Firefox */ 1297 | } 1298 | 1299 | table.jsoneditor-search div.jsoneditor-results { 1300 | color: white; 1301 | padding-right: 5px; 1302 | line-height: 24px; 1303 | padding-top: 2px; 1304 | } 1305 | 1306 | table.jsoneditor-search { 1307 | position: absolute; 1308 | right: 4px; 1309 | top: 4px; 1310 | border-collapse: collapse; 1311 | border-spacing: 0; 1312 | } 1313 | 1314 | table.jsoneditor-search div.jsoneditor-frame { 1315 | border: 1px solid transparent; 1316 | background-color: white; 1317 | padding: 0 2px; 1318 | margin: 0; 1319 | } 1320 | 1321 | table.jsoneditor-search div.jsoneditor-frame table { 1322 | border-collapse: collapse; 1323 | } 1324 | 1325 | table.jsoneditor-search input { 1326 | width: 120px; 1327 | border: none; 1328 | outline: none; 1329 | margin: 1px; 1330 | line-height: 20px; 1331 | } 1332 | 1333 | table.jsoneditor-search button { 1334 | width: 16px; 1335 | height: 24px; 1336 | padding: 0; 1337 | margin: 0; 1338 | border: none; 1339 | background: url("img/jsoneditor-icons.svg"); 1340 | vertical-align: top; 1341 | } 1342 | 1343 | table.jsoneditor-search button:hover { 1344 | background-color: transparent; 1345 | } 1346 | 1347 | table.jsoneditor-search button.jsoneditor-refresh { 1348 | width: 18px; 1349 | background-position: -99px -73px; 1350 | } 1351 | 1352 | table.jsoneditor-search button.jsoneditor-next { 1353 | cursor: pointer; 1354 | background-position: -124px -73px; 1355 | } 1356 | 1357 | table.jsoneditor-search button.jsoneditor-next:hover { 1358 | background-position: -124px -49px; 1359 | } 1360 | 1361 | table.jsoneditor-search button.jsoneditor-previous { 1362 | cursor: pointer; 1363 | background-position: -148px -73px; 1364 | margin-right: 2px; 1365 | } 1366 | 1367 | table.jsoneditor-search button.jsoneditor-previous:hover { 1368 | background-position: -148px -49px; 1369 | } 1370 | div.jsoneditor div.autocomplete.dropdown { 1371 | position: absolute; 1372 | background: white; 1373 | box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); 1374 | border: 1px solid #d3d3d3; 1375 | z-index: 100; 1376 | overflow-x: hidden; 1377 | overflow-y: auto; 1378 | cursor: default; 1379 | margin: 0; 1380 | padding-left: 2pt; 1381 | padding-right: 5pt; 1382 | text-align: left; 1383 | outline: 0; 1384 | font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif; 1385 | font-size: 10pt; 1386 | } 1387 | 1388 | div.jsoneditor div.autocomplete.dropdown .item { 1389 | color: #333; 1390 | } 1391 | 1392 | div.jsoneditor div.autocomplete.dropdown .item.hover { 1393 | background-color: #ddd; 1394 | } 1395 | 1396 | div.jsoneditor div.autocomplete.hint { 1397 | color: #aaa; 1398 | top: 4px; 1399 | left: 4px; 1400 | } 1401 | div.jsoneditor-treepath { 1402 | padding: 0 5px; 1403 | overflow: hidden; 1404 | white-space: nowrap; 1405 | outline: none; 1406 | } 1407 | 1408 | div.jsoneditor-treepath.show-all { 1409 | word-wrap: break-word; 1410 | white-space: normal; 1411 | position: absolute; 1412 | background-color: #ebebeb; 1413 | z-index: 999; 1414 | box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); 1415 | } 1416 | 1417 | div.jsoneditor-treepath div.jsoneditor-contextmenu-root { 1418 | position: absolute; 1419 | left: 0; 1420 | } 1421 | 1422 | div.jsoneditor-treepath span.jsoneditor-treepath-show-all-btn { 1423 | position: absolute; 1424 | background-color: #ebebeb; 1425 | left: 0; 1426 | height: 20px; 1427 | padding: 0 3px; 1428 | cursor: pointer; 1429 | } 1430 | 1431 | div.jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn { 1432 | display: none; 1433 | } 1434 | 1435 | div.jsoneditor-treepath span.jsoneditor-treepath-element { 1436 | margin: 1px; 1437 | font-family: arial, sans-serif; 1438 | font-size: 10pt; 1439 | } 1440 | 1441 | div.jsoneditor-treepath span.jsoneditor-treepath-seperator { 1442 | margin: 2px; 1443 | font-size: 9pt; 1444 | font-family: arial, sans-serif; 1445 | } 1446 | 1447 | div.jsoneditor-treepath span.jsoneditor-treepath-element:hover, 1448 | div.jsoneditor-treepath span.jsoneditor-treepath-seperator:hover { 1449 | cursor: pointer; 1450 | text-decoration: underline; 1451 | } 1452 | div.jsoneditor-statusbar { 1453 | line-height: 26px; 1454 | height: 26px; 1455 | margin-top: -1px; 1456 | color: #808080; 1457 | background-color: #ebebeb; 1458 | border-top: 1px solid #d3d3d3; 1459 | -moz-box-sizing: border-box; 1460 | -webkit-box-sizing: border-box; 1461 | box-sizing: border-box; 1462 | font-size: 10pt; 1463 | } 1464 | 1465 | div.jsoneditor-statusbar > .jsoneditor-curserinfo-label { 1466 | margin: 0 2px 0 4px; 1467 | } 1468 | 1469 | div.jsoneditor-statusbar > .jsoneditor-curserinfo-val { 1470 | margin-right: 12px; 1471 | } 1472 | 1473 | div.jsoneditor-statusbar > .jsoneditor-curserinfo-count { 1474 | margin-left: 4px; 1475 | } 1476 | 1477 | div.jsoneditor-statusbar > .jsoneditor-validation-error-icon { 1478 | float: right; 1479 | width: 24px; 1480 | height: 24px; 1481 | padding: 0; 1482 | margin-top: 1px; 1483 | background: url("img/jsoneditor-icons.svg") -168px -48px; 1484 | cursor: pointer; 1485 | } 1486 | 1487 | div.jsoneditor-statusbar > .jsoneditor-validation-error-count { 1488 | float: right; 1489 | margin: 0 4px 0 0; 1490 | cursor: pointer; 1491 | } 1492 | 1493 | div.jsoneditor-statusbar > .jsoneditor-parse-error-icon { 1494 | float: right; 1495 | width: 24px; 1496 | height: 24px; 1497 | padding: 0; 1498 | margin: 1px; 1499 | background: url("img/jsoneditor-icons.svg") -25px 0px; 1500 | } 1501 | div.jsoneditor-navigation-bar { 1502 | width: 100%; 1503 | height: 26px; 1504 | line-height: 26px; 1505 | padding: 0; 1506 | margin: 0; 1507 | border-bottom: 1px solid #d3d3d3; 1508 | -moz-box-sizing: border-box; 1509 | -webkit-box-sizing: border-box; 1510 | box-sizing: border-box; 1511 | color: #808080; 1512 | background-color: #ebebeb; 1513 | overflow: hidden; 1514 | font-family: arial, sans-serif; 1515 | font-size: 10pt; 1516 | } 1517 | /*! 1518 | * Selectr 2.4.0 1519 | * https://github.com/Mobius1/Selectr 1520 | * 1521 | * Released under the MIT license 1522 | */ 1523 | 1524 | .selectr-container { 1525 | position: relative; 1526 | } 1527 | 1528 | .selectr-container li { 1529 | list-style: none; 1530 | } 1531 | 1532 | .selectr-hidden { 1533 | position: absolute; 1534 | overflow: hidden; 1535 | clip: rect(0px, 0px, 0px, 0px); 1536 | width: 1px; 1537 | height: 1px; 1538 | margin: -1px; 1539 | padding: 0; 1540 | border: 0 none; 1541 | } 1542 | 1543 | .selectr-visible { 1544 | position: absolute; 1545 | left: 0; 1546 | top: 0; 1547 | width: 100%; 1548 | height: 100%; 1549 | opacity: 0; 1550 | z-index: 11; 1551 | } 1552 | 1553 | .selectr-desktop.multiple .selectr-visible { 1554 | display: none; 1555 | } 1556 | 1557 | .selectr-desktop.multiple.native-open .selectr-visible { 1558 | top: 100%; 1559 | min-height: 200px !important; 1560 | height: auto; 1561 | opacity: 1; 1562 | display: block; 1563 | } 1564 | 1565 | .selectr-container.multiple.selectr-mobile .selectr-selected { 1566 | z-index: 0; 1567 | } 1568 | 1569 | .selectr-selected { 1570 | position: relative; 1571 | z-index: 1; 1572 | box-sizing: border-box; 1573 | width: 100%; 1574 | padding: 7px 28px 7px 14px; 1575 | cursor: pointer; 1576 | border: 1px solid #999; 1577 | border-radius: 3px; 1578 | background-color: #fff; 1579 | } 1580 | 1581 | .selectr-selected::before { 1582 | position: absolute; 1583 | top: 50%; 1584 | right: 10px; 1585 | width: 0; 1586 | height: 0; 1587 | content: ''; 1588 | -o-transform: rotate(0deg) translate3d(0px, -50%, 0px); 1589 | -ms-transform: rotate(0deg) translate3d(0px, -50%, 0px); 1590 | -moz-transform: rotate(0deg) translate3d(0px, -50%, 0px); 1591 | -webkit-transform: rotate(0deg) translate3d(0px, -50%, 0px); 1592 | transform: rotate(0deg) translate3d(0px, -50%, 0px); 1593 | border-width: 4px 4px 0 4px; 1594 | border-style: solid; 1595 | border-color: #6c7a86 transparent transparent; 1596 | } 1597 | 1598 | .selectr-container.open .selectr-selected::before, 1599 | .selectr-container.native-open .selectr-selected::before { 1600 | border-width: 0 4px 4px 4px; 1601 | border-style: solid; 1602 | border-color: transparent transparent #6c7a86; 1603 | } 1604 | 1605 | .selectr-label { 1606 | display: none; 1607 | overflow: hidden; 1608 | width: 100%; 1609 | white-space: nowrap; 1610 | text-overflow: ellipsis; 1611 | } 1612 | 1613 | .selectr-placeholder { 1614 | color: #6c7a86; 1615 | } 1616 | 1617 | .selectr-tags { 1618 | margin: 0; 1619 | padding: 0; 1620 | white-space: normal; 1621 | } 1622 | 1623 | .has-selected .selectr-tags { 1624 | margin: 0 0 -2px; 1625 | } 1626 | 1627 | .selectr-tag { 1628 | list-style: none; 1629 | position: relative; 1630 | float: left; 1631 | padding: 2px 25px 2px 8px; 1632 | margin: 0 2px 2px 0; 1633 | cursor: default; 1634 | color: #fff; 1635 | border: medium none; 1636 | border-radius: 10px; 1637 | background: #acb7bf none repeat scroll 0 0; 1638 | } 1639 | 1640 | .selectr-container.multiple.has-selected .selectr-selected { 1641 | padding: 5px 28px 5px 5px; 1642 | } 1643 | 1644 | .selectr-options-container { 1645 | position: absolute; 1646 | z-index: 10000; 1647 | top: calc(100% - 1px); 1648 | left: 0; 1649 | display: none; 1650 | box-sizing: border-box; 1651 | width: 100%; 1652 | border-width: 0 1px 1px; 1653 | border-style: solid; 1654 | border-color: transparent #999 #999; 1655 | border-radius: 0 0 3px 3px; 1656 | background-color: #fff; 1657 | } 1658 | 1659 | .selectr-container.open .selectr-options-container { 1660 | display: block; 1661 | } 1662 | 1663 | .selectr-input-container { 1664 | position: relative; 1665 | display: none; 1666 | } 1667 | 1668 | .selectr-clear, 1669 | .selectr-input-clear, 1670 | .selectr-tag-remove { 1671 | position: absolute; 1672 | top: 50%; 1673 | right: 22px; 1674 | width: 20px; 1675 | height: 20px; 1676 | padding: 0; 1677 | cursor: pointer; 1678 | -o-transform: translate3d(0px, -50%, 0px); 1679 | -ms-transform: translate3d(0px, -50%, 0px); 1680 | -moz-transform: translate3d(0px, -50%, 0px); 1681 | -webkit-transform: translate3d(0px, -50%, 0px); 1682 | transform: translate3d(0px, -50%, 0px); 1683 | border: medium none; 1684 | background-color: transparent; 1685 | z-index: 11; 1686 | } 1687 | 1688 | .selectr-clear, 1689 | .selectr-input-clear { 1690 | display: none; 1691 | } 1692 | 1693 | .selectr-container.has-selected .selectr-clear, 1694 | .selectr-input-container.active .selectr-input-clear { 1695 | display: block; 1696 | } 1697 | 1698 | .selectr-selected .selectr-tag-remove { 1699 | right: 2px; 1700 | } 1701 | 1702 | .selectr-clear::before, 1703 | .selectr-clear::after, 1704 | .selectr-input-clear::before, 1705 | .selectr-input-clear::after, 1706 | .selectr-tag-remove::before, 1707 | .selectr-tag-remove::after { 1708 | position: absolute; 1709 | top: 5px; 1710 | left: 9px; 1711 | width: 2px; 1712 | height: 10px; 1713 | content: ' '; 1714 | background-color: #6c7a86; 1715 | } 1716 | 1717 | .selectr-tag-remove::before, 1718 | .selectr-tag-remove::after { 1719 | top: 4px; 1720 | width: 3px; 1721 | height: 12px; 1722 | background-color: #fff; 1723 | } 1724 | 1725 | .selectr-clear:before, 1726 | .selectr-input-clear::before, 1727 | .selectr-tag-remove::before { 1728 | -o-transform: rotate(45deg); 1729 | -ms-transform: rotate(45deg); 1730 | -moz-transform: rotate(45deg); 1731 | -webkit-transform: rotate(45deg); 1732 | transform: rotate(45deg); 1733 | } 1734 | 1735 | .selectr-clear:after, 1736 | .selectr-input-clear::after, 1737 | .selectr-tag-remove::after { 1738 | -o-transform: rotate(-45deg); 1739 | -ms-transform: rotate(-45deg); 1740 | -moz-transform: rotate(-45deg); 1741 | -webkit-transform: rotate(-45deg); 1742 | transform: rotate(-45deg); 1743 | } 1744 | 1745 | .selectr-input-container.active, 1746 | .selectr-input-container.active .selectr-clear { 1747 | display: block; 1748 | } 1749 | 1750 | .selectr-input { 1751 | top: 5px; 1752 | left: 5px; 1753 | box-sizing: border-box; 1754 | width: calc(100% - 30px); 1755 | margin: 10px 15px; 1756 | padding: 7px 30px 7px 9px; 1757 | border: 1px solid #999; 1758 | border-radius: 3px; 1759 | } 1760 | 1761 | .selectr-notice { 1762 | display: none; 1763 | box-sizing: border-box; 1764 | width: 100%; 1765 | padding: 8px 16px; 1766 | border-top: 1px solid #999; 1767 | border-radius: 0 0 3px 3px; 1768 | background-color: #fff; 1769 | } 1770 | 1771 | .selectr-container.notice .selectr-notice { 1772 | display: block; 1773 | } 1774 | 1775 | .selectr-container.notice .selectr-selected { 1776 | border-radius: 3px 3px 0 0; 1777 | } 1778 | 1779 | .selectr-options { 1780 | position: relative; 1781 | top: calc(100% + 2px); 1782 | display: none; 1783 | overflow-x: auto; 1784 | overflow-y: scroll; 1785 | max-height: 200px; 1786 | margin: 0; 1787 | padding: 0; 1788 | } 1789 | 1790 | .selectr-container.open .selectr-options, 1791 | .selectr-container.open .selectr-input-container, 1792 | .selectr-container.notice .selectr-options-container { 1793 | display: block; 1794 | } 1795 | 1796 | .selectr-option { 1797 | position: relative; 1798 | display: block; 1799 | padding: 5px 20px; 1800 | list-style: outside none none; 1801 | cursor: pointer; 1802 | font-weight: normal; 1803 | } 1804 | 1805 | .selectr-options.optgroups > .selectr-option { 1806 | padding-left: 25px; 1807 | } 1808 | 1809 | .selectr-optgroup { 1810 | font-weight: bold; 1811 | padding: 0; 1812 | } 1813 | 1814 | .selectr-optgroup--label { 1815 | font-weight: bold; 1816 | margin-top: 10px; 1817 | padding: 5px 15px; 1818 | } 1819 | 1820 | .selectr-match { 1821 | text-decoration: underline; 1822 | } 1823 | 1824 | .selectr-option.selected { 1825 | background-color: #ddd; 1826 | } 1827 | 1828 | .selectr-option.active { 1829 | color: #fff; 1830 | background-color: #5897fb; 1831 | } 1832 | 1833 | .selectr-option.disabled { 1834 | opacity: 0.4; 1835 | } 1836 | 1837 | .selectr-option.excluded { 1838 | display: none; 1839 | } 1840 | 1841 | .selectr-container.open .selectr-selected { 1842 | border-color: #999 #999 transparent #999; 1843 | border-radius: 3px 3px 0 0; 1844 | } 1845 | 1846 | .selectr-container.open .selectr-selected::after { 1847 | -o-transform: rotate(180deg) translate3d(0px, 50%, 0px); 1848 | -ms-transform: rotate(180deg) translate3d(0px, 50%, 0px); 1849 | -moz-transform: rotate(180deg) translate3d(0px, 50%, 0px); 1850 | -webkit-transform: rotate(180deg) translate3d(0px, 50%, 0px); 1851 | transform: rotate(180deg) translate3d(0px, 50%, 0px); 1852 | } 1853 | 1854 | .selectr-disabled { 1855 | opacity: .6; 1856 | } 1857 | 1858 | .selectr-empty, 1859 | .has-selected .selectr-placeholder { 1860 | display: none; 1861 | } 1862 | 1863 | .has-selected .selectr-label { 1864 | display: block; 1865 | } 1866 | 1867 | /* TAGGABLE */ 1868 | 1869 | .taggable .selectr-selected { 1870 | padding: 4px 28px 4px 4px; 1871 | } 1872 | 1873 | .taggable .selectr-selected::after { 1874 | display: table; 1875 | content: " "; 1876 | clear: both; 1877 | } 1878 | 1879 | .taggable .selectr-label { 1880 | width: auto; 1881 | } 1882 | 1883 | .taggable .selectr-tags { 1884 | float: left; 1885 | display: block; 1886 | } 1887 | 1888 | .taggable .selectr-placeholder { 1889 | display: none; 1890 | } 1891 | 1892 | .input-tag { 1893 | float: left; 1894 | min-width: 90px; 1895 | width: auto; 1896 | } 1897 | 1898 | .selectr-tag-input { 1899 | border: medium none; 1900 | padding: 3px 10px; 1901 | width: 100%; 1902 | font-family: inherit; 1903 | font-weight: inherit; 1904 | font-size: inherit; 1905 | } 1906 | 1907 | .selectr-input-container.loading::after { 1908 | position: absolute; 1909 | top: 50%; 1910 | right: 20px; 1911 | width: 20px; 1912 | height: 20px; 1913 | content: ''; 1914 | -o-transform: translate3d(0px, -50%, 0px); 1915 | -ms-transform: translate3d(0px, -50%, 0px); 1916 | -moz-transform: translate3d(0px, -50%, 0px); 1917 | -webkit-transform: translate3d(0px, -50%, 0px); 1918 | transform: translate3d(0px, -50%, 0px); 1919 | -o-transform-origin: 50% 0 0; 1920 | -ms-transform-origin: 50% 0 0; 1921 | -moz-transform-origin: 50% 0 0; 1922 | -webkit-transform-origin: 50% 0 0; 1923 | transform-origin: 50% 0 0; 1924 | -moz-animation: 500ms linear 0s normal forwards infinite running spin; 1925 | -webkit-animation: 500ms linear 0s normal forwards infinite running spin; 1926 | animation: 500ms linear 0s normal forwards infinite running spin; 1927 | border-width: 3px; 1928 | border-style: solid; 1929 | border-color: #aaa #ddd #ddd; 1930 | border-radius: 50%; 1931 | } 1932 | 1933 | @-webkit-keyframes spin { 1934 | 0% { 1935 | -webkit-transform: rotate(0deg) translate3d(0px, -50%, 0px); 1936 | transform: rotate(0deg) translate3d(0px, -50%, 0px); 1937 | } 1938 | 1939 | 100% { 1940 | -webkit-transform: rotate(360deg) translate3d(0px, -50%, 0px); 1941 | transform: rotate(360deg) translate3d(0px, -50%, 0px); 1942 | } 1943 | } 1944 | 1945 | @keyframes spin { 1946 | 0% { 1947 | -webkit-transform: rotate(0deg) translate3d(0px, -50%, 0px); 1948 | transform: rotate(0deg) translate3d(0px, -50%, 0px); 1949 | } 1950 | 1951 | 100% { 1952 | -webkit-transform: rotate(360deg) translate3d(0px, -50%, 0px); 1953 | transform: rotate(360deg) translate3d(0px, -50%, 0px); 1954 | } 1955 | } 1956 | 1957 | .selectr-container.open.inverted .selectr-selected { 1958 | border-color: transparent #999 #999; 1959 | border-radius: 0 0 3px 3px; 1960 | } 1961 | 1962 | .selectr-container.inverted .selectr-options-container { 1963 | border-width: 1px 1px 0; 1964 | border-color: #999 #999 transparent; 1965 | border-radius: 3px 3px 0 0; 1966 | background-color: #fff; 1967 | } 1968 | 1969 | .selectr-container.inverted .selectr-options-container { 1970 | top: auto; 1971 | bottom: calc(100% - 1px); 1972 | } 1973 | 1974 | .selectr-container ::-webkit-input-placeholder { 1975 | color: #6c7a86; 1976 | opacity: 1; 1977 | } 1978 | 1979 | .selectr-container ::-moz-placeholder { 1980 | color: #6c7a86; 1981 | opacity: 1; 1982 | } 1983 | 1984 | .selectr-container :-ms-input-placeholder { 1985 | color: #6c7a86; 1986 | opacity: 1; 1987 | } 1988 | 1989 | .selectr-container ::placeholder { 1990 | color: #6c7a86; 1991 | opacity: 1; 1992 | } -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_jsoneditor.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | # This flag says that the code is written to work on both Python 2 and Python 3 | # 3. If at all possible, it is good practice to do this. If you cannot, you 4 | # will need to generate wheels for each Python version that you support. 5 | universal=1 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | AUTHOR = 'Vsevolod Novikov' 2 | AUTHOR_EMAIL = 'nnseva@gmail.com' 3 | URL = 'https://github.com/nnseva/django-jsoneditor' 4 | 5 | import jsoneditor 6 | 7 | from setuptools import setup, find_packages 8 | 9 | description = 'Django JSON Editor' 10 | 11 | with open('README.rst') as f: 12 | long_description = f.read() 13 | 14 | setup( 15 | name = 'django-jsoneditor', 16 | version = jsoneditor.__version__, 17 | description = description, 18 | author = AUTHOR, 19 | author_email = AUTHOR_EMAIL, 20 | url = URL, 21 | long_description = long_description, 22 | packages = [ 23 | 'jsoneditor', 24 | 'jsoneditor.fields' 25 | ], 26 | package_data = { 27 | 'jsoneditor':[ 28 | 'static/jsoneditor/*.js', 29 | 'static/jsoneditor/*.css', 30 | 'static/jsoneditor/img/*', 31 | 'static/django-jsoneditor/*.js', 32 | 'static/django-jsoneditor/*.css', 33 | ] 34 | }, 35 | include_package_data = True, 36 | zip_safe = False, 37 | install_requires=['packaging'] 38 | ) 39 | -------------------------------------------------------------------------------- /testapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnseva/django-jsoneditor/dfc1ad59ef7da77c754a1beb31f07417e2a3a334/testapp/__init__.py -------------------------------------------------------------------------------- /testapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from . import models 4 | # Register your models here. 5 | 6 | class TestStackedInline(admin.StackedInline): 7 | model = models.TestSubModel1 8 | extra = 1 9 | 10 | class TestTabularInline(admin.StackedInline): 11 | model = models.TestSubModel2 12 | extra = 1 13 | 14 | class TestAdmin(admin.ModelAdmin): 15 | inlines = ( 16 | TestStackedInline, 17 | TestTabularInline 18 | ) 19 | pass 20 | 21 | admin.site.register(models.TestModel,TestAdmin) -------------------------------------------------------------------------------- /testapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import jsoneditor.fields.jsonfield 6 | #import jsoneditor.fields.django_json_field 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='TestModel', 17 | fields=[ 18 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 19 | # ('test_django_json_field', jsoneditor.fields.django_json_field.JSONField(default='null', help_text=b'Test JSON editor for the django-json-field from https://github.com/derek-schaefer/django-json-field', null=True, verbose_name=b'Test JSON 1', blank=True)), 20 | ('test_django_jsonfield', jsoneditor.fields.jsonfield.JSONField(help_text=b'Test JSON editor for the django-jsonfield from https://github.com/bradjasper/django-jsonfield', null=True, verbose_name=b'Test JSON 2', blank=True)), 21 | ], 22 | ), 23 | migrations.CreateModel( 24 | name='TestSubModel1', 25 | fields=[ 26 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 27 | ('test_inline_json_field', jsoneditor.fields.jsonfield.JSONField(default='null', help_text=b'Test JSON editor for the django-json-field from https://github.com/derek-schaefer/django-json-field', null=True, verbose_name=b'Test JSON 1', blank=True)), 28 | ('par', models.ForeignKey(to='testapp.TestModel', on_delete=models.CASCADE)), 29 | ], 30 | ), 31 | migrations.CreateModel( 32 | name='TestSubModel2', 33 | fields=[ 34 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 35 | ('test_inline_json_field', jsoneditor.fields.jsonfield.JSONField(default='null', help_text=b'Test JSON editor for the django-json-field from https://github.com/derek-schaefer/django-json-field', null=True, verbose_name=b'Test JSON 1', blank=True)), 36 | ('par', models.ForeignKey(to='testapp.TestModel', on_delete=models.CASCADE)), 37 | ], 38 | ), 39 | ] 40 | -------------------------------------------------------------------------------- /testapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnseva/django-jsoneditor/dfc1ad59ef7da77c754a1beb31f07417e2a3a334/testapp/migrations/__init__.py -------------------------------------------------------------------------------- /testapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | #from jsoneditor.fields.django_json_field import JSONField as JSONField1 4 | #from jsoneditor.fields.django_jsonfield import JSONField as JSONField2 5 | from jsoneditor.fields.jsonfield import JSONField as JSONField2 6 | # Create your models here. 7 | 8 | class TestModel(models.Model): 9 | # test_django_json_field = JSONField1(verbose_name="Test JSON 1",null=True,blank=True,help_text="Test JSON editor for the django-json-field from https://github.com/derek-schaefer/django-json-field") 10 | test_django_jsonfield = JSONField2() 11 | 12 | class TestSubModel1(models.Model): 13 | par = models.ForeignKey(TestModel, on_delete=models.CASCADE) 14 | test_inline_json_field = JSONField2(verbose_name="Test JSON 2",null=True,blank=True,help_text="Test JSON editor for the django-jsonfield from https://github.com/bradjasper/django-jsonfield") 15 | 16 | class TestSubModel2(models.Model): 17 | par = models.ForeignKey(TestModel, on_delete=models.CASCADE) 18 | test_inline_json_field = JSONField2(verbose_name="Test JSON 2",null=True,blank=True,help_text="Test JSON editor for the django-jsonfield from https://github.com/bradjasper/django-jsonfield") 19 | -------------------------------------------------------------------------------- /testapp/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /testapp/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /testapp2/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnseva/django-jsoneditor/dfc1ad59ef7da77c754a1beb31f07417e2a3a334/testapp2/__init__.py -------------------------------------------------------------------------------- /testapp2/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from . import models 4 | # Register your models here. 5 | 6 | class TestStackedInline(admin.StackedInline): 7 | model = models.TestSubModel1 8 | extra = 1 9 | 10 | class TestTabularInline(admin.StackedInline): 11 | model = models.TestSubModel2 12 | extra = 1 13 | 14 | class TestAdmin(admin.ModelAdmin): 15 | inlines = ( 16 | TestStackedInline, 17 | TestTabularInline 18 | ) 19 | pass 20 | 21 | admin.site.register(models.TestModel,TestAdmin) -------------------------------------------------------------------------------- /testapp2/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.13 on 2017-06-02 09:56 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | import jsoneditor.fields.django3_jsonfield 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | initial = True 13 | 14 | dependencies = [ 15 | ] 16 | 17 | operations = [ 18 | migrations.CreateModel( 19 | name='TestModel', 20 | fields=[ 21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 22 | ('test_django_jsonfield', jsoneditor.fields.django3_jsonfield.JSONField(blank=True, help_text=b'Test JSON editor for the django postgres-specific JSONField', null=True, verbose_name=b'Test JSON')), 23 | ], 24 | ), 25 | migrations.CreateModel( 26 | name='TestSubModel1', 27 | fields=[ 28 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 29 | ('test_inline_json_field', jsoneditor.fields.django3_jsonfield.JSONField(blank=True, help_text=b'Test JSON editor for the django postgres-specific JSONField', null=True, verbose_name=b'Test JSON')), 30 | ('par', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='testapp2.TestModel')), 31 | ], 32 | ), 33 | migrations.CreateModel( 34 | name='TestSubModel2', 35 | fields=[ 36 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 37 | ('test_inline_json_field', jsoneditor.fields.django3_jsonfield.JSONField(blank=True, help_text=b'Test JSON editor for the django postgres-specific JSONField', null=True, verbose_name=b'Test JSON')), 38 | ('par', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='testapp2.TestModel')), 39 | ], 40 | ), 41 | ] 42 | -------------------------------------------------------------------------------- /testapp2/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnseva/django-jsoneditor/dfc1ad59ef7da77c754a1beb31f07417e2a3a334/testapp2/migrations/__init__.py -------------------------------------------------------------------------------- /testapp2/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from jsoneditor.fields.django3_jsonfield import JSONField 4 | # Create your models here. 5 | 6 | class TestModel(models.Model): 7 | test_django_jsonfield = JSONField(verbose_name="Test JSON",null=True,blank=True,help_text="Test JSON editor for the django postgres-specific JSONField") 8 | 9 | class TestSubModel1(models.Model): 10 | par = models.ForeignKey(TestModel, on_delete=models.CASCADE) 11 | test_inline_json_field = JSONField(verbose_name="Test JSON",null=True,blank=True,help_text="Test JSON editor for the django postgres-specific JSONField") 12 | 13 | class TestSubModel2(models.Model): 14 | par = models.ForeignKey(TestModel, on_delete=models.CASCADE) 15 | test_inline_json_field = JSONField(verbose_name="Test JSON",null=True,blank=True,help_text="Test JSON editor for the django postgres-specific JSONField") 16 | -------------------------------------------------------------------------------- /testapp2/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /testapp2/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | --------------------------------------------------------------------------------