Trouble styling a DIV with two background images using Javascript Objects - javascript

I can only get the CSS styled image to load. The browser does not display imgB. The source code also only shows imgA. I just want to call the backgroundImage value of the Object at the time of the specific loop
My HTML.
<div onclick="displayCards()">Display Cards</div>
My Javascript Objects contain properties for these DIV elements. The different cards each have a unique image imgB. I created an array for the Objects so I can loop through them with a for loop.
var card_troop = { title : "troop" , type : "Unit" , image : "url(troop.png)" } ;
var card_base = { title : "base" , type : "Structure" , image : "url(base.png)" } ;
var card_wood = { title : "wood" , type : "Resource" , image : "url(wood.png)" } ;
var list = [
card_troop ,
card_base ,
card_wood
] ;
The DIV elements are created by my displayCards() function, that are appended to the body of my HTML document.
function displayCards()
{
card = document.createElement("div") ;
var card_id = document.createAttribute("id") ;
card_id.value = list[x].title ;
card.setAttributeNode(card_id) ;
var card_class = document.createAttribute("class") ;
switch (list[x].type) // Card Theme Comparison
{
case "Unit" :
card_class.value = "unit" ;
break ;
case "Structure" :
card_class.value = "structure" ;
break ;
case "Resource" :
card_class.value = "resource" ;
break ;
}
card.setAttributeNode(card_class) ;
var imgA = card.style.backgroundImage ;
var imgB = list[x].image ;
card.style.backgroundImage = imgA + " , " + imgB ;
}
Using the switch Comparison, switch (list[x].type), defined by the Object Property type:, each DIV will have one of three CSS backgroundImage values.
div.unit { background-image:url( theme_unit.png ) ; }
div.structure { background-image:url( theme_structure.png ) ; }
div.resource { background-image:url( theme_resource.png) ; }
Another function builder() calls displayCards() and appends the Object card.
function builder()
{
for ( x = 0 ; x < 9 ; x++ )
{
displayCards() ;
document.body.appendChild(card) ;
}
}
I believe my problem lies here. Since the DIV is still not appended.
To note:imgA is a higher index than imgB and has transparency to allow imgB to be seen.
var imgA = card.style.backgroundImage ;
var imgB = list[x].image ;
card.style.backgroundImage = imgA + " , " + imgB ;
I am a minimalist coder and this is the shortest I could come up with. I do not want to have to repeat URL's more than once. My list of Objects is going to get much longer than three.
NO JQUERY

var card_troop = { title : "troop" , type : "Unit" , image : "url(troop.png)" } ;
var card_base = { title : "base" , type : "Structure" , image : "url(base.png)" } ;
var card_wood = { title : "wood" , type : "Resource" , image : "url(wood.png)" } ;
var list = [
card_troop,
card_base,
card_wood
];
function buildCard(card) {
var elem = document.createElement('div'),
elemCloned,
computedBackgroundUrl,
backgroundUrl;
elem.id = card.title;
elem.className = card.type.toLowerCase();
// Clone element and temporary append to body
elemCloned = elem.cloneNode();
elemCloned.style.display = 'none';
document.body.appendChild(elemCloned);
computedBackgroundUrl = window.getComputedStyle(elemCloned)['background-image'];
if (computedBackgroundUrl) {
var match = computedBackgroundUrl.match(/^url\((.*)\)/);
if (match) {
backgroundUrl = match[1];
}
}
// remove element after retrieved background-image value
elemCloned.parentNode.removeChild(elemCloned);
elemCloned = null;
elem.style.backgroundImage = (backgroundUrl ? 'url(' + backgroundUrl + '), ' : '') + card.image;
computedBackgroundUrl = null;
backgroundUrl = null;
return elem;
}
function displayCards() {
var body = document.body;
for (var i = 0, len = list.length; i < len; i++) {
body.appendChild( buildCard(list[i]) );
}
}

