Skip to content

Commit

Permalink
Fork of v1.3.2
Browse files Browse the repository at this point in the history
  • Loading branch information
k-gutnik committed Jul 2, 2024
0 parents commit 4ecb1f6
Show file tree
Hide file tree
Showing 21 changed files with 1,154 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/.idea
/vendor
/node_modules
package-lock.json
composer.phar
composer.lock
phpunit.xml
.phpunit.result.cache
.DS_Store
Thumbs.db

79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Laravel Nova Searchable Select Field

A Searchable Select Field for Laravel Nova. This field joins the functionalities of the `BelongsTo`field
and `Select` field.

Basically a regular Select field where you specify the resource you want to search for and no "relationships"
are needed. This means, you can use it also in additional JSON fields in your database.

## Installation

_Composer_

```
composer require sloveniangooner/searchable-select
```

## Usage

Just like the regular select field, but instead of the `options` method you provide the `resource` method
with your resource name.

```php
use Sloveniangooner\SearchableSelect\SearchableSelect;
...

SearchableSelect::make('Content', 'content_id')->resource("contents")
... or
SearchableSelect::make("Content", "content_id")->resource(\App\Nova\Content::class)
```

![](usage.gif)

You can pass all the regular options like:

```php
SearchableSelect::make('Content', 'content_id')
->resource("contents")
->help("Help text")
->displayUsingLabels()
->nullable()
```

But also three additional options:

```php
SearchableSelect::make('Content', 'content_id')
->resource("contents")
->label("custom_label_field") // Defaults to the static $title attribute of the resource class
->labelPrefix("custom_prefix_field") // Allows you to prefix the label field with one other field, i.e. "code":"label"
->value("custom_value_field") // Defaults to 'id'
```

You can now also choose the multiple option. Needs a `text` or `json` field in the database.

```php
SearchableSelect::make('Content', 'content_id')
->resource("contents")
->multiple()
->displayUsingLabels()
->nullable()
```

![](multiple.gif)

Another option is to define the maximum number of items shown in the search. (Default: 20)

```php
SearchableSelect::make("Content", "content_id")
->resource("contents")
->max(10)
```

You can use the base model's search method instead of the Nova resource's search method with `useBaseSearch()`.

```php
SearchableSelect::make('Content', 'content_id')
->resource("contents")
->useBaseSearch()
```
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "sloveniangooner/searchable-select",
"description": "A Laravel Nova field.",
"keywords": [
"laravel",
"nova"
],
"license": "MIT",
"require": {
"php": ">=7.1.0"
},
"autoload": {
"psr-4": {
"Sloveniangooner\\SearchableSelect\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Sloveniangooner\\SearchableSelect\\FieldServiceProvider"
]
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
1 change: 1 addition & 0 deletions dist/css/field.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.searchable-select__selected-resources>div{background-color:var(\-\-30)}
1 change: 1 addition & 0 deletions dist/js/field.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions dist/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"/js/field.js": "/js/field.js",
"/css/field.css": "/css/field.css"
}
Binary file added multiple.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"cross-env": "^5.0.0",
"laravel-mix": "^1.0",
"laravel-nova": "^1.0"
},
"dependencies": {
"popper.js": "^1.15.0",
"vue": "^2.5.0",
"vue-clickaway": "^2.2.2"
}
}
70 changes: 70 additions & 0 deletions resources/js/components/DetailField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<template>
<div>
<panel-item :field="field">
<template slot="value">
<div v-if="fieldValue" class="text-90">
<div v-if="field.isMultiple">{{resourceLabels.join(', ')}}</div>
<div v-else>{{ fieldValue }}</div>
</div>
<div v-else>&mdash;</div>
</template>
</panel-item>
</div>
</template>

<script>
export default {
props: ['resource', 'resourceName', 'resourceId', 'field'],
data() {
return {
resources: []
}
},
mounted() {
if (this.field.isMultiple) {
this.getAvailableResources()
}
},
computed: {
resourceLabels() {
let values = []
this.resources.forEach(r => values.push(r.display))
return values
},
fieldValue() {
if (
this.field.value === '' ||
this.field.value === null ||
this.field.value === undefined ||
this.field.value === '[]'
) {
return false
}
return String(this.field.value)
}
},
methods: {
getAvailableResources() {
return Nova.request()
.get(
`/nova-vendor/searchable-select/${this.field.searchableResource}`,
{
params: {
label: this.field.label,
labelPrefix: this.field.labelPrefix,
value: this.field.valueField,
searchable: this.field.searchable == true ? 1 : 0,
use_resource_ids: this.field.isMultiple,
resource_ids: this.field.value
}
}
)
.then(response => {
// Turn off initializing the existing resource after the first time
this.resources = response.data.resources
})
}
}
}
</script>
Loading

0 comments on commit 4ecb1f6

Please sign in to comment.