how to create a complex javascript structure - javascript

i want to create a structure like that:
[{title:'Imágenes', extensions:'jpg,gif,png'}, {title:'Todos', extensions:'*'}]
but i need to create it from a string, in this way (in "js+jquery+php rare mode"):
items = 'Imágenes jpg,gif,png|Todos *'.split('|').each(function() {
list(title, ext) = explode(' ', $this);
filters[] = array('title' => title, 'ext' => ext);
});
i found structures like:
var theStatus = new Object();
function testIt() {
theStatus.Home = 'mouseover';
theStatus['Place'] = 'click';
for (var i in theStatus)
{
alert('theStatus[\''+i+'\'] is ' + theStatus[i])
}
}
and like:
$.alerts = {
verticalOffset: -75,
horizontalOffset: 0,
repositionOnResize: true,
overlayOpacity: .01,
overlayColor: '#FFF'
}
but i cant do nothing functional.
Thanks in advance.

This is how I would do it:
items = 'Imágenes jpg,gif,png|Todos *'.split("|").map(function (itemString) {
var parts = itemString.split(" ");
return { title: parts[0], extensions: parts[1] };
});
Or you can do this if you use jQuery and need to support older browsers:
items = $.map('Imágenes jpg,gif,png|Todos *'.split("|"), function () {
var parts = this.split(" ");
return { title: parts[0], extensions: parts[1] };
});

Your pseudocode is close.
Try the following vanilla javascript:
var str = 'Imágenes jpg,gif,png|Todos *';
var objs = str.split('|');
var objects = [];
for (var i = 0; i < objs.length; i++) {
var parts = objs[i].split(' ');
objects.push({ title: parts[0], extensions: parts[1] });
}
// objects is now an array of custom objects in the format you specified.

Related

ExtendScript - Use Arrow Keys to shift focus from searchbox to list

I have the below script:
picked = myItems (['item 1', 'item 2', 'item 3', 'item 4', 'new item 1', 'new item 2']);
function myItems (templates) {
var w = new Window ('dialog {text: "Item List", alignChildren: "fill"}');
var entry = w.add ('edittext {active: true}')
entry.graphics.font= ScriptUI.newFont ("Arial", "Bold", 12);
var list = w.add ('listbox', [0, 0, 200, 100], templates);
list.selection = 0;
list.graphics.font= ScriptUI.newFont ("Arial", "Italic", 14);
entry.onChanging = function ()
{
var temp = entry.text,
tempArray = [];
for (var i = 0; i < templates.length; i++)
if (templates[i].toLowerCase().indexOf (temp) == 0)
tempArray.push (templates[i]);
else if (templates[i].toUpperCase().indexOf (temp) == 0)
tempArray.push (templates[i]);
if (tempArray.length > 0)
{
tempList = w.add ("listbox", list.bounds, tempArray, {scrolling: true});
tempList.graphics.font= ScriptUI.newFont ("Times New Roman", "Regular", 14);
w.remove(list);
list = tempList;
list.selection = 0;
list.onDoubleClick=function(){
if (list.selected){
var buttonname = list.selection.text
var templatefile = new File (searchpath + "/" + buttonname + '.psd');
mainfunction (templatefile)
}
w.close();
}
}
}
ListItem.add
var B = w.add ('button', undefined, 'Ok', {name: 'ok'})
list.onDoubleClick=function(){
if (list.selected){
var buttonname = list.selection.text
var templatefile = new File (searchpath + "/" + buttonname + '.psd');
mainfunction (templatefile)
}
w.close();
}
if (w.show () != 2){
var buttonname = list.selection.text
var templatefile = new File (searchpath + "/" + buttonname + '.psd');
mainfunction (templatefile)
}
w.close();
}
On ExtendScript this creates a search box with a list below. Using the tab key you can switch between the search box and the list. I want to be able to also use the arrow keys to switch between the search box and the list. Can anyone advise if this is possible?
I have seen some results on jQuery, but sadly ExtendScript does not support jQuery, however it does support ScriptUI.
Many Thanks,
EDIT
I found this to be a resolution:
w.addEventListener ("keydown", function (kd) {pressed (kd)});
function pressed (k)
{
if (k.keyIdentifier === "Down" && entry.active = true)
list.active = true;
else if (k.keyIdentifier === "Up" && list.active = true)
entry.active = true ;
else
list.scrolling = true;
}
However, it does not work with Photoshop CC 2014. Does anyone know what I may be able to change to allow backwards compatibility?

How to customize autocomplete function of the CodeMirror

