Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
paragraphs-3312044
Manage
Activity
Members
Labels
Plan
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Issue forks
paragraphs-3312044
Commits
4247ecd6
Commit
4247ecd6
authored
10 years ago
by
Jeroen Bobbeldijk
Browse files
Options
Downloads
Patches
Plain Diff
Added functionality as described in
#2138767
parent
8b9738b0
No related branches found
Branches containing commit
Tags
7.x-1.x-dev-editmode
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
paragraphs.module
+170
-8
170 additions, 8 deletions
paragraphs.module
with
170 additions
and
8 deletions
paragraphs.module
+
170
−
8
View file @
4247ecd6
...
...
@@ -2,7 +2,7 @@
define
(
'PARAGRAPHS_DEFAULT_TITLE'
,
'Paragraph'
);
define
(
'PARAGRAPHS_DEFAULT_TITLE_MULTIPLE'
,
'Paragraphs'
);
define
(
'PARAGRAPHS_DEFAULT_EDIT_MODE'
,
'open'
);
/**
* Loads a paragraphs item.
...
...
@@ -682,6 +682,17 @@ function paragraphs_menu() {
'file'
=>
'paragraphs.admin.inc'
,
);
$items
[
'paragraphs/edit/ajax'
]
=
array
(
'title'
=>
'Edit item callback'
,
'page callback'
=>
'paragraphs_edit_js'
,
'delivery callback'
=>
'ajax_deliver'
,
'access callback'
=>
TRUE
,
'theme callback'
=>
'ajax_base_page_theme'
,
'type'
=>
MENU_CALLBACK
,
'file path'
=>
'includes'
,
'file'
=>
'form.inc'
,
);
$items
[
'paragraphs/remove/ajax'
]
=
array
(
'title'
=>
'Remove item callback'
,
'page callback'
=>
'paragraphs_remove_js'
,
...
...
@@ -892,6 +903,19 @@ function paragraphs_field_instance_settings_form($field, $instance) {
'#required'
=>
TRUE
,
);
$element
[
'default_edit_mode'
]
=
array
(
'#type'
=>
'select'
,
'#title'
=>
t
(
'Default edit mode'
),
'#description'
=>
t
(
'The default edit mode the paragraph item is in.'
),
'#options'
=>
array
(
'open'
=>
t
(
'Open'
),
'closed'
=>
t
(
'Closed'
),
),
'#default_value'
=>
isset
(
$settings
[
'default_edit_mode'
])
?
$settings
[
'default_edit_mode'
]
:
PARAGRAPHS_DEFAULT_EDIT_MODE
,
'#required'
=>
TRUE
,
);
if
(
!
count
(
$bundles
))
{
$element
[
'allowed_bundles_explain'
]
=
array
(
'#type'
=>
'markup'
,
...
...
@@ -1247,10 +1271,22 @@ function paragraphs_field_widget_form_build(&$form, &$form_state, $field, $insta
$deleted_paragraph
=
FALSE
;
$default_edit_mode
=
isset
(
$instance
[
'settings'
][
'default_edit_mode'
])
?
$instance
[
'settings'
][
'default_edit_mode'
]
:
PARAGRAPHS_DEFAULT_EDIT_MODE
;
$being_edited_paragraph
=
TRUE
;
if
(
$default_edit_mode
===
'closed'
)
{
$being_edited_paragraph
=
FALSE
;
}
if
(
isset
(
$field_state
[
'entity'
][
$delta
]))
{
if
(
isset
(
$field_state
[
'entity'
][
$delta
]
->
removed
)
&&
$field_state
[
'entity'
][
$delta
]
->
removed
)
{
$deleted_paragraph
=
TRUE
;
}
if
(
$being_edited_paragraph
||
(
isset
(
$field_state
[
'entity'
][
$delta
]
->
being_edited
)
&&
$field_state
[
'entity'
][
$delta
]
->
being_edited
))
{
$being_edited_paragraph
=
TRUE
;
}
else
{
$being_edited_paragraph
=
FALSE
;
}
$paragraph_item
=
$field_state
[
'entity'
][
$delta
];
}
else
{
...
...
@@ -1262,6 +1298,8 @@ function paragraphs_field_widget_form_build(&$form, &$form_state, $field, $insta
// load.
if
(
empty
(
$paragraph_item
)
&&
$bundle
)
{
$paragraph_item
=
entity_create
(
'paragraphs_item'
,
array
(
'bundle'
=>
$bundle
,
'field_name'
=>
$field_name
));
$paragraph_item
->
being_edited
=
TRUE
;
$being_edited_paragraph
=
TRUE
;
}
if
(
!
empty
(
$paragraph_item
))
{
...
...
@@ -1282,17 +1320,38 @@ function paragraphs_field_widget_form_build(&$form, &$form_state, $field, $insta
}
if
(
!
$deleted_paragraph
)
{
field_attach_form
(
'paragraphs_item'
,
$paragraph_item
,
$element
,
$form_state
,
$language
);
if
(
empty
(
$element
[
'#required'
]))
{
$element
[
'#after_build'
][]
=
'paragraphs_field_widget_embed_delay_required_validation'
;
}
if
(
isset
(
$paragraph_item
))
{
$element
[
'actions'
]
=
array
(
'#type'
=>
'actions'
,
'#weight'
=>
9999
,
);
if
(
$being_edited_paragraph
)
{
field_attach_form
(
'paragraphs_item'
,
$paragraph_item
,
$element
,
$form_state
,
$language
);
if
(
empty
(
$element
[
'#required'
]))
{
$element
[
'#after_build'
][]
=
'paragraphs_field_widget_embed_delay_required_validation'
;
}
}
else
{
$element
[
'actions'
]
=
array
(
'#type'
=>
'actions'
,
'#weight'
=>
9999
,
);
$element
[
'actions'
][
'edit_button'
]
=
array
(
'#delta'
=>
$delta
,
'#name'
=>
implode
(
'_'
,
$parents
)
.
'_edit_button'
,
'#type'
=>
'submit'
,
'#value'
=>
t
(
'Edit'
),
'#validate'
=>
array
(),
'#submit'
=>
array
(
'paragraphs_edit_submit'
),
'#limit_validation_errors'
=>
array
(),
'#ajax'
=>
array
(
'path'
=>
'paragraphs/edit/ajax'
,
'effect'
=>
'fade'
,
),
'#weight'
=>
999
,
);
}
if
(
isset
(
$paragraph_item
))
{
$element
[
'actions'
][
'remove_button'
]
=
array
(
'#delta'
=>
$delta
,
'#name'
=>
implode
(
'_'
,
$parents
)
.
'_remove_button'
,
...
...
@@ -1584,6 +1643,66 @@ function paragraphs_remove_submit($form, &$form_state) {
$form_state
[
'rebuild'
]
=
TRUE
;
}
/**
* Submit callback to editing an item from the field UI multiple wrapper.
*
* When a edited button is submitted, we need to find the item that it
* referenced and delete it. Since field UI has the deltas as a straight
* unbroken array key, we have to renumber everything down. Since we do this
* we *also* need to move all the deltas around in the $form_state['values']
* and $form_state['input'] so that user changed values follow. This is a bit
* of a complicated process.
*/
function
paragraphs_edit_submit
(
$form
,
&
$form_state
)
{
$button
=
$form_state
[
'triggering_element'
];
$delta
=
$button
[
'#delta'
];
// Where in the form we'll find the parent element.
$address
=
array_slice
(
$button
[
'#array_parents'
],
0
,
-
3
);
// Go one level up in the form, to the widgets container.
$parent_element
=
drupal_array_get_nested_value
(
$form
,
$address
);
$field_name
=
$parent_element
[
'#field_name'
];
$langcode
=
$parent_element
[
'#language'
];
$parents
=
$parent_element
[
'#field_parents'
];
$field_state
=
field_form_get_state
(
$parents
,
$field_name
,
$langcode
,
$form_state
);
if
(
isset
(
$field_state
[
'entity'
][
$delta
]))
{
$field_state
[
'entity'
][
$delta
]
->
being_edited
=
1
;
}
// Fix the weights. Field UI lets the weights be in a range of
// (-1 * item_count) to (item_count). This means that when we remove one,
// the range shrinks; weights outside of that range then get set to
// the first item in the select by the browser, floating them to the top.
// We use a brute force method because we lost weights on both ends
// and if the user has moved things around, we have to cascade because
// if I have items weight weights 3 and 4, and I change 4 to 3 but leave
// the 3, the order of the two 3s now is undefined and may not match what
// the user had selected.
$input
=
drupal_array_get_nested_value
(
$form_state
[
'input'
],
$address
);
// Sort by weight,
// but first remove garbage values to ensure proper '_weight' sorting
unset
(
$input
[
'add_more'
]);
uasort
(
$input
,
'_field_sort_items_helper'
);
// Reweight everything in the correct order.
$weight
=
-
1
*
$field_state
[
'items_count'
]
+
1
;
foreach
(
$input
as
$key
=>
$item
)
{
if
(
$item
)
{
$input
[
$key
][
'_weight'
]
=
$weight
++
;
}
}
drupal_array_set_nested_value
(
$form_state
[
'input'
],
$address
,
$input
);
field_form_set_state
(
$parents
,
$field_name
,
$langcode
,
$form_state
,
$field_state
);
$form_state
[
'rebuild'
]
=
TRUE
;
}
/**
* Submit callback to remove an item from the field UI multiple wrapper.
*
...
...
@@ -1727,6 +1846,49 @@ function paragraphs_restore_submit($form, &$form_state) {
}
/**
* Page callback to handle AJAX for editing a paragraphs item.
*
* This is a direct page callback. The actual job of deleting the item is
* done in the submit handler for the button, so all we really need to
* do is process the form and then generate output. We generate this
* output by doing a replace command on the id of the entire form element.
*/
function
paragraphs_edit_js
()
{
// drupal_html_id() very helpfully ensures that all html IDS are unique
// on a page. Unfortunately what it doesn't realize is that the IDs
// we are generating are going to replace IDs that already exist, so
// this actually works against us.
if
(
isset
(
$_POST
[
'ajax_html_ids'
]))
{
unset
(
$_POST
[
'ajax_html_ids'
]);
}
list
(
$form
,
$form_state
)
=
ajax_get_form
();
drupal_process_form
(
$form
[
'#form_id'
],
$form
,
$form_state
);
// Get the information on what we're removing.
$button
=
$form_state
[
'triggering_element'
];
// Go two levels up in the form, to the whole widget.
$element
=
drupal_array_get_nested_value
(
$form
,
array_slice
(
$button
[
'#array_parents'
],
0
,
-
4
));
// Now send back the proper AJAX command to replace it.
$return
=
array
(
'#type'
=>
'ajax'
,
'#commands'
=>
array
(
ajax_command_replace
(
'#'
.
$element
[
'#id'
],
drupal_render
(
$element
))
),
);
// Because we're doing this ourselves, messages aren't automatic. We have
// to add them.
$messages
=
theme
(
'status_messages'
);
if
(
$messages
)
{
$return
[
'#commands'
][]
=
ajax_command_prepend
(
'#'
.
$element
[
'#id'
],
$messages
);
}
return
$return
;
}
/**
* Page callback to handle AJAX for removing a paragraphs item.
*
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment