Replace jQuery UI dialogs
August 23, 2025 · AI Conversations
<script>
$(function () {
$('#react-delete-confirm-dialog').dialog({ autoOpen: false, modal: true });
$('#clone-confirm-dialog').dialog({ autoOpen: false, modal: true });
// Initialize error dialog with OK button
$('#error-dialog').dialog({
autoOpen: false,
modal: true,
buttons: {
OK: function () {
$(this).dialog('close');
}
}
});
// Initialize copy confirm dialog
$('#copy-confirm-dialog').dialog({
autoOpen: false,
modal: true,
buttons: {
OK: function () {
$(this).dialog('close');
}
}
});
// Initialize success dialogs with reload button
$('#success-dialog').dialog({
autoOpen: false,
modal: true,
buttons: {
OK: function () {
$(this).dialog('close');
window.location.reload();
}
}
});
$('#success-dialog-clone').dialog({
autoOpen: false,
modal: true,
buttons: {
OK: function () {
$(this).dialog('close');
window.location.reload();
}
}
});
});
function deleteFeed(id) {
$('#react-delete-confirm-dialog').dialog('option', 'buttons', {
Cancel: function () {
$(this).dialog('close');
// No further action
},
Delete: function () {
$('#react-delete-confirm-dialog').dialog('close');
$.ajax({
url: '/shopping_feed/api/delete/' + id,
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json'
},
success: function (data) {
if (data.success) {
// Assuming setFeeds is used to update a React state.
// Replace with manual DOM manipulation if needed.
$('#success-dialog').dialog('open');
} else {
$('#error-dialog').dialog('open');
}
},
error: function () {
$('#error-dialog').dialog({
modal: true,
buttons: {
OK: function () {
$(this).dialog('close');
}
}
});
}
});
}
});
$('#react-delete-confirm-dialog').dialog('open');
}
function cloneFeed(id) {
$('#clone-confirm-dialog').dialog('option', 'buttons', {
Cancel: function () {
$(this).dialog('close');
// No further action on cancel
},
Clone: function () {
$('#clone-confirm-dialog').dialog('close');
$.ajax({
url: '/shopping_feed/api/clone/' + id,
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json'
},
success: function (data) {
console.log(data);
if (data.success) {
$('#success-dialog-clone').dialog('open');
} else {
$('#error-dialog').dialog('option', 'buttons', {
OK: function () {
$(this).dialog("close");
}
});
$('#error-dialog').dialog('open');
}
},
error: function () {
$('#error-dialog').dialog('option', 'buttons', {
OK: function () {
$(this).dialog("close");
}
});
$('#error-dialog').dialog('open');
}
});
}
});
$('#clone-confirm-dialog').dialog('open');
}
function copyFeed(feedurl) {
// Create a temporary input element
var $tempInput = $('<input>');
$('body').append($tempInput);
$tempInput.val(feedurl).select();
try {
var successful = document.execCommand('copy');
$tempInput.remove();
if (successful) {
$('#copy-confirm-dialog').dialog('open');
} else {
$('#error-dialog').dialog('option', 'buttons', {
OK: function () {
$(this).dialog("close");
}
});
$('#error-dialog').dialog('open');
}
} catch (err) {
console.error("Failed to copy: ", err);
$('#error-dialog').dialog('option', 'buttons', {
OK: function () {
$(this).dialog("close");
}
});
$('#error-dialog').dialog('open');
}
}
</script>
replace custom disalog with concrete cms 9 provided dialog
### What changes
1. **Remove** all the hidden “ blocks.
2. **Use** `ConcreteAlert` helpers for info/success/error + confirm prompts.
3. **Use** the modern Clipboard API for copy.
### Drop‑in JS (replace your `
<script>
...
</script>
` with this)
<script>
/* If you ever see "ConcreteAlert is undefined" on a non-dashboard page,
* make sure the "app" asset is loaded from the view/controller:
* View::getInstance()->requireAsset('core/app');
*/
function showSuccess(msg) { ConcreteAlert.notify({ title: 'Success', message: msg }); }
function showError(msg) { ConcreteAlert.error(msg || 'An error occurred while processing your request.'); }
function showInfo(msg) { ConcreteAlert.dialog('Info', msg); } // simple OK dialog
function confirmAction(title, message, onConfirm) {
ConcreteAlert.confirm(message, function () { onConfirm && onConfirm(); }, title);
}
// DELETE
function deleteFeed(id) {
confirmAction('Delete Feed',
'Are you sure you want to delete this feed? This will delete the feed and all its data.',
function () {
$.ajax({
url: '/shopping_feed/api/delete/' + id,
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },
success: function (data) {
if (data && data.success) {
showSuccess('Feed deleted successfully!');
window.location.reload();
} else {
showError();
}
},
error: function () { showError(); }
});
}
);
}
// CLONE
function cloneFeed(id) {
confirmAction('Clone Feed', 'Duplicate this feed?', function () {
$.ajax({
url: '/shopping_feed/api/clone/' + id,
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },
success: function (data) {
if (data && data.success) {
showSuccess('Feed cloned successfully!');
window.location.reload();
} else {
showError();
}
},
error: function () { showError(); }
});
});
}
// COPY
async function copyFeed(feedurl) {
try {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(feedurl);
} else {
// Fallback for older browsers
const ta = document.createElement('textarea');
ta.value = feedurl;
ta.style.position = 'fixed';
ta.style.left = '-9999px';
document.body.appendChild(ta);
ta.focus(); ta.select();
document.execCommand('copy');
document.body.removeChild(ta);
}
showInfo('Feed URL copied to clipboard!');
} catch (e) {
showError('Could not copy the URL.');
}
}
</script>
### Clean up your markup
– Delete these blocks entirely:
`#copy-confirm-dialog`, `#error-dialog`, `#clone-confirm-dialog`, `#success-dialog`, `#success-dialog-clone`, `#react-delete-confirm-dialog`.
They’re no longer needed—`ConcreteAlert` renders its own UI.
### Notes
– On **dashboard pages**, `ConcreteAlert` is already available. If you ever reuse this on a **front‑end** page, load the app asset in your controller/view (`requireAsset('core/app')`). citeturn1search1
That’s it—now your UI is v9‑native with no jQuery UI dependency.
<script>
n // Helper wrappers around Concrete CMS v9 alert utilitiesn function showSuccess(msg) { ConcreteAlert.notify({ title: <?php echo json_encode(t("Success")); ?>, message: msg }); }n function showError(msg) { ConcreteAlert.error(msg || <?php echo json_encode(t("An error occurred while processing your request.")); ?>); }n function showInfo(msg) { ConcreteAlert.dialog(<?php echo json_encode(t("Info")); ?>, msg); }n function confirmAction(title, message, onConfirm) {n ConcreteAlert.confirm(message, function () { if (typeof onConfirm === 'function') onConfirm(); }, title);n }nn // Delete feed (confirm -> POST -> notify)n function deleteFeed(id) {n confirmAction(n <?php echo json_encode(t("Delete Feed")); ?>,n <?php echo json_encode(t("Are you sure you want to delete this feed? This will delete the feed and all its data.")); ?>,n function () {n $.ajax({n url: '/shopping_feed/api/delete/' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t("Feed deleted successfully!")); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn // Clone feed (confirm -> POST -> notify)n function cloneFeed(id) {n confirmAction(n <?php echo json_encode(t("Clone Feed")); ?>,n <?php echo json_encode(t("Duplicate this feed?")); ?>,n function () {n $.ajax({n url: '/shopping_feed/api/clone/' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t("Feed cloned successfully!")); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn // Copy using Clipboard API with fallbackn async function copyFeed(feedurl) {n try {n if (navigator.clipboard && window.isSecureContext) {n await navigator.clipboard.writeText(feedurl);n } else {n // Fallback for older browsers / non-secure contextn var ta = document.createElement('textarea');n ta.value = feedurl; ta.style.position = 'fixed'; ta.style.left = '-9999px';n document.body.appendChild(ta); ta.focus(); ta.select(); document.execCommand('copy');n document.body.removeChild(ta);n }n showInfo(<?php echo json_encode(t("Feed URL copied to clipboard!")); ?>);n } catch (e) {n showError(<?php echo json_encode(t("Could not copy the URL.")); ?>);n }n }n
</script>
"}]}
Basicalt folly concrete cms 9 page standards
– Follow Concrete CMS v9 listing page patterns.
– Add a dashboard-style search box above the **Add Feed** button.
– Use `$this->url()` everywhere (no hardcoded `/index.php`).
– Preserve `q` and `limit` across pagination and dropdown changes.
– Keep everything translated via `t()` and alerts via `ConcreteAlert`.
Want me to also wire the search to your controller (e.g., filter `$feeds` by `$q` in the Single Page controller) or add server-side sorting headers?
also move search bar right above Add feed button like attched default concrete cms pages
<script>
n // Helper wrappers around Concrete CMS v9 alert utilitiesn function showSuccess(msg) { ConcreteAlert.notify({ title: <?php echo json_encode(t('Success')); ?>, message: msg }); }n function showError(msg) { ConcreteAlert.error(msg || <?php echo json_encode(t('An error occurred while processing your request.')); ?>); }n function showInfo(msg) { ConcreteAlert.dialog(<?php echo json_encode(t('Info')); ?>, msg); }n function confirmAction(title, message, onConfirm) {n ConcreteAlert.confirm(message, function () { if (typeof onConfirm === 'function') onConfirm(); }, title);n }nn // Delete feed (confirm -> POST -> notify)n function deleteFeed(id) {n confirmAction(n <?php echo json_encode(t('Delete Feed')); ?>,n <?php echo json_encode(t('Are you sure you want to delete this feed? This will delete the feed and all its data.')); ?>,n function () {n $.ajax({n url: '<?php echo h($this->url('/shopping_feed/api/delete/')); ?>' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t('Feed deleted successfully!')); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn // Clone feed (confirm -> POST -> notify)n function cloneFeed(id) {n confirmAction(n <?php echo json_encode(t('Clone Feed')); ?>,n <?php echo json_encode(t('Duplicate this feed?')); ?>,n function () {n $.ajax({n url: '<?php echo h($this->url('/shopping_feed/api/clone/')); ?>' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t('Feed cloned successfully!')); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn // Copy using Clipboard API with fallbackn async function copyFeed(feedurl) {n try {n if (navigator.clipboard && window.isSecureContext) {n await navigator.clipboard.writeText(feedurl);n } else {n // Fallback for older browsers / non-secure contextn var ta = document.createElement('textarea');n ta.value = feedurl; ta.style.position = 'fixed'; ta.style.left = '-9999px';n document.body.appendChild(ta); ta.focus(); ta.select(); document.execCommand('copy');n document.body.removeChild(ta);n }n showInfo(<?php echo json_encode(t('Feed URL copied to clipboard!')); ?>);n } catch (e) {n showError(<?php echo json_encode(t('Could not copy the URL.')); ?>);n }n }n
</script>
"}]}
<script>
n // Helper wrappers around Concrete CMS v9 alert utilitiesn function showSuccess(msg) { ConcreteAlert.notify({ title: <?php echo json_encode(t('Success')); ?>, message: msg }); }n function showError(msg) { ConcreteAlert.error(msg || <?php echo json_encode(t('An error occurred while processing your request.')); ?>); }n function showInfo(msg) { ConcreteAlert.dialog(<?php echo json_encode(t('Info')); ?>, msg); }n function confirmAction(title, message, onConfirm) {n ConcreteAlert.confirm(message, function () { if (typeof onConfirm === 'function') onConfirm(); }, title);n }nn // Delete feed (confirm -> POST -> notify)n function deleteFeed(id) {n confirmAction(n <?php echo json_encode(t('Delete Feed')); ?>,n <?php echo json_encode(t('Are you sure you want to delete this feed? This will delete the feed and all its data.')); ?>,n function () {n $.ajax({n url: '<?php echo h($this->url('/shopping_feed/api/delete/')); ?>' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t('Feed deleted successfully!')); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn // Clone feed (confirm -> POST -> notify)n function cloneFeed(id) {n confirmAction(n <?php echo json_encode(t('Clone Feed')); ?>,n <?php echo json_encode(t('Duplicate this feed?')); ?>,n function () {n $.ajax({n url: '<?php echo h($this->url('/shopping_feed/api/clone/')); ?>' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t('Feed cloned successfully!')); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn // Copy using Clipboard API with fallbackn async function copyFeed(feedurl) {n try {n if (navigator.clipboard && window.isSecureContext) {n await navigator.clipboard.writeText(feedurl);n } else {n // Fallback for older browsers / non-secure contextn var ta = document.createElement('textarea');n ta.value = feedurl; ta.style.position = 'fixed'; ta.style.left = '-9999px';n document.body.appendChild(ta); ta.focus(); ta.select(); document.execCommand('copy');n document.body.removeChild(ta);n }n showInfo(<?php echo json_encode(t('Feed URL copied to clipboard!')); ?>);n } catch (e) {n showError(<?php echo json_encode(t('Could not copy the URL.')); ?>);n }n }n
</script>
"}]}
I m talking about dailog Go button when click does not perform action like delete,clone,copy
<script>
n // Ensure ConcreteAlert confirm buttons use primary style and fire actions properlyn function confirmAction(title, message, onConfirm) {n ConcreteAlert.confirm(message, function () {n if (typeof onConfirm === 'function') {n onConfirm();n }n }, title, {n buttons: [n { class: 'btn btn-secondary', label: <?php echo json_encode(t('Cancel')); ?>, callback: function(){} },n { class: 'btn btn-primary', label: <?php echo json_encode(t('Go')); ?>, callback: function(){ if (typeof onConfirm === 'function') onConfirm(); } }n ]n });n }nn function showSuccess(msg) { ConcreteAlert.notify({ title: <?php echo json_encode(t('Success')); ?>, message: msg }); }n function showError(msg) { ConcreteAlert.error(msg || <?php echo json_encode(t('An error occurred while processing your request.')); ?>); }n function showInfo(msg) { ConcreteAlert.dialog(<?php echo json_encode(t('Info')); ?>, msg); }nn function deleteFeed(id) {n confirmAction(n <?php echo json_encode(t('Delete Feed')); ?>,n <?php echo json_encode(t('Are you sure you want to delete this feed? This will delete the feed and all its data.')); ?>,n function () {n $.ajax({n url: '<?php echo h($this->url('/shopping_feed/api/delete/')); ?>' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t('Feed deleted successfully!')); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn function cloneFeed(id) {n confirmAction(n <?php echo json_encode(t('Clone Feed')); ?>,n <?php echo json_encode(t('Duplicate this feed?')); ?>,n function () {n $.ajax({n url: '<?php echo h($this->url('/shopping_feed/api/clone/')); ?>' + id,n method: 'POST',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && data.success) {n showSuccess(<?php echo json_encode(t('Feed cloned successfully!')); ?>);n window.location.reload();n } else { showError(); }n },n error: function () { showError(); }n });n }n );n }nn async function copyFeed(feedurl) {n try {n if (navigator.clipboard && window.isSecureContext) {n await navigator.clipboard.writeText(feedurl);n } else {n var ta = document.createElement('textarea');n ta.value = feedurl; ta.style.position = 'fixed'; ta.style.left = '-9999px';n document.body.appendChild(ta); ta.focus(); ta.select(); document.execCommand('copy');n document.body.removeChild(ta);n }n showInfo(<?php echo json_encode(t('Feed URL copied to clipboard!')); ?>);n } catch (e) {n showError(<?php echo json_encode(t('Could not copy the URL.')); ?>);n }n }n
</script>
"}]}
and on click no action perform just error show right bottom in red
`ConcreteAlert.confirm(message, onConfirm, title /*, onCancel? */)`
That extra object was being treated as a parameter, so the button label became `[Object Object]` and the confirm callback never ran (hence the red error toast).
I’ve now fixed the canvas:
– Reverted to the **built‑in confirm** (no custom options).
– Kept default primary styling; then (optionally) rename the primary button to **“Go”** after the dialog opens without breaking the handler.
– Prevented anchor default navigation with `return false;` on the action links.
– Console‑logs XHR errors for easier debugging.
You should now see:
– Dialog primary button shows correctly (blue background), not `[Object Object]`.
– Clicking **Go/OK** actually triggers **delete/clone/copy** actions.
If you want to keep the default “OK” text instead of “Go”, I can remove the tiny snippet that renames the button label.
– Stop customizing dialog buttons (no more label issues).
– Add a robust `ajaxJSON()` wrapper that:
– Injects Concrete’s CSRF token automatically (`CCM_SECURITY_TOKEN` → sent as `ccm_token` + header).
– Forces `dataType: 'json'` and surfaces server error messages if provided.
– Use that wrapper for both **delete** and **clone**.
– Keep `copy` as-is (no server call).
This should make the dialog’s **OK** trigger the action, and the server accept it instead of throwing a CSRF/permission error. If you still get a red error, check your endpoint expects a different token handle or method. If your routes validate a specific token (e.g., `Token::validate('shopping_feed_delete')`), tell me the handle name and I’ll wire it to the request (or we can generate it in PHP and print it into the page).
this not add / before id
<script>
n function showSuccess(msg) { ConcreteAlert.notify({ title: <?php echo json_encode(t('Success')); ?>, message: msg }); }n function showError(msg) { ConcreteAlert.error(msg || <?php echo json_encode(t('An error occurred while processing your request.')); ?>); }n function showInfo(msg) { ConcreteAlert.dialog(<?php echo json_encode(t('Info')); ?>, msg); }nn function confirmAction(title, message, onConfirm) {n ConcreteAlert.confirm(message, function () {n if (typeof onConfirm === 'function') onConfirm();n }, title);n }nn var CSRF_TOKEN = (typeof window.CCM_SECURITY_TOKEN !== 'undefined') ? window.CCM_SECURITY_TOKEN : (typeof window.ccm_token !== 'undefined' ? window.ccm_token : null);nn function ajaxJSON(opts) {n var payload = opts.data || {};n if (CSRF_TOKEN) {n payload.ccm_token = CSRF_TOKEN;n }n $.ajax({n url: opts.url,n method: opts.method || 'POST',n data: payload,n dataType: 'json',n headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },n success: function (data) {n if (data && (data.success === true || data.ok === true)) {n if (typeof opts.onSuccess === 'function') opts.onSuccess(data);n } else {n var msg = (data && (data.error || data.message)) ? data.error || data.message : null;n showError(msg);n }n },n error: function (xhr) {n console.error('[AJAX ERROR]', xhr);n var msg = null;n try { var j = JSON.parse(xhr.responseText); msg = j.error || j.message; } catch (e) {}n showError(msg);n }n });n }nn function deleteFeed(id) {n confirmAction(n <?php echo json_encode(t('Delete Feed')); ?>,n <?php echo json_encode(t('Are you sure you want to delete this feed? This will delete the feed and all its data.')); ?>,n function () {n ajaxJSON({n url: '<?php echo rtrim(h($this->url('/shopping_feed/api/delete')), '/'); ?>/' + id,n method: 'POST',n onSuccess: function () {n showSuccess(<?php echo json_encode(t('Feed deleted successfully!')); ?>);n window.location.reload();n }n });n }n );n }nn function cloneFeed(id) {n confirmAction(n <?php echo json_encode(t('Clone Feed')); ?>,n <?php echo json_encode(t('Duplicate this feed?')); ?>,n function () {n ajaxJSON({n url: '<?php echo rtrim(h($this->url('/shopping_feed/api/clone')), '/'); ?>/' + id,n method: 'POST',n onSuccess: function () {n showSuccess(<?php echo json_encode(t('Feed cloned successfully!')); ?>);n window.location.reload();n }n });n }n );n }nn async function copyFeed(feedurl) {n try {n if (navigator.clipboard && window.isSecureContext) {n await navigator.clipboard.writeText(feedurl);n } else {n var ta = document.createElement('textarea');n ta.value = feedurl; ta.style.position = 'fixed'; ta.style.left = '-9999px';n document.body.appendChild(ta); ta.focus(); ta.select(); document.execCommand('copy');n document.body.removeChild(ta);n }n showInfo(<?php echo json_encode(t('Feed URL copied to clipboard!')); ?>);n } catch (e) {n showError(<?php echo json_encode(t('Could not copy the URL.')); ?>);n }n }n
</script>
"}]}
<?php echo rtrim(h($this->url('/shopping_feed/api/clone')), '/'); ?>/' + id
and same for `delete`.
This should fix the “missing slash” issue and hit the correct route.
All Groups
Cloth
electornics
Featured and not featured
Only featured
Only not featured
<script>
$(document).ready(function() {
$('a[data-cs-filter-featured]').on('click', function(e) {
e.preventDefault();
var $a = $(this),
featured = $a.data('cs-filter-featured'),
$form = $a.closest('form'),
$featured = $form.find('input[name="featured"]');
if (typeof featured === 'number') {
featured = featured.toString();
}
if ($featured.val() === featured) {
return;
}
$featured.val(featured);
$form.submit();
});
});
</script>
10
10
25
50
100
<script>
function deleteFeed(id) {
ConcreteAlert.confirm(
<?php echo json_encode(t('Are you sure you want to delete this feed? This will delete the feed and all its data.')) ?>,
function () {
$.ajax({
url: '/shopping_feed/api/delete/' + id,
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },
success: function (data) {
if (data.success) {
ConcreteAlert.notify({ message: <?php echo json_encode(t('Feed deleted successfully!')) ?>, title: <?php echo json_encode(t('Success')) ?> });
window.location.reload();
} else {
ConcreteAlert.error({ message: <?php echo json_encode(t('An error occurred while processing your request.')) ?> });
}
},
error: function () {
ConcreteAlert.error({ message: <?php echo json_encode(t('An error occurred while processing your request.')) ?> });
}
});
}
);
}
function cloneFeed(id) {
ConcreteAlert.confirm(
<?php echo json_encode(t('Do you want to duplicate this feed?')) ?>,
function () {
$.ajax({
url: '/shopping_feed/api/clone/' + id,
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' },
success: function (data) {
if (data.success) {
ConcreteAlert.notify({ message: <?php echo json_encode(t('Feed cloned successfully!')) ?>, title: <?php echo json_encode(t('Success')) ?> });
window.location.reload();
} else {
ConcreteAlert.error({ message: <?php echo json_encode(t('An error occurred while processing your request.')) ?> });
}
},
error: function () {
ConcreteAlert.error({ message: <?php echo json_encode(t('An error occurred while processing your request.')) ?> });
}
});
}
);
}
function copyFeed(feedurl) {
var $tempInput = $('<input>');
$('body').append($tempInput);
$tempInput.val(feedurl).select();
try {
var successful = document.execCommand('copy');
$tempInput.remove();
if (successful) {
ConcreteAlert.notify({ message: <?php echo json_encode(t('Feed URL copied to clipboard!')) ?>, title: <?php echo json_encode(t('Copy URL')) ?> });
} else {
ConcreteAlert.error({ message: <?php echo json_encode(t('Failed to copy to clipboard.')) ?> });
}
} catch (err) {
$tempInput.remove();
ConcreteAlert.error({ message: <?php echo json_encode(t('Failed to copy to clipboard.')) ?> });
}
}
</script>
HOw put search bar right side of breadcrumb lile other default lsitinf page search in concrete cms
– Right‑aligned inside `ccm-dashboard-header-search` (like other default listing pages).
– Uses `ccm-header-search-form` + `input-group` with the magnifier icon button.
– Keeps your Add Feed + Items-per-page controls below in the header menu.
If you prefer the search to sit on the same line as the breadcrumb/title bar, this is the correct spot—Concrete places `ccm-dashboard-header-search` in that area. If your theme doesn’t render the search row, make sure your dashboard page view includes the default dashboard header layout and `core/app` assets.