Deleting from within the edit page - laravel-backpack

Hi I'm trying to make it so I can have a delete button within the edit page to just directly delete whatever crud resource is being edited, now I began with taking a look at the list view and trying to reverse engineer the jQuery stuff that creates the delete buttons in the list and for the life of me I can't figure out how to do it. I tried grabbing the blade code in the delete.blade.php view and when I click the button that generates I get a 403 forbidden error. Now I was thinking I could continue messing with the jQuery but shouldn't that delete button code also work? My conclusion so far is I'm missing something stupidly obvious regarding permissions maybe? We're running the crud permissions package as well, would that impact anything? It's weird because I have the button in the
#if ($crud->hasAccess('delete'))
checking stuff so shouldn't that mean I already have permissions? I sure can delete the items from the list view still.
Sorry if I'm confusing, I'm a bit of a super tired dad and could use some help :p

Are you sure you're pointing the AJAX call in the right direction?
The list.blade.js javascript points to the current page, because it's the same URL, just a different protocol. If you place it on another page, it won't work as-is. You have to point it to $this->crud->route, still using the DELETE method. So something like this:
function register_delete_button_action() {
$("[data-button-type=delete]").unbind('click');
// CRUD Delete
// ask for confirmation before deleting an item
$("[data-button-type=delete]").click(function(e) {
e.preventDefault();
var delete_button = $(this);
var delete_url = '{{ url($this->crud->route) }}'; <---- notice the change here
if (confirm("{{ trans('backpack::crud.delete_confirm') }}") == true) {
$.ajax({
url: delete_url,
type: 'DELETE',
success: function(result) {
// Show an alert with the result
new PNotify({
title: "{{ trans('backpack::crud.delete_confirmation_title') }}",
text: "{{ trans('backpack::crud.delete_confirmation_message') }}",
type: "success"
});
// delete the row from the table
delete_button.parentsUntil('tr').parent().remove();
},
error: function(result) {
// Show an alert with the result
new PNotify({
title: "{{ trans('backpack::crud.delete_confirmation_not_title') }}",
text: "{{ trans('backpack::crud.delete_confirmation_not_message') }}",
type: "warning"
});
}
});
} else {
new PNotify({
title: "{{ trans('backpack::crud.delete_confirmation_not_deleted_title') }}",
text: "{{ trans('backpack::crud.delete_confirmation_not_deleted_message') }}",
type: "info"
});
}
});
}

Related

How to simulate click event for tinyMCE v6x custom toolbar button programmatically

This is simple enough in earlier version of tinyMCE, but I can't find a way to make it work in v6x (suggested answers here only apply to earlier versions, that I can see)
Here's my button:
tinymce.PluginManager.add('newButton', (editor, url) => {
editor.ui.registry.addButton('newButton', {
text: 'Click me',
enabled: true,
onAction: () => {
alert('You clicked me')
}
})
return {
getMetadata: () => ({
name: 'newButton',
url: ''
})
}
});
tinymce.init({
selector: "textarea",
plugins: "newButton",
toolbar1: "newButton"
});
This works fine - click the button and you get an alert telling you you have. What I want to do now is call this click event from code (JaveScript) - I was hoping
tinymce.activeEditor.buttons['newButton'].onclick();
would work, as it does for - say - the "code" plugin; i.e. add this plugin (and button) to the editor and calling
tinymce.activeEditor.buttons['code'].onclick();
simulates clicking the toolbar button. So... how can I "click" my own custon toolbar button?
[edit] well.. that last line did work, I swear it did. Now it doesn't. wt.. :(
This may not be the "right" way (well, I know it isn't!) but I've found a way that works :)
First, I need a way to identify/find my custom button. I figured out tinymce renders them as div elements, and using
var divs = document.querySelectorAll('button');
divs.forEach((div) => {
console.log(div.innerHTML);
})
I am able to identify it and find the HTML used - it is not graced with an id, but we can use the innerHTML property (as identified) to get it and then simulate a click- viz:
var divs = document.querySelectorAll('button');
divs.forEach((div) => {
// NB 'DOC' is the text property of my custom button
if (div.innerHTML === '<span class="tox-tbtn__select-label">DOC</span>') {
// now we can simulate a click on it:
var evt = new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true
});
div.dispatchEvent(evt);
return;
}
})
(Thanks to the second answer, by Derek, here:
How to simulate a mouse click using JavaScript?
for the simulate click code)
[edit] better to use a for-loop rather than forEach as there's no sensible way to break out of the latter - that "return" doesn't actually do anything.

