How to detect multiple selections in elFinder - javascript

I added a new toolbar button and an new context menu item to elFinder.
Works nicely but this item should be enabled only if one plain file is selected. So should be dimmed when no file selected and should be dimmed when multiple files are selected or if is selected an directory.
I learned than in the elFinder.prototype.commands.mycmd I should set the this.getstate return value to:
0 if the toolbar/context-menu item should be enabled and
-1 if it should be disabled
So, now have this:
el
Finder.prototype.commands.mycmd= function() {
var self = this,
fm = self.fm;
self.disableOnSearch = true;
self.title = 'mycmd';
self.getstate = function() {
// need help here to add the "directory is selected check"
return fm.selected().length == 1 ? 0 : -1;
}
self.exec = function() {
alert("hello");
}
}
Unfortunately, i know only Perl, so it is a bit hard for me digging thru all elFinder's javascript code to figure out how to master the condition.
Know anybody elFinder enough deeply to help me with the condition?

Just find the solution in the elFinder's download.js.
This works - at least for now.. ;)
elFinder.prototype.commands.mycmd= function() {
var self = this,
fm = self.fm;
self.disableOnSearch = true;
filter = function(hashes) {
return $.map(self.files(hashes), function(f) { return f.mime == 'directory' ? null : f });
};
self.title = 'mycmd';
self.getstate = function() {
var sel = self.fm.selected(),
cnt = sel.length;
return !self._disabled && cnt == 1 && cnt == filter(sel).length ? 0 : -1;
}
self.exec = function() {
alert("hello");
}
}

Related

Get RadComboBox client side old checked items

I have a multi selectable telerik RadComboBox component on my page. I'm using an "OnClientDropDownClosed" client side event. I do post back manually, not automatic. What i want is, when the dropdown closed, i want to compare the old checked items with the new checked items on client side. How can i get the old checked items and the new checked items via javascript?
I found the solution. I keep the old selected IdList. On rad combo box closed function, i compare the two lists.
var oldSelectedIdList = [];
function radComboBoxSelectedIdList() {
var selectedIdList = [];
var combo = $find("<%= RadComboBox.ClientID %>");
var items = combo.get_items();
var checkedIndices = items._parent._checkedIndices;
var checkedIndicesCount= checkedIndices.length;
for (var itemIndex = 0; itemIndex < checkedIndicesCount; itemIndex++){
var item = items.getItem(checkedIndices[itemIndex]);
selectedIdList.push(item._properties._data.value);
}
return selectedIdList;
}
$(document).ready(function () {
oldSelectedIdList = radComboBoxSelectedIdList();
});
function areThereAnyChangesAtTheSelection()
{
var selectedIdList = radComboBoxSelectedIdList();
var isTheCountOfEachSelectionEqual = (selectedIdList.length == oldSelectedIdList.length);
if(isTheCountOfEachSelectionEqual == false)
return true;
var oldIdListMINUSNewIdList = $(oldSelectedIdList).not(selectedIdList).get();
var newIdListMINUSOldIdList= $(selectedIdList).not(oldSelectedIdList).get();
if (oldIdListMINUSNewIdList.length != 0 || newIdListMINUSOldIdList.length != 0)
return true;
return false;
}
function onRadComboBoxClosed(sender, args) {
if (areThereAnyChangesAtTheSelection())
//Your Code Here
}

Hide div with js, but without affecting html code

Let's say we have a div with id = '123'
Ho to make it invisible with js without affecting its html code?
So document.getElementById('123').style.display = 'none' is not an option.
JS only
UPD:
I just have interesting task! I have to hide some comments with js from guestbook , but when I change html code to hide it, Server somehow understands what I've done and redirects me to warning Page. So I have to do something with that.
UPD2:
I had obfuscated script on my page
function check_divs() {
var try_again = true;
var arr_divs = document.getElementById('content').getElementsByTagName('div');
if (arr_divs.length != divs_count) {
try_again = false;
} else {
for (var i = 0; i < arr_divs.length; i++) {
if ((arr_divs[i].style.display == 'none') || (arr_divs[i].style.position == 'absolute')) {
try_again = false;
};
};
}; if (try_again) {
setTimeout(check_divs, 998);
} else {
document.location.href = '/alert.html';
};
}
This one, so my solution was to clear all timeouts.
document.getElementById('123').style.visibility = 'hidden';
or
document.getElementById('123').setAttribute('style','display:none');
or
document.getElementById('123').setAttribute('style','visibility:hidden');
or if you have jQuery libraries
$('#123').css('visibility','hidden')
or
$('#123').css('display','none')
Any of that help?

