Skip to content

2.2 #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 17, 2019
Merged

2.2 #30

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
### Security
- Nothing

## 2.2.0 - 2019-03-17

### Added
- modal_view parameters to use own modal view
- `serialize` parameter to define which current field values should be passed to the foreign CrudController

## 2.1.0 - 2019-02-10

### Added
Expand Down
33 changes: 30 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,21 +164,36 @@ With this package your are also able to add a create button for the foreign CRUD

### Modal view

#### By route

By default the modals are loaded automatically by using `entity` in `on_the_fly` of the field definition, e.g. resulting in `backpack_url($field['on_the_fly']['entity']).'/ajax/create'` for the create modal.

You can overwrite this behavior for all modals by setting an attribute:

```
'on_the_fly' => [
'entity' => 'entity',
'create_modal' => 'route/to/modal/html',
'edit_modal' => 'route/to/modal/html',
'delete_modal' => 'route/to/modal/html',
'create_modal' => 'route/to/modal/html',
'edit_modal' => 'route/to/modal/html',
'delete_modal' => 'route/to/modal/html',
]
```

> Please be aware that by using this attributes you will be completely responsible for the content of the modal! The defined request has to provide valid HTML which is then filled in `<div class="modal-content"></div>`

#### By view

Instead of defining a route you can also use a custom view by:

```
'on_the_fly' => [
'entity' => 'entity',
'create_modal_view' => 'view.to.create.modal',
'edit_modal_view' => 'view.to.edit.modal',
'delete_modal_view' => 'view.to.delete.modal',
]
```

### Search logic