I want to customize an autocomplete function to Codemirror.
So I have build this code:
CodeMirror.commands.autocomplete = function (cm) {
var arrayTabNONDefault = new Array();
var stringaCampi = null;
var arrayTabellaCampo = null;
var textVal = cm.getValue();
textVal = textVal.toUpperCase();
var res = textVal.match("SELECT(.*)FROM");
if (res != null) {
stringaCampi = res[1];
arrayTabellaCampo = stringaCampi.split(",");
var nomeTab = null;
for (var i = 0; i < arrayTabellaCampo.length; i++) {
nomeTab = (arrayTabellaCampo[i].split(".")[0]).trim();
if (hintTables[nomeTab] == null)
hintTables[nomeTab] = new Array();
} //FINE FOR
} //FINE IF
CodeMirror.showHint(cm, CodeMirror.hint.sql, {
tables: hintTables
});
cm.on("beforeChange", function (cm, change) {
var before = cm.getRange({ line: 0, ch: 0 }, change.from);
var text = cm.getRange(change.from, change.to);
var after = cm.getRange(change.to, { line: cm.lineCount() + 1, ch: 0 });
if (before.indexOf("FROM") !== -1)
// alert("Ho scritto FROM");
console.log("before change", before, text, after);
});
cm.on("change", function (cm, change) {
var from = change.from;
var text = change.text.join("\n");
var removed = change.removed.join("\n");
var to = cm.posFromIndex(cm.indexFromPos(from) + text.length);
var before = cm.getRange({ line: 0, ch: 0 }, from);
var after = cm.getRange(to, { line: cm.lineCount() + 1, ch: 0 });
if (before.indexOf("FROM") !== -1)
console.log("after change", before, removed, text, after);
});
} //FINE ESTENSIONE
This is the content of hintTables
var hintTables = { "#T_TF_FilesList": ["FilesListHeaderID", "NumRecord", "FileTypeID", "FileID", "FilesListHeaderID", "NumRecord"],
"#T_TF_SelectedItems": ["EventHeaderID", "ItemType", "ItemID1", "ItemID2", "EventHeaderID", "ItemType", "ItemID1", "ItemID2"],
"#T_TFT_CacheSearchCriteriaHeaders": ["ID", "SyncDate", "FileTypeID", "CriteriaExpressionString", "CriteriaExpressionHash", "PageRecordsNumber", "PageNumber", "NumFiles"]
};
So I want that the system should propose a list of this table after I write FROM, or the system should to propose a list of stored procedures after I write EXECUTE.
It is possible to do this?
Are you trying to customize the SQL hint addon? If so, you should make changes inside sql-hint.js (under codemirror/addon/hint).
Basically what you should do is:
1.In your app.js (whatever js file for your main logic) call editor.showHint({hint: CodeMirror.hint.sql) on "change" event;
2.Inside sql-hint.js, return {list: hintTables, from: somePos, to: somePos} when the user types FROM or EXECUTE which can be detected by regular expression or inspecting the tokens at the line. I made up some code for your reference:
var cursor = editor.getCursor();
var tokenAtCursor = editor.getTokenAt(cursor);
if (tokenAtCursor.type == "FROM-and-EXECUTE")
return {list: hintTables,
from: CodeMirror.Pos(cur.line, tokenAtCursor.start),
to: CodeMirror.Pos(cur.line, tokenAtCursor.end)};
If I misunderstand your question and this answer is not helpful, please tell me and I will delete it.

jquery html(array) doesn't insert all items in array

When I run the javascript code below, it load specified amount of images from Flickr.
By var photos = photoGroup.getPhotos(10) code, I get 10 images from cache.
Then, I can see the object has exactly 10 items by checking console.log(photos);
But actual image appeared on the page is less than 10 items...
I have no idea why this work this way..
Thank you in advance.
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
var PhotoGroup = function(nativePhotos, callback) {
var _cache = new Array();
var numberOfPhotosLoaded = 0;
var containerWidth = $("#contents").css('max-width');
var containerHeight = $("#contents").css('max-height');
$(nativePhotos).each(function(key, photo) {
$("<img src='"+"http://farm" + photo["farm"] + ".staticflickr.com/" + photo["server"] + "/" + photo["id"] + "_" + photo["secret"] + "_b.jpg"+"'/>")
.attr("alt", photo['title'])
.attr("data-cycle-title", photo['ownername'])
.load(function() {
if(this.naturalWidth >= this.naturalHeight) {
$(this).attr("width", containerWidth);
} else {
$(this).attr("height", containerHeight);
}
_cache.push(this);
if(nativePhotos.length == ++numberOfPhotosLoaded)
callback();
})
});
var getRandom = function(max) {
return Math.floor((Math.random()*max)+1);
}
this.getPhotos = function(numberOfPhotos) {
var photoPool = new Array();
var maxRandomNumber = _cache.length-1;
while(photoPool.length != numberOfPhotos) {
var index = getRandom(maxRandomNumber);
if($.inArray(_cache[index], photoPool))
photoPool.push(_cache[index]);
}
return photoPool;
}
}
var Contents = function() {
var self = this;
var contentTypes = ["#slideShowWrapper", "#video"];
var switchTo = function(nameOfContent) {
$(contentTypes).each(function(contentType) {
$(contentType).hide();
});
switch(nameOfContent) {
case("EHTV") :
$("#video").show();
break;
case("slideShow") :
$("#slideShowWrapper").show();
break;
default :
break;
}
}
this.startEHTV = function() {
switchTo("EHTV");
document._video = document.getElementById("video");
document._video.addEventListener("loadstart", function() {
document._video.playbackRate = 0.3;
}, false);
document._video.addEventListener("ended", startSlideShow, false);
document._video.play();
}
this.startSlideShow = function() {
switchTo("slideShow");
var photos = photoGroup.getPhotos(10)
console.log(photos);
$('#slideShow').html(photos);
}
var api_key = '6242dcd053cd0ad8d791edd975217606';
var group_id = '2359176#N25';
var flickerAPI = 'http://api.flickr.com/services/rest/?jsoncallback=?';
var photoGroup;
$.getJSON(flickerAPI, {
api_key: api_key,
group_id: group_id,
format: "json",
method: "flickr.groups.pools.getPhotos",
}).done(function(data) {
photoGroup = new PhotoGroup(data['photos']['photo'], self.startSlideShow);
});
}
var contents = new Contents();
</script>
</head>
<body>
<div id="slideShow"></div>
</body>
</html>
I fix your method getRandom() according to this article, and completely re-write method getPhotos():
this.getPhotos = function(numberOfPhotos) {
var available = _cache.length;
if (numberOfPhotos >= available) {
// just clone existing array
return _cache.slice(0);
}
var result = [];
var indices = [];
while (result.length != numberOfPhotos) {
var r = getRandom(available);
if ($.inArray(r, indices) == -1) {
indices.push(r);
result.push(_cache[r]);
}
}
return result;
}
Check full solution here: http://jsfiddle.net/JtDzZ/
But this method still slow, because loop may be quite long to execute due to same random numbers occurred.
If you care about performance, you need to create other stable solution. For ex., randomize only first index of your images sequence.

Values are not being saved to the array

I am pretty new to javascript and jquery. I currently have a xml file that I'm trying to parse by using jquery and javascript, but for some reason the values that I store on the array are not being saved.
var categories = new Array(); // Array for the categories
var data = {
categories: []
};
var sources = [
{
src:'',
title: '',
desc: ''
}];
var i = 0;
$.get('fakeFeed.xml', function (info) {
$(info).find("item").each(function () {
var el = $(this);
var categoryName = el.find('category').text();
var p = categories.indexOf(categoryName);
sources[i] = [];
sources[i].src = el.find('media\\:content, content').attr('url');
sources[i].title = el.find("title").text();
sources[i].desc = 'Moscone Center';
if( p == -1) {
categories.push(categoryName);
var category = {
name: categoryName,
videos: []
};
}
i++;
});
});
If i do console.log(categories) it prints all the categories on the array but if I do console.log(categories.length) I keep getting 0...
console.log(categories.length); // This should be outputting 5 but I keep getting 0 for the size.
for (var i=0; i<categories.length; i++) {
var category = {
name: categories[i],
videos: []
};
}
I appreciate any help that anybody can give me. Thanks
$.get function is asynchronous so you should try putting the logging inside the callback function.
$.get('fakeFeed.xml', function (info) {
$(info).find("item").each(function () {
....
});
console.log(categories.length);
});

Combine two arrays into array of options

I have two arrays of strings: hrefs, thumbs. Need to combine this arrays into another array with structure like below. How to do that ? For clarity - i need to use Lightview API to call function Lightview.show(elements), where elements is result array i need to build.
HTML:
one
two
three
Arrays:
var hrefs = $('.lv').map(function() { return $(this).attr('href'); }).get();
var thumbs = $('.lv').map(function() { return $(this).attr('thumbnail'); }).get();
The desired result array (elements):
{
{hrefs[0],
{
thumbnail: thumbs[0]
}
},
{hrefs[1],
{
thumbnail: thumbs[1]
}
},
...
}
I've started with this, but i think it is something wrong...
var e = new Array();
$.each(hrefs, function(i, value) {
e[i] = new Array();
e[i][0] = value;
e[i][1] = {thumbnail: thumbs[i]};
});
Do you mean this?
var result = $('.lv').map(function() {
var o = {};
o[$(this).attr('href')] = { thumbnail: $(this).attr('thumbnail') } };
return o;
}).get();
Are you looking for something like this?
var hrefs = $('.lv').map(function() { return $(this).attr('href'); }).get();
var thumbs = $('.lv').map(function() { return $(this).attr('thumbnail'); }).get();
var arr = {};
for (i in hrefs) {
arr[hrefs[i]] = {
thumbnail: thumbs[i]
}
}
Another suggestion, with minimal use of JQuery for faster execution
var lvs = $('.lv');
var arr = {};
for (i=0; i< lvs.length; i++) {
arr[lvs[i].getAttribute('href')] = {
thumbnail: lvs[i].getAttribute('thumbnail')
}
}
You're almost there. Just do:
var e = [];
$.each(hrefs, function(i, value) {
e[i] = [];
e[i] = [ value, {thumbnail: thumbs[i]} ];
});
Or even shorter:
var e = [];
$.each(hrefs, function(i, value) {
e[i] = [ value, {thumbnail: thumbs[i]} ];
});
Try this
var result = {};
$.each( hrefs, function ( index ) {
result[ hrefs[ index ] ] = { thumbnail: thumbs[ index ] };
});

Categories