Never got efficient in js but your js solution should be the js parallel.
add/remove the class on the div and swap background images according to class in css. I'm assuming this would require less js as a bonus.
hope this helps.

You should work through this approach. Replace "backgroundimage" and "foregroundimage" with the appropriated URLs (of course).
Afterwards you can call the method showCard with a switch. showCard(true) shows the card's front. showCard(false) shows the card's back.
var card = function(title, type, image) {
this.title = title;
this.type = type;
this.image = image;
this.background = "url('backgroundimage')";
};
card.prototype.showCard = function(turn) {
if (turn) {
var ele = document.createElement("div");
ele.appendChild(document.createTextNode(this.title));
ele.appendChild(document.createTextNode(this.type));
ele.style.backgroundImage = this.image;
document.body.appendChild(ele);
} else {
var ele = document.createElement("div");
ele.style.backgroundImage = this.background;
document.body.appendChild(ele);
}
};
function displayCards() {
var card_troop = new card("TroopTitle", "TroopType", "url('foregroundimage')");
card_troop.showCard(true);
var card_troop_2 = new card("Troop2Title", "TroopType", "url('foregroundimage2')");
card_troop_2.showCard(false);
};
div {
min-width: 50px;
height: 120px;
border: solid;
float: left;
}
<input type="button" onclick="displayCards()" value="Display Cards" />

Related

Problem with function reading all attributes of given node

