How to bind a object to update the value using plain js? - javascript

I have a object with name value. Is it possible to bind that value to html element? - like angularjs
if so what is the correct way? or is it not possible?
here is my demo :
var ob = {};
ob.name = "Testing";
$('div').text(ob.name);
$('button').on('click', function(){
ob.name = "Update Name";
console.log( ob.name ) //name updates
})
button{
border:1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h1></h1> <!-- on click nothing updates automatically -->
</div>
<button>Click Here</button>

Javascript allows the creation of object "properties" where reading or writing can execute user-defined code.
What you can do is creating the HTML node and a Javascript object with a property so that when you write to the property the code updates the HTML node:
var d = document.createElement("div");
document.body.appendChild(d);
var obj = {get value() { return d.textContent; },
set value(x) { d.textContent = x; }};
obj.value = "foo"; // Will also update d content
Note that a property that allows writing needs a place where to store the data... in the above I used directly d.textContent so the two are actually synchronized (changing obj.value changes the DOM node and vice versa).

JavaScript itself doesnt support bidirectionalBinding from scratch.
To make your example work simply add the expression, that you have already figured out correct, to your onClickFunction.
var ob = {};
ob.name = "Testing";
$('div').text(ob.name);
$('button').on('click', function(){
ob.name = "Update Name";
$('div').text(ob.name); <!-- add here -->
console.log( ob.name ) //name updates
})
button{
border:1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h1></h1>
</div>
<button>Click Here</button>
Just to clarify! It is possible to implement something that you could
call bidirectionalBinding, but thats not what you want to do using
plain javascript! It would mean implementing eventListeners on your
textValue etc.

Related

Empty and write html to Div

I'm trying to write html but it says empty is not a function. I usually do this. I empty and then write something on the div.
var status = $('#terminalStatusDiv');
status.empty().html('<span class="terminalStatus">Connected</span>')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="terminalStatusDiv"></div>
The reason your code is not working as it is right now is because you used "status" as a variable name and it is a Global Property.
https://developer.mozilla.org/en-US/docs/Web/API/Window/status
var status1 = $('#terminalStatusDiv');
status1.empty().html('<span class="terminalStatus">Connected</span>')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="terminalStatusDiv"></div>
status is built in javascript keyword
var foo = $('#terminalStatusDiv');
foo.empty().html('<span class="terminalStatus">Connected</span>')

How do i make my submit answer continue stacking on top of each other

I am currently doing a school project and i need to stimulate a server side application. What i am substituting it with is "Local Storage" but i have an issue. I am able to have the text in my "Text box" stack on top of each other once user have submitted their question. Once they reload, the data will still be displayed. But i do not know how to stack on top of it AGAIN after they reload. Below is my testing code
<!doctype html>
<html>
<head>
<body onload="display()">
<input type="text" id="Name"></input>
<input type="submit" id="submit" onclick="SavetoStorage()"></input>
<p id ="hoho">
</p>
<script>
var name;
var groupOfName = ["Hello", "Chicken", "Pork","Beef"];
function SavetoStorage() {
var name = document.getElementById("Name").value;
groupOfName[groupOfName.length] = name;
var newone = groupOfName;
document.getElementById("hoho").innerHTML = newone;
localStorage.groupOfName = newone;
}
function display() {
var groupOfName = localStorage.groupOfName;
document.getElementById("hoho").innerHTML = groupOfName;
}
</script>
</head>
</body>
</html>
You need to be dynamically loading the groupOfName variable like so:
var tmp = localStorage.groupOfName; //this is a string
var groupOfName = Array.from(tmp); //turn it into an array
Hopefully this helps to point you in the right direction
You can use the setItem method from localstorage.
It uses 2 parameters:
a key and a value
so you can do something like this:
var inputValue = document.getElementById("Name").value;
localStorage.setItem("name", inputValue);
The above code sets the key "name" and that key holds the inputValue
So now you can retrieve the value by calling another local storage method called getItem:
var retrieveValue = localStorage.getItem("name");
The above code retrieves the item, and what does that item holds? the value from the input, so now you can add it to your html as you wish
So that's the basics but as you only have 1 input the value will be getting overwrited, and LocalStorage doesn't supports arrays but there's a workaround so you can use arrays, it goes something like this:
//this first part converts your array to string
localStorage.setItem("names", JSON.stringify(names));
//The second part returns your item and coverts it to an array again
var storedNames = JSON.parse(localStorage.getItem("names"));

button click, adds some text and number to a div. Doesn't work

I really need some help to create this order list. It's the mening that, when you click on the button it adds the text inside the addToList, to the div, so it shows up on the page. It should add the data (name, price), in javascript.
But can't get it to work properly.
<html>
<body>
<div id="myList">
</div>
<button onclick="addToList('donut', '25,-')">add</button>
</body>
</html>
<style>
#myList {
border: 1px solid black;
margin-bottom: 10px;
}
</style>
<script>
function displayListCart() {
var myList = document.getElementById("myList");
};
function addToList(name,price) {
var itemOrder = {};
//itemOrder with data
itemOrder.Name=name;
itemOrder.Price=price;
//Add newly created product to our shopping cart
listCart.push(itemOrder);
displayListCart();
}
</script>
Here is a Fiddle Demo.
I'm not a fan of inline calls to JavaScript functions because it violates separation of concerns, so I've changed the way the event is bound. This isn't part of your problem, but I'm using this approach:
HTML:
<div id="myList">
</div>
<button id="btn" data-name="donut" data-price="25,-">add</button>
Note:
I've added the values as data attributes on the button. You can then
access them from JavaScript.
JavaScript:
function displayListCart(listCart) {
var myList = document.getElementById("myList");
for (i = 0; i < listCart.length; i++) {
myList.innerHTML = myList.innerHTML + listCart[i].Name + " : " + listCart[i].Price;
}
};
function addToList(name, price) {
var itemOrder = {};
//itemOrder with data
itemOrder.Name = name;
//debugging -- check to make sure this returns what you expect
console.log(itemOrder.Name);
itemOrder.Price = price;
//debugging -- check to make sure this returns what you expect
console.log(itemOrder.Price);
//Add newly created product to our shopping cart
//declare listCart before you use it
var listCart = [];
listCart.push(itemOrder);
//pass listCart to the display function
displayListCart(listCart);
}
function getValues() {
addToList(myBtn.getAttribute('data-name'), myBtn.getAttribute('data-price'));
}
var myBtn = document.getElementById("btn");
myBtn.addEventListener("click", getValues, false);
Notes:
You need to declare listCart before you add objects to it.
I suspect you intended to pass listCart to the display function so that you can access the objects within it for display.
You were missing the logic that adds the values to the div. You need to iterate over the array and access the object properties.
First of all, if you open the Dev Tools, you will see an error - Uncaught ReferenceError: listCart is not defined. So the first thing you need to do is create listCart array, like this : var listCart = [];
Then you should modify your displayListCart function, to display a new div for every item in listCart, like this:
function displayListCart() {
var myList = document.getElementById("myList"),
myListContent = "";
listCart.forEach(function(cart) {
myListContent += "<div>" + cart.Name + ": " + cart.Price + "<div>";
});
myList.innerHTML = myListContent;
};
The code example

A HTML tag to store "javascript's data"?

I need to write some html with placeholder used for javascript.
ex:
<span><placeholder data-id="42" data-value="abc"/><span>
Later on, a script will access those placeholders and put content in (next to?) them.
<span><placeholder data-id="42" data-value="abc"><div class="Google"><input type="text" value="abc"/></div><span>
But the placeholder tag doesn't exist. What tag can be used? Using < input type="hidden" .../> all over feels wrong.
Creating Custom tag
var xFoo = document.createElement('placeholder');
xFoo.innerHTML = "TEST";
document.body.appendChild(xFoo);
Output:
<placeholder>TEST</placeholder>
DEMO
Note: However creating hidden input fields with unique ID is good practice.
give your span element an id like,
<span id="placeToAddItem"><span>
and then in jQuery,
$('#placeToAddItem').html('<div class="Google"><input type="text" value="abc"/></div>');
or else
var cloneDiv = $('.Google');
$('#placeToAddItem').html(cloneDiv);
Example
The best way to do this, is using <input type='hidden' id="someId" value=""> tags.
Then you can easily access them by using jQuery, and recall the variable or change it.
var value = $("#someId").val(); to get variable or $("#someId").val(value) to change it.
This complete, no jQuery solution allows you to specify the placeholder/replacement html as a string within the element that will be replaced.
EG HTML:
<div data-placeholder="<div class='Google'><input type='text' value='abc'/></div>"></div>
<div data-placeholder="<div class='Boogle'><input type='text' value='def'/></div>"></div>
<div data-placeholder="<div class='Ooogle'><label>with label <input type='text' value='ghi'/></label></div>"></div>
<span data-placeholder="<em>Post JS</em>">Pre JS</span>
<br />
<button id="test">click me</button>
JS:
Use querySelectorAll to select all elements with the attribute 'data-placeholder' (returns a NodeList)
var placeholders = document.querySelectorAll('[data-placeholder]'); //or by ids, classnames, element type etc
Extend the NodeList prototype with a simple 'each' method that allows us to iterate over the list.
NodeList.prototype.each = function(func) {
for (var i = 0; i < this.length; i++) {
func(this[i]);
}
return this;//return self to maintain chainability
};
Extend the Object prototype with a 'replaceWith' method that replaces the element with a new one created from a html string:
Object.prototype.replaceWith = function(htmlString) {
var temp = document.createElement('div');//create a temporary element
temp.innerHTML = htmlString;//set its innerHTML to htmlString
var newChild = temp.childNodes[0];//(or temp.firstChild) get the inner nodes
this.parentNode.replaceChild(newChild, this);//replace old node with new
return this;//return self to maintain chainability
};
Put it all together:
placeholders.each(function(self){
self.replaceWith(self.dataset.placeholder);//the 'data-placeholder' string
});
Another example but here we only replace one specific element with some hard-coded html on click:
document.getElementById("test").addEventListener('click', function() {
this.replaceWith("<strong>i was a button before</strong>");
}, false);
DEMO: http://jsfiddle.net/sjbnn68e/
use the code below :
var x = document.createElement('placeholder');
x.innerHTML = "example";
document.body.appendChild(x);

Replacing DIV content based on variable sent from another HTML file

I'm trying to get this JavaScript working:
I have an HTML email which links to this page which contains a variable in the link (index.html?content=email1). The JavaScript should replace the DIV content depending on what the variable for 'content' is.
<!-- ORIGINAL DIV -->
<div id="Email">
</div>
<!-- DIV replacement function -->
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
<!-- Email 1 Content -->
<script ="text/javascript">
var content = '<div class="test">Email 1 content</div>';
ReplaceContentInContainer('Email1',content);
}
</script>
<!-- Email 2 Content -->
<script ="text/javascript">
var content = '<div class="test">Email 2 content</div>';
ReplaceContentInContainer('Email2',content);
}
</script>
Any ideas what I've done wrong that is causing it not to work?
Rather than inserting the element as text into innerHTML create a DOM element, and append it manually like so:
var obj = document.createElement("div");
obj.innerText = "Email 2 content";
obj.className = "test"
document.getElementById("email").appendChild(obj);
See this working here: http://jsfiddle.net/BE8Xa/1/
EDIT
Interesting reading to help you decide if you want to use innerHTML or appendChild:
"innerHTML += ..." vs "appendChild(txtNode)"
The ReplaceContentInContainer calls specify ID's which are not present, the only ID is Email and also, how are the two scripts called, if they are in the same apge like in the example the second (with a corrected ID) would always overwrite the first and also you declare the content variable twice which is not permitted, multiple script blocks in a page share the same global namespace so any global variables has to be named uniquely.
David's on the money as to why your DOM script isn't working: there's only an 'Email' id out there, but you're referencing 'Email1' and 'Email2'.
As for grabbing the content parameter from the query string:
var content = (location.search.split(/&*content=/)[1] || '').split(/&/)[0];
I noticed you are putting a closing "}" after you call "ReplaceContentInContainer". I don't know if that is your complete problem but it would definitely cause the javascript not to parse correctly. Remove the closing "}".
With the closing "}", you are closing a block of code you never opened.
First of all, parse the query string data to find the desired content to show. To achieve this, add this function to your page:
<script type="text/javascript">
function ParseQueryString() {
var result = new Array();
var strQS = window.location.href;
var index = strQS.indexOf("?");
if (index > 0) {
var temp = strQS.split("?");
var arrData = temp[1].split("&");
for (var i = 0; i < arrData.length; i++) {
temp = arrData[i].split("=");
var key = temp[0];
var value = temp.length > 0 ? temp[1] : "";
result[key] = value;
}
}
return result;
}
</script>
Second step, have all possible DIV elements in the page, initially hidden using display: none; CSS, like this:
<div id="Email1" style="display: none;">Email 1 Content</div>
<div id="Email2" style="display: none;">Email 2 Content</div>
...
Third and final step, in the page load (after all DIV elements are loaded including the placeholder) read the query string, and if content is given, put the contents of the desired DIV into the "main" div.. here is the required code:
window.onload = function WindowLoad() {
var QS = ParseQueryString();
var contentId = QS["content"];
if (contentId) {
var source = document.getElementById(contentId);
if (source) {
var target = document.getElementById("Email");
target.innerHTML = source.innerHTML;
}
}
}
How about this? Hacky but works...
<!-- ORIGINAL DIV -->
<div id="Email"></div>
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
var txt = document.createTextNode(content);
container.appendChild(txt);
}
window.onload = function() {
var args = document.location.search.substr(1, document.location.search.length).split('&');
var key_value = args[0].split('=');
ReplaceContentInContainer('Email', key_value[1]);
}
</script>

Categories