Joomla custom admin button actions - joomla

I have no idea why this doesn't work, but none of my custom button actions (tasks) do anything in my component. In my view.html.php file I have:
JToolBarHelper::custom('reports.export_csv', 'csv', '', 'CSV', false);
JToolBarHelper::custom('reports.export_mailchimp', 'mailchimp', '', 'Mailchimp', false);
Then in my ReportsControllerReports file I have 2 methods (not just 2, there are some others but they aren't relevant), export_csv() and export_mailchimp(). Whenever I click the buttons I get a JS error which I assume is preventing the action from executing the code in those methods. Something about "b is undefined". I cannot find any differences between my code and that used in other Joomla (core) components, so if anyone could shed some light on this issue it would be greatly appreciated (as usual, the Joomla forums are totally useless).

#Cfyzz solution works.
I added this to view file:
<script type="text/javascript">
Joomla.submitbutton = function(pressbutton) {
switch(pressbutton) {
case 'google':
window.location = '<?=JRoute::_( 'http://google.com', false );?>';
break;
case 'stackoverflow':
window.location = '<?=JRoute::_( 'http://stackoverflow.com', false );?>';
break;
}
}
</script>
and this in view.html.php
JToolBarHelper::cancel('stackoverflow', 'Go Overflow');
JToolBarHelper::custom('google', 'checkin', '', 'Go Google', false);
Obviously you dont have to use "JRoute::_(" in this situation. I replaced inner links with 2 samples so it`s easier to understand.

You should override the Joomla's JS framework behavour
You should use the function in your custom JS file:
Joomla.submitbutton = function(pressbutton) {
switch(pressbutton) {
case 'export_cvs':
URL = JURI::base.'index.php?option=yourController&task=export_cvs&....
$.ajax({
url: URL,
type: post, etc
});
}
}
In my component everytrhing is ok and working properly

Related

Specific property of EmberJS loaded by AJAX and updated in view

I'm having an issue here when attempting to build an integration to our partners. They're gonna submit an image URL as a GET-variable, which I obviously don't want to print straight up. The submitted image URL is submitted back to our servers with AJAX to be sanitized, returned and then updated.
What I want to do here is when the model loads, I want to display a placeholder image, and when the sanitation check is done by the server, it will return the URL (the same or another placeholder) that is to be set as the template image source.
Now, the problem is that I don't get how to make Ember listen for the update of this event. I'm trying to use observes, but apparently, this isn't available in the route. Here's my current code:
ROUTE
MyApp.PartnerRoute = Ember.Route.extend({
imageUrl: "/img/placeholder.png";
getImageUrl: function(imageUrlToCheck) {
instance = this;
$.ajax({
url: "/ajax/get-image-url",
type: "post",
data: {
"imageUrl": imageUrlToCheck
},
success: function(response) {
if(response.status === 0) {
instance.set("imageUrl", response.data.imageUrl);
}
}
});
},
// Ember update property.
imageUrlDidChange: function() {
this.get("imageUrl");
}.observes("imageUrl"),
model: function(params) {
this.getImageUrl(params.imageUrl);
return {
heading: "Welcome!",
imageUrl: this.imageUrl
}
}
});
VIEW
<script type="text/x-handlebars" data-template-name="partner">
<h1>{{heading}}</h1>
<img {{bind-attr src=imageUrl}} />
</script>
I get the error message:
Uncaught TypeError: Object function () {
this.get("imageUrl");
} has no method 'observes'
I'm not at all sure as of how to make this happen. Am I going about this the wrong way? Any help is appreciated.
Thank you for your time.
Best regards,
dimhoLt
PS. I've extracted the applicable pieces of code from much bigger objects, so if there are any typos, missing commas etc, it's due to the copy-paste and is not applicable to the actual code.
EDIT:
Worth noting is that because of legacy functionality I haven't yet rewritten, I was forced to turn off Ember extended prototypes. This is, I guess, the major cause of the issue.
Since I wrote this, I've also gone over to using a fixed model instead of attempting to work directly with the route.
You need to use a setter
http://emberjs.jsbin.com/OxIDiVU/117/edit
model: function(params) {
var model = {
heading: "Welcome!",
imageUrl: this.imageUrl
};
this.getImageUrl(params.imageUrl).then(function(result){
Em.set(model, 'imageUrl', result.imageUrl);
});
return model;
}

loading content via ajax into a textarea with tinymce installed

I have the following script pulling in data from a wordpress database. It all works fine when selecting different options (pulls in the correct data etc).
I have now installed tinymce editor onto the textarea. Since this the content no longer shows.
<script>
$(document).ready(function()
{
$('#myselect').change(function()
{
var selected = $(this).find(':selected').html();
var id = $(this).find(':selected').val();
$.post('http://www.xxx/admin/email/ajax.php', {'beverage': selected, 'id':id }, function(data) {
$('#result').html(data);
});
});
});
</script>
Does anyone know what i am missing to make this work?
Any help would be greatly appreciated!
Cheers Dan
Found the solution myself, i needed to change the following:
$('#result').html(data);
to:
tinyMCE.get('result').setContent(data);

How to produce a settings dialog (and save the values)

These are my first steps with the Firefox AddOn SDK. What I'm trying to create is a simple 'settings dialogue'. I thought about a html page containing forms for the values and a submit button. Following the first mozilla tutorials I created a widget:
var widget = require('widget').Widget({
label: 'Settings',
id: 'settings',
//panel: text_entry
contentURL: data.url('images/stgfavicon.ico'),
contentScriptFile: data.url('scripts/submit.js'),
onClick: function() {
tabs.open(data.url('forms/settings.html'));
}
});
But since settings.js is not the contentScriptFile I got no communication between settings.html and settings.js. Is it possible to get this done without some (complex looking) messaging system? And how to save the values best? A JSON file?
Some links/examples/API names would help me a lot. :)
That's because you're trying to attach your script to the widget (which is not an HTML file). You need to attach it to the actual html file after the tab opens.
tabs.open({
url: data.url('forms/settings.html'),
onOpen: function onOpen(tab) {
tab.attach({ contentScriptFile: data.url('scripts/submit.js'); });
}
});
I haven't tested that out so there may be an error.
You should also look at the simple-prefs module if these are settings that aren't going to be adjusted frequently.

jquery .submit live click runs more than once

I use the following code to run my form ajax requests but when i use the live selector on a button i can see the ajax response fire 1 time, then if i re-try it 2 times, 3 times, 4 times and so on...
I use .live because i also have a feature to add a post and that appears instantly so the user can remove it without refreshing the page...
Then this leads to the above problem... using .click could solve this but it's not the ideal solution i'm looking for...
jQuery.fn.postAjax = function(success_callback, show_confirm) {
this.submit(function(e) {
e.preventDefault();
if (show_confirm == true) {
if (confirm('Are you sure you want to delete this item? You can\'t undo this.')) {
$.post(this.action, $(this).serialize(), $.proxy(success_callback, this));
}
} else {
$.post(this.action, $(this).serialize(), $.proxy(success_callback, this));
}
return false;
})
return this;
};
$(document).ready(function() {
$(".delete_button").live('click', function() {
$(this).parent().postAjax(function(data) {
if (data.error == true) {
} else {
}
}, true);
});
});​
EDIT: temporary solution is to change
this.submit(function(e) {
to
this.unbind('submit').bind('submit',function(e) {
the problem is how can i protect it for real because people who know how to use Firebug or the same tool on other browsers can easily alter my Javascript code and re-create the problem
If you don't want a new click event bound every time you click the button you need to unbind the event before re-binding it or you end up with multiple bindings.
To unbind events bound with live() you can use die(). I think the syntax using die() with live() is similar to this (untested):
$(document).ready(function(){
$('.delete_button').die('click').live('click', function(){
$(this).parent().postAjax(function(data){
if (data.error == true){
}else{
}
}, true);
});
});
However, if you are using jQuery 1.7 or later use on() instead of live() as live() has been deprecated since 1.7 and has many drawbacks.
See documentation for all the details.
To use on() you can bind like this (I'm assuming the delete_button is a dynamically added element) :
$(document).ready(function(){
$(document).off('click', '.delete_button').on('click', '.delete_button', function(){
$(this).parent().postAjax(function(data){
if (data.error == true){
}else{
}
}, true);
});
});
If you are using an earlier version of jQuery you can use undelegate() or unbind() and delegate() instead. I believe the syntax would be similar to on() above.
Edit (29-Aug-2012)
the problem is how can i protect it for real because people who know
how to use Firebug or the same tool on other browsers can easily alter
my Javascript code and re-create the problem
You can some-what protect your scripts but you cannot prevent anyone from executing their own custom scripts against your site.
To at least protect your own scripts to some degree you can:
Write any script in an external js file and include a reference to that in your site
Minify your files for release
Write any script in an external js file and include a reference to that in your site
That will make your html clean and leave no trace of the scripts. A user can off course see the script reference and follow that for that you can minify the files for release.
To include a reference to a script file:
<script type="text/javascript" src="/scripts/myscript.js"></script>
<script type="text/javascript" src="/scripts/myscript.min.js"></script>
Minify your files for release
Minifying your script files will remove any redundant spacing and shorten function names to letters and so no. Similar to the minified version of JQuery. The code still works but it is meaningless. Off course, the hard-core user could follow meaningless named code and eventually figure out what you are doing. However, unless you are worth hacking into I doubt anyone would bother on the average site.
Personally I have not gone through the minification process but here are some resources:
Wikipedia - Minification (programming)
Combine, minify and compress JavaScript files to load ASP.NET pages faster
How to minify (not obfuscate) your JavaScript using PHP
Edit (01-Sep-2012)
In response to adeneo's comment regarding the use of one().
I know you already found a solution to your problem by unbinding and rebinding to the submit event.
I believe though it is worth to include a mentioning of one() in this answer for completeness as binding an event with one() only executes the event ones and then unbinds itself again.
As your click event, when triggered, re-loads and rebinds itself anyway one() as an alternative to unbinding and re-binding would make sense too.
The syntax for that would be similar to on(), keeping the dynamic element in mind.
// Syntax should be right but not tested.
$(document).ready(function() {
$(document).one('click', '.delete_button', function() {
$(this).parent().postAjax(function(data) {
if (data.error == true) {} else {}
}, true);
});
});​
Related Resources
live()
die()
on()
off()
unbind()
delegate()
undelegate()
one()
EDIT AGAIN !!!! :
jQuery.fn.postAjax = function(show_confirm, success_callback) {
this.off('submit').on('submit', function(e) { //this is the problem, binding the submit function multiple times
e.preventDefault();
if (show_confirm) {
if (confirm('Are you sure you want to delete this item? You can\'t undo this.')) {
$.post(this.action, $(this).serialize(), $.proxy(success_callback, this));
}
} else {
$.post(this.action, $(this).serialize(), $.proxy(success_callback, this));
}
});
return this;
};
$(document).ready(function() {
$(this).on('click', '.delete_button', function(e) {
$(e.target.form).postAjax(true, function(data) {
if (data.error) {
} else {
}
});
});
});​
jQuery.fn.postAjax = function(success_callback, show_confirm) {
this.bind( 'submit.confirmCallback', //give your function a namespace to avoid removing other callbacks
function(e) {
$(this).unbind('submit.confirmCallback');
e.preventDefault();
if (show_confirm === true) {
if (confirm('Are you sure you want to delete this item? You can\'t undo this.')) {
$.post(this.action, $(this).serialize(), $.proxy(success_callback, this));
}
} else {
$.post(this.action, $(this).serialize(), $.proxy(success_callback, this));
}
return false;
})
return this;
};
$(document).ready(function() {
$(".delete_button").live('click', function() {
$(this).parent().postAjax(function(data) {
if (data.error == true) {
} else {
}
}, true);
});
});​
As for the "people could use Firebug to alter my javascript" argument, it does not hold : people can also see the request that is sent by your $.post(...), and send it twice.
You do not have control over what happens in the browser, and should protect your server side treatment, rather than hoping that "it won't show twice in the browser, so it will prevent my database from being corrupt".

Auto save joomla article for client

i know its sounds a bit crazy, but so many clients have problems with not saving their article properly.
I just wanted to use a simple method to trigger the onclick of the APPLY button inside a joomla article in edit mode.
Primarily back end editing as i have a good admin template that allows me to show clients the bare bones.
I know that by clicking apply the page reloads but thats better than nothing.
How on earth do i add do this?
I was hoping something like this would work but i dont quite know how to trigger a button that seems to reside inside a toolbar function of some sort.
I have this:
<script type="text/javascript">
$(document).ready(function() {
$('??????').trigger('click');
});
</script>
What would replace the question marks?
Also i know i would need to put a timer into the jquery code but how do i get the link below to trigger?
http://mydomain.com/administrator/index.php?option=com_content&sectionid=1&task=edit&cid[]=97
In the toolbar.content.html.php file joomla has this:
class TOOLBAR_content
{
function _EDIT($edit)
{
$cid = JRequest::getVar( 'cid', array(0), '', 'array' );
$cid = intval($cid[0]);
$text = ( $edit ? JText::_( 'Edit' ) : JText::_( 'New' ) );
JToolBarHelper::title( JText::_( 'Article' ).': <small><small>[ '. $text.' ]</small></small>', 'addedit.png' );
JToolBarHelper::preview( 'index.php?option=com_content&id='.$cid.'&tmpl=component', true );
JToolBarHelper::save();
/////////////////////////////////////
JToolBarHelper::apply(); // < // THIS IS WHAT I WANT TO TRIGGER
/////////////////////////////////////
if ( $edit ) {
// for existing articles the button is renamed `close`
JToolBarHelper::cancel( 'cancel', 'Close' );
} else {
JToolBarHelper::cancel();
}
}
...... more stuff here
}
I know this might sound crazy but wouldnt it be great if autosave could happen even without a reload, but i guess that would mean posting all the data using jquery rather than the php post and reload page method.
Anyways im not expecting a miracle here but if anyone could help that would be great.
Cheers in advance
John
PS:
i just tried something like this hoping maybe it will work but it just reloads the page:
function autosave()
{
window.location = "index.php?option=com_content&sectionid=<?php echo $_GET['sectionid'];?>&task=edit&cid[]=<?php echo $row->id;?>"
}
You won't be able to do it without forcing a reload unless you decide to re-write the whole of com_content with an ajax implementation.
Looking at the code you've posted I guessing Joomla! 1.5 - which by default has MooTools 1.12 or 1.2.5 (if you enabled the MooTools upgrade plugin in later versions of 1.5.x) - so more of a question but why not use that?
You will have to modify the admin template to embed the JS you need, 1.5 has few triggers and none that are really worth using in the admin screens (unless you're up for a fair bit of PHP coding)
Somewhere in the <head> tag of com_content's Article view you will need to add this:
<script type="text/javascript">
var interval = 30 //seconds
var timer = setTimeout(submitbutton('apply'),(interval * 1000));
}
</script>
Please note I haven't tried this just typed it straight into here.
Since you're on 1.5 have you tried the Simple Content Versioning extension - it has autosave functionality that appears to be what you want - and probably works whereas who knows with my code in #3.

Resources