Adding a custom context menu item to elFinder

I'm using elfinder and I would like to add new functionality by adding a command to the context menu. I found a solution on the github issue tracker of the project but I can't get it to work. Here's what I do:
var elf;
jQuery().ready(function() {
elFinder.prototype._options.commands.push('editimage');
elFinder.prototype._options.contextmenu.files.push('editimage');
elFinder.prototype.i18.en.messages['cmdeditimage'] = 'Edit Image';
elFinder.prototype.i18.de.messages['cmdeditimage'] = 'Bild bearbeiten';
elFinder.prototype.commands.editimage = function() {
this.exec = function(hashes) {
console.log('hallo');
}
}
elf = jQuery('#elfinder').elfinder({
...
//elfinder initialization
The context menu item does not show up, no error message is to be found in the console. I also tried putting editimage under contextmenu->"files" in the init part in case that was overwritten by the initialization.
I found the solution: The examples don't show the fact that you need to have a function called this.getstate inside of the elFinder.prototype.commands.yourcommand function. It shall return 0 when the icon is enabled and -1 when it's disabled.
So the full code for adding your own menu item or context menu item looks like this:
var elf;
jQuery().ready(function() {
elFinder.prototype.i18.en.messages['cmdeditimage'] = 'Edit Image';
elFinder.prototype.i18.de.messages['cmdeditimage'] = 'Bild bearbeiten';
elFinder.prototype._options.commands.push('editimage');
elFinder.prototype.commands.editimage = function() {
this.exec = function(hashes) {
//do whatever
}
this.getstate = function() {
//return 0 to enable, -1 to disable icon access
return 0;
}
}
...
elf = jQuery('#elfinder').elfinder({
lang: 'de', // language (OPTIONAL)
url : '/ext/elfinder-2.0-rc1/php/connector.php', //connector URL
width:'100%',
uiOptions : {
// toolbar configuration
toolbar : [
...
['quicklook', 'editimage'],
/*['copy', 'cut', 'paste'],*/
...
]},
contextmenu : {
...
// current directory file menu
files : [
'getfile', '|','open', 'quicklook', 'editimage', ...
]
}
}).elfinder('instance');
});
Hope this helps someone with the same problem.
Thanks for the answer, great!
One thing that wasn't clear was how the variables pass through.
So, for anyone else who finds this page....
elFinder.prototype.commands.editpres = function() {
this.exec = function(hashes) {
var file = this.files(hashes);
var hash = file[0].hash;
var fm = this.fm;
var url = fm.url(hash);
var scope = angular.element("body").scope();
scope.openEditorEdit(url);
}
// Getstate configured to only light up button if a file is selected.
this.getstate = function() {
var sel = this.files(sel),
cnt = sel.length;
return !this._disabled && cnt ? 0 : -1;
}
}
To get your icon to show up, add the following to your css file:
.elfinder-button-icon-editpres { background:url('../img/icons/editpres.png') no-repeat; }

Preserve a value of an element after change using jQuery

For internationalization support, I wrote code that changes the URL from #lang-select dropdown .The code is
$(document).ready(function(){
var sel = document.getElementById('lang-select');
sel.onchange = function(){window.location.replace($('#lang-select').val());};
});
the above code works fine and it changes the URL from http://0.0.0.0:3000/fr to http://0.0.0.0:3000/en.
Now I want to preserve the changed value, but without success. I have written the code below. I don't know why it is wrong/not working .
function langSelect(){
var available_languages = {
"en":"English",
"de":"Deutsch",
"ru" :"Россию",
"fr" : "Française"
};
var languageInUrl= document.URL.split("/")[3];
for(var shortLanguage in available_languages){
if(shortLanguage === languageInUrl) {
var langaugeOptionArray = $("#lang-select>option");
for(var i = 0 ; langaugeOptionArray.length > i ; i++){
if(langaugeOptionArray[i].label === available_languages[shortLanguage]){
langaugeOptionArray[i].selected = true;
return;
}
}
}
}
}
Please tell me what's wrong in above code and since what I am doing is not a new thing, please share what is the best practice to overcome this scenario.
Currently, I am using backend to accomplish this.
$(function() {
$('#lang-select').on("change",function(){
window.location.replace($(this).val());
});
});
function langSelect(){
var available_languages = {
"en":"English",
"de":"Deutsch",
"ru" :"Россию",
"fr" : "Française"
};
var languageInUrl= document.URL.split("/")[3];
var lang = available_languages[languageInUrl];
if (lang) {
var langaugeOptionArray = $("#lang-select>option");
langaugeOptionArray.each(function() {
if($(this).text() === lang){
$("#lang-select").val(lang);
return false;
}
});
}
}
I believe we can even do
if (lang) {
var opt = $("#lang-select").find('option[text="'+lang+'"]').val();
if (opt) $("#lang-select").val(opt);
}
Good luck

GM_registerMenuCommand is not defined

everybody. I'm puzzled as to why I keep getting the error "GM_registerMenuCommand is not defined" when I try to run a userscript that I created. I have tried this in Firefox using Scriptish 1.0b9 and the latest version of Greasemonkey. I even disabled all addons except Scriptish to see if it was a conflict, but with no joy.
I'm including jQuery in my userscript using this template by Erik Vold. Before trying this template, I put the exact same code block in the template proposed by Joan Piedra and everything worked fine. Unfortunately, Piedra's template did not work in Chrome, which is something that I think is necessary, considering Chrome's growing userbase. The snippet that's throwing the error is below:
// a function that loads jQuery and calls a callback function when jQuery has finished loading
function addJQuery(callback) {
var script = document.createElement("script");
script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js");
script.addEventListener('load', function() {
var script = document.createElement("script");
script.textContent = "(" + callback.toString() + ")();";
document.body.appendChild(script);
}, false);
document.body.appendChild(script);
}
// the guts of this userscript
function main() {
var isLevelupMove = false;
var isTutorMove = false;
var isTM = false;
var TMhead = $('#moves\\:machine');
var hasSecondEvo = false;
var hasFinalEvo1 = false;
var hasFinalEvo2 = false;
var header = $('.header-row').eq(1);
var TMmoves = new Array();
//This section deals with the user-defined colors
GM_registerMenuCommand("Color for pre-evolutionary-only moves", prevoColorPrompt);
GM_registerMenuCommand("Color for first evolution-only moves", evoColorPrompt);
if(localStorage.getItem('prevoColor') == null || localStorage.getItem('evoColor') == null)
{
localStorage.setItem('prevoColor', 'red');
localStorage.setItem('evoColor', 'orange');
}
var prevoColor = localStorage.getItem('prevoColor');
var evoColor = localStorage.getItem('evoColor');
function prevoColorPrompt()
{
var input = prompt("Please enter a desired 6-digit hex color-code for pre-evolutionary pokemon:")
localStorage.setItem('prevoColor', '#'+input);
}
function evoColorPrompt()
{
var input = prompt("Please enter the desired 6-digit hex color-code for first-evolution pokemon:")
localStorage.setItem('evoColor', '#'+input);
}
//This loop tests each 'th' element in a sample header row, determining how many Evos are currently present in the chart.
$('.header-row').eq(1).find('th').each(function(index)
{
if($(this).find('a').length != 0)
{
switch(index)
{
case 2:
hasSecondEvo = true;
break;
case 3:
hasFinalEvo1 = true;
break;
case 4:
hasFinalEvo2 = true;
break;
}
}
});
//All 'tr' siblings are TM moves, since it's the last section on the page
//This array puts only the names of the available TMs into the TMmoves array
TMhead.nextAll().each(function(index)
{
TMmoves.push($(this).children(":first").find('a').eq(0).html());
});
$('tr').each(function(index)
{
var moveName = $(this).children(":first").find('a').eq(0).html();
moveName = $.trim(moveName);
switch($(this).attr('id'))
{
case 'moves:level-up':
isLevelupMove = true;
break;
case 'moves:egg':
isLevelupMove = false;
break;
case 'moves:tutor':
isTutorMove = true;
case 'moves:machine':
isTM = true;
}
if(isLevelupMove || isTutorMove)
{
var babyMoveCell = $(this).find('td').eq(0);
babyMoveText = $.trim(babyMoveCell.html());
secondEvoCell = babyMoveCell.next();
secondEvoText = $.trim(secondEvoCell.html());
finalEvo1Cell = secondEvoCell.next();
finalEvo1Text = $.trim(finalEvo1Cell.html());
finalEvo2Cell = finalEvo1Cell.next();
finalEvo2Text = $.trim(finalEvo2Cell.html());
//This checks if evolutions have checkmarks
if(babyMoveText.length > 0)
{
if(hasSecondEvo && secondEvoText.length == 0 || hasFinalEvo1 && finalEvo1Text.length == 0 ||
hasFinalEvo2 && finalEvo2Text.length == 0)
{
//See if the move is a TM before proceeding
var tm = tmCheck(moveName);
if(!tm)
{
if(secondEvoText.length > 0)
{
babyMoveCell.css("color", evoColor);
secondEvoCell.css("color", evoColor);
babyMoveCell.prev().find('a').eq(0).css("color", evoColor); //highlights move name
}
else
{
babyMoveCell.css("color", prevoColor);
babyMoveCell.prev().find('a').eq(0).css("color", prevoColor);
}
}
}
}
else if(secondEvoText.length > 0)
{
if(hasFinalEvo1 && finalEvo1Text.length == 0 || hasFinalEvo2 && finalEvo2Text.length == 0)
{
var tm = tmCheck(moveName);
if(!tm)
{
secondEvoCell.css("color", evoColor);
babyMoveCell.prev().find('a').eq(0).css("color", evoColor);
}
}
}
}
});
function tmCheck(input)
{
var isTM = false;
//Iterate through TMmoves array to see if the input matches any entries
for(var i = 0; i < TMmoves.length; i++)
{
if(input == TMmoves[i])
{
isTM = true;
break;
}
}
if(isTM == true)
return true;
else
return false;
}
//alert("evoColor: " + localStorage.getItem('evoColor') + ". prevoColor: " + localStorage.getItem('prevoColor'))
}//end main()
// load jQuery and execute the main function
addJQuery(main);
This is the userscript I'm trying to implement this for. If anyone has any suggestions or ideas about why I'm getting the error, I'd love to hear them!
This does not work because, if you look carefully at what addJQuery does, you'll realize that it injects the code of the function you pass it into a script element that gets appended to the end of the body element.
This means that you're now working in the same space as the scripts the website has, so all GM_* are not going to be available. What you can do is to move some of the code which require those functions to outside the main function, but remember that the Greasemonkey sandbox means that code running inside the main function cannot communicate with code outside it directly. You can have indirect communication, through for example watching DOM manipulation, or even unsafeWindow, but looking at your code it does not appear to be easily separateable.
This approach will not work because addJQuery() is not transferring workspace objects to the page's scope, it's essentially recreating your code from the source.
That means that the GM_ functions are not usable because there is no link between the sandbox and the copy of the code that addJQuery() made.
If your script needs GM_ functions, then just use straight GM code with the // #require directive for things like jQuery. Your only option for Chrome is Tampermonkey.
In both cases, addJQuery()-like tricks are not needed.

Categories

Resources