Reputation: 21
I apologize if this question has been answered before, I've tried searching but haven't found anything that's helped me with this issue. On to the issue!
I'm attempting to update a community character sheet for Roll20. The sheet uses both HTLM and Javascript. I am trying to set up the sheet so that when a player selects the power type of the spell he's using (think spell school from D&D) it places a different icon onto the button for the spell.
The spells are contained within an HTML button component of a repeating_spell container that is designed to create new, unique buttons for each spell.
I am able to successfully have the image be a static image, the same image no matter the power type, but am unsure of how to dynamically change the HTML img tag based on the power type.
I recently realized that the site I'm designing this character sheet for doesn't allow the id flag within the img tag. I've edited my code to show the change. I'm currently trying to do this using the name= flag, and I'm not sure if the jQuery is finding it as I get no image returned. This is the current code for my img tag:
<img name="powertype" src="#" style="width: 15px; height: 15px; padding: 2px;">
with appropriate JS/jQuery references set in an if/else loop which checks the attribute set by the drop down using the following code:
on("change:spellschool", function(eventinfo){
getAttrs(["spellschool"], function(v) {
var spell_school = spellschool.toLowerCase();
if(spell_school === "biotic") {
document.getElementById("powertype").src = "https://n7.world/images/spells/biotic.svg";
}
else if(spell_school === "combat") {
document.getElementById("powertype").src = "https://n7.world/images/spells/combat.svg";
}
else if(spell_school === "tech") {
document.getElementById("powertype").src = "https://n7.world/images/spells/tech.svg";
}
else {
return;
}
});
});
However when I have the above code set, it simply returns a blank image with padding.
Upvotes: 2
Views: 506
Reputation: 43895
Details are commented in demo. Refer to JavaScript and Forms Tutorial. BTW the attribute id is a fundamental aspect of JavaScript and DOM, and cannot be disregarded by an API so easily. An id must be unique and I gather that you have attempted to assign an id to more than one element hence your unmitigated assumption that id "does not work". If for some reason you cannot get it to work by cutting and pasting into whatever (you did not really describe how you implement the code) -- try changing all ids into name. It's an advantage the <form>
element has is the HTMLFormElement API allows seamless association between id and name (they are interchangeable within a form).
// Array of images
const symbols = [
'https://i.ibb.co/StzKvdm/8.gif',
'https://i.ibb.co/6Jtv9mK/nec.gif',
'https://i.ibb.co/6BMt5f9/inv.gif',
'https://i.ibb.co/FgznhXj/abj.gif',
'https://i.ibb.co/Jk6X5wk/div.gif',
'https://i.ibb.co/wwX9xz5/ill.gif',
'https://i.ibb.co/wKqcxxF/trn.gif',
'https://i.ibb.co/86gpFf1/cnj.gif',
'https://i.ibb.co/R6BRtn9/enc.gif'
];
// Reference the first form on page
const form = document.forms[0];
// Collect all inputs, selects, buttons, fieldsets, etc.
const cast = form.elements;
// Reference select
const schools = cast.schools;
// Register select to the change event -- call function changeSymbol()
schools.onchange = changeSymbol;
/** changeSymbol(event)
@Param: event [object]: default Event.Object
As the select changes value so does the src of the element that is in front of it.
//A Pass event object
//B Get event.target (select#schools) value and convert it to a real number
//C Get the element that is in front of select
//D Change that element's src to the url in symbols array at the index of select value
//E* Change the data-idx value to index of select value as well
//F End function
*/
function changeSymbol(event) { //A
const index = Number(event.target.value); //B
const images = event.target.nextElementSibling; //C
images.src = symbols[index]; //D
images.dataset.idx = index; //E* [OPTIONAL]
return false; //F
}
// Register form to submit event -- call function magic()
form.onsubmit = magic;
/** magic(event)
@Param: event [object]: default Event.Object
This is left open for whatever purpose when the image is clicked
//A Pass event object
//B Prevent the form from sending data to a server
*/
function magic(event) { //A
event.preventDefault(); //B
}
:root {
font: 700 small-caps 3vw/2 'Tempus Sans ITC';
}
body {
color: #fff;
background: #000;
}
legend {
font-size: 2rem
}
select,
input {
display: inline-block;
font: inherit;
line-height: 2rem;
vertical-align: top;
margin: 0 10px;
}
select {
font-size: 1.5rem;
}
<form>
<fieldset>
<legend>Schools of Magic</legend>
<select name='schools'>
<option value='0' selected>Select a School</option>
<option value='1'>Necromancy</option>
<option value='2'>Invocation</option>
<option value='3'>Abjuration</option>
<option value='4'>Divination</option>
<option value='5'>Illusion</option>
<option value='6'>Transmutation</option>
<option value='7'>Conjuration</option>
<option value='8'>Enchantment</option>
</select>
<input name='images' src='https://i.ibb.co/StzKvdm/8.gif' type='image' width='220' height='220' data-idx='0'>
</fieldset>
</form>
Upvotes: 0
Reputation: 4226
I can't link an image in a SO snippet**, but but here's a vanilla-flavored solution that gets the path to the image. Setting the src
attribute of an img
element equal to pathSpan.innerHTML
works to display a .png or .jpg, so unless .svg
s behave differently, this should handle your use case.
const dropdown = document.getElementById("dropdown"),
pathSpan = document.getElementById("imgPath");
dropdown.addEventListener("change", updateImage);
function updateImage(event){
if(event.target.value == "1"){
pathSpan.innerHTML = "images/one";
}
else if(event.target.value == "2"){
pathSpan.innerHTML = "images/two";
}
else if(event.target.value == "3"){
pathSpan.innerHTML = "images/three";
}
else{
pathSpan.innerHTML = "";
}
}
<select id="dropdown">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<br />
<span>Path to image: </span><span id="imgPath">images/one</span>
**I sit corrected. Linking to a publicly available image on the web works fine, as Zak has proven in their answer. (In production, you may want to link to an image stored locally on your server instead, just so your code can't get broken by changes in an external site.)
Upvotes: 1
Reputation: 462
You can also do the same with Vanilla JS.
HTML:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<select id='spellschool'>
<option value="biotic">Biotic</option>
<option value="combat">Combat</option>
<option value="tech">Tech</option>
</select>
<img id="powertype" src="#" style="width: 150px; height: 150px; padding: 20px;">
<script src="main.js"></script>
</body>
</html>
JS:
const select = document.querySelector('#spellschool');
const img = document.querySelector('#powertype');
select.addEventListener('change', () => {
if (select.value === 'biotic') {
img.src = 'https://n7.world/images/spells/biotic.svg'
} else if (select.value === 'combat') {
img.src = 'https://n7.world/images/spells/combat.svg'
} else {
img.src = 'https://n7.world/images/spells/tech.svg'
}
})
And here's even better example
const select = document.querySelector('#spellschool');
const img = document.querySelector('#powertype');
select.addEventListener('change', (e) => {
img.src = `https://n7.world/images/spells/${e.target.value}.svg`
console.log(e.target.value)
})
Where we use the es6 `` (backpacks) to variable selected value to a string.
Upvotes: 0
Reputation: 7515
You have some syntactical errors in your JS --
Missing start quote on line 6:
Missing end parentheses on line 10:
Other than that .. I simplified it for you:
$('#spellschool').on('change', function(eventinfo){
if(this.value == "biotic") {
document.getElementById("powertype").src =
"https://n7.world/images/spells/biotic.svg";
} else if(this.value === "combat") {
document.getElementById("powertype").src =
"https://n7.world/images/spells/combat.svg";
} else if(this.value === "tech") {
document.getElementById("powertype").src =
"https://n7.world/images/spells/tech.svg";
} else {
return;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img id="powertype" src="#" style="width: 15px; height: 15px; padding: 2px;">
<select id="spellschool">
<option>Select one</option>
<option value="biotic">biotic</option>
<option value="combat">combat</option>
<option value="tech">tech</option>
</select>
Upvotes: 3