How to seperate Vue logic in a laravel app based on layout and page templates

I have a laravel app and a Vue instance attached to the body (or a div, just inside the body).
const app = new Vue({
el: '#app'
});
I think it makes sense to use the Vue instance for stuff relating to the layout (eg header, nav, footer logic).
Now I have a form that is visible on a specific route (e.g. example.com/thing/create). I want to add some logic to it, e.g. hiding a field based on selected option in the form. It is logic meant for just this form (not to be reused). I prefer not to put all the logic inline with the form but put it in the app.js. I could put it in the Vue instance bound to the body but that sounds odd as it only applies to the form that is much deeper into the dom.
I want to leave the markup of the form in the blade template (that inherits the layout).
I tried creating a component but am not sure how to bind this inside the main Vue instance. What is the best way to handle things for this form, put it in the app.js and have it somewhat structured, putting the variables somewhat into scope. Or is it really necessary to remove the main Vue instance bound to the full layout code?
What I tried was something like this, but it does not work (attaching it to the <form id="object-form"> seems to fail:
var ObjectForm = {
template: function() { return '#object-form'},
data: function() {
return {
selectedOption: 1
}
},
computed: {
displayField: function() {
// return true or false depending on form state
return true;
}
}
};
Things do work if I remove the #app Vue instance or when I put everything directly in the app Vue instance. But that seems messy, if I have similar variables for another form they should be seperated somewhat.
I would appreciate some advice regarding the structure (differentiate page layout and page specific forms) and if possible some example to put the form logic inside the main app.js.
I hope this helps kind of break things down for you and helps you understand Vue templating.
It is best to take advantage of Vue's components. For you it would look something like this. Some of this code depends on your file structure, but you should be able to understand it.
In your app.js file (or your main js file)
Vue.component('myform',require('./components/MyForm.vue'));
const app = new Vue({
el: "#app"
});
Then create the MyForm.vue file
<template>
<form>
Put Your Form Markup Here
</form>
</template>
<script>
// Here is where you would handle the form scripts.
// Use methods, props, data to help set up your component
module.exports = {
data: function() {
return {
selectedOption: 1
}
},
computed: {
displayField: function() {
// return true or false depending on form state
return true;
}
},
methods: {
// add methods for dynamically changing form values
}
}
</script>
Then you will be able to just call in your blade file.
<myform></myform>
I found out how to do it. The trick was to use an inline template. Surround the form in the view with:
<object-form inline-template>
<form>...</form>
</object-form>
Where object-form is the name of the component. In the ObjectForm code above I remove the template, like this:
var ObjectForm = {
data: function() {
return {
selectedOption: 1
}
},
computed: {
displayField: function() {
// return true or false depending on form state
return true;
}
}
};
I attach the component within the root vue app like this:
const app = new Vue({
el: 'body',
components: {
'object-form': ObjectForm
}
});
This way I can use the form as it was generated from the controller and view and I can separate it from the root (attached to body) methods and properties.
To organize it even better I can probably store the ObjectForm in a seperate .vue file the way #Tayler Foster suggested.

Combobox not show the correct language values in struts1

Im using ExtJS and Struts1 for an application, when user uses this app in english and displays the combobox (inside form), the selection is in another language (spanish) but not in english. After save the form and reload the page this parameter shows in english (but if user displays the combobox again it shows in spanish). What im doing wrong to show the combobox in the correct language?.
This is what happens:
The code has more than 4k lines, this is the combobox creation, if you need more lines i dont have any problem to put here.
var storeTipoProcedimiento = new Ext.data.SimpleStore({
proxy: dameProxy( 'gestionPlanes.do' ),
autoLoad: true,
fields: [
{name: 'idTipoProcedimiento', type: 'int'},
{name: 'descripcion'}
],
baseParams: {
method: 'buscarTipoProcedimiento'
}
});
//combo para buscar los tipos de procedimientos
function dameComboTipoProcedimiento(){
var combo = new Ext.form.ComboBox({
store: storeTipoProcedimiento
,valueField: 'idTipoProcedimiento'
,fieldLabel:'<bean:message key="label.gd.tab2.tipoProc"/>'
,displayField:'descripcion'
,labelStyle: 'color: red; width: 114px;'
,fieldClass: 'padding-left: 50px;'
,mode:'local'
,triggerAction:'all'
,editable: false
,name: 'Select_Tipo'
,id: 'Select_Tipo'
,hiddenName: 'idTipo'
,width: 190
,emptyText: '<bean:message key="label.gd.tab2.tipoProc.msgElijaTipo"/>'
,listeners: {
'collapse': function(){
tipoProcedimientoId = this.value;
},
select:{fn:function(combo){
tipoProcedimientoId = combo.getValue();
}}
}
});
return combo;
}
Check the response from server. Probably the request you are doing for loading combobox is probably returning Spanish data than english data.
May be server is able to recognize the first request as right localization but for the next hit it is failing to detect. Share the code for store and proxy settings. May be we can judge by seeing that.

How to render a view into a string in SailsJS?

In one controller I want to render a certain view with a certain layout to send an email with the resulting string, but I obviously do not need to show the result to the user. Is there a way to use the EJS engine that I'm using to render views to achieve this? Here's my a bit simplified controller action:
setEmail: function(req, res) {
var update = {
activationToken: _getToken(),
email: req.param('email')
};
Profile.update(res.locals.profile.id, update).then(function(profile) {
res.redirect(profileUrl);
mailer.sendActivationEmail(
update.email,
res.i18n('Подтвердите свой адрес электронной почты'),
emailString); // <=== Here is where I need the string rendered from a view
});
},
Use the view-hook
Profile.update(res.locals.profile.id, update).then(function(profile) {
res.redirect(profileUrl);
sails.hooks.views.render("viewname",profile, function(err,html){
if(err) return console.log(err);
mailer.sendActivationEmail(
update.email,
res.i18n('Подтвердите свой адрес электронной почты'),
html
);
})
});
Edit: right callback
I think I would rather use a specific email module like this one:
https://github.com/niftylettuce/node-email-templates
Which can access EJS templates

jquery disabled button not working with IE

In my code I disable the submit button with jquery and then do a check to enable it. It works fine but not in IE. Could some please help me out, Thanks
function checkPassword() {
$('input#password').mouseout(function(){
var password =$('#password').val();
//event.preventDefault();
//alert(password);
$.ajax({
type: "POST",
url: "ajax/pass.php",
cache: false,
datatype:"html",
data: "password="+ password,
success: function(msg){
if (msg) {
$('#feedbk').html(msg);
var name = $('#feedbk').text().length;
var valid = 'Valid Password.';
var n = valid.length
if (name == n) {
$('#submit').attr("disabled", false);
$('#feedbk').fadeOut(3000);
} else {
$('#submit').attr("disabled", true);
}
}
}
});
});
};
The solution is to use regular javascript
var el = document.getElementById(selectBoxCheckBoxOrButtonID);
el.removeAttribute('disabled');
I used straight JavaScript to sort out the problem
document.getElementById('selectBoxCheckBoxOrButtonID').removeAttribute('disabled');
Thanks #user843753 your solution work marvelously.
I am reiterating it here because I cannot comment at the moment and it looks so non- intuitive (What! not a jquery solution).
But why oh why is it not fixed in JQuery 1.6.2?
My original issues with IE include, re-enbled disable buttons, only be made visible on mouse-over.
In another case the re-enabled disabled buttons could not made visible with any user interaction.