Can you get an attribute default value so you don't have to repeat it in the following example:
<p title="foo" id="p">Hello, world!</p>
<input type="text" id="i">
<script>
var p = document.getElementById('p'),
i = document.getElementById('i');
i.oninput = function () {
p.title = this.value;
if (this.value == 'bar') {
p.title = 'foo';
}
};
</script>
DEMO
For text field elemets there's a property known as defaultValue: element.defaultValue.
Is there something like attribute.defaultValue? In other words, is there something like p.title = p.title.defaultValue for the above example?
Fiddle demo
If you build a nice reusable function like:
function el(id){
var e = document.getElementById(id), a = e.attributes; e.default = {};
for(var k in a)if(typeof a[k]==='object') e.default[a[k].nodeName] = a[k].nodeValue
return e;
}
not only it'll allow you to easily reference a desired element by ID like:
var p = el('p'),
i = el('i');
but also to retrieve at any point any default element attribute like:
p.default.title // "foo"
or in your example:
i.oninput = function () {
p.title = this.value;
if (this.value == 'bar') {
p.title = p.default.title ;
}
};
or shortened like http://jsfiddle.net/jU5Tv/6/ :
i.oninput = function () {
p.title = this.value==="bar" ? p.default.title : this.value;
};
so double pleasure in any way :)
What the function does is: returns a DOM HTMLElement, but at the same time loops any Element's assigned attribute and stores it inside a self-assigned Object called default.
There is not a default value property for input title attributes.
However, so that you're not repeating yourself you can store this in a variable before updating it:
var p = document.getElementById('p'),
i = document.getElementById('i');
var defaultTitle = p.title;
i.oninput = function () {
p.title = (this.value == 'bar') ? defaultTitle : this.value;
};
You could create a data attribute to hold your default title.
<p title="foo" data-default-title="foo" id="p">Hello, world!</p>
<input type="text" id="i">
In the JS:
if (this.value == 'bar') {
p.title = p.dataset.defaultTitle;
}
Related
I'm having a problem getting the form values by passing the two query parameters, id and type, from the url.
Let's assume the URL is:
... page.html?id=14&type=Title
I want the values of these to be shown in the form to then make the change later.
function getQueryVariable () {
var query = window.location.search.substring (1);
var vars = query.split ("&");
for (var i = 0; i <vars.length; i ++) {
var pair = vars [i] .split ("=");
}
}
function onLoad () {
var value = getQueryVariable ();
var id = document.getElementById ('id');
var type = document.getElementById ('type');
id.value = value;
type.value = value;
}
<div class = "container">
<form method ="post" id="save" action="javascript: myFunction()" onload="onLoad()">
<div class = "field">
<label for = "id"> ID: </label>
<input type = "number" id = "id" name = "id" />
</div>
<div class = "field">
<label for = "type"> Fragment Type: </label>
<input type = "text" id = "type" name = "type" />
</div>
<div class = "field">
<button type = "submit" class = "full"> Save changes </button>
</div>
</form>
</div>
As you can see from the code, I call the onLoad() function to load the data into the form.
I don't get any errors; the values of the getQueryVariable() function variables are correct, but I notice that it is not called.
myFunction() is not shown, but this is the function that will serve me later to modify the fields of the form.
Could you kindly help me?
First of all, you need to execute onLoad function,
then you need to create an object to store the values and pass it to another function.
And your loop is really out of the world, I corrected it, please try to understand my code and if you have questions feel free to comment.
Here you go, for query, I changed it to a string that you provided as an exemple, so it would work in snippet.
function getQueryVariable () {
var object = {}
var query = "id=14&type=Hello%20Title";
var vars = query.split ("&");
for (var i = 0; i <vars.length; i ++) {
let splitted = vars[i].split('=')
object[splitted[0]] = decodeURI(splitted[1])
}
return object;
}
function onLoad () {
var pairs = getQueryVariable ();
var id = document.getElementById ('id');
var type = document.getElementById ('type');
id.value = pairs.id;
type.value = pairs.type;
}
onLoad();
<div class = "container">
<form method ="post" id="save" action="javascript: myFunction()" onload="onLoad()">
<div class = "field">
<label for = "id"> ID: </label>
<input type = "number" id = "id" name = "id" />
</div>
<div class = "field">
<label for = "type"> Fragment Type: </label>
<input type = "text" id = "type" name = "type" />
</div>
<div class = "field">
<button type = "submit" class = "full"> Save changes </button>
</div>
</form>
</div>
Your getQueryVariable () function is not returning anything. You can try something like this:
function getQueryVariable () {
var query = window.location.search.substring (1);
var vars = query.split ("&");
var params = {}
for (var i = 0; i <vars.length; i ++) {
var pair = vars [i] .split ("=");
params[pair[0]] = pair[1]
}
return params
}
function onLoad () {
var params = getQueryVariable ();
var id = document.getElementById ('id');
var type = document.getElementById ('type');
id.value = params.id ;
type.value = params.type ;
}
Pretty new to javascript, i want to add and update my list but it doesn't work.
I tried adding following code but it didn't work
Product.prototype.addProduct = function() {
var elol = document.getElementById("lijst");
var nieuwNaam = document.createElement("li");
nieuwNaam.textContent= this.naam;
elol.appendChild(nieuwNaam);
var nieuwPrijs = document.createElement("li");
nieuwPrijs.textContent= this.prijs;
elol.appendChild(nieuwPrijs);
}
Product.prototype.getProducten = function() {
return this.naam + "(€ " + this.prijs +")";
}
This is the document i want wish would work propperly
<!DOCTYPE html>
<html>
<head>
<script src="oefwinkel.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
winkel.addProduct("Potlood", 10);
VulLijst();
var elBtn = document.getElementById("btn");
elBtn.onclick = VoegProductToe;
});
function VulLijst() {
var elol = document.getElementById("lijst");
var producten = winkel.getProducten("</li><li>");
if (producten.length > 0) {
elol.innerHTML = "<li>" + producten + "</li>";
} else {
elol.innerHTML = "";
}
}
function VoegProductToe() {
var naam = document.getElementById("txtNaam").value;
var prijs = document.getElementById("txtPrijs").value;
winkel.addProduct(naam, prijs);
VulLijst();
}
function Product(naam, prijs) {
this.naam = naam;
this.prijs = prijs;
}
</script>
</head>
<body>
<div><label for="txtNaam">Naam:</label>
<input type="text" id="txtNaam" /></div>
<div><label for="txtPrijs">Prijs:</label>
<input type="number" id="txtPrijs" /></div>
<input type="button" id="btn" value="Toevoegen/Updaten" />
<ol id="lijst">
</ol>
</body>
</html>
There is no list output how do i correct this?..
I really can't find the solution, what did i miss.. huh?
You had a few things missing,
The HTML code.
The winkel object was undefined.
The VulLijst function was doing nothing... because addProduct was taking care of this already.
You are relying on the instance fields (this.naam and this.prijs), but what you want to do is pass in method parameters (external variables).
As for updating, you will need to store a list of Products, clear the child elements of lijst, and re-add the items that represent the list.
Note: One thing I am confused about is why you named your class—that represents a list—Product, when it should really be an Inventory that allows you to ADD Product objects.
Code
// Uncaught ReferenceError: winkel is not defined
var winkel = new Product();
function Product(naam, prijs) {
this.naam = naam;
this.prijs = prijs;
}
Product.prototype.addProduct = function(naam, prijs) {
naam = naam || this.naam; // Default or instance field
prijs = prijs || this.prijs; // Default or instance field
console.log(naam, prijs);
var elol = document.getElementById("lijst");
var nieuwNaam = document.createElement("li");
nieuwNaam.textContent = naam;
elol.appendChild(nieuwNaam);
var nieuwPrijs = document.createElement("li");
nieuwPrijs.textContent = prijs;
elol.appendChild(nieuwPrijs);
}
Product.prototype.getProducten = function(naam, prijs) {
naam = naam || this.naam; // Default or instance field
prijs = prijs || this.prijs; // Default or instance field
return naam + " (€ " + prijs + ")";
}
document.addEventListener("DOMContentLoaded", function() {
winkel.addProduct("Potlood", 10); // Why are you adding a product to a product?
var elBtn = document.getElementById("btn");
elBtn.onclick = VoegProductToe;
});
function VoegProductToe() {
var naam = document.getElementById("txtNaam").value;
var prijs = document.getElementById("txtPrijs").value;
winkel.addProduct(naam, prijs);
}
label { font-weight: bold; }
<label>Product</label>
<input id="txtNaam" value="Something" />
<input id="txtPrijs"value="1.99" />
<button id="btn">Add</button>
<br/>
<ul id="lijst"></ul>
Explained
I will openly admit, I'm not 100% sure what you're trying to do, I assume that's due to a language barrier my side though, I'm not sure of the natural language that you use on a daily basis, i.e. some of the variable names seem unclear to me, but that's my problem, not yours! :)
Anyway, I used some guess work to figure out what you're trying to achieve, and I assumed that you're simply trying to have some sort of product list where each product has a name and a price attached to it?
You want to be able to add a product to the list, based on two input fields, then some button to add to/update that product list.
I've broken up the code into a couple of simple functions, with this solution you can add/remove as many functions, classes or whatever you want. In this answer you can clearly see that there's some render function, and some onUpdate function, I just went with these generic names for the sake of simplicity.
If you have any issues with this solution, please provide as much feedback as possible! I hope that it's been of some help one way or another.
// A simple product list.
const ProductList = () => {
const products = [];
let el = null;
// What you wish to return, aka an object...
return {
addProduct: (name, price) => {
products.push({
name: name,
price: price
});
onUpdate();
render(el, products);
},
setRoot: root => {
el = root;
},
// removeFromList, etc...
};
};
// A simple on update function.
const onUpdate = () => {
console.clear();
console.log('Update!');
};
// A 'simple' render function.
const render = (el, products) => {
if (el == null) return;
const template = obj => `<li>${obj.name} €${obj.price}</li>`;
let html = '';
products.forEach(product => html += template(product));
el.innerHTML = html;
};
// A function to dispatch some event(s).
const dispatchEvents = products => {
const btn = document.getElementById("btn");
const price = document.getElementById("price");
const name = document.getElementById("name");
// Just an example.
const isValid = () => {
if (price.value != '' && name.value != '') return true;
return false;
};
// Handle the on click event.
btn.onclick = () => {
if (isValid()) {
products.addProduct(name.value, price.value);
name.value = '';
price.value = '';
}
};
};
// A simple dom ready function.
const ready = () => {
const products = ProductList();
products.setRoot(document.getElementById("productList"));
products.addProduct('Demo', 10);
products.addProduct('Other', 19.99);
dispatchEvents(products);
};
document.addEventListener("DOMContentLoaded", ready);
<div>
<label for="name">name:</label>
<input type="text" id="name" />
</div>
<div>
<label for="price">Prijs:</label>
<input type="number" id="price" />
</div>
<input type="button" id="btn" value="Update" />
<ol id="productList">
</ol>
I have found this very short yet handy two way binding code written in pure JavaScript. The data binding works fine, but what I want is to take the value from the first input and multiply it by a desired number and bind the outcome to the next input. I will appreciate any kind of help.
This is my HTML Code:
<input class="age" type="number">
<input class="age" type="number">
and the JavaScript Code:
var $scope = {};
(function () {
var bindClasses = ["age"];
var attachEvent = function (classNames) {
classNames.forEach(function (className) {
var elements = document.getElementsByClassName(className);
for (var index in elements) {
elements[index].onkeyup = function () {
for (var index in elements) {
elements[index].value = this.value;
}
}
}
Object.defineProperty($scope, className, {
set: function (newValue) {
for (var index in elements) {
elements[index].value = newValue;
}
}
});
});
};
attachEvent(bindClasses);
})();
If the desired results is take first input value, do something with it, put it to second input then why so serious?
(function () {
var bindClasses = ["age"];
var attachEvent = function (classNames) {
classNames.forEach( function( className ) {
var els = document.getElementsByClassName( className ),
from, to;
if ( 2 > els.length ) {
return;
}
from = els[0];
to = els[els.length - 1];
from.addEventListener( 'keyup', function() {
var v = this.value;
// Do whatever you want with that value
// Then assign it to last el
if ( isNaN( v ) ) {
return;
}
v = v / 2;
to.value = v;
});
});
};
attachEvent(bindClasses);
})();
Another simple approach to two-way binding in JS could be something like this:
<!-- index.html -->
<form action="#" onsubmit="vm.onSubmit(event, this)">
<input onchange="vm.username=this.value" type="text" id="Username">
<input type="submit" id="Submit">
</form>
<script src="vm.js"></script>
// vm.js - vanialla JS
let vm = {
_username: "",
get username() {
return this._username;
},
set username(value) {
this._username = value;
},
onSubmit: function (event, element) {
console.log(this.username);
}
}
JS Getters and Setters are quite nice for this - especially when you look at the browser support for this.
I am trying to dynamically create a Javascript Object and add property and value that are inputted from a text field, the user will type example:
person=name
it will create a new object called person with value name
My code: html
<p class="console">
<input type="text" id="caption"/>
</p>
JavaScript
// my object
myObj = {}
$('#caption').keypress(function(e){
if (e.which == 13) {
// get input value
caption = captionEl.val();
var prop = $.trim(caption.substring(3,caption.indexOf("=")));
var val = $.trim(caption.substring(caption.indexOf("=")+1,caption.length));
// set the property ) NOT WORKING
myObj["'"+prop+"'"]= val;
alert(myObj["'"+prop+"'"]);
}
});
could you help me please to fix it?
myObj = {}
$('#caption').keypress(function(e){
if (e.which == 13) {
// get input value
caption = $(this).val();
var prop = $.trim(caption.substring(3,caption.indexOf("=")));
var val = $.trim(caption.substring(caption.indexOf("=")+1,caption.length));
// set the property ) NOT WORKING
myObj[prop]= val;
alert(myObj[prop]);
}
});
Doesnt seem that you have captionEL defined, use
caption = $("#caption").val();
and it should work
Here's a demo of what I'm talking about - http://jsfiddle.net/MatthewKosloski/qLpT9/
I want to execute code if "Foo" has been clicked, and a number has been entered in the input.. and if "send" has been clicked.
<h1>Foo</h1>
<input type="text" id="amount" placeholder="Enter in a number."/>
<button id="send">Send</button>
I'm pretty sure I'm overthinking this, I'd appreciate the help on such a concise question.
try this one: jfiddle link
var send = document.getElementById("send");
var h1 = document.getElementsByTagName("h1");
var foo_clicked = 0;
h1[0].onclick = function(){foo_clicked += 1; };
send.onclick = function(){
if(document.getElementById("amount").value !='' && foo_clicked >0 )
alert ('poor rating');
};
As per your statement & taking some assumptions, try this way:
(This executes function twice - When there is a change of text or a click of the button).
HTML:
<h1 id="">Foo</h1>
<input type="text" id="amount" placeholder="Enter in a number."/>
<button id="sendBtn">send</button>
JS:
document.getElementById("amount").addEventListener("change",poorRatingCalculation);
document.getElementById("sendBtn").addEventListener("click",poorRatingCalculation);
function poorRatingCalculation() {
var rating = document.getElementById("amount").value;
if(rating=="poor") alert("Poor Service");
}
DEMO: http://jsfiddle.net/wTqEv/
A better, self contained example:
http://jsfiddle.net/qLpT9/7/
(function()
{
var clicked = false;
var header = document.getElementById("header");
var amount = document.getElementById("amount");
var send = document.getElementById("send");
header.addEventListener("click", function()
{
clicked = true;
});
send.addEventListener("click", function()
{
if(!clicked)
{
return
}
// Foo has been clicked
var value = amount.value;
console.log(value;)
});
})();
Is this what you were looking for?
http://jsfiddle.net/qLpT9/5/
function poorRatingCalculation(){
if(myInput.value) {
alert(myInput.value);
}
}
var foo = document.getElementById("foo"),
myInput = document.getElementById("amount");
foo.addEventListener("click", poorRatingCalculation, false)