The "instant field" triggers the `ajaxIndex()` of the `EntityCrudController` where the field is defined and uses the fields `model` and `attribute` parameters to perform the search on the foreign model.
Expand Down Expand Up @@ -237,6 +252,18 @@ Instant Fields will try to auto-fill the select2 input after creating a new entr
]
```

### Passing current field values to foreign `EntityCrudController`

Sometimes you will need current values to be used for the creation of an foreign entity. You may define `serialize` with the IDs of the fields you need in the store request:

```
'on_the_fly' => [
'serialize' => ['type_id', 'name'],
]
```

So the current values of `type_id` and `name` will be available in the `$request` of the `ajaxStore` method of your foreign `EntityCrudController` (you will have to overwrite it).

### Fields

Publish the fields in your project and modify functionality
Expand Down
2 changes: 1 addition & 1 deletion resources/views/fields/inc/button-add.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class="btn btn-primary"
style="border-radius: 0px"
data-toggle="modal"
data-target="#{{ $field['on_the_fly']['entity'] ?? 'ajax_entity' }}_create_modal"
data-load-url="{{ $field['on_the_fly']['create_modal'] ?? backpack_url($field['on_the_fly']['entity']).'/ajax/create?field_name='.$field['name'].'&attribute='.($field['on_the_fly']['attribute'] ?? 'name') }}">
data-load-url="{{ $field['on_the_fly']['create_modal'] ?? backpack_url($field['on_the_fly']['entity']).'/ajax/create?field_name='.$field['name'].'&attribute='.($field['on_the_fly']['attribute'] ?? 'name').'&create_modal_view='.($field['on_the_fly']['create_modal_view'] ?? 'webfactor::modal.create').'&attribute='.($field['on_the_fly']['attribute'] ?? 'name') }}">
<i class="fa fa-plus"></i>
</button>
</span>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/fields/inc/button-delete.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class="btn btn-danger {{ isset($field['value']) ?: 'disabled'}}"
data-toggle="modal"
data-id="{{ $field['value'] ?? '' }}"
data-target="#{{ $field['on_the_fly']['entity'] ?? 'ajax_entity' }}_delete_modal"
data-load-url="{{ $field['on_the_fly']['delete_modal'] ?? backpack_url($field['on_the_fly']['entity']).'/ajax/delete?field_name='.$field['name'].'&attribute='.($field['on_the_fly']['attribute'] ?? 'name') }}">
data-load-url="{{ $field['on_the_fly']['delete_modal'] ?? backpack_url($field['on_the_fly']['entity']).'/ajax/delete?field_name='.$field['name'].'&delete_modal_view='.($field['on_the_fly']['delete_modal_view'] ?? 'webfactor::modal.delete').'&attribute='.($field['on_the_fly']['attribute'] ?? 'name') }}">
<i class="fa fa-trash"></i>
</button>
</span>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/fields/inc/button-edit.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class="btn btn-warning {{ isset($field['value']) ?: 'disabled'}}"
data-toggle="modal"
data-id="{{ $field['value'] ?? '' }}"
data-target="#{{ $field['on_the_fly']['entity'] ?? 'ajax_entity' }}_edit_modal"
data-load-url="{{ $field['on_the_fly']['edit_modal'] ?? backpack_url($field['on_the_fly']['entity']).'/ajax/edit?field_name='.$field['name'].'&attribute='.($field['on_the_fly']['attribute'] ?? 'name') }}">
data-load-url="{{ $field['on_the_fly']['edit_modal'] ?? backpack_url($field['on_the_fly']['entity']).'/ajax/edit?field_name='.$field['name'].'&edit_modal_view='.($field['on_the_fly']['edit_modal_view'] ?? 'webfactor::modal.edit').'&attribute='.($field['on_the_fly']['attribute'] ?? 'name') }}">
<i class="fa fa-pencil"></i>
</button>
</span>
Expand Down
7 changes: 6 additions & 1 deletion resources/views/fields/select2_from_ajax.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,13 @@ class="form-control"
// load create modal content
$("#{{ $field['on_the_fly']['entity'] ?? 'ajax_entity' }}_create_modal").on('show.bs.modal', function (e) {
var loadurl = $(e.relatedTarget).data('load-url');
var form = $(e.relatedTarget).closest('form');

$(this).find('.modal-content').load(loadurl);
var data = form.serializeArray().filter(function(index){
return $.inArray(index.name, <?php echo json_encode($field['on_the_fly']['serialize'] ?? []); ?>) >= 0;
});

$(this).find('.modal-content').load(loadurl + '&' + $.param(data));
});

// load edit/delete modal content
Expand Down
8 changes: 7 additions & 1 deletion resources/views/fields/select2_from_ajax_multiple.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,13 @@
// load create modal content
$("#{{ $field['on_the_fly']['entity'] ?? 'ajax_entity' }}_create_modal").on('show.bs.modal', function (e) {
var loadurl = $(e.relatedTarget).data('load-url');
$(this).find('.modal-content').load(loadurl);
var form = $(e.relatedTarget).closest('form');

var data = form.serializeArray().filter(function (index) {
return $.inArray(index.name, <?php echo json_encode($field['on_the_fly']['serialize'] ?? []); ?>) >= 0;
});

$(this).find('.modal-content').load(loadurl + '&' + $.param(data));
});

// trigger select2 for each untriggered select2 box
Expand Down
46 changes: 32 additions & 14 deletions resources/views/modal/create.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
<h3 class="box-title">{{ trans('backpack::crud.add_a_new') }} {{ $crud->entity_name }}</h3>
@endsection

@php
$requestData = [];

foreach ($request->input() as $key => $item) {
$requestData[] = [
'name' => $key,
'value' => $item,
];
}
@endphp

@section('content')
<div class="row">
<div class="col-md-10 col-md-offset-1">
Expand All @@ -28,25 +39,32 @@
$("#create_{{ $entity }}").submit(function (e) {
e.preventDefault(); // avoid to execute the actual submit of the form.

var requestData = <?php echo json_encode($requestData); ?>;

$.ajax({
type: "PUT",
url: "/{{ ltrim($crud->route . '/ajax', '/') }}",
data: $("#create_{{ $entity }}").serialize(), // serializes the form's elements.
success: function (data) {
new PNotify({
type: "success",
title: "{{ trans('backpack::base.success') }}",
text: "{{ trans('backpack::crud.insert_success') }}"
});
url: "/{{ ltrim($crud->route . '/ajax', '/') }}",
data
:
$("#create_{{ $entity }}").serialize() + '&' + $.param(requestData), // serializes the form's elements.
success
:

function (data) {
new PNotify({
type: "success",
title: "{{ trans('backpack::base.success') }}",
text: "{{ trans('backpack::crud.insert_success') }}"
});

$("#{{ $entity }}_create_modal").modal('hide');
$("#{{ $entity }}_create_modal").modal('hide');

// provide auto-fill
// provide auto-fill

if ($("#select2_ajax_{{ $field_name }}").length) {
searchfield = $("#select2_ajax_{{ $field_name }}")
if ($("#select2_ajax_{{ $request->input('field_name') }}").length) {
searchfield = $("#select2_ajax_{{ $request->input('field_name') }}")
} else {
searchfield = $("#select2_ajax_multiple_{{ $field_name }}")
searchfield = $("#select2_ajax_multiple_{{ $request->input('field_name') }}")
}

searchfield.select2('open');
Expand All @@ -55,7 +73,7 @@
// Dropdown = single, Selection = multiple
var search = searchfield.data('select2').dropdown.$search || searchfield.data('select2').selection.$search;
// This is undocumented and may change in the future
var userInput = $("#create_{{ $entity }} [name='{{ $attribute }}']").serializeArray();
var userInput = $("#create_{{ $entity }} [name='{{ $request->input('attribute') }}']").serializeArray();

search.val(userInput[0]['value']);
search.trigger('input');
Expand Down
4 changes: 2 additions & 2 deletions resources/views/modal/delete.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

{{ trans('backpack::crud.delete_confirm') }}<br><br>

{{ $entry->{$attribute} }}
{{ $entry->{$request->input('attribute')} }}

</div>
</div>
Expand Down Expand Up @@ -39,7 +39,7 @@
$("#{{ $entity }}_delete_modal").modal('hide');

// Clear select
$("#select2_ajax_{{ $field_name }}").val(null).trigger('change');
$("#select2_ajax_{{ $request->input('field_name') }}").val(null).trigger('change');
},
error: function (data) {
new PNotify({
Expand Down
8 changes: 4 additions & 4 deletions resources/views/modal/edit.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@

// provide auto-fill

if ($("#select2_ajax_{{ $field_name }}").length) {
searchfield = $("#select2_ajax_{{ $field_name }}")
if ($("#select2_ajax_{{ $request->input('field_name') }}").length) {
searchfield = $("#select2_ajax_{{ $request->input('field_name') }}")
} else {
searchfield = $("#select2_ajax_multiple_{{ $field_name }}")
searchfield = $("#select2_ajax_multiple_{{ $request->input('field_name') }}")
}

searchfield.val(null).trigger('change');
Expand All @@ -55,7 +55,7 @@
// Dropdown = single, Selection = multiple
var search = searchfield.data('select2').dropdown.$search || searchfield.data('select2').selection.$search;
// This is undocumented and may change in the future
var userInput = $("#edit_{{ $entity }} [name='{{ $attribute }}']").serializeArray();
var userInput = $("#edit_{{ $entity }} [name='{{ $request->input('attribute') }}']").serializeArray();

search.val(userInput[0]['value']);
search.trigger('input');
Expand Down
57 changes: 38 additions & 19 deletions src/Traits/HandlesAjaxRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ trait HandlesAjaxRequest
public function handleAjaxRequest(Request $request, $mode = null)
{
if ($mode == 'create') {
return $this->ajaxCreate();
return $this->ajaxCreate($request);
}

if ($mode == 'edit') {
return $this->ajaxEdit();
return $this->ajaxEdit($request);
}

if ($mode == 'delete') {
return $this->ajaxDelete();
return $this->ajaxDelete($request);
}

if (strtolower($request->method()) == 'put') {
Expand All @@ -47,6 +47,7 @@ public function handleAjaxRequest(Request $request, $mode = null)
* Provides the search algorithm for the select2 field. Overwrite it in
* the EntityCrudController if you need some special functionalities
*
* @param Request $request
* @return mixed
*/
public function ajaxIndex(Request $request)
Expand All @@ -67,60 +68,60 @@ public function ajaxIndex(Request $request)

/**
* Returns the HTML that is used for displaying the on-the-fly modal of the adding an entity
* @param Request $request
* @return string
*/
public function ajaxCreate()
public function ajaxCreate(Request $request)
{
$this->crud->hasAccessOrFail('create');

return \View::make('webfactor::modal.create')
return \View::make($this->getModalView($request, 'create', 'webfactor::modal.create'))
->with('action', 'create')
->with('entity', $this->getAjaxEntity())
->with('crud', $this->crud)
->with('fields', $this->crud->getCreateFields())
->with('title', trans('backpack::crud.add') . ' ' . $this->crud->entity_name)
->with('field_name', request()->input('field_name'))
->with('attribute', request()->input('attribute'))
->with('request', $request)
->render();
}

/**
* Returns the HTML that is used for displaying the on-the-fly modal of the editing an entity
* @param Request $request
* @return string
*/
public function ajaxEdit()
public function ajaxEdit(Request $request)
{
$this->crud->hasAccessOrFail('update');

return \View::make('webfactor::modal.edit')
return \View::make($this->getModalView($request, 'edit', 'webfactor::modal.edit'))
->with('action', 'edit')
->with('id', request()->input('id'))
->with('id', $request->input('id'))
->with('entity', $this->getAjaxEntity())
->with('crud', $this->crud)
->with('fields', $this->crud->getUpdateFields(request()->input('id')))
->with('fields', $this->crud->getUpdateFields($request->input('id')))
->with('title', trans('backpack::crud.add') . ' ' . $this->crud->entity_name)
->with('field_name', request()->input('field_name'))
->with('attribute', request()->input('attribute'))
->with('request', $request)
->render();
}

/**
* Returns the HTML that is used for displaying the on-the-fly modal of the deleting an entity
* @param Request $request
* @return string
*/
public function ajaxDelete()
public function ajaxDelete(Request $request)
{
$this->crud->hasAccessOrFail('delete');

return \View::make('webfactor::modal.delete')
return \View::make($this->getModalView($request, 'delete', 'webfactor::modal.delete'))
->with('action', 'delete')
->with('id', request()->input('id'))
->with('entry', $this->crud->model::find(request()->input('id')))
->with('id', $request->input('id'))
->with('entry', $this->crud->model::find($request->input('id')))
->with('entity', $this->getAjaxEntity())
->with('crud', $this->crud)
->with('title', trans('backpack::crud.add') . ' ' . $this->crud->entity_name)
->with('field_name', request()->input('field_name'))
->with('attribute', request()->input('attribute'))
->with('request', $request)
->render();
}

Expand Down Expand Up @@ -200,6 +201,8 @@ public function ajaxDestroy(int $id)
/**
* Validates the request and returns an error bag if it fails
*
* @param Request $request
* @param array $rules
* @return mixed
*/
public function ajaxValidationFails(Request $request, array $rules)
Expand Down Expand Up @@ -266,6 +269,7 @@ private function ajaxRespondError()
/**
* Formats the message for the notification
*
* @param $message
* @return string
*/
private function ajaxFormatMessage($message)
Expand All @@ -288,4 +292,19 @@ private function ajaxFormatMessage($message)

return $message;
}

/**
* @param Request $request
* @param string $mode
* @param string $fallbackView
* @return array|string|null
*/
private function getModalView(Request $request, string $mode, string $fallbackView)
{
if (\View::exists($request->input($mode . '_modal_view'))) {
return $request->input($mode . '_modal_view');
}

return $fallbackView;
}
}