├── .editorconfig ├── .github └── workflows │ ├── behat-test.yml │ ├── cs-lint.yml │ └── integrations.yml ├── .gitignore ├── .phpcs.xml.dist ├── README.md ├── bin └── install-wp-tests.sh ├── composer.json ├── css ├── custom-metadata-manager.css ├── images │ ├── calendar.png │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ ├── ui-bg_flat_75_ffffff_40x100.png │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ ├── ui-bg_glass_65_ffffff_1x400.png │ ├── ui-bg_glass_75_dadada_1x400.png │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ ├── ui-bg_glass_95_fef1ec_1x400.png │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── ui-icons_222222_256x240.png │ ├── ui-icons_2e83ff_256x240.png │ ├── ui-icons_454545_256x240.png │ ├── ui-icons_888888_256x240.png │ └── ui-icons_cd0a0a_256x240.png ├── jquery-ui-smoothness.css ├── select2.css ├── select2.png ├── select2x2.png └── spinner.gif ├── custom_metadata.php ├── custom_metadata_examples.php ├── js ├── custom-metadata-manager.js ├── images │ └── calendar.png ├── jquery-ui-timepicker.min.js └── select2.min.js ├── phpunit.xml.dist ├── screenshot-1.jpg ├── screenshot-2.jpg ├── screenshot-3.jpg └── tests └── bootstrap.php /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # It is based on https://core.trac.wordpress.org/browser/trunk/.editorconfig 3 | # See https://editorconfig.org for more information about the standard. 4 | 5 | # WordPress Coding Standards 6 | # https://make.wordpress.org/core/handbook/coding-standards/ 7 | 8 | root = true 9 | 10 | [*] 11 | charset = utf-8 12 | end_of_line = lf 13 | insert_final_newline = true 14 | trim_trailing_whitespace = true 15 | indent_style = tab 16 | 17 | [{*.yml,*.feature}] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | [*.md] 22 | trim_trailing_whitespace = false 23 | 24 | [*.txt] 25 | end_of_line = crlf 26 | -------------------------------------------------------------------------------- /.github/workflows/behat-test.yml: -------------------------------------------------------------------------------- 1 | name: Behat Testing 2 | 3 | on: 4 | push: 5 | paths: 6 | - '.github/workflows/behat-test.yml' 7 | - '**.php' 8 | - '**.feature' 9 | - 'behat.yml' 10 | - 'composer.json' 11 | pull_request: 12 | paths: 13 | - '.github/workflows/behat-test.yml' 14 | - '**.php' 15 | - '**.feature' 16 | - 'behat.yml' 17 | - 'composer.json' 18 | types: 19 | - opened 20 | - reopened 21 | - synchronize 22 | 23 | workflow_dispatch: 24 | 25 | jobs: 26 | behat: 27 | uses: automattic/wpvip-plugins-.github/.github/workflows/reusable-behat-test.yml@trunk 28 | -------------------------------------------------------------------------------- /.github/workflows/cs-lint.yml: -------------------------------------------------------------------------------- 1 | name: CS & Lint 2 | 3 | on: 4 | # Run on all pushes and on all pull requests. 5 | # Prevent the "push" build from running when there are only irrelevant changes. 6 | push: 7 | paths-ignore: 8 | - "**.md" 9 | pull_request: 10 | # Allow manually triggering the workflow. 11 | workflow_dispatch: 12 | 13 | jobs: 14 | checkcs: 15 | name: "Basic CS and QA checks" 16 | runs-on: ubuntu-latest 17 | 18 | env: 19 | XMLLINT_INDENT: " " 20 | 21 | steps: 22 | - name: Setup PHP 23 | uses: shivammathur/setup-php@v2 24 | with: 25 | php-version: "7.4" 26 | coverage: none 27 | tools: cs2pr 28 | 29 | # Show PHP lint violations inline in the file diff. 30 | # @link https://github.com/marketplace/actions/xmllint-problem-matcher 31 | - name: Register PHP lint violations to appear as file diff comments 32 | uses: korelstar/phplint-problem-matcher@v1 33 | 34 | # Show XML violations inline in the file diff. 35 | # @link https://github.com/marketplace/actions/xmllint-problem-matcher 36 | - name: Register XML violations to appear as file diff comments 37 | uses: korelstar/xmllint-problem-matcher@v1 38 | 39 | - name: Checkout code 40 | uses: actions/checkout@v2 41 | 42 | # Validate the composer.json file. 43 | # @link https://getcomposer.org/doc/03-cli.md#validate 44 | - name: Validate Composer installation 45 | run: composer validate --no-check-all 46 | 47 | # Install dependencies and handle caching in one go. 48 | # @link https://github.com/marketplace/actions/install-composer-dependencies 49 | - name: Install Composer dependencies 50 | uses: ramsey/composer-install@v1 51 | 52 | # Lint PHP. 53 | - name: Lint PHP against parse errors 54 | run: composer lint-ci | cs2pr 55 | 56 | # Needed as runs-on: system doesn't have xml-lint by default. 57 | # @link https://github.com/marketplace/actions/xml-lint 58 | - name: Lint phpunit.xml.dist 59 | uses: ChristophWurst/xmllint-action@v1 60 | with: 61 | xml-file: ./phpunit.xml.dist 62 | xml-schema-file: ./vendor/phpunit/phpunit/phpunit.xsd 63 | 64 | # Check the code-style consistency of the PHP files. 65 | # - name: Check PHP code style 66 | # continue-on-error: true 67 | # run: vendor/bin/phpcs --report-full --report-checkstyle=./phpcs-report.xml 68 | 69 | # - name: Show PHPCS results in PR 70 | # run: cs2pr ./phpcs-report.xml 71 | -------------------------------------------------------------------------------- /.github/workflows/integrations.yml: -------------------------------------------------------------------------------- 1 | name: Run PHPUnit 2 | 3 | on: 4 | # Run on all pushes and on all pull requests. 5 | # Prevent the "push" build from running when there are only irrelevant changes. 6 | push: 7 | paths-ignore: 8 | - "**.md" 9 | pull_request: 10 | # Allow manually triggering the workflow. 11 | workflow_dispatch: 12 | 13 | jobs: 14 | test: 15 | name: WP ${{ matrix.wordpress }} on PHP ${{ matrix.php }} 16 | # Ubuntu-20.x includes MySQL 8.0, which causes `caching_sha2_password` issues with PHP < 7.4 17 | # https://www.php.net/manual/en/mysqli.requirements.php 18 | # TODO: change to ubuntu-latest when we no longer support PHP < 7.4 19 | runs-on: ubuntu-18.04 20 | 21 | env: 22 | WP_VERSION: ${{ matrix.wordpress }} 23 | 24 | strategy: 25 | matrix: 26 | wordpress: ["5.5", "5.6", "5.7"] 27 | php: ["5.6", "7.0", "7.1", "7.2", "7.3", "7.4"] 28 | include: 29 | - php: "8.0" 30 | # Ignore platform requirements, so that PHPUnit 7.5 can be installed on PHP 8.0 (and above). 31 | composer-options: "--ignore-platform-reqs" 32 | extensions: pcov 33 | ini-values: pcov.directory=., "pcov.exclude=\"~(vendor|tests)~\"" 34 | coverage: pcov 35 | exclude: 36 | - php: "8.0" 37 | wordpress: "5.5" 38 | fail-fast: false 39 | 40 | steps: 41 | - name: Checkout code 42 | uses: actions/checkout@v2 43 | 44 | - name: Setup PHP ${{ matrix.php }} 45 | uses: shivammathur/setup-php@v2 46 | with: 47 | php-version: ${{ matrix.php }} 48 | extensions: ${{ matrix.extensions }} 49 | ini-values: ${{ matrix.ini-values }} 50 | coverage: ${{ matrix.coverage }} 51 | 52 | - name: Setup problem matchers for PHP 53 | run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" 54 | 55 | # Setup PCOV since we're using PHPUnit < 8 which has it integrated. Requires PHP 7.1. 56 | # Ignore platform reqs to make it install on PHP 8. 57 | # https://github.com/krakjoe/pcov-clobber 58 | - name: Setup PCOV 59 | if: ${{ matrix.php == 8.0 }} 60 | run: | 61 | composer require pcov/clobber --ignore-platform-reqs 62 | vendor/bin/pcov clobber 63 | 64 | - name: Setup Problem Matchers for PHPUnit 65 | run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" 66 | 67 | - name: Install Composer dependencies 68 | uses: ramsey/composer-install@v1 69 | with: 70 | composer-options: "${{ matrix.composer-options }}" 71 | 72 | - name: Start MySQL Service 73 | run: sudo systemctl start mysql.service 74 | 75 | - name: Prepare environment for integration tests 76 | run: composer prepare-ci 77 | 78 | - name: Run integration tests (single site) 79 | if: ${{ matrix.php != 8.0 }} 80 | run: composer test 81 | - name: Run integration tests (single site with code coverage) 82 | if: ${{ matrix.php == 8.0 }} 83 | run: composer coverage-ci 84 | - name: Run integration tests (multisite) 85 | run: composer test-ms 86 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor/ 3 | wpcom-helper.php 4 | custom-metadata.php 5 | -------------------------------------------------------------------------------- /.phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | Custom ruleset for custom-metadata plugin. 4 | 5 | 6 | 7 | 8 | 9 | . 10 | 12 | /vendor/ 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Custom Metadata Manager for WordPress 2 | 3 | This code-only developer WordPress plugin allows you to add custom fields to your object types (post, pages, custom post types, users) 4 | 5 | This is a WordPress Plugin. We sync changes between github and the [WordPress.org plugin repository](http://wordpress.org/extend/plugins/custom-metadata/). Why? Because collaboration is made much easier on github :) 6 | 7 | **NOTE**: The plugin requires WordPress 3.5+ 8 | 9 | 10 | # Installation 11 | 12 | 1. Install through the WordPress admin or upload the plugin folder to your `/wp-content/plugins/` directory 13 | 2. Activate the plugin through the 'Plugins' menu in WordPress 14 | 3. Add the necessary code to register your custom groups and fields to your functions.php or plugin. 15 | 4. Enjoy! 16 | 17 | # Frequently Asked Questions 18 | 19 | 20 | ## Why a code-based approach instead of a UI? 21 | 22 | Because the UI thing has [been](http://wordpress.org/extend/plugins/verve-meta-boxes/) [done](http://wordpress.org/extend/plugins/fresh-page/) [before](http://wordpress.org/extend/plugins/pods/). And this more closely aligns with the existing WordPress approach of registering new types of content (post types, taxonomies, etc.) 23 | 24 | This is also a developer feature, aimed towards site builders. And real developers don't need UIs ;) 25 | 26 | (But really, though, the main benefit of this fact comes into play when you're working with multiple environments, i.e. development/local, qa/staging, production. This approach makes it easy to replicate UIs and features without having to worry about database synchronization and other crazy things.) 27 | 28 | For another really well-done, really powerful code-based plugin for managing custom fields, check out [Easy Custom Fields](http://wordpress.org/extend/plugins/easy-custom-fields/) and the [Custom Metaboxes and Fields For WordPress Class](https://github.com/jaredatch/Custom-Metaboxes-and-Fields-for-WordPress). 29 | 30 | 31 | ## Why isn't the function just `add_metadata_field`? Do you really need the stupid `x_`? 32 | 33 | We're being good and ["namespacing" our public functions](http://andrewnacin.com/2010/05/11/in-wordpress-prefix-everything/). You should too. 34 | 35 | 36 | ## How do I use this plugin? 37 | 38 | There are usage instructions below 39 | 40 | # Changelog 41 | 42 | ## 0.8 (currently under development) 43 | 44 | * added ability to group several fields as a `multifield`; see `x_add_metadata_multifield()`, props @greatislander, @rinatkhaziev and @PhilippSchreiber for their contributions there 45 | * allow field types that save as multiples but don't display as cloneable or multiples 46 | * added the `taxonomy_checkbox` and `taxonomy_multi_select` field types, props @greatislander 47 | * made use of the `selected()` and `checked()` functions in WordPress instead of clumsy if statements 48 | * limit or exclude groups and fields using a custom callback 49 | * adjusted the copyright to include 2013 and to list "The Contributors" instead of specific individuals 50 | * adjusted the list of contributors in the plugin 51 | * adjusted the plugin URL and removed the donate URL 52 | * adjusted files for code standards 53 | * fixed PHP warning with empty values for date fields 54 | * moved filtering of instance vars to `init` instead of on `construct` which runs too early 55 | * added new field types: `number`, `email`, `telephone`, `datetimepicker`, `timepicker` and `link` (which uses the WP link manager) 56 | * added ability to add default value for certain field types 57 | * added ability to set placeholder for certain fields 58 | * updated the examples file 59 | * rewrote the `upload` field to use the media manager from WordPress 3.5+. Note the `upload` field is now `readonly` by default (but can be set to `false` when you setup the field) 60 | * updated JavaScript to be up to standard with coding standards and be fully compatible with jQuery 1.9+ 61 | * replaced chosen.js with select2.js 62 | * reformat and clean up css file 63 | * added ability for groups to display a description 64 | * added ability to limit capabilities for entire groups using `required_cap` 65 | * convert plugin class to singleton 66 | 67 | ## 0.7 68 | 69 | * added the ability to have readonly fields with the new `readonly` paramater 70 | 71 | ## 0.6 72 | 73 | * note: the plugin now requires WordPress 3.3+ (chiefly for the wysiwyg & datepicker fields) 74 | * update/clean-up the examples file 75 | * properly enqueue admin css for WP 3.3+ 76 | * added a filter for the `CUSTOM_METADATA_MANAGER_URL` constant 77 | * fix fields not appearing when editing users in WP 3.3+ (props @FolioVision) 78 | * now passing the `$value` for a `display_callback` (props @FolioVision) 79 | * use the new `wp_editor()` function (since WP 3.3+) instead of `the_editor()` (now deprecated) 80 | * wysiwyg fields are no longer cloneable (may be revisited in a future version) 81 | * note: metaboxes that have a wysiwyg field will break when moved, this is not a bug per-se (may be revisited in a future version) 82 | * password fields are now cloneable 83 | * added filters for most of the plugin's internal variables 84 | * now using WordPress' built-in jQuery UI for the datepicker field 85 | * updated the screenshots 86 | * updated the instructions in readme.txt 87 | 88 | ## 0.5.7 89 | 90 | * pass additional params for `display_callback` 91 | 92 | ## 0.5.6 93 | 94 | * fix bugs with datepicker 95 | 96 | ## 0.5.5 97 | 98 | * remove all whitespace 99 | * fix some bugs with the tinymce field 100 | 101 | ## 0.5.4 102 | 103 | * fix display_callback for fields 104 | 105 | ## 0.5.3 106 | 107 | * removed php opening shorttags ` $group_slug, // Label for the group 205 | 'context' => 'normal', // (post only) 206 | 'priority' => 'default', // (post only) 207 | 'autosave' => false, // (post only) Should the group be saved in autosave? NOT IMPLEMENTED YET! 208 | 'exclude' => '', // see below for details 209 | 'include' => '', // see below for details 210 | ); 211 | ``` 212 | 213 | ### Adding Metadata Fields 214 | 215 | `x_add_metadata_field( $slug, $object_types, $args );` 216 | 217 | 218 | #### Parameters 219 | 220 | * `$slug` (string) The key under which the metadata will be stored. For post_types, prefix the slug with an underscore (e.g. `_hidden`) to hide it from the the Custom Fields box. 221 | * `$object_types` (string|array) The object types to which this field should be added. Supported: post, page, any custom post type, user, comment. 222 | 223 | 224 | #### Options and Overrides 225 | 226 | ```php 227 | $args = array( 228 | 'group' => '', // The slug of group the field should be added to. This needs to be registered with x_add_metadata_group first. 229 | 'field_type' => 'text', // The type of field; 'text', 'textarea', 'password', 'checkbox', 'radio', 'select', 'upload', 'wysiwyg', 'datepicker', 'taxonomy_select', 'taxonomy_radio' 230 | 'label' => '', // Label for the field 231 | 'description' => '', // Description of the field, displayed below the input 232 | 'values' => array(), // Values for select and radio buttons. Associative array 233 | 'display_callback' => '', // Callback to custom render the field 234 | 'sanitize_callback' => '', // Callback to sanitize data before it's saved 235 | 'display_column' => false, // Add the field to the columns when viewing all posts 236 | 'display_column_callback' => '', // Callback to render output for the custom column 237 | 'required_cap' => '', // The cap required to view and edit the field 238 | 'exclude' => '', // see below for details 239 | 'include' => '', // see below for details 240 | 'multiple' => false, // true or false, can the field be duplicated with a click of a button? 241 | 'readonly' => false, // makes the field be readonly (works with text, textarea, password, upload and datepicker fields) 242 | ); 243 | ``` 244 | 245 | #### Include / Exclude 246 | 247 | You can exclude fields and groups from specific object. For example, with the following, field-1 will show up for all posts except post #123: 248 | 249 | ```php 250 | $args = array( 251 | 'exclude' => 123 252 | ); 253 | x_add_metadata_field( 'field-1', 'post', $args ); 254 | ``` 255 | 256 | Alternatively, you can limit ("include") fields and groups to specific objects. The following will ''only'' show group-1 to post #456: 257 | 258 | ```php 259 | $args = array( 260 | 'include' => 123 261 | ); 262 | x_add_metadata_group( 'group-1', 'post', $args ); 263 | ``` 264 | 265 | You can pass in an array of IDs: 266 | 267 | ```php 268 | $args = array( 269 | 'include' => array( 123, 456, 789 ); 270 | ); 271 | ``` 272 | 273 | With multiple object types, you can pass in an associative array: 274 | 275 | ```php 276 | $args = array( 277 | 'exclude' => array( 278 | 'post' => 123, 279 | 'user' => array( 123, 456, 789 ) 280 | ) 281 | ); 282 | ``` 283 | You can also pass in a callback to programattically include or exclude posts: 284 | 285 | ```php 286 | $args = array( 287 | 'exclude' => function( $thing_slug, $thing, $object_type, $object_id, $object_slug ) { 288 | // exclude from all posts that are in the aside category. 289 | return in_category( 'aside', $object_id ); 290 | } 291 | ); 292 | ``` 293 | 294 | ```php 295 | $args = array( 296 | 'include' => function( $thing_slug, $thing, $object_type, $object_id, $object_slug ) { 297 | // include for posts that are not published. 298 | $post = get_post( $object_id ); 299 | return 'publish' != $post->post_status; 300 | } 301 | ); 302 | ``` 303 | 304 | # Examples 305 | 306 | For examples, please see the [custom_metadata_examples.php](https://github.com/jkudish/custom-metadata/blob/master/custom_metadata_examples.php) file included with the plugin. Add a constant to your wp-config.php called `CUSTOM_METADATA_MANAGER_DEBUG` with a value of `true` to see it in action: 307 | 308 | `define( 'CUSTOM_METADATA_MANAGER_DEBUG', true );` 309 | 310 | 311 | # License 312 | 313 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 314 | 315 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 316 | 317 | You should have received a copy of the GNU General Public License along with this program; if not, write to: 318 | 319 | Free Software Foundation, Inc. 320 | 51 Franklin Street, Fifth Floor, 321 | Boston, MA 322 | 02110-1301, USA. 323 | -------------------------------------------------------------------------------- /bin/install-wp-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -lt 3 ]; then 4 | echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" 5 | exit 1 6 | fi 7 | 8 | DB_NAME=$1 9 | DB_USER=$2 10 | DB_PASS=$3 11 | DB_HOST=${4-localhost} 12 | WP_VERSION=${5-latest} 13 | SKIP_DB_CREATE=${6-false} 14 | 15 | TMPDIR=${TMPDIR-/tmp} 16 | TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//") 17 | WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib} 18 | WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress} 19 | 20 | download() { 21 | if [ `which curl` ]; then 22 | curl -s "$1" > "$2"; 23 | elif [ `which wget` ]; then 24 | wget -nv -O "$2" "$1" 25 | fi 26 | } 27 | 28 | if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then 29 | WP_BRANCH=${WP_VERSION%\-*} 30 | WP_TESTS_TAG="branches/$WP_BRANCH" 31 | 32 | elif [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then 33 | WP_TESTS_TAG="branches/$WP_VERSION" 34 | elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then 35 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then 36 | # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x 37 | WP_TESTS_TAG="tags/${WP_VERSION%??}" 38 | else 39 | WP_TESTS_TAG="tags/$WP_VERSION" 40 | fi 41 | elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then 42 | WP_TESTS_TAG="trunk" 43 | else 44 | # http serves a single offer, whereas https serves multiple. we only want one 45 | download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json 46 | grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json 47 | LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') 48 | if [[ -z "$LATEST_VERSION" ]]; then 49 | echo "Latest WordPress version could not be found" 50 | exit 1 51 | fi 52 | WP_TESTS_TAG="tags/$LATEST_VERSION" 53 | fi 54 | set -ex 55 | 56 | install_wp() { 57 | 58 | if [ -d $WP_CORE_DIR ]; then 59 | return; 60 | fi 61 | 62 | mkdir -p $WP_CORE_DIR 63 | 64 | if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then 65 | mkdir -p $TMPDIR/wordpress-trunk 66 | rm -rf $TMPDIR/wordpress-trunk/* 67 | svn export --quiet https://core.svn.wordpress.org/trunk $TMPDIR/wordpress-trunk/wordpress 68 | mv $TMPDIR/wordpress-trunk/wordpress/* $WP_CORE_DIR 69 | else 70 | if [ $WP_VERSION == 'latest' ]; then 71 | local ARCHIVE_NAME='latest' 72 | elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then 73 | # https serves multiple offers, whereas http serves single. 74 | download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json 75 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then 76 | # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x 77 | LATEST_VERSION=${WP_VERSION%??} 78 | else 79 | # otherwise, scan the releases and get the most up to date minor version of the major release 80 | local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'` 81 | LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1) 82 | fi 83 | if [[ -z "$LATEST_VERSION" ]]; then 84 | local ARCHIVE_NAME="wordpress-$WP_VERSION" 85 | else 86 | local ARCHIVE_NAME="wordpress-$LATEST_VERSION" 87 | fi 88 | else 89 | local ARCHIVE_NAME="wordpress-$WP_VERSION" 90 | fi 91 | download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz 92 | tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR 93 | fi 94 | 95 | download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php 96 | } 97 | 98 | install_test_suite() { 99 | # portable in-place argument for both GNU sed and Mac OSX sed 100 | if [[ $(uname -s) == 'Darwin' ]]; then 101 | local ioption='-i.bak' 102 | else 103 | local ioption='-i' 104 | fi 105 | 106 | # set up testing suite if it doesn't yet exist 107 | if [ ! -d $WP_TESTS_DIR ]; then 108 | # set up testing suite 109 | mkdir -p $WP_TESTS_DIR 110 | rm -rf $WP_TESTS_DIR/{includes,data} 111 | svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes 112 | svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data 113 | fi 114 | 115 | if [ ! -f wp-tests-config.php ]; then 116 | download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php 117 | # remove all forward slashes in the end 118 | WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") 119 | sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php 120 | sed $ioption "s:__DIR__ . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php 121 | sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php 122 | sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php 123 | sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php 124 | sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php 125 | fi 126 | 127 | } 128 | 129 | recreate_db() { 130 | shopt -s nocasematch 131 | if [[ $1 =~ ^(y|yes)$ ]] 132 | then 133 | mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA 134 | create_db 135 | echo "Recreated the database ($DB_NAME)." 136 | else 137 | echo "Leaving the existing database ($DB_NAME) in place." 138 | fi 139 | shopt -u nocasematch 140 | } 141 | 142 | create_db() { 143 | mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA 144 | } 145 | 146 | install_db() { 147 | 148 | if [ ${SKIP_DB_CREATE} = "true" ]; then 149 | return 0 150 | fi 151 | 152 | # parse DB_HOST for port or socket references 153 | local PARTS=(${DB_HOST//\:/ }) 154 | local DB_HOSTNAME=${PARTS[0]}; 155 | local DB_SOCK_OR_PORT=${PARTS[1]}; 156 | local EXTRA="" 157 | 158 | if ! [ -z $DB_HOSTNAME ] ; then 159 | if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then 160 | EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" 161 | elif ! [ -z $DB_SOCK_OR_PORT ] ; then 162 | EXTRA=" --socket=$DB_SOCK_OR_PORT" 163 | elif ! [ -z $DB_HOSTNAME ] ; then 164 | EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" 165 | fi 166 | fi 167 | 168 | # create database 169 | if [ $(mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute='show databases;' | grep ^$DB_NAME$) ] 170 | then 171 | echo "Reinstalling will delete the existing test database ($DB_NAME)" 172 | read -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB 173 | recreate_db $DELETE_EXISTING_DB 174 | else 175 | create_db 176 | fi 177 | } 178 | 179 | install_wp 180 | install_test_suite 181 | install_db 182 | 183 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "automattic/custom-metadata", 3 | "type": "wordpress-plugin", 4 | "description": "An easy way to add custom fields to your object types", 5 | "homepage": "https://github.com/Automattic/custom-metadata/", 6 | "license": "GPL-2.0-or-later", 7 | "authors": [ 8 | { 9 | "name": "Automattic", 10 | "homepage": "https://automattic.com/" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.6", 15 | "composer/installers": "~1.0" 16 | }, 17 | "require-dev": { 18 | "automattic/vipwpcs": "^2.2", 19 | "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7", 20 | "php-parallel-lint/php-parallel-lint": "^1.0", 21 | "phpcompatibility/phpcompatibility-wp": "^2.1", 22 | "phpunit/phpunit": "^4 || ^5 || ^6 || ^7", 23 | "squizlabs/php_codesniffer": "^3.5", 24 | "wp-coding-standards/wpcs": "^2.3.0", 25 | "yoast/phpunit-polyfills": "^0.2.0" 26 | }, 27 | "scripts": { 28 | "cbf": [ 29 | "@php ./vendor/bin/phpcbf" 30 | ], 31 | "coverage": [ 32 | "@php ./vendor/bin/phpunit --coverage-html ./build/coverage-html" 33 | ], 34 | "coverage-ci": [ 35 | "@php ./vendor/bin/phpunit" 36 | ], 37 | "cs": [ 38 | "@php ./vendor/bin/phpcs" 39 | ], 40 | "lint": [ 41 | "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git" 42 | ], 43 | "lint-ci": [ 44 | "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git --checkstyle" 45 | ], 46 | "prepare-ci": [ 47 | "bash bin/install-wp-tests.sh wordpress_test root root localhost" 48 | ], 49 | "test": [ 50 | "@php ./vendor/bin/phpunit --testsuite WP_Tests" 51 | ], 52 | "test-ms": [ 53 | "@putenv WP_MULTISITE=1", 54 | "@composer test" 55 | ] 56 | }, 57 | "support": { 58 | "issues": "https://github.com/Automattic/custom-metadata/issues", 59 | "source": "https://github.com/Automattic/custom-metadata" 60 | }, 61 | "config": { 62 | "allow-plugins": { 63 | "composer/installers": true, 64 | "dealerdirect/phpcodesniffer-composer-installer": true 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /css/custom-metadata-manager.css: -------------------------------------------------------------------------------- 1 | /* group descriptions */ 2 | .custom-metadata-group-description { 3 | margin: 15px 0; 4 | } 5 | 6 | /* general fields */ 7 | .custom-metadata-field { 8 | margin-bottom: 15px 9 | } 10 | .inside > .custom-metadata-field:first-child { 11 | margin-top: 20px 12 | } 13 | .custom-metadata-field > label { 14 | display: block; 15 | font-size: 13px; 16 | line-height: 18px; 17 | font-weight: bold; 18 | margin: 5px 0; 19 | } 20 | .custom-metadata-field .description { 21 | display: block; 22 | font-size: 11px; 23 | margin-top: 3px; 24 | } 25 | .custom-metadata-field > div > label { 26 | display: block; 27 | margin: 5px 0; 28 | } 29 | .custom-metadata-field .error { 30 | color: red; 31 | font-style: italic; 32 | } 33 | .custom-metadata-field .del-multiple { 34 | color: red; 35 | } 36 | .custom-metadata-field input ~ .del-multiple { 37 | margin-left: 5px; 38 | } 39 | 40 | /* text fields */ 41 | .custom-metadata-field input[type="text"], 42 | .custom-metadata-field input[type="url"], 43 | .custom-metadata-field input[type="password"], 44 | .custom-metadata-field input[type="email"] { 45 | width: 65%; 46 | margin: 3px 0; 47 | } 48 | 49 | /* number fields */ 50 | .custom-metadata-field input[type="number"] { 51 | width: 65px; 52 | } 53 | 54 | /* radio fields */ 55 | .custom-metadata-field > div > label > input[type="radio"] { 56 | margin-right: 5px; 57 | } 58 | 59 | /* checkbox fields */ 60 | .custom-metadata-field.checkbox { 61 | background: transparent; 62 | } 63 | 64 | .custom-metadata-field input[type="checkbox"] { 65 | margin-right: 5px; 66 | } 67 | 68 | /* upload & link fields */ 69 | .custom-metadata-field input.upload_field, 70 | .custom-metadata-field input.link_field { 71 | width: 60%; 72 | } 73 | 74 | .custom-metadata-field.upload input[type="button"], 75 | .custom-metadata-field.link input[type="button"] { 76 | margin-left: 10px; 77 | } 78 | 79 | /* datepicker fields */ 80 | .custom-metadata-field.datepicker input { 81 | width: 200px 82 | } 83 | 84 | /* timepicker fields */ 85 | .ui-timepicker-div .ui-widget-header { 86 | margin-bottom: 8px; 87 | } 88 | .ui-timepicker-div dl { 89 | text-align: left; 90 | } 91 | .ui-timepicker-div dl dt { 92 | height: 25px; margin-bottom: -25px; 93 | } 94 | .ui-timepicker-div dl dd { 95 | margin: 0 10px 10px 65px; 96 | } 97 | .ui-timepicker-div td { 98 | font-size: 90%; 99 | } 100 | .ui-tpicker-grid-label { 101 | background: none; border: none; margin: 0; padding: 0; 102 | } 103 | .ui-timepicker-rtl{ 104 | direction: rtl; 105 | } 106 | .ui-timepicker-rtl dl { 107 | text-align: right; 108 | } 109 | .ui-timepicker-rtl dl dd { 110 | margin: 0 65px 10px 10px; 111 | } 112 | 113 | /* textarea fields */ 114 | .custom-metadata-field textarea { 115 | width: 99%; 116 | height: 4em; 117 | margin-top: 5px; 118 | } 119 | .custom-metadata-field textarea[readonly="readonly"] { 120 | background-color: #eee; 121 | } 122 | 123 | /* wysiwyg fields */ 124 | .custom-metadata-field.wysiwyg > label, 125 | .user-metadata-group .custom-metadata-field.wysiwyg > label { 126 | display: block; 127 | width: 100%; 128 | float: none; 129 | } 130 | .custom-metadata-field.wysiwyg .wp-editor-container { 131 | background: #fff 132 | } 133 | 134 | 135 | /* user fields */ 136 | .user-metadata-group .custom-metadata-field > label { 137 | color: #222; 138 | display: block; 139 | text-align: left; 140 | vertical-align: top; 141 | width: 200px; 142 | font-size: 13px; 143 | line-height: 24px; 144 | float: left; 145 | } 146 | .user-metadata-group .custom-metadata-field input[type=text], 147 | .user-metadata-group .custom-metadata-field input[type=url], 148 | .user-metadata-group .custom-metadata-field input[type=password], 149 | .user-metadata-group .custom-metadata-field input[type=email] { 150 | width: 25em; 151 | } 152 | .user-metadata-group .custom-metadata-field textarea { 153 | width: 25em; 154 | } 155 | .user-metadata-group .custom-metadata-field .description { 156 | margin-left: 200px; 157 | } 158 | 159 | /* select2 fields */ 160 | .custom-metadata-field select { 161 | min-width: 200px; 162 | max-width: 400px; 163 | } 164 | .custom-metadata-field select[multiple], 165 | .custom-metadata-field .custom-metadata-select2 { 166 | width: 400px; 167 | } 168 | #wpbody-content { 169 | overflow: visible !important; /* otherwise the chosen selector gets cut off at the bottom */ 170 | } 171 | 172 | /* multifields */ 173 | .custom-metadata-multifield { 174 | padding-top: 5px; 175 | } 176 | #poststuff .custom-metadata-multifield h2 { 177 | margin: 0; 178 | } 179 | .custom-metadata-multifield-grouping { 180 | border-top: 1px dashed #ccc; 181 | padding: 5px 0; 182 | margin: 2px; 183 | position: relative; 184 | } 185 | .custom-metadata-multifield-grouping .custom-metadata-field { 186 | float: left; 187 | width: auto; 188 | margin-left: 20px; 189 | } 190 | .custom-metadata-multifield-grouping .custom-metadata-field:first-child { 191 | margin-left: 0; 192 | } 193 | .custom-metadata-multifield-grouping .custom-metadata-field input[type="text"], 194 | .custom-metadata-multifield-grouping .custom-metadata-field input[type="url"], 195 | .custom-metadata-multifield-grouping .custom-metadata-field input[type="password"], 196 | .custom-metadata-multifield-grouping .custom-metadata-field input[type="email"] { 197 | width: 150px; 198 | } 199 | 200 | .custom-metadata-multifield-clone, 201 | .custom-metadata-multifield-delete { 202 | position: absolute; 203 | display: block; 204 | top: 50%; 205 | right: 25px; 206 | padding: 0 3px 4px; 207 | font-size: 35px; 208 | line-height: 20px; 209 | text-decoration: none; 210 | border: 1px solid; 211 | border-radius: 50%; 212 | } 213 | .custom-metadata-multifield-clone { 214 | margin-top: -17px; 215 | color: green; 216 | border-color: green; 217 | } 218 | .custom-metadata-multifield-delete ~ .custom-metadata-multifield-clone { 219 | margin-top: -35px; 220 | } 221 | .custom-metadata-multifield-delete { 222 | margin-top: 17px; 223 | padding: 1px 6px 4px; 224 | color: red; 225 | border-color: red; 226 | } 227 | .custom-metadata-multifield-clone:hover, 228 | .custom-metadata-multifield-clone:active, 229 | .custom-metadata-multifield-delete:hover, 230 | .custom-metadata-multifield-delete:active { 231 | border-color: #d54e21; 232 | } -------------------------------------------------------------------------------- /css/images/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/calendar.png -------------------------------------------------------------------------------- /css/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /css/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /css/jquery-ui-smoothness.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.10.2 - 2013-03-16 2 | * http://jqueryui.com 3 | * Includes: jquery.ui.core.css, jquery.ui.datepicker.css 4 | * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ 5 | 6 | /* Layout helpers 7 | ----------------------------------*/ 8 | .ui-helper-hidden { 9 | display: none; 10 | } 11 | .ui-helper-hidden-accessible { 12 | border: 0; 13 | clip: rect(0 0 0 0); 14 | height: 1px; 15 | margin: -1px; 16 | overflow: hidden; 17 | padding: 0; 18 | position: absolute; 19 | width: 1px; 20 | } 21 | .ui-helper-reset { 22 | margin: 0; 23 | padding: 0; 24 | border: 0; 25 | outline: 0; 26 | line-height: 1.3; 27 | text-decoration: none; 28 | font-size: 100%; 29 | list-style: none; 30 | } 31 | .ui-helper-clearfix:before, 32 | .ui-helper-clearfix:after { 33 | content: ""; 34 | display: table; 35 | border-collapse: collapse; 36 | } 37 | .ui-helper-clearfix:after { 38 | clear: both; 39 | } 40 | .ui-helper-clearfix { 41 | min-height: 0; /* support: IE7 */ 42 | } 43 | .ui-helper-zfix { 44 | width: 100%; 45 | height: 100%; 46 | top: 0; 47 | left: 0; 48 | position: absolute; 49 | opacity: 0; 50 | filter:Alpha(Opacity=0); 51 | } 52 | 53 | .ui-front { 54 | z-index: 100; 55 | } 56 | 57 | 58 | /* Interaction Cues 59 | ----------------------------------*/ 60 | .ui-datepicker .ui-state-disabled { 61 | cursor: default !important; 62 | } 63 | 64 | 65 | /* Icons 66 | ----------------------------------*/ 67 | 68 | /* states and images */ 69 | .ui-datepicker .ui-icon { 70 | display: block; 71 | text-indent: -99999px; 72 | overflow: hidden; 73 | background-repeat: no-repeat; 74 | } 75 | 76 | 77 | /* Misc visuals 78 | ----------------------------------*/ 79 | 80 | /* Overlays */ 81 | .ui-datepicker { 82 | width: 17em; 83 | padding: .2em .2em 0; 84 | display: none; 85 | } 86 | .ui-datepicker .ui-datepicker-header { 87 | position: relative; 88 | padding: .2em 0; 89 | } 90 | .ui-datepicker .ui-datepicker-prev, 91 | .ui-datepicker .ui-datepicker-next { 92 | position: absolute; 93 | top: 2px; 94 | width: 1.8em; 95 | height: 1.8em; 96 | } 97 | .ui-datepicker .ui-datepicker-prev-hover, 98 | .ui-datepicker .ui-datepicker-next-hover { 99 | top: 1px; 100 | } 101 | .ui-datepicker .ui-datepicker-prev { 102 | left: 2px; 103 | } 104 | .ui-datepicker .ui-datepicker-next { 105 | right: 2px; 106 | } 107 | .ui-datepicker .ui-datepicker-prev-hover { 108 | left: 1px; 109 | } 110 | .ui-datepicker .ui-datepicker-next-hover { 111 | right: 1px; 112 | } 113 | .ui-datepicker .ui-datepicker-prev span, 114 | .ui-datepicker .ui-datepicker-next span { 115 | display: block; 116 | position: absolute; 117 | left: 50%; 118 | margin-left: -8px; 119 | top: 50%; 120 | margin-top: -8px; 121 | } 122 | .ui-datepicker .ui-datepicker-title { 123 | margin: 0 2.3em; 124 | line-height: 1.8em; 125 | text-align: center; 126 | } 127 | .ui-datepicker .ui-datepicker-title select { 128 | font-size: 1em; 129 | margin: 1px 0; 130 | } 131 | .ui-datepicker select.ui-datepicker-month-year { 132 | width: 100%; 133 | } 134 | .ui-datepicker select.ui-datepicker-month, 135 | .ui-datepicker select.ui-datepicker-year { 136 | width: 49%; 137 | } 138 | .ui-datepicker table { 139 | width: 100%; 140 | font-size: .9em; 141 | border-collapse: collapse; 142 | margin: 0 0 .4em; 143 | } 144 | .ui-datepicker th { 145 | padding: .7em .3em; 146 | text-align: center; 147 | font-weight: bold; 148 | border: 0; 149 | } 150 | .ui-datepicker td { 151 | border: 0; 152 | padding: 1px; 153 | } 154 | .ui-datepicker td span, 155 | .ui-datepicker td a { 156 | display: block; 157 | padding: .2em; 158 | text-align: right; 159 | text-decoration: none; 160 | } 161 | .ui-datepicker .ui-datepicker-buttonpane { 162 | background-image: none; 163 | margin: .7em 0 0 0; 164 | padding: 0 .2em; 165 | border-left: 0; 166 | border-right: 0; 167 | border-bottom: 0; 168 | } 169 | .ui-datepicker .ui-datepicker-buttonpane button { 170 | float: right; 171 | margin: .5em .2em .4em; 172 | cursor: pointer; 173 | padding: .2em .6em .3em .6em; 174 | width: auto; 175 | overflow: visible; 176 | } 177 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { 178 | float: left; 179 | } 180 | 181 | /* with multiple calendars */ 182 | .ui-datepicker.ui-datepicker-multi { 183 | width: auto; 184 | } 185 | .ui-datepicker-multi .ui-datepicker-group { 186 | float: left; 187 | } 188 | .ui-datepicker-multi .ui-datepicker-group table { 189 | width: 95%; 190 | margin: 0 auto .4em; 191 | } 192 | .ui-datepicker-multi-2 .ui-datepicker-group { 193 | width: 50%; 194 | } 195 | .ui-datepicker-multi-3 .ui-datepicker-group { 196 | width: 33.3%; 197 | } 198 | .ui-datepicker-multi-4 .ui-datepicker-group { 199 | width: 25%; 200 | } 201 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, 202 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { 203 | border-left-width: 0; 204 | } 205 | .ui-datepicker-multi .ui-datepicker-buttonpane { 206 | clear: left; 207 | } 208 | .ui-datepicker-row-break { 209 | clear: both; 210 | width: 100%; 211 | font-size: 0; 212 | } 213 | 214 | /* RTL support */ 215 | .ui-datepicker-rtl { 216 | direction: rtl; 217 | } 218 | .ui-datepicker-rtl .ui-datepicker-prev { 219 | right: 2px; 220 | left: auto; 221 | } 222 | .ui-datepicker-rtl .ui-datepicker-next { 223 | left: 2px; 224 | right: auto; 225 | } 226 | .ui-datepicker-rtl .ui-datepicker-prev:hover { 227 | right: 1px; 228 | left: auto; 229 | } 230 | .ui-datepicker-rtl .ui-datepicker-next:hover { 231 | left: 1px; 232 | right: auto; 233 | } 234 | .ui-datepicker-rtl .ui-datepicker-buttonpane { 235 | clear: right; 236 | } 237 | .ui-datepicker-rtl .ui-datepicker-buttonpane button { 238 | float: left; 239 | } 240 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, 241 | .ui-datepicker-rtl .ui-datepicker-group { 242 | float: right; 243 | } 244 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, 245 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { 246 | border-right-width: 0; 247 | border-left-width: 1px; 248 | } 249 | 250 | /* Component containers 251 | ----------------------------------*/ 252 | .ui-widget.ui-datepicker { 253 | font-family: Verdana,Arial,sans-serif; 254 | font-size: 1.1em; 255 | } 256 | .ui-widget.ui-datepicker .ui-widget { 257 | font-size: 1em; 258 | } 259 | .ui-widget.ui-datepicker input, 260 | .ui-widget.ui-datepicker select, 261 | .ui-widget.ui-datepicker textarea, 262 | .ui-widget.ui-datepicker button { 263 | font-family: Verdana,Arial,sans-serif; 264 | font-size: 1em; 265 | } 266 | .ui-widget-content.ui-datepicker { 267 | border: 1px solid #aaaaaa; 268 | background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; 269 | color: #222222; 270 | } 271 | .ui-widget-content.ui-datepicker a { 272 | color: #222222; 273 | } 274 | .ui-datepicker .ui-widget-header { 275 | border: 1px solid #aaaaaa; 276 | background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; 277 | color: #222222; 278 | font-weight: bold; 279 | } 280 | .ui-datepicker .ui-widget-header a { 281 | color: #222222; 282 | } 283 | 284 | /* Interaction states 285 | ----------------------------------*/ 286 | .ui-datepicker .ui-state-default, 287 | .ui-datepicker.ui-widget-content .ui-state-default, 288 | .ui-datepicker .ui-widget-header .ui-state-default { 289 | border: 1px solid #d3d3d3; 290 | background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; 291 | font-weight: normal; 292 | color: #555555; 293 | } 294 | .ui-datepicker .ui-state-default a, 295 | .ui-datepicker .ui-state-default a:link, 296 | .ui-datepicker .ui-state-default a:visited { 297 | color: #555555; 298 | text-decoration: none; 299 | } 300 | .ui-datepicker .ui-state-hover, 301 | .ui-datepicker.ui-widget-content .ui-state-hover, 302 | .ui-datepicker .ui-widget-header .ui-state-hover, 303 | .ui-datepicker .ui-state-focus, 304 | .ui-datepicker.ui-widget-content .ui-state-focus, 305 | .ui-datepicker .ui-widget-header .ui-state-focus { 306 | border: 1px solid #999999; 307 | background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; 308 | font-weight: normal; 309 | color: #212121; 310 | } 311 | .ui-datepicker .ui-state-hover a, 312 | .ui-datepicker .ui-state-hover a:hover, 313 | .ui-datepicker .ui-state-hover a:link, 314 | .ui-datepicker .ui-state-hover a:visited { 315 | color: #212121; 316 | text-decoration: none; 317 | } 318 | .ui-datepicker .ui-state-active, 319 | .ui-datepicker.ui-widget-content .ui-state-active, 320 | .ui-datepicker .ui-widget-header .ui-state-active { 321 | border: 1px solid #aaaaaa; 322 | background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; 323 | font-weight: normal; 324 | color: #212121; 325 | } 326 | .ui-datepicker .ui-state-active a, 327 | .ui-datepicker .ui-state-active a:link, 328 | .ui-datepicker .ui-state-active a:visited { 329 | color: #212121; 330 | text-decoration: none; 331 | } 332 | 333 | /* Interaction Cues 334 | ----------------------------------*/ 335 | .ui-datepicker .ui-state-highlight, 336 | .ui-datepicker.ui-widget-content .ui-state-highlight, 337 | .ui-datepicker .ui-widget-header .ui-state-highlight { 338 | border: 1px solid #fcefa1; 339 | background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; 340 | color: #363636; 341 | } 342 | .ui-datepicker .ui-state-highlight a, 343 | .ui-datepicker.ui-widget-content .ui-state-highlight a, 344 | .ui-datepicker .ui-widget-header .ui-state-highlight a { 345 | color: #363636; 346 | } 347 | .ui-datepicker .ui-state-error, 348 | .ui-datepicker.ui-widget-content .ui-state-error, 349 | .ui-datepicker .ui-widget-header .ui-state-error { 350 | border: 1px solid #cd0a0a; 351 | background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; 352 | color: #cd0a0a; 353 | } 354 | .ui-datepicker .ui-state-error a, 355 | .ui-datepicker.ui-widget-content .ui-state-error a, 356 | .ui-datepicker .ui-widget-header .ui-state-error a { 357 | color: #cd0a0a; 358 | } 359 | .ui-datepicker .ui-state-error-text, 360 | .ui-datepicker.ui-widget-content .ui-state-error-text, 361 | .ui-datepicker .ui-widget-header .ui-state-error-text { 362 | color: #cd0a0a; 363 | } 364 | .ui-datepicker .ui-priority-primary, 365 | .ui-datepicker.ui-widget-content .ui-priority-primary, 366 | .ui-datepicker .ui-widget-header .ui-priority-primary { 367 | font-weight: bold; 368 | } 369 | .ui-datepicker .ui-priority-secondary, 370 | .ui-datepicker.ui-widget-content .ui-priority-secondary, 371 | .ui-datepicker .ui-widget-header .ui-priority-secondary { 372 | opacity: .7; 373 | filter:Alpha(Opacity=70); 374 | font-weight: normal; 375 | } 376 | .ui-datepicker .ui-state-disabled, 377 | .ui-datepicker.ui-widget-content .ui-state-disabled, 378 | .ui-datepicker .ui-widget-header .ui-state-disabled { 379 | opacity: .35; 380 | filter:Alpha(Opacity=35); 381 | background-image: none; 382 | } 383 | .ui-datepicker .ui-state-disabled .ui-icon { 384 | filter:Alpha(Opacity=35); /* For IE8 - See #6059 */ 385 | } 386 | 387 | /* Icons 388 | ----------------------------------*/ 389 | 390 | /* states and images */ 391 | .ui-datepicker .ui-icon { 392 | width: 16px; 393 | height: 16px; 394 | } 395 | .ui-datepicker .ui-icon, 396 | .ui-datepicker .ui-widget-content .ui-icon { 397 | background-image: url(images/ui-icons_222222_256x240.png); 398 | } 399 | .ui-datepicker .ui-widget-header .ui-icon { 400 | background-image: url(images/ui-icons_222222_256x240.png); 401 | } 402 | .ui-datepicker .ui-state-default .ui-icon { 403 | background-image: url(images/ui-icons_888888_256x240.png); 404 | } 405 | .ui-datepicker .ui-state-hover .ui-icon, 406 | .ui-datepicker .ui-state-focus .ui-icon { 407 | background-image: url(images/ui-icons_454545_256x240.png); 408 | } 409 | .ui-datepicker .ui-state-active .ui-icon { 410 | background-image: url(images/ui-icons_454545_256x240.png); 411 | } 412 | .ui-datepicker .ui-state-highlight .ui-icon { 413 | background-image: url(images/ui-icons_2e83ff_256x240.png); 414 | } 415 | .ui-datepicker .ui-state-error .ui-icon, 416 | .ui-datepicker .ui-state-error-text .ui-icon { 417 | background-image: url(images/ui-icons_cd0a0a_256x240.png); 418 | } 419 | 420 | /* positioning */ 421 | .ui-datepicker .ui-icon-blank { background-position: 16px 16px; } 422 | .ui-datepicker .ui-icon-carat-1-n { background-position: 0 0; } 423 | .ui-datepicker .ui-icon-carat-1-ne { background-position: -16px 0; } 424 | .ui-datepicker .ui-icon-carat-1-e { background-position: -32px 0; } 425 | .ui-datepicker .ui-icon-carat-1-se { background-position: -48px 0; } 426 | .ui-datepicker .ui-icon-carat-1-s { background-position: -64px 0; } 427 | .ui-datepicker .ui-icon-carat-1-sw { background-position: -80px 0; } 428 | .ui-datepicker .ui-icon-carat-1-w { background-position: -96px 0; } 429 | .ui-datepicker .ui-icon-carat-1-nw { background-position: -112px 0; } 430 | .ui-datepicker .ui-icon-carat-2-n-s { background-position: -128px 0; } 431 | .ui-datepicker .ui-icon-carat-2-e-w { background-position: -144px 0; } 432 | .ui-datepicker .ui-icon-triangle-1-n { background-position: 0 -16px; } 433 | .ui-datepicker .ui-icon-triangle-1-ne { background-position: -16px -16px; } 434 | .ui-datepicker .ui-icon-triangle-1-e { background-position: -32px -16px; } 435 | .ui-datepicker .ui-icon-triangle-1-se { background-position: -48px -16px; } 436 | .ui-datepicker .ui-icon-triangle-1-s { background-position: -64px -16px; } 437 | .ui-datepicker .ui-icon-triangle-1-sw { background-position: -80px -16px; } 438 | .ui-datepicker .ui-icon-triangle-1-w { background-position: -96px -16px; } 439 | .ui-datepicker .ui-icon-triangle-1-nw { background-position: -112px -16px; } 440 | .ui-datepicker .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 441 | .ui-datepicker .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 442 | .ui-datepicker .ui-icon-arrow-1-n { background-position: 0 -32px; } 443 | .ui-datepicker .ui-icon-arrow-1-ne { background-position: -16px -32px; } 444 | .ui-datepicker .ui-icon-arrow-1-e { background-position: -32px -32px; } 445 | .ui-datepicker .ui-icon-arrow-1-se { background-position: -48px -32px; } 446 | .ui-datepicker .ui-icon-arrow-1-s { background-position: -64px -32px; } 447 | .ui-datepicker .ui-icon-arrow-1-sw { background-position: -80px -32px; } 448 | .ui-datepicker .ui-icon-arrow-1-w { background-position: -96px -32px; } 449 | .ui-datepicker .ui-icon-arrow-1-nw { background-position: -112px -32px; } 450 | .ui-datepicker .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 451 | .ui-datepicker .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 452 | .ui-datepicker .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 453 | .ui-datepicker .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 454 | .ui-datepicker .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 455 | .ui-datepicker .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 456 | .ui-datepicker .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 457 | .ui-datepicker .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 458 | .ui-datepicker .ui-icon-arrowthick-1-n { background-position: 0 -48px; } 459 | .ui-datepicker .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 460 | .ui-datepicker .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 461 | .ui-datepicker .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 462 | .ui-datepicker .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 463 | .ui-datepicker .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 464 | .ui-datepicker .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 465 | .ui-datepicker .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 466 | .ui-datepicker .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 467 | .ui-datepicker .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 468 | .ui-datepicker .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 469 | .ui-datepicker .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 470 | .ui-datepicker .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 471 | .ui-datepicker .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 472 | .ui-datepicker .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 473 | .ui-datepicker .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 474 | .ui-datepicker .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 475 | .ui-datepicker .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 476 | .ui-datepicker .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 477 | .ui-datepicker .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 478 | .ui-datepicker .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 479 | .ui-datepicker .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 480 | .ui-datepicker .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 481 | .ui-datepicker .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 482 | .ui-datepicker .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 483 | .ui-datepicker .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 484 | .ui-datepicker .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 485 | .ui-datepicker .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 486 | .ui-datepicker .ui-icon-arrow-4 { background-position: 0 -80px; } 487 | .ui-datepicker .ui-icon-arrow-4-diag { background-position: -16px -80px; } 488 | .ui-datepicker .ui-icon-extlink { background-position: -32px -80px; } 489 | .ui-datepicker .ui-icon-newwin { background-position: -48px -80px; } 490 | .ui-datepicker .ui-icon-refresh { background-position: -64px -80px; } 491 | .ui-datepicker .ui-icon-shuffle { background-position: -80px -80px; } 492 | .ui-datepicker .ui-icon-transfer-e-w { background-position: -96px -80px; } 493 | .ui-datepicker .ui-icon-transferthick-e-w { background-position: -112px -80px; } 494 | .ui-datepicker .ui-icon-folder-collapsed { background-position: 0 -96px; } 495 | .ui-datepicker .ui-icon-folder-open { background-position: -16px -96px; } 496 | .ui-datepicker .ui-icon-document { background-position: -32px -96px; } 497 | .ui-datepicker .ui-icon-document-b { background-position: -48px -96px; } 498 | .ui-datepicker .ui-icon-note { background-position: -64px -96px; } 499 | .ui-datepicker .ui-icon-mail-closed { background-position: -80px -96px; } 500 | .ui-datepicker .ui-icon-mail-open { background-position: -96px -96px; } 501 | .ui-datepicker .ui-icon-suitcase { background-position: -112px -96px; } 502 | .ui-datepicker .ui-icon-comment { background-position: -128px -96px; } 503 | .ui-datepicker .ui-icon-person { background-position: -144px -96px; } 504 | .ui-datepicker .ui-icon-print { background-position: -160px -96px; } 505 | .ui-datepicker .ui-icon-trash { background-position: -176px -96px; } 506 | .ui-datepicker .ui-icon-locked { background-position: -192px -96px; } 507 | .ui-datepicker .ui-icon-unlocked { background-position: -208px -96px; } 508 | .ui-datepicker .ui-icon-bookmark { background-position: -224px -96px; } 509 | .ui-datepicker .ui-icon-tag { background-position: -240px -96px; } 510 | .ui-datepicker .ui-icon-home { background-position: 0 -112px; } 511 | .ui-datepicker .ui-icon-flag { background-position: -16px -112px; } 512 | .ui-datepicker .ui-icon-calendar { background-position: -32px -112px; } 513 | .ui-datepicker .ui-icon-cart { background-position: -48px -112px; } 514 | .ui-datepicker .ui-icon-pencil { background-position: -64px -112px; } 515 | .ui-datepicker .ui-icon-clock { background-position: -80px -112px; } 516 | .ui-datepicker .ui-icon-disk { background-position: -96px -112px; } 517 | .ui-datepicker .ui-icon-calculator { background-position: -112px -112px; } 518 | .ui-datepicker .ui-icon-zoomin { background-position: -128px -112px; } 519 | .ui-datepicker .ui-icon-zoomout { background-position: -144px -112px; } 520 | .ui-datepicker .ui-icon-search { background-position: -160px -112px; } 521 | .ui-datepicker .ui-icon-wrench { background-position: -176px -112px; } 522 | .ui-datepicker .ui-icon-gear { background-position: -192px -112px; } 523 | .ui-datepicker .ui-icon-heart { background-position: -208px -112px; } 524 | .ui-datepicker .ui-icon-star { background-position: -224px -112px; } 525 | .ui-datepicker .ui-icon-link { background-position: -240px -112px; } 526 | .ui-datepicker .ui-icon-cancel { background-position: 0 -128px; } 527 | .ui-datepicker .ui-icon-plus { background-position: -16px -128px; } 528 | .ui-datepicker .ui-icon-plusthick { background-position: -32px -128px; } 529 | .ui-datepicker .ui-icon-minus { background-position: -48px -128px; } 530 | .ui-datepicker .ui-icon-minusthick { background-position: -64px -128px; } 531 | .ui-datepicker .ui-icon-key { background-position: -112px -128px; } 532 | .ui-datepicker .ui-icon-lightbulb { background-position: -128px -128px; } 533 | .ui-datepicker .ui-icon-scissors { background-position: -144px -128px; } 534 | .ui-datepicker .ui-icon-clipboard { background-position: -160px -128px; } 535 | .ui-datepicker .ui-icon-copy { background-position: -176px -128px; } 536 | .ui-datepicker .ui-icon-contact { background-position: -192px -128px; } 537 | .ui-datepicker .ui-icon-image { background-position: -208px -128px; } 538 | .ui-datepicker .ui-icon-video { background-position: -224px -128px; } 539 | .ui-datepicker .ui-icon-script { background-position: -240px -128px; } 540 | .ui-datepicker .ui-icon-alert { background-position: 0 -144px; } 541 | .ui-datepicker .ui-icon-info { background-position: -16px -144px; } 542 | .ui-datepicker .ui-icon-notice { background-position: -32px -144px; } 543 | .ui-datepicker .ui-icon-help { background-position: -48px -144px; } 544 | .ui-datepicker .ui-icon-check { background-position: -64px -144px; } 545 | .ui-datepicker .ui-icon-bullet { background-position: -80px -144px; } 546 | .ui-datepicker .ui-icon-radio-on { background-position: -96px -144px; } 547 | .ui-datepicker .ui-icon-radio-off { background-position: -112px -144px; } 548 | .ui-datepicker .ui-icon-pin-w { background-position: -128px -144px; } 549 | .ui-datepicker .ui-icon-pin-s { background-position: -144px -144px; } 550 | .ui-datepicker .ui-icon-play { background-position: 0 -160px; } 551 | .ui-datepicker .ui-icon-pause { background-position: -16px -160px; } 552 | .ui-datepicker .ui-icon-seek-next { background-position: -32px -160px; } 553 | .ui-datepicker .ui-icon-seek-prev { background-position: -48px -160px; } 554 | .ui-datepicker .ui-icon-seek-end { background-position: -64px -160px; } 555 | .ui-datepicker .ui-icon-seek-start { background-position: -80px -160px; } 556 | .ui-datepicker .ui-icon-seek-first { background-position: -80px -160px; } 557 | .ui-datepicker .ui-icon-stop { background-position: -96px -160px; } 558 | .ui-datepicker .ui-icon-eject { background-position: -112px -160px; } 559 | .ui-datepicker .ui-icon-volume-off { background-position: -128px -160px; } 560 | .ui-datepicker .ui-icon-volume-on { background-position: -144px -160px; } 561 | .ui-datepicker .ui-icon-power { background-position: 0 -176px; } 562 | .ui-datepicker .ui-icon-signal-diag { background-position: -16px -176px; } 563 | .ui-datepicker .ui-icon-signal { background-position: -32px -176px; } 564 | .ui-datepicker .ui-icon-battery-0 { background-position: -48px -176px; } 565 | .ui-datepicker .ui-icon-battery-1 { background-position: -64px -176px; } 566 | .ui-datepicker .ui-icon-battery-2 { background-position: -80px -176px; } 567 | .ui-datepicker .ui-icon-battery-3 { background-position: -96px -176px; } 568 | .ui-datepicker .ui-icon-circle-plus { background-position: 0 -192px; } 569 | .ui-datepicker .ui-icon-circle-minus { background-position: -16px -192px; } 570 | .ui-datepicker .ui-icon-circle-close { background-position: -32px -192px; } 571 | .ui-datepicker .ui-icon-circle-triangle-e { background-position: -48px -192px; } 572 | .ui-datepicker .ui-icon-circle-triangle-s { background-position: -64px -192px; } 573 | .ui-datepicker .ui-icon-circle-triangle-w { background-position: -80px -192px; } 574 | .ui-datepicker .ui-icon-circle-triangle-n { background-position: -96px -192px; } 575 | .ui-datepicker .ui-icon-circle-arrow-e { background-position: -112px -192px; } 576 | .ui-datepicker .ui-icon-circle-arrow-s { background-position: -128px -192px; } 577 | .ui-datepicker .ui-icon-circle-arrow-w { background-position: -144px -192px; } 578 | .ui-datepicker .ui-icon-circle-arrow-n { background-position: -160px -192px; } 579 | .ui-datepicker .ui-icon-circle-zoomin { background-position: -176px -192px; } 580 | .ui-datepicker .ui-icon-circle-zoomout { background-position: -192px -192px; } 581 | .ui-datepicker .ui-icon-circle-check { background-position: -208px -192px; } 582 | .ui-datepicker .ui-icon-circlesmall-plus { background-position: 0 -208px; } 583 | .ui-datepicker .ui-icon-circlesmall-minus { background-position: -16px -208px; } 584 | .ui-datepicker .ui-icon-circlesmall-close { background-position: -32px -208px; } 585 | .ui-datepicker .ui-icon-squaresmall-plus { background-position: -48px -208px; } 586 | .ui-datepicker .ui-icon-squaresmall-minus { background-position: -64px -208px; } 587 | .ui-datepicker .ui-icon-squaresmall-close { background-position: -80px -208px; } 588 | .ui-datepicker .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 589 | .ui-datepicker .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 590 | .ui-datepicker .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 591 | .ui-datepicker .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 592 | .ui-datepicker .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 593 | .ui-datepicker .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 594 | 595 | 596 | /* Misc visuals 597 | ----------------------------------*/ 598 | 599 | /* Corner radius */ 600 | .ui-datepicker .ui-corner-all, 601 | .ui-datepicker .ui-corner-top, 602 | .ui-datepicker .ui-corner-left, 603 | .ui-datepicker .ui-corner-tl { 604 | border-top-left-radius: 4px; 605 | } 606 | .ui-datepicker .ui-corner-all, 607 | .ui-datepicker .ui-corner-top, 608 | .ui-datepicker .ui-corner-right, 609 | .ui-datepicker .ui-corner-tr { 610 | border-top-right-radius: 4px; 611 | } 612 | .ui-datepicker .ui-corner-all, 613 | .ui-datepicker .ui-corner-bottom, 614 | .ui-datepicker .ui-corner-left, 615 | .ui-datepicker .ui-corner-bl { 616 | border-bottom-left-radius: 4px; 617 | } 618 | .ui-datepicker .ui-corner-all, 619 | .ui-datepicker .ui-corner-bottom, 620 | .ui-datepicker .ui-corner-right, 621 | .ui-datepicker .ui-corner-br { 622 | border-bottom-right-radius: 4px; 623 | } -------------------------------------------------------------------------------- /css/select2.css: -------------------------------------------------------------------------------- 1 | /* 2 | Version: 3.4.1 Timestamp: Thu Jun 27 18:02:10 PDT 2013 3 | */ 4 | .select2-container { 5 | margin: 0; 6 | position: relative; 7 | display: inline-block; 8 | /* inline-block for ie7 */ 9 | zoom: 1; 10 | *display: inline; 11 | vertical-align: middle; 12 | } 13 | 14 | .select2-container, 15 | .select2-drop, 16 | .select2-search, 17 | .select2-search input{ 18 | /* 19 | Force border-box so that % widths fit the parent 20 | container without overlap because of margin/padding. 21 | 22 | More Info : http://www.quirksmode.org/css/box.html 23 | */ 24 | -webkit-box-sizing: border-box; /* webkit */ 25 | -khtml-box-sizing: border-box; /* konqueror */ 26 | -moz-box-sizing: border-box; /* firefox */ 27 | -ms-box-sizing: border-box; /* ie */ 28 | box-sizing: border-box; /* css3 */ 29 | } 30 | 31 | .select2-container .select2-choice { 32 | display: block; 33 | height: 26px; 34 | padding: 0 0 0 8px; 35 | overflow: hidden; 36 | position: relative; 37 | 38 | border: 1px solid #aaa; 39 | white-space: nowrap; 40 | line-height: 26px; 41 | color: #444; 42 | text-decoration: none; 43 | 44 | -webkit-border-radius: 4px; 45 | -moz-border-radius: 4px; 46 | border-radius: 4px; 47 | 48 | -webkit-background-clip: padding-box; 49 | -moz-background-clip: padding; 50 | background-clip: padding-box; 51 | 52 | -webkit-touch-callout: none; 53 | -webkit-user-select: none; 54 | -khtml-user-select: none; 55 | -moz-user-select: none; 56 | -ms-user-select: none; 57 | user-select: none; 58 | 59 | background-color: #fff; 60 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white)); 61 | background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%); 62 | background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%); 63 | background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%); 64 | background-image: -ms-linear-gradient(top, #ffffff 0%, #eeeeee 50%); 65 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0); 66 | background-image: linear-gradient(top, #ffffff 0%, #eeeeee 50%); 67 | } 68 | 69 | .select2-container.select2-drop-above .select2-choice { 70 | border-bottom-color: #aaa; 71 | 72 | -webkit-border-radius:0 0 4px 4px; 73 | -moz-border-radius:0 0 4px 4px; 74 | border-radius:0 0 4px 4px; 75 | 76 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white)); 77 | background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%); 78 | background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%); 79 | background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%); 80 | background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 90%); 81 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); 82 | background-image: linear-gradient(top, #eeeeee 0%,#ffffff 90%); 83 | } 84 | 85 | .select2-container.select2-allowclear .select2-choice .select2-chosen { 86 | margin-right: 42px; 87 | } 88 | 89 | .select2-container .select2-choice > .select2-chosen { 90 | margin-right: 26px; 91 | display: block; 92 | overflow: hidden; 93 | 94 | white-space: nowrap; 95 | 96 | -ms-text-overflow: ellipsis; 97 | -o-text-overflow: ellipsis; 98 | text-overflow: ellipsis; 99 | } 100 | 101 | .select2-container .select2-choice abbr { 102 | display: none; 103 | width: 12px; 104 | height: 12px; 105 | position: absolute; 106 | right: 24px; 107 | top: 8px; 108 | 109 | font-size: 1px; 110 | text-decoration: none; 111 | 112 | border: 0; 113 | background: url('select2.png') right top no-repeat; 114 | cursor: pointer; 115 | outline: 0; 116 | } 117 | 118 | .select2-container.select2-allowclear .select2-choice abbr { 119 | display: inline-block; 120 | } 121 | 122 | .select2-container .select2-choice abbr:hover { 123 | background-position: right -11px; 124 | cursor: pointer; 125 | } 126 | 127 | .select2-drop-undermask { 128 | border: 0; 129 | margin: 0; 130 | padding: 0; 131 | position: absolute; 132 | left: 0; 133 | top: 0; 134 | z-index: 9998; 135 | background-color: transparent; 136 | filter: alpha(opacity=0); 137 | } 138 | 139 | .select2-drop-mask { 140 | border: 0; 141 | margin: 0; 142 | padding: 0; 143 | position: absolute; 144 | left: 0; 145 | top: 0; 146 | z-index: 9998; 147 | /* styles required for IE to work */ 148 | background-color: #fff; 149 | opacity: 0; 150 | filter: alpha(opacity=0); 151 | } 152 | 153 | .select2-drop { 154 | width: 100%; 155 | margin-top: -1px; 156 | position: absolute; 157 | z-index: 9999; 158 | top: 100%; 159 | 160 | background: #fff; 161 | color: #000; 162 | border: 1px solid #aaa; 163 | border-top: 0; 164 | 165 | -webkit-border-radius: 0 0 4px 4px; 166 | -moz-border-radius: 0 0 4px 4px; 167 | border-radius: 0 0 4px 4px; 168 | 169 | -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); 170 | -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); 171 | box-shadow: 0 4px 5px rgba(0, 0, 0, .15); 172 | } 173 | 174 | .select2-drop-auto-width { 175 | border-top: 1px solid #aaa; 176 | width: auto; 177 | } 178 | 179 | .select2-drop-auto-width .select2-search { 180 | padding-top: 4px; 181 | } 182 | 183 | .select2-drop.select2-drop-above { 184 | margin-top: 1px; 185 | border-top: 1px solid #aaa; 186 | border-bottom: 0; 187 | 188 | -webkit-border-radius: 4px 4px 0 0; 189 | -moz-border-radius: 4px 4px 0 0; 190 | border-radius: 4px 4px 0 0; 191 | 192 | -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); 193 | -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); 194 | box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); 195 | } 196 | 197 | .select2-drop-active { 198 | border: 1px solid #5897fb; 199 | border-top: none; 200 | } 201 | 202 | .select2-drop.select2-drop-above.select2-drop-active { 203 | border-top: 1px solid #5897fb; 204 | } 205 | 206 | .select2-container .select2-choice .select2-arrow { 207 | display: inline-block; 208 | width: 18px; 209 | height: 100%; 210 | position: absolute; 211 | right: 0; 212 | top: 0; 213 | 214 | border-left: 1px solid #aaa; 215 | -webkit-border-radius: 0 4px 4px 0; 216 | -moz-border-radius: 0 4px 4px 0; 217 | border-radius: 0 4px 4px 0; 218 | 219 | -webkit-background-clip: padding-box; 220 | -moz-background-clip: padding; 221 | background-clip: padding-box; 222 | 223 | background: #ccc; 224 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee)); 225 | background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%); 226 | background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%); 227 | background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%); 228 | background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%); 229 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0); 230 | background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%); 231 | } 232 | 233 | .select2-container .select2-choice .select2-arrow b { 234 | display: block; 235 | width: 100%; 236 | height: 100%; 237 | background: url('select2.png') no-repeat 0 1px; 238 | } 239 | 240 | .select2-search { 241 | display: inline-block; 242 | width: 100%; 243 | min-height: 26px; 244 | margin: 0; 245 | padding-left: 4px; 246 | padding-right: 4px; 247 | 248 | position: relative; 249 | z-index: 10000; 250 | 251 | white-space: nowrap; 252 | } 253 | 254 | .select2-search input { 255 | width: 100%; 256 | height: auto !important; 257 | min-height: 26px; 258 | padding: 4px 20px 4px 5px; 259 | margin: 0; 260 | 261 | outline: 0; 262 | font-family: sans-serif; 263 | font-size: 1em; 264 | 265 | border: 1px solid #aaa; 266 | -webkit-border-radius: 0; 267 | -moz-border-radius: 0; 268 | border-radius: 0; 269 | 270 | -webkit-box-shadow: none; 271 | -moz-box-shadow: none; 272 | box-shadow: none; 273 | 274 | background: #fff url('select2.png') no-repeat 100% -22px; 275 | background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); 276 | background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); 277 | background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); 278 | background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); 279 | background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%); 280 | background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%); 281 | } 282 | 283 | .select2-drop.select2-drop-above .select2-search input { 284 | margin-top: 4px; 285 | } 286 | 287 | .select2-search input.select2-active { 288 | background: #fff url('select2-spinner.gif') no-repeat 100%; 289 | background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); 290 | background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); 291 | background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); 292 | background: url('select2-spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); 293 | background: url('select2-spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%); 294 | background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%); 295 | } 296 | 297 | .select2-container-active .select2-choice, 298 | .select2-container-active .select2-choices { 299 | border: 1px solid #5897fb; 300 | outline: none; 301 | 302 | -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); 303 | -moz-box-shadow: 0 0 5px rgba(0,0,0,.3); 304 | box-shadow: 0 0 5px rgba(0,0,0,.3); 305 | } 306 | 307 | .select2-dropdown-open .select2-choice { 308 | border-bottom-color: transparent; 309 | -webkit-box-shadow: 0 1px 0 #fff inset; 310 | -moz-box-shadow: 0 1px 0 #fff inset; 311 | box-shadow: 0 1px 0 #fff inset; 312 | 313 | -webkit-border-bottom-left-radius: 0; 314 | -moz-border-radius-bottomleft: 0; 315 | border-bottom-left-radius: 0; 316 | 317 | -webkit-border-bottom-right-radius: 0; 318 | -moz-border-radius-bottomright: 0; 319 | border-bottom-right-radius: 0; 320 | 321 | background-color: #eee; 322 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); 323 | background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%); 324 | background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); 325 | background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%); 326 | background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%); 327 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); 328 | background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%); 329 | } 330 | 331 | .select2-dropdown-open.select2-drop-above .select2-choice, 332 | .select2-dropdown-open.select2-drop-above .select2-choices { 333 | border: 1px solid #5897fb; 334 | border-top-color: transparent; 335 | 336 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, white), color-stop(0.5, #eeeeee)); 337 | background-image: -webkit-linear-gradient(center top, white 0%, #eeeeee 50%); 338 | background-image: -moz-linear-gradient(center top, white 0%, #eeeeee 50%); 339 | background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); 340 | background-image: -ms-linear-gradient(bottom, #ffffff 0%,#eeeeee 50%); 341 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); 342 | background-image: linear-gradient(bottom, #ffffff 0%,#eeeeee 50%); 343 | } 344 | 345 | .select2-dropdown-open .select2-choice .select2-arrow { 346 | background: transparent; 347 | border-left: none; 348 | filter: none; 349 | } 350 | .select2-dropdown-open .select2-choice .select2-arrow b { 351 | background-position: -18px 1px; 352 | } 353 | 354 | /* results */ 355 | .select2-results { 356 | max-height: 200px; 357 | padding: 0 0 0 4px; 358 | margin: 4px 4px 4px 0; 359 | position: relative; 360 | overflow-x: hidden; 361 | overflow-y: auto; 362 | -webkit-tap-highlight-color: rgba(0,0,0,0); 363 | } 364 | 365 | .select2-results ul.select2-result-sub { 366 | margin: 0; 367 | padding-left: 0; 368 | } 369 | 370 | .select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px } 371 | .select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px } 372 | .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px } 373 | .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px } 374 | .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px } 375 | .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px } 376 | .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px } 377 | 378 | .select2-results li { 379 | list-style: none; 380 | display: list-item; 381 | background-image: none; 382 | } 383 | 384 | .select2-results li.select2-result-with-children > .select2-result-label { 385 | font-weight: bold; 386 | } 387 | 388 | .select2-results .select2-result-label { 389 | padding: 3px 7px 4px; 390 | margin: 0; 391 | cursor: pointer; 392 | 393 | min-height: 1em; 394 | 395 | -webkit-touch-callout: none; 396 | -webkit-user-select: none; 397 | -khtml-user-select: none; 398 | -moz-user-select: none; 399 | -ms-user-select: none; 400 | user-select: none; 401 | } 402 | 403 | .select2-results .select2-highlighted { 404 | background: #3875d7; 405 | color: #fff; 406 | } 407 | 408 | .select2-results li em { 409 | background: #feffde; 410 | font-style: normal; 411 | } 412 | 413 | .select2-results .select2-highlighted em { 414 | background: transparent; 415 | } 416 | 417 | .select2-results .select2-highlighted ul { 418 | background: white; 419 | color: #000; 420 | } 421 | 422 | 423 | .select2-results .select2-no-results, 424 | .select2-results .select2-searching, 425 | .select2-results .select2-selection-limit { 426 | background: #f4f4f4; 427 | display: list-item; 428 | } 429 | 430 | /* 431 | disabled look for disabled choices in the results dropdown 432 | */ 433 | .select2-results .select2-disabled.select2-highlighted { 434 | color: #666; 435 | background: #f4f4f4; 436 | display: list-item; 437 | cursor: default; 438 | } 439 | .select2-results .select2-disabled { 440 | background: #f4f4f4; 441 | display: list-item; 442 | cursor: default; 443 | } 444 | 445 | .select2-results .select2-selected { 446 | display: none; 447 | } 448 | 449 | .select2-more-results.select2-active { 450 | background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%; 451 | } 452 | 453 | .select2-more-results { 454 | background: #f4f4f4; 455 | display: list-item; 456 | } 457 | 458 | /* disabled styles */ 459 | 460 | .select2-container.select2-container-disabled .select2-choice { 461 | background-color: #f4f4f4; 462 | background-image: none; 463 | border: 1px solid #ddd; 464 | cursor: default; 465 | } 466 | 467 | .select2-container.select2-container-disabled .select2-choice .select2-arrow { 468 | background-color: #f4f4f4; 469 | background-image: none; 470 | border-left: 0; 471 | } 472 | 473 | .select2-container.select2-container-disabled .select2-choice abbr { 474 | display: none; 475 | } 476 | 477 | 478 | /* multiselect */ 479 | 480 | .select2-container-multi .select2-choices { 481 | height: auto !important; 482 | height: 1%; 483 | margin: 0; 484 | padding: 0; 485 | position: relative; 486 | 487 | border: 1px solid #aaa; 488 | cursor: text; 489 | overflow: hidden; 490 | 491 | background-color: #fff; 492 | background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); 493 | background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); 494 | background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); 495 | background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); 496 | background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%); 497 | background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%); 498 | } 499 | 500 | .select2-locked { 501 | padding: 3px 5px 3px 5px !important; 502 | } 503 | 504 | .select2-container-multi .select2-choices { 505 | min-height: 26px; 506 | } 507 | 508 | .select2-container-multi.select2-container-active .select2-choices { 509 | border: 1px solid #5897fb; 510 | outline: none; 511 | 512 | -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); 513 | -moz-box-shadow: 0 0 5px rgba(0,0,0,.3); 514 | box-shadow: 0 0 5px rgba(0,0,0,.3); 515 | } 516 | .select2-container-multi .select2-choices li { 517 | float: left; 518 | list-style: none; 519 | } 520 | .select2-container-multi .select2-choices .select2-search-field { 521 | margin: 0; 522 | padding: 0; 523 | white-space: nowrap; 524 | } 525 | 526 | .select2-container-multi .select2-choices .select2-search-field input { 527 | padding: 5px; 528 | margin: 1px 0; 529 | 530 | font-family: sans-serif; 531 | font-size: 100%; 532 | color: #666; 533 | outline: 0; 534 | border: 0; 535 | -webkit-box-shadow: none; 536 | -moz-box-shadow: none; 537 | box-shadow: none; 538 | background: transparent !important; 539 | } 540 | 541 | .select2-container-multi .select2-choices .select2-search-field input.select2-active { 542 | background: #fff url('select2-spinner.gif') no-repeat 100% !important; 543 | } 544 | 545 | .select2-default { 546 | color: #999 !important; 547 | } 548 | 549 | .select2-container-multi .select2-choices .select2-search-choice { 550 | padding: 3px 5px 3px 18px; 551 | margin: 3px 0 3px 5px; 552 | position: relative; 553 | 554 | line-height: 13px; 555 | color: #333; 556 | cursor: default; 557 | border: 1px solid #aaaaaa; 558 | 559 | -webkit-border-radius: 3px; 560 | -moz-border-radius: 3px; 561 | border-radius: 3px; 562 | 563 | -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); 564 | -moz-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); 565 | box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); 566 | 567 | -webkit-background-clip: padding-box; 568 | -moz-background-clip: padding; 569 | background-clip: padding-box; 570 | 571 | -webkit-touch-callout: none; 572 | -webkit-user-select: none; 573 | -khtml-user-select: none; 574 | -moz-user-select: none; 575 | -ms-user-select: none; 576 | user-select: none; 577 | 578 | background-color: #e4e4e4; 579 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0 ); 580 | background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); 581 | background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); 582 | background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); 583 | background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); 584 | background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); 585 | background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); 586 | } 587 | .select2-container-multi .select2-choices .select2-search-choice .select2-chosen { 588 | cursor: default; 589 | } 590 | .select2-container-multi .select2-choices .select2-search-choice-focus { 591 | background: #d4d4d4; 592 | } 593 | 594 | .select2-search-choice-close { 595 | display: block; 596 | width: 12px; 597 | height: 13px; 598 | position: absolute; 599 | right: 3px; 600 | top: 4px; 601 | 602 | font-size: 1px; 603 | outline: none; 604 | background: url('select2.png') right top no-repeat; 605 | } 606 | 607 | .select2-container-multi .select2-search-choice-close { 608 | left: 3px; 609 | } 610 | 611 | .select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover { 612 | background-position: right -11px; 613 | } 614 | .select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close { 615 | background-position: right -11px; 616 | } 617 | 618 | /* disabled styles */ 619 | .select2-container-multi.select2-container-disabled .select2-choices{ 620 | background-color: #f4f4f4; 621 | background-image: none; 622 | border: 1px solid #ddd; 623 | cursor: default; 624 | } 625 | 626 | .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice { 627 | padding: 3px 5px 3px 5px; 628 | border: 1px solid #ddd; 629 | background-image: none; 630 | background-color: #f4f4f4; 631 | } 632 | 633 | .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none; 634 | background:none; 635 | } 636 | /* end multiselect */ 637 | 638 | 639 | .select2-result-selectable .select2-match, 640 | .select2-result-unselectable .select2-match { 641 | text-decoration: underline; 642 | } 643 | 644 | .select2-offscreen, .select2-offscreen:focus { 645 | clip: rect(0 0 0 0); 646 | width: 1px; 647 | height: 1px; 648 | border: 0; 649 | margin: 0; 650 | padding: 0; 651 | overflow: hidden; 652 | position: absolute; 653 | outline: 0; 654 | left: 0px; 655 | } 656 | 657 | .select2-display-none { 658 | display: none; 659 | } 660 | 661 | .select2-measure-scrollbar { 662 | position: absolute; 663 | top: -10000px; 664 | left: -10000px; 665 | width: 100px; 666 | height: 100px; 667 | overflow: scroll; 668 | } 669 | /* Retina-ize icons */ 670 | 671 | @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) { 672 | .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b { 673 | background-image: url('select2x2.png') !important; 674 | background-repeat: no-repeat !important; 675 | background-size: 60px 40px !important; 676 | } 677 | .select2-search input { 678 | background-position: 100% -21px !important; 679 | } 680 | } 681 | -------------------------------------------------------------------------------- /css/select2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/select2.png -------------------------------------------------------------------------------- /css/select2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/select2x2.png -------------------------------------------------------------------------------- /css/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/custom-metadata/d5108c6176faf657c948fa14ccf9b02b625ad3a9/css/spinner.gif -------------------------------------------------------------------------------- /custom_metadata_examples.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | 23 | /** 24 | * register a test post type just for the examples 25 | * 26 | * @return void 27 | */ 28 | add_action( 'init', 'x_init_custom_post_types' ); 29 | function x_init_custom_post_types() { 30 | 31 | $labels = array( 32 | 'name' => _x( 'Tests', 'post type general name' ), 33 | 'singular_name' => _x( 'Test', 'post type singular name' ), 34 | 'add_new' => _x( 'Add New', 'Test' ), 35 | 'add_new_item' => __( 'Add New Test' ), 36 | 'edit_item' => __( 'Edit Test' ), 37 | 'new_item' => __( 'New Test' ), 38 | 'all_items' => __( 'All Tests' ), 39 | 'view_item' => __( 'View Test' ), 40 | 'search_items' => __( 'Search Tests' ), 41 | 'not_found' => __( 'No Tests found' ), 42 | 'not_found_in_trash' => __( 'No Tests found in Trash' ), 43 | 'parent_item_colon' => '', 44 | 'menu_name' => 'Tests' 45 | 46 | ); 47 | $args = array( 48 | 'labels' => $labels, 49 | 'public' => true, 50 | 'publicly_queryable' => true, 51 | 'show_ui' => true, 52 | 'show_in_menu' => true, 53 | 'query_var' => true, 54 | 'rewrite' => true, 55 | 'capability_type' => 'post', 56 | 'has_archive' => true, 57 | 'hierarchical' => false, 58 | 'menu_position' => null, 59 | 'supports' => array( 'title' ) 60 | ); 61 | register_post_type( 'x_test', $args ); 62 | } 63 | 64 | 65 | /** 66 | * register custom metadata groups and fields 67 | * this is the example code that you should use 68 | * make sure to use the 'admin_init' hook as below 69 | * 70 | * @return void 71 | */ 72 | add_action( 'custom_metadata_manager_init_metadata', 'x_init_custom_fields' ); 73 | function x_init_custom_fields() { 74 | 75 | // adds a new group to the test post type 76 | x_add_metadata_group( 'x_metaBox1', 'x_test', array( 77 | 'label' => 'Group with Multiple Fields' 78 | ) ); 79 | 80 | // adds another group to the test post type + posts + users 81 | x_add_metadata_group( 'x_metaBox2', array( 'x_test', 'post', 'user' ), array( 82 | 'label' => 'Group for Post and User', 83 | 'description' => "Here's a group with a description!", 84 | ) ); 85 | 86 | // adds a text field to the first group 87 | x_add_metadata_field( 'x_fieldName1', 'x_test', array( 88 | 'group' => 'x_metaBox1', // the group name 89 | 'description' => 'This is field #1. It\'s a simple text field.', // description for the field 90 | 'label' => 'Text Field', // field label 91 | 'display_column' => true // show this field in the column listings 92 | ) ); 93 | 94 | // adds a text field to the 2nd group 95 | x_add_metadata_field( 'x_fieldName2', 'x_test', array( 96 | 'group' => 'x_metaBox1', 97 | 'display_column' => 'My Column (with Custom Callback)', // show this field in the column listings 98 | 'display_column_callback' => 'x_field_name2_callback', // custom function to display the column results (see below) 99 | 'label' => 'Text with Custom Callback', 100 | ) ); 101 | 102 | 103 | // adds a cloneable textarea field to the 1st group 104 | x_add_metadata_field( 'x_fieldTextarea1', 'x_test', array( 105 | 'group' => 'x_metaBox1', 106 | 'field_type' => 'textarea', 107 | 'multiple' => true, 108 | 'label' => 'Repeatable Text Area', 109 | ) ); 110 | 111 | // adds a readonly textarea field to the 1st group 112 | x_add_metadata_field( 'x_fieldTextareaReadOnly1', 'x_test', array( 113 | 'group' => 'x_metaBox1', 114 | 'field_type' => 'textarea', 115 | 'readonly' => true, 116 | 'label' => 'Read Only Text Area', 117 | ) ); 118 | 119 | // adds a readonly text field to the 1st group 120 | x_add_metadata_field( 'x_fieldTextReadOnly1', 'x_test', array( 121 | 'group' => 'x_metaBox1', 122 | 'readonly' => true, 123 | 'label' => 'Read Only Text Area', 124 | ) ); 125 | 126 | // adds a wysiwyg (full editor) field to the 2nd group 127 | x_add_metadata_field( 'x_fieldWysiwyg1', array( 'x_test', 'user' ), array( 128 | 'group' => 'x_metaBox2', 129 | 'field_type' => 'wysiwyg', 130 | 'label' => 'TinyMCE / Wysiwyg field', 131 | ) ); 132 | 133 | // adds a datepicker field to the 1st group 134 | x_add_metadata_field( 'x_fieldDatepicker1', 'x_test', array( 135 | 'group' => 'x_metaBox1', 136 | 'field_type' => 'datepicker', 137 | 'label' => 'Datepicker field', 138 | ) ); 139 | 140 | // adds a datetimepicker field to the 1st group 141 | x_add_metadata_field( 'x_fieldDatetimepicker1', 'x_test', array( 142 | 'group' => 'x_metaBox1', 143 | 'field_type' => 'datetimepicker', 144 | 'label' => 'Datetimepicker field', 145 | ) ); 146 | 147 | // adds a timepicker field to the 1st group 148 | x_add_metadata_field( 'x_fieldTimepicker1', 'x_test', array( 149 | 'group' => 'x_metaBox1', 150 | 'field_type' => 'timepicker', 151 | 'label' => 'Timepicker field', 152 | ) ); 153 | 154 | // adds a colorpicker field to the 1st group 155 | x_add_metadata_field( 'x_fieldColorpicker1', 'x_test', array( 156 | 'group' => 'x_metaBox1', 157 | 'field_type' => 'colorpicker', 158 | 'label' => 'Colorpicker field', 159 | ) ); 160 | 161 | // adds an upload field to the 1st group 162 | x_add_metadata_field( 'x_fieldUpload1', 'x_test', array( 163 | 'group' => 'x_metaBox1', 164 | 'field_type' => 'upload', 165 | 'readonly' => true, 166 | 'label' => 'Upload field', 167 | ) ); 168 | 169 | // adds a checkbox field to the first group 170 | x_add_metadata_field( 'x_fieldCheckbox1', 'x_test', array( 171 | 'group' => 'x_metaBox1', 172 | 'field_type' => 'checkbox', 173 | 'label' => 'Checkbox field', 174 | ) ); 175 | 176 | // adds a radio button field to the first group 177 | x_add_metadata_field( 'x_fieldRadio1', 'x_test', array( 178 | 'group' => 'x_metaBox1', 179 | 'field_type' => 'radio', 180 | 'values' => array( // set possible value/options 181 | 'option1' => 'Option #1', // key => value pair (key is stored in DB) 182 | 'option2' => 'Option #2', 183 | ), 184 | 'label' => 'Radio field', 185 | ) ); 186 | 187 | // adds a select box in the first group 188 | x_add_metadata_field( 'x_fieldSelect1', 'x_test', array( 189 | 'group' => 'x_metaBox1', 190 | 'field_type' => 'select', 191 | 'values' => array( // set possible value/options 192 | 'option1' => 'Option #1', // key => value pair (key is stored in DB) 193 | 'option2' => 'Option #2', 194 | ), 195 | 'label' => 'Select field', 196 | ) ); 197 | 198 | // adds a multi-select field in the first group 199 | x_add_metadata_field( 'x_field_multi_select', 'x_test', array( 200 | 'group' => 'x_metaBox1', 201 | 'field_type' => 'multi_select', 202 | 'values' => array( // set possible value/options 203 | 'option1' => 'Option #1', // key => value pair (key is stored in DB) 204 | 'option2' => 'Option #2', 205 | 'option3' => 'Option #3', 206 | 'option4' => 'Option #4', 207 | ), 208 | 'label' => 'Multi Select field', 209 | ) ); 210 | 211 | // adds a multi-select field with chosen in the first group 212 | // note: `select2` and `chosen` args do the exact same (add select2) 213 | // but for the purposes of testing, we're using chosen here 214 | x_add_metadata_field( 'x_field_multi_select_chosen', 'x_test', array( 215 | 'group' => 'x_metaBox1', 216 | 'field_type' => 'multi_select', 217 | 'values' => array( // set possible value/options 218 | 'option1' => 'Option #1', // key => value pair (key is stored in DB) 219 | 'option2' => 'Option #2', 220 | 'option3' => 'Option #3', 221 | 'option4' => 'Option #4', 222 | ), 223 | 'label' => 'Multi Select field (with chosen)', 224 | 'chosen' => true, 225 | ) ); 226 | 227 | // adds a select field with select2 in the first group 228 | x_add_metadata_field( 'x_field_select_select2', 'x_test', array( 229 | 'group' => 'x_metaBox1', 230 | 'field_type' => 'select', 231 | 'values' => array( // set possible value/options 232 | 'option1' => 'Option #1', // key => value pair (key is stored in DB) 233 | 'option2' => 'Option #2', 234 | 'option3' => 'Option #3', 235 | 'option4' => 'Option #4', 236 | ), 237 | 'label' => 'Select field (with select2)', 238 | 'select2' => true, 239 | ) ); 240 | 241 | // adds a taxonomy checkbox field in the first group 242 | x_add_metadata_field( 'x_field_taxonomy_checkbox', 'x_test', array( 243 | 'group' => 'x_metaBox1', 244 | 'field_type' => 'taxonomy_checkbox', 245 | 'taxonomy' => 'category', 246 | 'label' => 'Category checkbox field', 247 | ) ); 248 | 249 | // adds a taxonomy select field in the first group 250 | x_add_metadata_field( 'x_field_taxonomy_select', 'x_test', array( 251 | 'group' => 'x_metaBox1', 252 | 'field_type' => 'taxonomy_select', 253 | 'taxonomy' => 'category', 254 | 'label' => 'Category select field', 255 | ) ); 256 | 257 | // adds a taxonomy multiselect field in the first group 258 | x_add_metadata_field( 'x_field_taxonomy_multi_select', 'x_test', array( 259 | 'group' => 'x_metaBox1', 260 | 'field_type' => 'taxonomy_multi_select', 261 | 'taxonomy' => 'category', 262 | 'label' => 'Category multiselect field', 263 | ) ); 264 | 265 | // adds a taxonomy multiselect w/ select2 field in the first group 266 | x_add_metadata_field( 'x_field_taxonomy_multi_select2', 'x_test', array( 267 | 'group' => 'x_metaBox1', 268 | 'field_type' => 'taxonomy_multi_select', 269 | 'taxonomy' => 'category', 270 | 'label' => 'Category multiselect w/ select2 field', 271 | 'select2' => true, 272 | ) ); 273 | 274 | // adds a number field in the first group (with no min/max) 275 | x_add_metadata_field( 'x_field_number', 'x_test', array( 276 | 'group' => 'x_metaBox1', 277 | 'field_type' => 'number', 278 | 'label' => 'Number field', 279 | ) ); 280 | 281 | // adds a number field in the first group (with min/max) 282 | x_add_metadata_field( 'x_field_number_with_min_max', 'x_test', array( 283 | 'group' => 'x_metaBox1', 284 | 'field_type' => 'number', 285 | 'min' => '-3', 286 | 'max' => '25', 287 | 'multiple' => true, 288 | 'label' => 'Number field (with min/max + cloneable)', 289 | ) ); 290 | 291 | // adds an email field in the first group 292 | x_add_metadata_field( 'x_field_email', 'x_test', array( 293 | 'group' => 'x_metaBox1', 294 | 'field_type' => 'email', 295 | 'label' => 'Email field', 296 | ) ); 297 | 298 | // adds a link field in the first group 299 | x_add_metadata_field( 'x_field_link', 'x_test', array( 300 | 'group' => 'x_metaBox1', 301 | 'field_type' => 'link', 302 | 'label' => 'Link field', 303 | ) ); 304 | 305 | // adds a telephone field in the first group (with default value) 306 | x_add_metadata_field( 'x_field_telephone', 'x_test', array( 307 | 'group' => 'x_metaBox1', 308 | 'field_type' => 'tel', 309 | 'label' => 'Telephone field', 310 | 'default_value' => '123-4567' 311 | ) ); 312 | 313 | // adds a text field with a default value 314 | x_add_metadata_field( 'x_field_text_default', 'x_test', array( 315 | 'group' => 'x_metaBox1', 316 | 'field_type' => 'text', 317 | 'label' => 'Text field with default value', 318 | 'default_value' => 'lorem ipsum' 319 | ) ); 320 | 321 | // adds a text field with placeholder 322 | x_add_metadata_field( 'x_field_textarea_placeholder', 'x_test', array( 323 | 'group' => 'x_metaBox1', 324 | 'field_type' => 'textarea', 325 | 'label' => 'Textarea field with placeholder', 326 | 'placeholder' => 'some placeholder text', 327 | ) ); 328 | 329 | // adds a password field with placeholder 330 | x_add_metadata_field( 'x_field_password_placeholder', 'x_test', array( 331 | 'group' => 'x_metaBox1', 332 | 'field_type' => 'password', 333 | 'label' => 'Password field with placeholder', 334 | 'placeholder' => 'some placeholder text', 335 | ) ); 336 | 337 | // adds a number field with placeholder 338 | x_add_metadata_field( 'x_field_number_placeholder', 'x_test', array( 339 | 'group' => 'x_metaBox1', 340 | 'field_type' => 'number', 341 | 'label' => 'Number field with placeholder', 342 | 'placeholder' => 'some placeholder text', 343 | ) ); 344 | 345 | // adds an email field with placeholder 346 | x_add_metadata_field( 'x_field_email_placeholder', 'x_test', array( 347 | 'group' => 'x_metaBox1', 348 | 'field_type' => 'email', 349 | 'label' => 'Email field with placeholder', 350 | 'placeholder' => 'some placeholder text', 351 | ) ); 352 | 353 | // adds a link field with placeholder 354 | x_add_metadata_field( 'x_field_link_placeholder', 'x_test', array( 355 | 'group' => 'x_metaBox1', 356 | 'field_type' => 'link', 357 | 'label' => 'Link field with placeholder', 358 | 'placeholder' => 'some placeholder text', 359 | ) ); 360 | 361 | // adds an telephone field with placeholder 362 | x_add_metadata_field( 'x_field_telephone_placeholder', 'x_test', array( 363 | 'group' => 'x_metaBox1', 364 | 'field_type' => 'tel', 365 | 'label' => 'Telephone field with placeholder', 366 | 'placeholder' => 'some placeholder text', 367 | ) ); 368 | 369 | // adds an upload field with placeholder 370 | x_add_metadata_field( 'x_field_upload_placeholder', 'x_test', array( 371 | 'group' => 'x_metaBox1', 372 | 'field_type' => 'upload', 373 | 'label' => 'Upload field with placeholder', 374 | 'placeholder' => 'some placeholder text', 375 | ) ); 376 | 377 | // adds an datepicker field with placeholder 378 | x_add_metadata_field( 'x_field_datepicker_placeholder', 'x_test', array( 379 | 'group' => 'x_metaBox1', 380 | 'field_type' => 'datepicker', 381 | 'label' => 'Datepicker field with placeholder', 382 | 'placeholder' => 'some placeholder text', 383 | ) ); 384 | 385 | // adds a datetimepicker field with placeholder 386 | x_add_metadata_field( 'x_field_datetimepicker_placeholder', 'x_test', array( 387 | 'group' => 'x_metaBox1', 388 | 'field_type' => 'datetimepicker', 389 | 'label' => 'Datetimepicker field with placeholder', 390 | 'placeholder' => 'some placeholder text', 391 | ) ); 392 | 393 | // adds a timepicker field with placeholder 394 | x_add_metadata_field( 'x_field_timepicker_placeholder', 'x_test', array( 395 | 'group' => 'x_metaBox1', 396 | 'field_type' => 'timepicker', 397 | 'label' => 'Timepicker field with placeholder', 398 | 'placeholder' => 'some placeholder text', 399 | ) ); 400 | 401 | // adds a mulitifield 402 | x_add_metadata_multifield( 'x_test_multifield', 'x_test', array( 403 | 'group' => 'x_metabox1', 404 | 'label' => 'Multifield test', 405 | 'description' => 'This is a great multifield', 406 | ) ); 407 | 408 | // adds a text field to the multifield 409 | x_add_metadata_field( 'multifield_field_1', 'x_test', array( 410 | 'group' => 'x_metabox1', // the group name 411 | 'multifield' => 'x_test_multifield', 412 | 'description' => 'This is field #1 of the multifield.', 413 | 'label' => 'Text Field', // field label 414 | 'field_type' => 'text', 415 | ) ); 416 | 417 | // adds an upload text field to the multifield 418 | x_add_metadata_field( 'multifield_field_2', 'x_test', array( 419 | 'group' => 'x_metabox1', // the group name 420 | 'multifield' => 'x_test_multifield', 421 | 'description' => 'This is field #2 of the multifield.', 422 | 'label' => 'Upload Field', // field label 423 | 'field_type' => 'upload', 424 | ) ); 425 | 426 | 427 | // adds an upload text field to the multifield 428 | x_add_metadata_field( 'multifield_field_3', 'x_test', array( 429 | 'group' => 'x_metabox1', // the group name 430 | 'multifield' => 'x_test_multifield', 431 | 'description' => 'This is field #4 of the multifield.', 432 | 'label' => 'Telephone Field', // field label 433 | 'field_type' => 'tel', 434 | ) ); 435 | 436 | // adds a text field to the multifield 437 | x_add_metadata_field( 'multifield_field_4', 'x_test', array( 438 | 'group' => 'x_metabox1', // the group name 439 | 'multifield' => 'x_test_multifield', 440 | 'description' => 'This is field #4 of the multifield.', 441 | 'label' => 'Password Field', // field label 442 | 'field_type' => 'password', 443 | ) ); 444 | 445 | 446 | // adds a field to posts and users 447 | x_add_metadata_field( 'x_fieldName2', array( 'post', 'user' ), array( 448 | 'group' => 'x_metaBox2', 449 | 'label' => 'Text field', 450 | ) ); 451 | 452 | // adds a field with a custom display callback (see below) 453 | x_add_metadata_field( 'x_fieldCustomHidden1', 'x_test', array( 454 | 'group' => 'x_metaBox1', 455 | 'display_callback' => 'x_field_customhidden1_callback', // this function is defined below 456 | 'label' => 'Hidden field', 457 | ) ); 458 | 459 | 460 | // field with capabilities limited 461 | x_add_metadata_field( 'x_cap-limited-field', 'x_test', array( 462 | 'label' => 'Cap Limited Field (edit_posts)', 463 | 'required_cap' => 'edit_posts' // limit to users who can edit posts 464 | ) ); 465 | 466 | // field with role limited 467 | x_add_metadata_field( 'x_author-cap-limited-field', 'user', array( 468 | 'label' => 'Cap Limited Field (author)', 469 | 'required_cap' => 'author' // limit to authors 470 | ) ); 471 | 472 | // comment field 473 | x_add_metadata_field( 'x_commentField1', 'comment', array( 474 | 'label' => 'Field for Comment', 475 | 'display_column' => true 476 | ) ); 477 | 478 | // field that exludes posts 479 | x_add_metadata_field( 'x_fieldNameExcluded1', 'post', array( 480 | 'description' => 'This field is excluded from Post ID#2476', 481 | 'label' => 'Excluded Field', 482 | 'exclude' => 2476 483 | ) ); 484 | 485 | // field that includes certain posts only 486 | x_add_metadata_field( 'x_fieldNameIncluded1', 'post', array( 487 | 'description' => 'This field is only included on Post ID#2476', 488 | 'label' => 'Included Field', 489 | 'include' => 2476 490 | ) ); 491 | 492 | x_add_metadata_field( 'x_fieldExcludeCallback', 'post', array( 493 | 'description' => 'This field is excluded using a custom callback; will be excluded from posts in the "aside" category', 494 | 'label' => 'Excluded Field (with callback)', 495 | 'exclude' => 'x_custom_exclude_callback', 496 | ) ); 497 | 498 | /** 499 | * 500 | * 501 | * @param unknown $thing_slug string Slug of the field or group 502 | * @param unknown $thing object Field or Group args set up when registering 503 | * @param unknown $object_type string What type of object (post, comment, user) 504 | * @param unknown $object_id int|string ID of the object 505 | * @param unknown $object_slug string 506 | */ 507 | function x_custom_exclude_callback( $thing_slug, $thing, $object_type, $object_id, $object_slug ) { 508 | // exclude from all posts that are in the aside category 509 | return in_category( 'aside', $object_id ); 510 | } 511 | 512 | x_add_metadata_field( 'x_fieldIncludedCallback', 'post', array( 513 | 'description' => 'This field is included using a custom callback; will only be included for posts that are not published', 514 | 'label' => 'Included Field (with callback)', 515 | 'include' => 'x_custom_include_callback', 516 | ) ); 517 | 518 | function x_custom_include_callback( $thing_slug, $thing, $object_type, $object_id, $object_slug ) { 519 | $post = get_post( $object_id ); 520 | return 'publish' != $post->post_status; 521 | } 522 | } 523 | 524 | /** 525 | * this is an example of a column callback function 526 | * it echoes out a bogus description, but it's just so you can see how it works 527 | * 528 | * @param string $field_slug the slug/id of the field 529 | * @param object $field the field object 530 | * @param string $object_type what object type is the field associated with 531 | * @param int $object_id the ID of the current object 532 | * @param string $value the value of the field 533 | * @return void 534 | */ 535 | function x_field_name2_callback( $field_slug, $field, $object_type, $object_id, $value ) { 536 | echo sprintf( 'The value of field "%s" is %s.
Here\'s a LOLCat', $field_slug, $value ? $value : 'not set' ); 537 | } 538 | 539 | /** 540 | * this is another example of a custom callback function 541 | * we've chosen not to include all of the params this time 542 | * 543 | * @param string $field_slug the slug/id of the field 544 | * @param object $field the field object 545 | * @param string $object_type what object type is the field associated with 546 | * @return void 547 | */ 548 | function x_field_customhidden1_callback( $field_slug, $field, $value ) { 549 | if ( ! $value ) $value = 'This is a secret hidden value! Don\'t tell anyone!'; 550 | ?> 551 |
552 |

This is a hidden field rendered with a custom callback. The value is "".

553 | 554 |
555 | tp_inst._defaults.hourMax?tp_inst._defaults.hourMax:tp_inst._defaults.hour;tp_inst.minute=tp_inst._defaults.minutetp_inst._defaults.minuteMax?tp_inst._defaults.minuteMax:tp_inst._defaults.minute;tp_inst.second=tp_inst._defaults.secondtp_inst._defaults.secondMax?tp_inst._defaults.secondMax:tp_inst._defaults.second;tp_inst.millisec=tp_inst._defaults.millisectp_inst._defaults.millisecMax?tp_inst._defaults.millisecMax:tp_inst._defaults.millisec;tp_inst.ampm="";tp_inst.$input=$input;if(o.altField){tp_inst.$altInput=$(o.altField).css({cursor:"pointer"}).focus(function(){$input.trigger("focus")})}if(tp_inst._defaults.minDate===0||tp_inst._defaults.minDateTime===0){tp_inst._defaults.minDate=new Date}if(tp_inst._defaults.maxDate===0||tp_inst._defaults.maxDateTime===0){tp_inst._defaults.maxDate=new Date}if(tp_inst._defaults.minDate!==undefined&&tp_inst._defaults.minDate instanceof Date){tp_inst._defaults.minDateTime=new Date(tp_inst._defaults.minDate.getTime())}if(tp_inst._defaults.minDateTime!==undefined&&tp_inst._defaults.minDateTime instanceof Date){tp_inst._defaults.minDate=new Date(tp_inst._defaults.minDateTime.getTime())}if(tp_inst._defaults.maxDate!==undefined&&tp_inst._defaults.maxDate instanceof Date){tp_inst._defaults.maxDateTime=new Date(tp_inst._defaults.maxDate.getTime())}if(tp_inst._defaults.maxDateTime!==undefined&&tp_inst._defaults.maxDateTime instanceof Date){tp_inst._defaults.maxDate=new Date(tp_inst._defaults.maxDateTime.getTime())}tp_inst.$input.bind("focus",function(){tp_inst._onFocus()});return tp_inst},_addTimePicker:function(e){var t=this.$altInput&&this._defaults.altFieldTimeOnly?this.$input.val()+" "+this.$altInput.val():this.$input.val();this.timeDefined=this._parseTime(t);this._limitMinMaxDateTime(e,false);this._injectTimePicker()},_parseTime:function(e,t){if(!this.inst){this.inst=$.datepicker._getInst(this.$input[0])}if(t||!this._defaults.timeOnly){var n=$.datepicker._get(this.inst,"dateFormat");try{var r=parseDateTimeInternal(n,this._defaults.timeFormat,e,$.datepicker._getFormatConfig(this.inst),this._defaults);if(!r.timeObj){return false}$.extend(this,r.timeObj)}catch(i){$.timepicker.log("Error parsing the date/time string: "+i+"\ndate/time string = "+e+"\ntimeFormat = "+this._defaults.timeFormat+"\ndateFormat = "+n);return false}return true}else{var s=$.datepicker.parseTime(this._defaults.timeFormat,e,this._defaults);if(!s){return false}$.extend(this,s);return true}},_injectTimePicker:function(){var e=this.inst.dpDiv,t=this.inst.settings,n=this,r="",i="",s={},o={},u=null;if(e.find("div.ui-timepicker-div").length===0&&t.showTimepicker){var a=' style="display:none;"',f='
'+'
"+t.timeText+"
"+'
";for(var l=0,c=this.units.length;l"+t[r+"Text"]+""+'
";if(t["show"+i]&&t[r+"Grid"]>0){f+='
';if(r=="hour"){for(var h=t[r+"Min"];h<=s[r];h+=parseInt(t[r+"Grid"],10)){o[r]++;var p=$.datepicker.formatTime(useAmpm(t.pickerTimeFormat||t.timeFormat)?"hht":"HH",{hour:h},t);f+='"}}else{for(var d=t[r+"Min"];d<=s[r];d+=parseInt(t[r+"Grid"],10)){o[r]++;f+='"}}f+="
'+p+"'+(d<10?"0":"")+d+"
"}f+="
"}f+='
"+t.timezoneText+"
";f+='
";f+="
";var v=$(f);if(t.timeOnly===true){v.prepend('
'+'
'+t.timeOnlyTitle+"
"+"
");e.find(".ui-datepicker-header, .ui-datepicker-calendar").hide()}for(var l=0,c=n.units.length;l0){u=100*o[r]*t[r+"Grid"]/(s[r]-t[r+"Min"]);v.find(".ui_tpicker_"+r+" table").css({width:u+"%",marginLeft:t.isRTL?"0":u/(-2*o[r])+"%",marginRight:t.isRTL?u/(-2*o[r])+"%":"0",borderCollapse:"collapse"}).find("td").click(function(e){var t=$(this),i=t.html(),s=parseInt(i.replace(/[^0-9]/g),10),o=i.replace(/[^apm]/ig),u=t.data("for");if(u=="hour"){if(o.indexOf("p")!==-1&&s<12){s+=12}else{if(o.indexOf("a")!==-1&&s===12){s=0}}}n.control.value(n,n[u+"_slider"],r,s);n._onTimeChange();n._onSelectHandler()}).css({cursor:"pointer",width:100/o[r]+"%",textAlign:"center",overflow:"hidden"})}}this.timezone_select=v.find(".ui_tpicker_timezone").append("").find("select");$.fn.append.apply(this.timezone_select,$.map(t.timezoneList,function(e,t){return $("