I'm currently making a program for my players in an RPG to be able to select their character skills from drop-down menus which will 1. Display the title of the skill under the results section and also in the Selected Advantages section(top right). 2. Display the description of the skill under its title.
It is working mostly as intended except for a bug I have discovered. I can select the desired advantage and it will appear as expected. It will also remove the selection when I click on the delete button under the Selected Advantages section at the top right of the page.
The problem is that if I reselect the same advantage it will display the advantage description twice at the bottom of the page, if I do the same again it will display three times, and so on.
When I delete a selection the container is removed but when they are selected again the subsequent descriptions are also contained in a single container instead of creating a new one.
Here is my code so far.
Note: I have only included the object for Absolute Direction but have tested with others and get the same duplication result.
const createDivElement = document.createElement('div');
//Creates containers for the selected advantage descriptions.
function createContainer(advantageName) {
const placeAdvantageDescription = document.getElementById('place-text');
placeAdvantageDescription.appendChild(createDivElement);
createDivElement.setAttribute("id", `container-${advantageName}`);
}
//Creates and adds the text for the selected advantages title, points and description.
//should I make this three seperate functions???
function addAdvantageText(advantageObject) {
const createTitleElement = document.createElement('p');
const createPointsElement = document.createElement('p');
const createDescriptionElement = document.createElement('p');
//creates Title
createDivElement.append(createTitleElement);
createTitleElement.classList.add("title");
createTitleElement.innerText = advantageObject.title;
//creates points
createDivElement.append(createPointsElement);
createPointsElement.classList.add("points");
createPointsElement.innerText = `${advantageObject.points}.`;
//creates description
createDivElement.append(createDescriptionElement);
createDescriptionElement.classList.add("description-text");
createDescriptionElement.innerHTML = advantageObject.description;
}
//creates sub catagories for selected advantage and adds the extra text if applicable.
function addSubCategories(advantageObject) {
if (advantageObject.subCategory1) {
let createSubCategory1 = document.createElement('p');
createDivElement.append(createSubCategory1);
createSubCategory1.innerHTML = `<strong>${advantageObject.subCategory1.name}:</strong> ${advantageObject.subCategory1.text}<br><strong><em>${advantageObject.subCategory1.sub1Points}</em></strong>.`;
}
if (advantageObject.subCategory2) {
let createSubCategory2 = document.createElement('p');
createDivElement.append(createSubCategory2);
createSubCategory2.innerHTML = `<strong>${advantageObject.subCategory2.name}:</strong> ${advantageObject.subCategory2.text}<br><strong><em>${advantageObject.subCategory2.sub2Points}</em></strong>.`;
}
if (advantageObject.subCategory3) {
let createSubCategory3 = document.createElement('p');
createDivElement.append(createSubCategory3);
createSubCategory3.innerHTML = `<strong>${advantageObject.subCategory3.name}:</strong> ${advantageObject.subCategory3.text}<br><strong><em>${advantageObject.subCategory3.sub3Points}</em></strong>.`;
}
if (advantageObject.subCategory4) {
let createSubCategory4 = document.createElement('p');
createDivElement.append(createSubCategory4);
createSubCategory4.innerHTML = `<strong>${advantageObject.subCategory4.name}:</strong> ${advantageObject.subCategory4.text}<br><strong><em>${advantageObject.subCategory4.sub4Points}</em></strong>.`;
}
if (advantageObject.extraText) {
let createExtraText = document.createElement('p');
createDivElement.appendChild(createExtraText);
createExtraText.innerHTML = advantageObject.extraText;
}
}
//adds name of chosen advantages in Selected Advantages column and a delete button for each.
function addToSelectedColumn(advantageName) {
const hr = document.createElement('hr');
const button = document.createElement('button');
const createSelectedAdvantageDiv = document.createElement('div');
const placeSelectedText = document.getElementById('selected-items');
placeSelectedText.appendChild(createSelectedAdvantageDiv);
createSelectedAdvantageDiv.append(advantageName.toUpperCase());
createSelectedAdvantageDiv.setAttribute("id", `selected-items-container-${advantageName}`);
createSelectedAdvantageDiv.append(button);
button.setAttribute("id", `delete-${advantageName}`);
createSelectedAdvantageDiv.append(hr);
}
function removeAdvantageText(removeThis) {
let advantageDescriptionToRemove = document.getElementById(`container-${removeThis}`);
let selectedAdvantageToRemove = document.getElementById(`selected-items-container-${removeThis}`);
advantageDescriptionToRemove.remove();
selectedAdvantageToRemove.remove();
}
function removeAdvantage(advantageToDelete) {
document.getElementById(`delete-${advantageToDelete}`).addEventListener("click", function() {
removeAdvantageText(advantageToDelete);
})
};
function addAdvantage(advantageInString, advantageObjectName) {
createContainer(advantageInString);
addToSelectedColumn(advantageInString);
addAdvantageText(advantageObjectName);
addSubCategories(advantageObjectName);
}
//Event listeners for when users select advantage. They will check for matching selection then call addAdvantage() with arguments.
//AAAAAAAAAAAAAAAA
document.getElementById("submit-advantage-a").addEventListener("click", function(e) {
e.preventDefault();
const userAdvantageA = document.getElementById('user-advantages-a').value;
if (userAdvantageA === 'absolute direction') {
addAdvantage('absolute direction', absoluteDirection);
removeAdvantage('absolute direction');
} else if (userAdvantageA === 'absolute timing') {
addAdvantage('absolute timing', absoluteTiming);
removeAdvantage('absolute timing');
} else if (userAdvantageA === 'acute senses') {
addAdvantage('acute senses', acuteSenses);
removeAdvantage('acute senses');
}
});
let absoluteDirection = {
title: "Absolute Direction",
points: "5 or 10 points",
description: "You have an excellent sense of direction.This ability comes in two levels:",
subCategory1: {
name: "Absolute Direction",
text: "You always know which way is north, and you can always retrace a path you have followed within the past month, no matter how faint or confusing. This ability does not work in environments such as interstellar space or the limbo of the astral plane, but it does work underground, underwater, and on other planets. This gives +3 to Body Sense and Navigation (Air, Land, or Sea).<br> (Note: The navigational sense that guides migratory creatures to their destination is too crude to qualify; treat it as a 0-point feature.)",
sub1Points: "5 points"
},
subCategory2: {
name: "3D Spatial Sense",
text: "As above, but works in three dimensions. This ability is useful in deep space – although it does not help you if you travel across dimensions. You get the skill bonuses to Piloting and +2 to Aerobatics, Free Fall, and Navigation (Hyperspace or Space).",
sub2Points: "10 points"
}
}
.container {
border-bottom: solid 2px black;
padding: 1rem 2rem;
}
.title {
font-size: 1.5rem;
font-weight: bolder;
text-align: center;
}
.points {
font-weight: bold;
}
#selected-items-container {
float: right;
background-color: gray;
color: white;
text-align: center;
width: 20rem;
margin-right: 4rem;
}
.forms {
margin-left: 2rem;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/style.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script type="text/javascript" src="/script.js" async></script>
<title>GCRC</title>
</head>
<body>
<a id="home-nav" href="*">Home</a>
<div class="make-choice">
<div id="selected-items-container"><strong>SELECTED ADVANTAGES</strong>
<hr>
<div id="selected-items"></div>
</div>
<div class="forms">
<h1>Select your characters advantages</h1>
<p>A.</p>
<form method="GET">
<select name="user-advantages-a" id="user-advantages-a">
<option value="absolute direction">Absolute Direction</option>
<option value="absolute timing">Absolute Timing</option>
<option value="acute senses">Acute Senses</option>
</select>
<input id="submit-advantage-a" type="submit" />
</form>
<p>B.</p>
<form method="GET">
<select name="user-advantages-b" id="user-advantages-b">
<option value="binding">Binding</option>
<option value="blessed">Blessed</option>
<option value="brachiator">Brachiator</option>
</select>
<input id="submit-advantage-b" type="submit" />
</form>
<p>C.</p>
<form method="GET">
<select name="user-advantages-c" id="user-advantages-c">
<option value="catfall">Catfall</option>
<option value="chameleon">Chameleon</option>
<option value="channeling">Channeling</option>
</select>
<input id="submit-advantage-c" type="submit" />
</form>
<p>D.</p>
<form method="GET">
<select name="user-advantages-d" id="user-advantages-d">
<option value="damage resistance">Damage Resistance</option>
<option value="danger sense">Danger Sense</option>
<option value="daredevil">Daredevil</option>
</select>
<input id="submit-advantage-d" type="submit" />
</form>
</div>
</div>
<hr>
<div class="display-choice">
<p>Advantages</p>
<div class="advantages">
<div id="place-text"></div>
</div>
</div>
</body>
</html>
Related
I have to do a web page for school that converts temperature between celsius and fahrenheit.
I tried to make it with 2 input boxes that change value based on the value of the other input box, when I write something on one of the input boxes for the first time it works, but then even though on the code the value changes, on the page it doesn't appear.
I am new to javascript and html in general and I don't know what I'm doing wrong.
This is the code:
function cambiagradi(x,y) {
if (document.getElementById(x).value == "Centigradi") {
document.getElementById(y).value = "Fahrenheit";
}
else {
document.getElementById(y).value = "Centigradi";
}
}
function Conversione(from,to,gradi) {
var x = document.getElementById(from).value;
if (document.getElementById(gradi).value == "Centigradi") {
document.getElementById(to).setAttribute("value", (x-32)*5/9);
}
else {
document.getElementById(to).setAttribute("value", (x*9/5)+32);
}
}
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="background-color: #008080;">
<h1 style="text-align:center">Convertitore Temperatura</h1>
<div class="container" style="display:flex; justify-content: center">
<div style=" padding: 1%; ">
<p>
<input type="text" id="box1" oninput="Conversione('box1','box2','Gradi2')">
</p>
<p style="margin-left:10%">
<label for="Gradi1">Gradi</label>
<select id="Gradi1" onchange="cambiagradi('Gradi1','Gradi2')">
<option value="Centigradi">Centigradi</option>
<option value="Fahrenheit">Fahrenheit</option>
</select>
</p>
</div>
<div style=" padding: 1%; ">=</div>
<div style=" padding: 1%; ">
<p>
<input type="text" id="box2" oninput="Conversione('box2','box1','Gradi1')">
</p>
<p style="margin-left:10%">
<label for="Gradi2">Gradi</label>
<select id="Gradi2" onchange="cambiagradi('Gradi2','Gradi1')">
<option value="Fahrenheit">Fahrenheit</option>
<option value="Centigradi">Centigradi</option>
</select>
</p>
</div>
</div>
</body>
</html>
Thanks in advance!
You should just set the value of the element and all would work as expected.
The explanation you can find here.
function Conversione(from, to, gradi) {
const x = document.getElementById(from).value;
if (document.getElementById(gradi).value == "Centigradi") {
document.getElementById(to).value = ((x - 32) * 5) / 9;
} else {
document.getElementById(to).value = (x * 9) / 5 + 32;
}
}
Some explanations within the code. Tell me if you need more. It looks more complicated but it avoids inline JavaScript which is good :)
// Define your elements as variables first as you're going to use them multiple times :
const gradi1 = document.getElementById("Gradi1");
const gradi2 = document.getElementById("Gradi2");
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
// Now, always use gradi1, gradi2, box1 and box2 instead of document.getElementById ....
// Then, avoid INLINE JavaScript ! (onchange="")
// We're gonna add 'event listener' to your elements
gradi1.addEventListener("change", function(){
cambiagradi(this); // 'this' means you'll know which element triggered the event when calling the function
}, false);
gradi2.addEventListener("change", function(){
cambiagradi(this);
}, false);
box1.addEventListener("input", function(){
Conversione(this)
}, false);
box2.addEventListener("input", function(){
Conversione(this)
}, false);
// You passed 'this' previously, so its back here with the name you want (ex: ancora_this)
function cambiagradi(ancora_this) {
if (ancora_this.id == "Gradi1") {
if (ancora_this.selectedIndex == 0) { // 'selectedIndex' means selected option position in the dropdown menu (begins at 0)
gradi2.selectedIndex = 1;
} else {
gradi2.selectedIndex = 0;
}
} else {
if (ancora_this.selectedIndex == 1) {
gradi1.selectedIndex = 0;
} else {
gradi1.selectedIndex = 1;
}
}
}
function Conversione(ancora_this) {
var target, conv, unit;
if (ancora_this.id == "box1") {
target = box2;
unit = gradi1;
} else {
target = box1;
unit = gradi2;
}
if (unit.selectedIndex == 0) {
conv = (Number(ancora_this.value) * 9/5) + 32;
} else {
conv = (Number(ancora_this.value) - 32)*5/9;
}
target.value = conv;
}
body {
background-color: #008080
}
h1 {
text-align: center
}
.container {
display: flex;
justify-content: center
}
.container div {
padding: 1%;
}
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Convertitore Temperatura</h1>
<div class="container">
<div>
<p>
<!-- type="number" is better because it only allows numbers -->
<input type="number" id="box1">
</p>
<p style="margin-left:10%">
<label for="Gradi1">Gradi</label>
<select id="Gradi1">
<option value="Centigradi" selected>Centigradi</option>
<option value="Fahrenheit">Fahrenheit</option>
</select>
</p>
</div>
<div>=</div>
<div>
<p>
<input type="number" id="box2">
</p>
<p style="margin-left:10%">
<label for="Gradi2">Gradi</label>
<select id="Gradi2">
<!-- I switched the order to have the same 'index' on both SELECT menus
Also, I added 'selected' to have a default selected unit at start -->
<option value="Centigradi">Centigradi</option>
<option value="Fahrenheit" selected>Fahrenheit</option>
</select>
</p>
</div>
</div>
</body>
</html>
I've read up on inserting css rules using Javascript and have managed to get it working (after some trial & error). So I have 2 questions:
Q.1 Why is an index < 1 not working - see Mozilla example (and many others) below:
// push a new rule onto the top of my stylesheet - doesn't work...
myStyle.insertRule("#blanc { color: white }", 0); // returns Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to insert the rule.
// change the index and it works!
myStyle.insertRule("#blanc { color: white }", 1);
This article by David Walsh (very helpful), explains that the default for index is -1. He uses 1 in his example, which is what worked for me. Anything less than 1, ie 0 or -1 (as per the default) threw the following errors:
Index -1 error:
Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': The index provided (4294967295) is larger than the maximum index (2071).
Index 0 error:
Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to insert the rule.
It's not a huge problem, but it does mean I can't control specificity. I can use !important or rework the css/inserted rule so that it overrides any existing styles, but as I'm just learning JavaScript, I'd really like to know why it's not working as expected. Does anyone have any ideas?
Q.2 Having got it to work using index 1, I now want to pull in values dynamically. I have the item names in an array, which is used to create multiple objects, inside which are the property values I want to use for the individual style rules for that object.
Basically what I'm trying to output is this (which works):
styleSheet.insertRule("#item { border-top-color: #000000; border-right-color: #ffffff; }", 1);
But using variables, something like this:
styleSheet.insertRule("[itemName] { border-top-color: [itemName.value1]; border-right-color: [itemName.value2]; }", 1); // itemName.valueX being the object's array item
I've tried heaps of things, but I can't get the array item bit to work, ie colour and colour4 should actually be itemName.value1/2 or a var that equals the same. This is the closest I've got so far...
styleSheet.insertRule("#" + name + " { border-top-color: " + colour + "; border-right-color: " + colour4 + " !important; }", 1); // 1st rule works, 2nd doesn't show anything
It all works lovely if I write it manually (as per the 1st example), but how to do it dynamically? I've found info on insertRule, but not using dynamic values - can anyone help/point me in the right direction?
Many thanks in advance!
Expanded WIP for more clarity:
function itemColours() {
for (i = 3; i < itemsArray.length; i++) {
let name = itemsArray[i];
let colour = #000000;
console.log(item1.value); // returns the hex value I want to use in the rule
styleSheet.insertRule("#" + name + " { border-top-color: " + colour + "; border-right-color: " + name + ".value !important; }", 1);
// rule 1 works, rule 2 doesn't...
}
Update 2
This demo:
can accept user data to use insertRule() and deleteRule().
has an Add Set button which will create and append a clone of the <form> part of the document
has 3 styleSheets Bootstrap [0], CSSOM, and the <style> tag.
Demo 4
// Just for demo
.as-console-wrapper {
width: 170px;
max-height: 40px;
transform: translateX(340px)
}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' title='Bootstrap-3.3.7'>
<link href='https://glpjt.s3-us-west-1.amazonaws.com/ir/cssom.css' rel="stylesheet" title='CSSOM'>
<style title='Tag'>
body {
max-width: 96%;
visibility: hidden;
font: 400 16px/1.2 Verdana
}
ul.x-list.x-list {
margin-left: 0;
padding-left: 1em;
text-indent: -1em;
list-style-type: none;
}
li.x-item.x-item {
list-style: none;
line-height: 1.5;
}
.x-flex.x-flex {
display: flex;
justify-content: center;
align-items: center;
}
.x-col {
display: flex;
flex-direction: column
}
option::before {
content: attr(name)
}
#idx {
max-width: 6ch;
}
label {
margin: 10px auto 10px -15px
}
#add {
position: fixed;
z-index: 1;
top: 50px;
left: 20px
}
</style>
</head>
<body>
<main class='container' style='padding:50px 0 20px 20px'>
<form id='cssom' class='row x-col'>
<div class='btn-group col-sm-12'>
<input id='add' class='btn-lg btn-success' type='button' value='Add Set'>
</div>
<section class='row'>
<!--=================================[0]-->
<fieldset class='set0 col-sm-12'>
<hr>
<div class='row x-flex'>
<!--=================================[1]-->
<label class='form-control-label col-sm-2'>CSS Rule</label>
<textarea id='rul0' class='form-control col-sm-10' rows='2'>li.x-item.x-item::before {content: '\1f539\00a0';list-style:none;font-size:small;position:relative;bottom:2px}</textarea>
</div>
<div class='form-inline row'>
<label class='form-control-label col-sm-2'>Stylesheet</label>
<select id='sht0' class='form-control col-sm-4'>
<optgroup label="LINK">
<!--================================[3]-->
<option value='0' selected name='Bootstrap-3.3.7'> [0]</option>
<option value='1' name='CSSOM'> [1]</option>
</optgroup>
<optgroup label="STYLE">
<option value='2' name='Tag'> [2]</option>
</optgroup>
</select>
<label class='form-control-label col-sm-1'>Rule Index</label>
<input id='idx0' class='form-control col-sm-1' type='number' min='-1' value='0'>
<!--==========[4]-->
<div class="btn-group col-sm-4">
<!--=====[5]-->
<input id='ins0' class='btn btn-primary' type='button' value='Insert Rule' onclick='modRule(this)'>
<!--======[6]-->
<input id='del0' class='btn btn-danger' type='button' value='Delete Rule' onclick='modRule(this)'>
</div>
</div>
</fieldset>
</section>
<hr><br>
</form>
<hgroup class='x-inline'>
<!--====================================[hgroup.x-inline]-->
<h1 class='h1'>CSSStyleSheet</h1>
<h2 class='h2'>.insertRule()</h2>
</hgroup>
<article class='text-primary'>
<blockquote class='blockquote'>
<h3 id="Restrictions" class='h3'>Restrictions</h3>
<p>CSS stylesheet rule-lists have a number of intuitive and not-so-intuitive <a class="external" href="https://drafts.csswg.org/cssom/#insert-a-css-rule">restrictions</a> affecting how and where rules can be inserted. Violating these will likely
cause an error raised as a <a title="The DOMException interface represents an abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API." href="https://developer.mozilla.org/en-US/docs/Web/API/DOMException"><code>DOMException</code></a> </p>
<!--==========================[ul.x-list | li.x-fade]-->
<ul id='list' class='list-group-flush x-list'>
<li class='list-group-item-text fade x-fade x-item'>If index > number of rules in the stylesheet (the <a title="A CSSRuleList is an (indirect-modify only) array-like object containing an ordered collection of CSSRule objects." href="https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList"><code>CSSRuleList</code></a>.length),
then aborts with IndexSizeError.</li>
<li class='list-group-item-warning x-item'>If rule cannot be inserted at index 0 due to some CSS constraint, then aborts with HierarchyRequestError.</li>
<li class='list-group-item-danger x-item'>If more than one rule is given in the rule parameter, then aborts with SyntaxError</li>
<li class='list-group-item-text x-fade x-item'>If trying to insert an #import at-rule after a style rule, then aborts with HierarchyRequestError.</li>
<li class='list-group-item-text x-fade x-item'>If rule is #namespace at-rule and list has more than just #import at-rules and/or #namespace at-rules, then aborts with InvalidStateError.</li>
</ul>
</blockquote>
<footer class='blockquote-footer'>
<!--===============================[[cite.x-cite]-->
<cite class='x-cite'><a href='https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule#Restrictions'>CSSStyleSheet.insertRule() - Wed APIs #Restrictions | MDN</a></cite> </footer>
</article>
</main>
<script>
var cnt = 0;
var form = document.forms[0];
var add = document.getElementById('add');
function modRule(ID) {
var e = window.event;
var i = ID.id.split('').pop();
console.log('ruleIndex: ' + i);
var sheets = document.styleSheets;
var sheet = document.getElementById('sht' + i);
var rulez = document.getElementById('rul' + i);
var index = document.getElementById('idx' + i);
var vSht = parseInt(sheet.value, 10);
var vIdx = parseInt(index.value, 10);
var vRul = rulez.value;
if (e.target.value === 'Delete Rule') {
switch (vSht) {
case 0:
sheets[0].deleteRule(vIdx);
break;
case 1:
sheets[1].deleteRule(vIdx);
break;
case 2:
sheets[2].deleteRule(vIdx);
break;
default:
sheets[0].deleteRule(vIdx);
break;
}
} else if (e.target.value === 'Insert Rule') {
switch (vSht) {
case 0:
sheets[0].insertRule(vRul, vIdx);
break;
case 1:
sheets[1].insertRule(vRul, vIdx);
break;
case 2:
sheets[2].insertRule(vRul, vIdx);
break;
default:
sheets[0].insertRule(vRul, vIdx);
break;
}
} else {
return;
}
}
add.addEventListener('click', addSet, false);
function addSet(e) {
cnt++;
var set = document.querySelector('.set0');
var opt = document.options
var dupe = set.cloneNode(true);
dupe.className = 'set' + cnt;
var fields = Array.from(dupe.querySelectorAll('[id]'));
var ids = fields.map(function(ID, idx) {
var zero = ID.id.lastIndexOf("0");
ID.id = ID.id.slice(0, zero);
ID.id = ID.id + cnt;
if (ID.id === 'rul' + cnt) {
ID.textContent = 'p {color:red}';
}
console.log('id: ' + ID.id + ' val: ' + ID.value);
return ID.value;
});
form.appendChild(dupe);
}
</script>
</body>
</html>
Update
If the stylesheet is big, wouldn't it be more efficient to dynamically create a new stylesheet for them?
Yes, but not an external <link> it's far more efficient and a ton more easier to dynamically manipulate a <style> block at the bottom of the </head>.
Not only is it simple, it's powerful since it's at the bottom of the cascade it'll override anything from an external <link>.
Also another thing to consider is that a HTTP request isn't needed unlike an external file which requires it and that' adds to your website's latency.
Demo 3 features 3 functions:
injectCSS() will be called mere microseconds before it's counterpart injectJS() at window.onload. It will create a <style> block within the </head> along with whatever styles we want initially.
injectJS() loads after injectCSS() because as a general rule style should always load before script. It will create a <script> tag and append it as the last child of the <body> tag specifically right before the closing </body> tag. Just like injectCSS() it may have anything within its tags that's script.
inject() calls both injectCSS() and injectJS() asynchronously to ensure that the former will always load before the latter.
As far as this demo relates to the OP, injectCSS() is the function that we should concern ourselves with as was already explained previously.
Details are commented in the demo
For faster loading time, please review the PLUNKER instead.
Demo 3
<!DOCTYPE html>
<html>
<head>
<style>
html {
font: 400 100%/1 Consolas;
}
html,
body {
height: 100%;
width: 100%;
}
main {
height: auto;
width: 100%;
padding: 10px;
}
section {
height: auto;
width: 100%;
padding: 10px
}
fieldset {
min-width: 70%;
margin: 20px 0;
padding: 10px;
}
var {
background: rgba(0, 0, 0, .7);
color: lime;
}
</style>
</head>
<body>
<h1></h1>
<main>
<p><var>injectCSS =</var> All paragraphs will be red</p>
<section>
<form id='test0'>
<fieldset>
<legend>Test Log</legend>
<label for='msg0'>injectCSS()...:
<output id='msg0'></output></label>
<br>
<label for='msg1'>injectJS()....:
<output id='msg1'></output></label>
</fieldset>
</form>
</section>
<section>
</section>
</main>
<footer>
<p>Review this page with Firebug/DevTools and we'll see an extra <style> tag in the <head> and we'll see an extra <script> tag right before the closing <\body> tag.</p>
</footer>
<script>
// HTMLFormControlsCollection★
var x0 = document.forms[0].elements;
var m0 = x0.msg0;
var m1 = x0.msg1;
// Input strings of styles and scripts that are to be injected
var css = "p {color:red}";
var js = "document.querySelector('h1').innerHTML = '<var>injectJS =</var> H1 HTML'";
/* This function manages injectCSS() and injectJS() functions by using
|| the async/await★ keywords. Times are provided by
|| performance.now()★ method.
*/ //* ✎ Delete/add the first * to disable/enable this version of inject().
// The proceeding edit ✎ must be done as well.
var inject = async function() {
var wait0 = injectCSS.call(this, css);
var wait1 = injectJS.call(this, js);
m0.value = performance.now();
var init1 = await wait1;
m1.value = performance.now()
return false;
};
/*/// ✎ Delete/add the first / to enable/disable this version of inject().
// The previous edit ✎ must be done as well.
var inject = function() {
injectCSS.call(this, css);
m0.value = performance.now();
injectJS.call(this, js);
m1.value = performance.now()
return false;
};
/* These 2 functions do the same thing but with different content.
|| They could be refactored into one function but I made them
|| separately to show injectCSS() sepatately for QA SO46985099.
|| Both creates a tag, then writes the code in it, and then appends
|| it to DOM.
*/
function injectCSS(style) {
var sty = document.createElement("style");
sty.innerHTML = style;
document.querySelector('head').appendChild(sty);
}
function injectJS(script) {
var scr = document.createElement("script");
scr.innerHTML = script;
document.body.appendChild(scr);
}
/* The main function inject() is called at window.load. This is the last
|| loading event possible in which we are able call our function. This
|| ensures that specific CSS is loaded before specific JS is called.
|| This is the last step in the loading process, therefore there should be
|| no more styles to render or script that blocks.
*/
window.onload = inject;
</script>
</body>
</html>
Demo Outline
Collects all <link> and <style> into a styleSheetList using document.stylesheets
Converts it into an array called sheetArray with Array.from()
The target is the 3rd <link> which is sheetArray[2]
Then there are 2 rules inserted at index 0 and index 1 successfully.
This is done through a for loop and arrays as the dynamic parameters and interpolation of Template Literals.
This demo does not function on SO, go to PLUNKER for a functioning demo.
Note: In the demo content is an excerpt from MDN that defines the restrictions of insertRule(). The highlighted items may apply to your specific errors.
Demo 1 - index.html [Review PLUNKER for a working demo]
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css' rel='stylesheet'>
<link href="style.css" rel="stylesheet">
<link href='cssom.css' rel="stylesheet">
</head>
<body>
<main class='container'>
<hgroup class='x-inline'>
<!--====================================[hgroup.x-inline]-->
<h1 class='h1'>CSSStyleSheet</h1>
<h2 class='h2'>.insertRule()</h2>
</hgroup>
<article class='text-primary'>
<blockquote class='blockquote'>
<h3 id="Restrictions" class='h3'>Restrictions</h3>
<p>CSS stylesheet rule-lists have a number of intuitive and not-so-intuitive <a class="external" href="https://drafts.csswg.org/cssom/#insert-a-css-rule">restrictions</a> affecting how and where rules can be inserted. Violating these will likely
cause an error raised as a <a title="The DOMException interface represents an abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API." href="https://developer.mozilla.org/en-US/docs/Web/API/DOMException"><code>DOMException</code></a> </p>
<!--==========================[ul.x-list | li.x-fade]-->
<ul class='list-group-flush x-list'>
<li class='list-group-item-text x-fade'>If index > number of rules in the stylesheet (the <a title="A CSSRuleList is an (indirect-modify only) array-like object containing an ordered collection of CSSRule objects." href="https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList"><code>CSSRuleList</code></a>.length),
then aborts with IndexSizeError.</li>
<li class='list-group-item-warning'>If rule cannot be inserted at index 0 due to some CSS constraint, then aborts with HierarchyRequestError.</li>
<li class='list-group-item-danger'>If more than one rule is given in the rule parameter, then aborts with SyntaxError</li>
<li class='list-group-item-text x-fade'>If trying to insert an #import at-rule after a style rule, then aborts with HierarchyRequestError.</li>
<li class='list-group-item-text x-fade'>If rule is #namespace at-rule and list has more than just #import at-rules and/or #namespace at-rules, then aborts with InvalidStateError.</li>
</ul>
</blockquote>
<footer class='blockquote-footer'>
<!--===============================[[cite.x-cite]-->
<cite class='x-cite'><a href='https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule#Restrictions'>CSSStyleSheet.insertRule() - Wed APIs #Restrictions | MDN</a></cite> </footer>
</article>
</main>
<script>
var sheets = document.styleSheets;
var sheetArray = Array.from(sheets);
var sel = ['ul.x-list', 'li::before'];
var dec = [`margin-left: 0; padding-left: 1em; text-indent: -1em;`, `content: '🔹';`];
var idx = [0, 1];
var qty = idx.length;
for (let r = 0; r < qty; r++) {
sheetArray[2].insertRule(`${sel[r]} {${dec[r]}}`, idx[r]);
}
</script>
</body>
</html>
Deno 2 - cssom.css
/*0*/
hgroup.x-inline {display:flex; justify-content:center; align-items: center;}
/*1*/
ul.x-list.x-list {list-style: none;}
/*2*/
li.x-fade.x-fade {color:rgba(0,0,0,.3);}
/*3*/
cite.x-cite.x-cite {position:relative; left:60%}
/*4*/
cite.x-cite.x-cite::before {content:"\2014 \00A0"}
/*5*/
.blockquote-footer::before {content: '';}
/*6*/
li.list-group-item {line-height:1.5}
/*7*/
a {text-shadow: 2px 5px 3px rgba(192,192,192,.8)}
I have created a small application locally on my machine using HTML, CSS and JavaScript. I am using a plugin to run the JavaScript on the site. My small application loads different pictures from drop down lists and uses a SendMail JavaScript function as well. How can I add this page as one of my WordPress pages? I used a BlankSlate plugin to clean one of my pages up and whenever I paste my code into the page it gets scrambled and doesent work. It loads my drop down lists and some titles but pictures are gone and background isnt present. I am new to using WordPress and I want to add this small app to my site. Any help would be great or suggestions and how to copy it over. ( Sorry for the messy, unorganized code. Still learning and practicing, but this is what I am trying to turn into a page )
<html lang="en"><head>
<meta charset="utf-8">
<meta name="description" content=" A page for exploring html documents">
<title>BuildIt-AR App</title>
<head>
<link href="https://fonts.googleapis.com/css?family=Rock+Salt" rel="stylesheet">
</head>
<style>
.body {max-width:1920px; margin:0 auto;}
.centered {max-width:720px; margin:0 auto;}
.floatLeft {
float:left;}
select {
display:block; clear:both;
}
.myBox{
clear:both;
max-width: 375px;
max-height: 225px;
padding-top:275px;
}
.textlines {
padding-top:350px;
}
body{
background-image: url("https://www.xmple.com/wallpaper/grey-gradient-linear-1920x1080-c2-708090-dcdcdc-a-285-f-14.svg");
background-repeat: repeat-x;
border: 5px inset lightgrey;
}
font{
font-family: 'Rock Salt', cursive;
position: fixed;
font-size: 350%;
top: 20%;
left: 50%;
margin-top: -50px;
margin-left: -100px;
letter-spacing: 3px;
text-shadow: 2.2px 1.5px grey;
}
select{
}
</style>
<script type="application/javascript">
var pictureList1 = [
"http://i66.tinypic.com/xds135.png",
"http://i68.tinypic.com/28cdhxh.png",
"http://i66.tinypic.com/169s4mc.png",
];
function change_image(id) {
var idx = document.getElementById('picDD').value - 1; // javascript is zero-indexed
document.getElementById('pic').src = pictureList1[idx];
y = document.getElementById("picDD");
//x.value = y.options[y.selectedIndex].text;
document.getElementById("stock").value = stock[y.selectedIndex];
}
var pictureList2 = [
"http://i65.tinypic.com/2wmqefs.png",
"http://i63.tinypic.com/s4za11.png",
"http://i66.tinypic.com/6e3ibq.png",
];
function change_image2(id) {
var idx = document.getElementById('picDD2').value - 1; // javascript is zero-indexed
document.getElementById('pic2').src = pictureList2[idx];
y = document.getElementById("picDD2");
//x.value = y.options[y.selectedIndex].text;
document.getElementById("body").value = body[y.selectedIndex];
}
var pictureList3 = [
"http://i65.tinypic.com/2n9dslt.png",
" http://i65.tinypic.com/289h35y.png",
"http://i64.tinypic.com/vxnpzd.png",
];
function change_image3(id) {
var idx = document.getElementById('picDD3').value - 1; // javascript is zero-indexed
document.getElementById('pic3').src = pictureList3[idx];
y = document.getElementById("picDD3");
//x.value = y.options[y.selectedIndex].text;
document.getElementById("barrel").value = barrel[y.selectedIndex];
}
var barrel = new Array();
var body = new Array();
var stock = new Array();
barrel[0] = "Assault Barrel $89.95";
body[0] = "BlackOut Body $231.95";
stock[0] = "Slide Stock $78.95";
barrel[1] = "Sniper Barrel $395.95";
body[1] = "SlideFire Body $278.95";
stock[1] = "Fold Stock $178.95";
barrel[2] = "Tactical Barrel $278.95";
body[2] = "Green Body $134.95";
stock[2] = "Steady Stock $78.95";
barrel[3] = 4;
body[3] = "asmith";
stock[3] = "Andy Smith";
// function change_image3() {
//x = document.getElementById("users");
//
function sendMail() {
var link = "mailto:example#gmail.com"
+ "?cc=gunbuilder#builditar.com"
+ "&subject=" + escape("BuildIt-AR Order Form")
+ "&body=" + escape(document.getElementById('name').value + "\n" + document.getElementById('barrel').value + "\n" + document.getElementById('body').value + "\n" + document.getElementById('stock').value);
window.location.href = link;
}
</script>
</head>
<body>
<div class="centered">
<div class="floatLeft">
<img id="pic" src="http://i66.tinypic.com/xds135.png" class="myBox">
<select id="picDD" onchange="change_image();">
<option value="1" selected="">Stock #1</option>
<option value="2">Stock #2</option>
<option value="3">Stock #3</option>
</select>
</div></div>
<div class="floatLeft">
<img id="pic2" src="http://i65.tinypic.com/2wmqefs.png" class="myBox">
<select id="picDD2" onchange="change_image2();">
<option value="1" selected="">Body #1</option>
<option value="2">Body #2</option>
<option value="3">Body #3</option>
</select>
</div>
<div class="floatLeft">
<img id="pic3" src="http://i64.tinypic.com/vxnpzd.png" class="myBox">
<select id="picDD3" onchange="change_image3();">
<option value="1" selected="">Barrel #1</option>
<option value="2">Barrel #2</option>
<option value="3">Barrel #3</option>
</select>
</div>
<div class="textlines">
<input type="text" placeholder="<Name>" id="name">
<p>Barrel <input type="text" id="barrel" name="id" ></p>
<p>Body <input type="text" id="body" name="username" ></p>
<p>Stock <input type="text" id="stock" name="full_name" ></p>
<font size="10">BuildIt-AR</font>
<button onclick="sendMail(); return false">Send</button>
</body></html>
I think it's best to create a custom shortcode for this. Something like [buildit], this code then get's replaced by your app code.
You could use a free plugin like Snippy to do this. Full disclosure, I'm the author of the plugin.
Snippy lets you can create your own shortcodes and pick names for them. Then you can add pieces of HTML, CSS, and JavaScript to the shortcode (in Snippy these are named "bits"). You then place the shortcode on a page or post, and Snippy will output your HTML instead. A lot easier than learning the WordPress API or modify PHP files.
In your situation, I would advise to copy all the HTML inside the <body> tag and add it to an HTML "bit". You can move the font embed <link> in there as well. Snippy will take it from there.
Create a new page http://your-site.com/wp-admin/post-new.php?post_type=page then create a new page template in your theme folder
wp-content/your-theme/page-{slug}.php
and in that file add your app. If you like you can even create custom header and footer files too.
wp-content/your-theme/header-app.php
wp-content/your-theme/footer-app.php
Then in your page-{slug}.php file just add
<?php get_header('app'); ?>
<!-- your content -->
<?php get_footer('app'); ?>
I have two methods for changing a bpm, both work basically the same way, they just take in input two separate ways. One of the function works, and the other one semi-works.
If you select method 1, and then chose 3 beats, it will switch immediately back to 4 beats. However, if you use method 2 and select 3 beats, it will stay on 3 beats.
If someone could explain this behavior, that'd be awesome!
/*
** Augie Luebbers & Toni Rigolosi
** Group 15
*/
//Take the button in our html and store it as a variable.
var runButton = document.getElementById('run-button');
//Create an event listener for the aforementioned button.
runButton.addEventListener('click', doWork, false);
/*
** For some reason when we created this second event
** beacuse without it, it was returning null value
** because it executed before the DOM fully loaded.
** More info: http://goo.gl/uUROPz , http://goo.gl/0Z1HdJ <-- Stack Overflow links
*/
window.onload=function()
{
/*
** After investing about 4 hours into the extra credit we realised
** that the method used to change between beats 3 and 4 was specific
** originally we had used a method of finding the value of an input field with the type number
** as we had so much time devoted, we didn't want to straight out remove it
** so we incorporated both and a method of switching between them
*/
var changeMethodButton = document.getElementById('changemethod-button');
changeMethodButton.addEventListener('click', changeBeatMenu, false);
};
function changeBeatMenu ()
{
//Clear the selection methods
document.getElementById('selectionMain').setAttribute("class", "hidden");
document.getElementById('changebeat-button1').setAttribute("class", "hidden");
document.getElementById('beats').setAttribute("class", "hidden");
document.getElementById('changebeat-button2').setAttribute("class", "hidden");
//make a variable with the value of the first radio button.
//We only need one because there are only two options and we are using an 'if else statement'
var radio = document.getElementById("beat-method-1").checked;
if (radio)
{
//Set the selection method to visible
document.getElementById('selectionMain').setAttribute("class", "visible");
document.getElementById('changebeat-button1').setAttribute("class", "visible");
//create an event for the new button for the selection method
var changeBeatButton1 = document.getElementById('changebeat-button1');
changeBeatButton1.addEventListener('click', changeBeat1, false);
} else {
//set the number method to visible
document.getElementById('beats').setAttribute("class", "visible");
document.getElementById('changebeat-button2').setAttribute("class", "visible");
//create an event for the new button for the number method
var changeBeatButton2 = document.getElementById('changebeat-button2');
changeBeatButton2.addEventListener('click', changeBeat2, false);
}
}
function changeBeat1 ()
{
//creates an object holding the selection input field
var dropDown = document.getElementById("selectionMain");
//creates a variable with the selected item in the field
var dropDownValue = dropDown.options[dropDown.selectedIndex].value;
//as we are changing between 3 and 4, we test to see if it equal 3
if (dropDownValue == 3)
{
//if it does, make the fourth element hidden
document.getElementById('beat-4').setAttribute("class", "hidden");
} else {
//but if it's not 3, it's 4 so...
//we put the fourth element back to it's default state which also happens to be visible
document.getElementById('beat-4').setAttribute("class", "beat inactive");
}
}
//Does the same thing as the above function..
//but it uses a number input field instead of a selection input field
function changeBeat2 ()
{
var beats = document.getElementById('beats');
beatsInteger = beats.value;
if (beatsInteger == 3)
{
document.getElementById('beat-4').setAttribute("class", "hidden");
} else {
document.getElementById('beat-4').setAttribute("class", "beat inactive");
}
}
//Create a timer based on input
function doWork ()
{
var timer = calcMs();
setInterval(function(){ oscillate(); }, timer);
}
//Calculate beats per millisecond
function calcMs ()
{
var bpm = document.getElementById('bpm');
var Ms = (60000/bpm.value);
return Ms;
}
//Oscillate the divs between 1 and 4.
var buffer = 0;
var beatsInteger = 4;
function oscillate ()
{
var i;
for (i = 1; i <= beatsInteger; i++)
{
document.getElementById('beat-' + i).setAttribute("class", "beat inactive");
}
var myBeat = buffer % beatsInteger + 1;
document.getElementById('beat-' + myBeat).setAttribute("class", "beat active");
buffer++;
}
/*
** Augie Luebbers & Toni Rigolosi
** Group 15
*/
#header {
margin-bottom: 20px;
}
.beat {
width: 100px;
height: 50px;
margin-bottom: 20px;
padding: 10px;
text-align: center;
}
.inactive {
background-color: #d3d3d3;
border: 1px solid #000000;
}
.active {
background-color: #FFD1DC;;
border : 3px solid #FF0000;
}
.hidden {
visibility: hidden;
display: none;
}
.visible {
visibility: visible;
display: inline;
}
<!--
--
-- Augie Luebbers & Toni Rigolosi
-- Group 15
--
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Lab 3: Metronome</title>
<meta name="description" content="Project 3">
<link rel="stylesheet" href="css/metro.css">
</head>
<body>
<section id="header">
<h3>Metronome</h3>
<label for="bpm">BPM</label>
<input type="text" name="bpm" id="bpm" placeholder="enter bpm"/>
<button name="run-button" id="run-button">Start</button>
<br>
<label for="selection">SELECTION</label>
<input type="radio" name="beat-method" value="method-1" id="beat-method-1"> Method 1
<input type="radio" name="beat-method" value="method-2" id="beat-method-2"> Method 2
<button name="changemethod-button" id="changemethod-button">Submit</button>
<br>
<select id="selectionMain" class="hidden">
<option value="3">3</option>
<option value="4">4</option>
</select>
<button name="changebeat-button1" id="changebeat-button1" class="hidden">Change Beat</button>
<!-- or -->
<label for="beats" class="hidden">BEATS</label>
<input type="number" name="beat" id="beats" min="3" max="4" step="1" value="4" class="hidden">
<button name="changebeat-button2" id="changebeat-button2" class="hidden">Change Beat</button>
</section>
<div id="beat-1" class="beat inactive">One</div>
<div id="beat-2" class="beat inactive">Two</div>
<div id="beat-3" class="beat inactive">Three</div>
<div id="beat-4" class="beat inactive">Four</div>
<script src="js/app.js"></script>
</body>
</html>
I have an html page in which I have a textbox (Type your text) and TextArea list. I need to type into the textbox and then click Add button so that whatever is there in textbox goes to my TextArea list. I need to type in this below format in the textbox.
Name=Value
This textbox will be used by the user to quickly add Name Value pairs to the list which is just below that textbox. let's say if we type Hello=World in the above textbox and click add, then in the below list, it should show as
Hello=World
And if we again type ABC=PQR in the same textbox, then in the below list, it should show like this so that means it should keep adding new Name Value pair just below its original entry.
Hello=World
ABC=PQR
But if the syntax is incorrect like if it is not in Name=Value pair then it should not add anything to the list and instead show a pop up that wrong input format. Names and Values can contain only alpha-numeric characters. I also have three more buttons Sort by name, Sort by value and Delete button. Once I click either of these buttons, then it should sort entries in TextArea list using either name or value and delete entries as well. Now I have all above things working fine without any issues.
Here is my jsfiddle. I need to use plain HTML, CSS and Javascript, I don't want to use any library yet as I want to keep it simple as I am still learning. Now I am trying to see whether we can make UI more responsive like the UI should adjust based on what screen size is viewing it. For example, if viewed on a mobile phone (i.e. Android or iPhone), the page should automatically adjust to present the layout in a better way. This also applies to re-sizing the browser on desktop, and viewing the page on a tablet.
What are the changes I need to make in my CSS or HTML to make it more responsive? Any improvements I can make here? Since my UI is very simple so there should be some easy way or some improvements I can make here.
Below is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<style type="text/css">
.main{
background:white;
padding: 35px;
border-radius: 5px;
}
#my-text-box {
font-size: 18px;
height: 1.5em;
width: 585px;
}
#list{
width:585px;
height:300px;
font-size: 18px;
}
.form-section{
overflow:hidden;
width:700px;
}
.fleft{float:left}
.fright{float:left; padding-left:15px;}
.fright button{display:block; margin-bottom:10px;}
html, body {
height: 100%;
font-family: "Calibri";
font-size: 20px;
}
html {
display: table;
margin: auto;
}
body {
display: table-cell;
vertical-align: middle;
background-color: #5C87B2;
}
</style>
<script language="javascript" type="text/javascript">
document.getElementById('add').onclick = addtext;
function addtext() {
var nameValue = document.getElementById('my-text-box').value;
if (/^([a-zA-Z0-9]+=[a-zA-Z0-9]+)$/.test(nameValue)){
var x = document.getElementById("list");
var option = document.createElement("option");
option.text = nameValue;
x.add(option);
}
else
alert('Incorrect Name Value pair format.');
}
document.getElementById('btnDelete').onclick = deleteText;
function deleteText(){
var myList = document.getElementById('list');
var i;
for (i = myList.length - 1; i>=0; i--) {
if (myList.options[i].selected) {
myList.remove(i);
}
}
}
document.getElementById('sortByValue').onclick = sortByValue;
function sortByValue(){
var myList = document.getElementById('list');
var values = new Array();
for (var i=0;i<myList.options.length;i++) {
values[i] = myList.options[i].text;
}
values.sort(function(a, b){
if(a != "" && b != ""){
return a.split('=')[1].localeCompare(b.split('=')[1])
} else {
return 0
}
});
clearList(myList);
fillList(myList, values);
}
document.getElementById('sortByName').onclick = sortByName;
function sortByName(){
var myList = document.getElementById('list');
var values = new Array();
for (var i=0;i<myList.options.length;i++) {
values[i] = myList.options[i].text;
}
values.sort(function (a, b){
if(a != "" && b != ""){
return a.split('=')[0].localeCompare(b.split('=')[0])
} else {
return 0
}
});
clearList(myList);
fillList(myList, values);
}
function clearList(list) {
while (list.options.length > 0) {
list.options[0] = null;
}
}
function fillList(myList, values){
for (var i=0;i<values.length;i++) {
var option = document.createElement("option");
option.text = values[i];
myList.options[i] = option;
}
}
</script>
</head>
<body>
<div class = 'main'>
<h3>Test</h3>
<label for="pair">Type your text</label></br>
<div class="form-section">
<div class="fleft">
<input type='text' id='my-text-box' value="Name=Value" />
</div>
<div class="fright">
<button type="button" id='add' onclick='addtext()'>Add</button>
</div>
</div>
<label for="pairs">Name/Value Pair List</label></br>
<div class="form-section">
<div class="fleft">
<select id="list" multiple></select>
</div>
<div class="fright">
<button type="button" id='sortByName' onclick='sortByName()'>Sort by name</button>
<button type="button" id='sortByValue' onclick='sortByValue()'>Sort by value</button>
<button type="button" id='btnDelete' onclick='deleteText()'>Delete</button>
<button type="button">Show XML</button>
</div>
</div>
</div>
</body>
</html>
W3 have a number of resources on responsive web design:
http://www.w3schools.com/html/html_responsive.asp
http://www.w3schools.com/css/css_responsive_intro.asp
Without using PHP to detect the browser/user agent, your responsive design will typically involve ensuring the site is more fluid and flowing, allowing for changing browser widths (as in the first example above) and/or by delivering differing stylesheets depending on the viewport size and media type in CSS (second example).