// function to read all attributes
function get_attributes(source_node) { // source of attributes
var i, attribute, size, tab = [];
attribute = { name: "", value: "" } // new type
size = source_node.attributes.length; // reading size
for (i = 0; i < size; i++) {
attribute.name = source_node.attributes[i].name;
attribute.value = source_node.attributes[i].value;
tab[i] = attribute; //putting attribute into table
alert(tab[i].name + " - " + tab[i].value);
}
return tab; //returning filled table
}
Problem is, table (tab) consists only last red parameter :(
Anyone?
Source_node can be anything. ie "document.body"
it works if declared inside loop
...
for (i = 0; i < size; i++) {
VAR attribute =[];
attribute.name = source_node.attributes[i].name;
attribute.value = source_node.attributes[i].value;
tab[i] = attribute; //putting attribute into table
}
....

Illustrator scripting

I am writing a script for an active doc in Illustrator. The active doc already has the spot swatch for "LEAD" in it. All the paths I have to set and symbols need to be set to this swatch. I have worked my way around it by deleting the swatch then re-adding it to the doc. This works for all my paths and objects created. There are 3 symbols in the active doc that are being placed by scrip, that are already set to the spot swatch. When my script deletes the swatch it resets the symbol to 100% black process. Is there a way to pull the swatch from the active doc?All path items reqiure the leadSpotColor variable to set that color. The LEAD swatch already exist in the active doc. If i do not add the swatch remove line before hand it errors out, but the swatch remove line sets my symbols already in the active doc to 100% process black, and they also need to be set to the LEAD swatch.
if ( app.documents.length = "LEAD" ) {
swatchToDelete = app.activeDocument.swatches["LEAD"];
swatchToDelete.remove();
}
var leadSpot = doc.spots.add();
var leadSpotColor = new CMYKColor();
leadSpotColor.cyan = 0;
leadSpotColor.magenta = 0;
leadSpotColor.yellow = 0;
leadSpotColor.black = 100;
leadSpot.name = "LEAD";
leadSpot.colorType = ColorModel.SPOT;
leadSpot.color = leadSpotColor;
var leadSpotColor = new SpotColor();
leadSpotColor.spot = leadSpot;
Why would you want to delete the swatch if you can just edit it ?
var main = function(){
var doc,
leadClr, c;
if(!app.documents.length) return;
doc = app.activeDocument;
leadClr = getLeadColor(doc);
if ( leadClr===null ) {
var leadSpot = doc.spots.add();
var leadSpotColor = new CMYKColor();
leadSpotColor.cyan = 0;
leadSpotColor.magenta = 0;
leadSpotColor.yellow = 0;
leadSpotColor.black = 100;
leadSpot.name = "LEAD";
leadSpot.colorType = ColorModel.SPOT;
leadSpot.color = leadSpotColor;
var leadSpotColor = new SpotColor();
leadSpotColor.spot = leadSpot;
}
else {
c = leadClr.color.spot.color;
c.cyan = 0;
c.magenta = 0;
c.yellow = 0;
c.black = 100;
}
};
var getLeadColor = function(doc){
var clrs = doc.swatches,
n = clrs.length;
while (n-- ) {
if ( clrs[n].name=="LEAD" ) return clrs[n];
}
return null;
}
main();
I would recommend adding some prevention mechanism like ensure swatch is actually a spot prior to reach teh spot property.
First of all first line of your code is wrong
if ( app.documents.length = "LEAD" )
How you can compare length with string "LEAD", its should be a number and also in if statement we use conditional operator and what you are doing is assigning value in if statement.
Here is the script for LEAD spot, that will give you spot color if exist otherwise it will create new spot color with name "LEAD"
function main() {
var currentDocument;
var leadSpotColor;
if (!app.documents.length) {
alert("No document is open");
return;
}
currentDocument = app.activeDocument;
leadSpotColor = getLeadSpotColor(currentDocument);
applyColorToAllPath(leadSpotColor, currentDocument);
}
function getLeadSpotColor(currentDocument) {
try {
var leadSpotColor = currentDocument.spots.getByName('LEAD')
return leadSpotColor;
} catch (e) {
var color = new CMYKColor();
color.cyan = 0;
color.magenta = 0;
color.yellow = 0;
color.black = 100;
var newSpot = currentDocument.spots.add();
newSpot.name = "LEAD";
newSpot.colorType = ColorModel.SPOT;
newSpot.color = color;
var leadSpotColor = new SpotColor();
leadSpotColor.spot = newSpot;
return leadSpotColor;
}
}
function applyColorToAllPath(leadSpotColor, currentDocument) {
// Change code as per your requiremnt. I just handled for pathItems. You can similary for symbols.
var pathItems = currentDocument.pathItems;
for (var i = 0; i < pathItems.length; i++) {
pathItems[i].filled = true;
pathItems[i].fillColor = leadSpotColor;
pathItems[i].stroke = true;
pathItems[i].strokeColor = leadSpotColor;
}
}
main();

backbone: how to pass data to a render view

is there a way to pass data to render
The following code is what I'm currently using:
render:function() {
var background =
var highlight = this.model.get('highlight');
$(this.el).find('div').each(function(index,element) {
if(index < highlight) {
$(element).css({'background': 'url("assets/img/alphabet/ok/ok.png"), url('+background+')'});
$(element).attr('id', 'ok');
} else {
$(element).removeAttr('id');
}
})
}
maybe like this pic:
... you can do something like this:
this.background : [],
//...
initialize : function(){
//...
this.background.push(string.charAt(i));
//...
},
render : function(){
//...
var background = this.background[index];
//...
}
but, maybe also for loop inside your initialize can stay inside render, because it render the view (with .append()).
EDIT NOTE:
I repeat, the possibilities to move around the loop in the initialization function in the render function.
I try to change your backbone view structure:
var WordView = Backbone.View.extend({
initialize : function(){
this.listenTo(this.model,"remove",this.remove);
},
render : function(){
var $Div,
string = this.model.get('string'), //use _string (string can cause some issue in IE)
highlight = this.model.get("highlight"),
letter_width = 36,
letter_heigth = 35,
word_width = string.length * letter_width;
if(this.model.get("x") + word_width > $(window).width()) this.model.set({x:$(window).width() - word_width});
$(this.el).css({
position:"absolute",
top : this.model.get("y"),
left : this.model.get("x")
});
var background,char;
for(var i; i < string.length; i++){
char = string.charAt(i);
background = "url('"+char+"') no-repeat";
$Div.removeAttr("id"); //seems useless
if(i < highlight){
background = "url('assets/img/alphabet/ok/ok.png'),url('"+char+"')";
$Div.id("ok"); //maybe is better $Div.class("ok");
}
$Div = $("<div>").clone();
$Div.css({
width : letter_width,
heigth : letter_height,
float: "left",
"background" : background
}).appendTo($(this.el));
}
}
});

TinyMCE problem with second show. Help

Added tinyMCE as inline editor. Have a next probllem : first time this is work good - show with custom style (as I setup), works correctly but when I click cancel and then start edit again I have empty editor - without text in edit area. so this is a code:
UPD : cm.Node - wrapper for docuement.createElement and el.setAttribute, cm.getByAttr('attr', 'attr_val', el) - get elemnt by attr from el. req - wrapper for AJAX, cm.merge - like array_merge in PHP
var EditBlock = function(){
var my = this;
var o = cm.merge({
'id' : '',
'act' : '',
'val' : '',
'nobr' : false,
'text' : false,
'onSaved' : function(){},
'onSave' : function(){},
'params' : {'iconsPath' : 'interface/common/images/stdc/nicEditorIcons.gif'}
}, arguments[0]);
var prefix = 'tinyMCE_' + Math.random() + '_';
var node = cm.getEl(o.id);
var txtArea = cm.addClass(cm.Node('textarea', {'id' : prefix + o.id, 'style': ('width:' + node.offsetWidth + 'px')}), prefix + o.id);
var saveBtn = cm.Node('input', {'type':'button', 'value':'Save'});
var cancelBtn = cm.Node('input', {'type':'button', 'value':'Cancel'});
var container = cm.Node('div', txtArea, cm.Node('div', saveBtn, cancelBtn));
var plainText = function(node){
var str = '';
var childs = node.childNodes;
for(var i = 0, ln = childs.length; i < ln; i++){
if(childs[i].nodeType == 3)
str += childs[i].nodeValue;
else if(childs[i].childNodes.length)
str += plainText(childs[i]);
}
return str;
}
var init = function(){
node.onclick = my.edit;
cancelBtn.onclick = my.close;
saveBtn.onclick = function(){
my.save();
my.close();
}
}
my.save = function(){
var tmp = cm.Node('div', tinyMCE.get(prefix + o.id).getContent());
var content = o.text? plainText(tmp) : tmp.innerHTML;
o.onSave(content);
node.innerHTML = content;
req({
'act' : o.act,
'data' : 'data[content]=' + escape(content) + (o.val? '&data[val]=' + o.val : ''), 'handler' : function(){o.onSaved(content)}
});
}
my.close = function(){
tinyMCE.init({
'editor_deselector' : prefix + o.id
});
container.parentNode.removeChild(container);
node.style.display = 'block';
}
my.edit = function(){
txtArea.value = node.innerHTML;
node.style.display = 'none';
node.parentNode.insertBefore(container, node);
var styles = '';
var styleRef = cm.getByAttr('rel', 'stylesheet');
for(var i = 0, ln = styleRef.length; i < ln; i++){
styles += (i > 0? ',' : '') + styleRef[i].href;
}
tinyMCE.init({
'height' : '100%',
'content_css' : styles + ',/sdtc-new/nc/interface/common/css/mce-editor.css',
'mode' : "specific_textareas",
'editor_selector' : prefix + o.id
});
}
init();
}
use this like :
new EditBlock({'onSave' : function(content){
page.content = content;
viewDepartment(page);
}, 'id':'depContent', 'act' : '/departments/setContent/', 'val' : page.id, 'params' : {buttonList : ['fontSize','bold','italic','underline','strikeThrough','html']}});
So ... again about problem. When first time start to edit that all works fine when click save - all works too (still exists some bugs but after saving I can click and start edit again) but when click cancel that editor is hide but when I click to edit again I have a empty edit area. I see to console and find that after canceling when I start editing again then I create new edit but old not destroy - only hidden.
I try to usetynyMCE.Editor class methods like hide and show and setContent and was a some result - after canceling I could edit egain but edit area was without styles and buttons.
Please help. If would be quaestion by code - I pleasure to answer.
Thanks.
Don't use hide() and show() here. You should shut down tinymce correctly in order to be able to reinitialize a tinymce editor with the same id as the first one.
To shut down an edtor instance use:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
To reinitialize use
tinymce.execCommand('mceAddControl',true,'editor_id');
Please note!
These have since changed, you may have better luck with (for newer versions, 4+ I think):
try mceRemoveEditor and mceAddEditor instead...as in:
tinymce.execCommand('mceRemoveEditor',true,'editor_id');
tinymce.execCommand('mceAddEditor',true,'editor_id');

Trouble hiding/showing divs in using DOM/js/css

I am trying to make a debugger that will be dynamiaclly created with some variables. The names on the left div need to show a div for the corresponding variables Description,Variable ID, and initial Value as well as another div that will show history and lock status when variables are updated later. Where I am having trouble is properly adding the show/hide to the dom I think. Everything starts hidden and then when I click a name the Variables for that name show up but the next click doesn't hide the values from the former. Also any cleanup/optimization advice?
<script type="text/javascript">
var variableIDArray = {};
function loadVariables(variables) {
if (typeof variables != "object") { alert(variables); return; }
var namearea = document.getElementById('namearea');
var description = document.getElementById('description');
var varid = document.getElementById('varid');
var initialvalue = document.getElementById('initialvalue');
var valuelock = document.getElementById('valuelock');
for (var i = 0; i < variables.length - 1; i++) {
var nameDiv = document.createElement('div');
nameDiv.id = variables[i].variableID + "namearea";
nameDiv.className = "nameDiv";
nameDiv.onclick = (function (varid) {
return function () { showvariable(varid); };
})(variables[i].variableID);
nameDiv.appendChild(document.createTextNode(variables[i].name));
namearea.appendChild(nameDiv);
var descriptionDiv = document.createElement('div');
descriptionDiv.id = variables[i].variableID + "description";
descriptionDiv.className = "descriptionDiv";
descriptionDiv.appendChild(document.createTextNode("Description : " + variables[i].description));
description.appendChild(descriptionDiv);
var varidDiv = document.createElement('div');
varidDiv.id = variables[i].variableID + "varid";
varidDiv.className = "varidDiv";
varidDiv.appendChild(document.createTextNode("Var ID : " + variables[i].variableID));
varid.appendChild(varidDiv);
var initialvalueDiv = document.createElement('div'); ;
initialvalueDiv.id = variables[i].variableID + "initialvalue";
initialvalueDiv.className = "initialvalueDiv";
initialvalueDiv.appendChild(document.createTextNode("Initial Value : " + variables[i].value));
initialvalue.appendChild(initialvalueDiv);
var valuelockDiv = document.createElement('div');
valuelockDiv.id = variables[i].variableID + "valuelock";
valuelockDiv.className = "valuelockDiv ";
valuelockDiv.appendChild(document.createTextNode("Value : " + variables[i].value));
valuelockDiv.appendChild(document.createTextNode("Lock : " + variables[i].locked.toString()));
valuelock.appendChild(valuelockDiv);
variableIDArray[variables[i].variableID];
}
};
function showvariable(varid) {
for (v in variableIDArray)
hide(variableIDArray[v]);
show(varid + "description");
show(varid + "varid");
show(varid + "initialvalue");
show(varid + "valuelock");
}
function show(elemid) {
document.getElementById(elemid).style.display = "block";
}
function hide(elemid) {
document.getElementById(elemid).style.display = "none";
}
Yes. jQuery. Will reduce your code to about 6 lines. :) http://jquery.com

Categories