Javascript constructor property not working when called - javascript

I'm having trouble creating a constructor property. In the firebug console the error says "telekomApp.validation.run is not a function". The this.run() function should be a property of TelekomApp constructor and I expect it too work as telekomApp.validation.run(), but it's not.
Please can you shed some light on this?
Many Thanks
JS:
(function(global) {
var TelekomApp = function() {
this.validation = function() {
var userNameField = document.getElementById("username-field"),
passwordField = document.getElementById("password-field"),
usernameMsg = document.getElementById("username-msg"),
passwordMsg = document.getElementById("password-msg");
this.run = function(tag) { // this method doesn't work...
var o = this;
};
};
};
// make global
global.TelekomApp = TelekomApp;
// instanciate
var telekomApp = new TelekomApp;
// initialise validation...
telekomApp.validation.run(document.getElementById("login-form"));
}(window));
HTML:
<div id="login">
<p id="message"></p>
<form id="login-form" action="#" method="post">
<fieldset>
<legend>Please login using your username and password</legend>
<ol>
<li>
<label for="username-field">Username <span>*</span></label>
<input type="text" id="username-field" placeholder="Type your username" />
<span id="username-msg"></span>
</li>
<li>
<label for="password-field">Password <span>*</span></label>
<input type="password" id="password-field" placeholder="Type your password" />
<span id="password-msg"></span>
</li>
<li id="button">
<input type="submit" id="login-btn" value="Log In" />
</li>
</ol>
</fieldset>
</form>
</div>

(function(global) {
var Validation = function() { //constructor for Validation
var userNameField = document.getElementById("username-field"),
passwordField = document.getElementById("password-field"),
usernameMsg = document.getElementById("username-msg"),
passwordMsg = document.getElementById("password-msg");
this.run = function(tag) { // this method doesn't work...
var o = this;
};
};
var TelekomApp = function() {
this.validation = new Validation();
};
// make global
global.TelekomApp = TelekomApp;
// instanciate
var telekomApp = new TelekomApp;
// initialise validation...
telekomApp.validation.run(document.getElementById("login-form"));
}(window));

telekomApp.validation.run would be added to the object when telekomApp.validation is called.
this.validation = function() { adds the function to the object but does not call it. Moreover this.run = function(tag) { adds run directly to telekomApp, not to telekomApp.validation.
A small change would do:
var Validation = function() {
...// your code here
}
this.validation = new Validation();

Related

knockoutjs using module pattern not working

I am trying to create simple knockout example using module pattern
var login = {}; //login namespace
//Constructor
login.UserData = function () {
var self = this;
self.UserName = ko.observable("");
self.Password = ko.observable("");
};
//View-Model
login.UserVM = function () {
this.userdata = new login.UserData(),
this.apiUrl = 'http://localhost:9090/',
this.authenticate = function () {
var data = JSON.parse(ko.toJSON(this.userdata));
var service = apiUrl + '/api/Cryptography/Encrypt';
DBconnection.fetchdata('POST', service, JSON.stringify(data.Password), response, function () { console.log('Cannot fetch data') }, null, true);
function response(res) {
console.log(res)
}
}
return {
authenticate: this.authenticate
}
}();
$(function () {
ko.applyBindings(login.UserVM); /* Apply the Knockout Bindings */
});
HTML CODE:
<form id="loginform" name="loginForm" method="POST">
<div id="form-root">
<div>
<label class="form-label">User Name:</label>
<input type="text" id="txtFirstName" name="txtFirstName" data-bind="value:login.UserData.UserName" />
</div>
<div>
<label class="form-label">Password:</label>
<input type="text" id="txtLastName" name="txtLastName" data-bind="value:login.UserData.Password" />
</div>
<div>
<input type="button" id="btnSubmit" value="Submit" data-bind="click: authenticate" />
</div>
</div>
</form>
the problem is am not able to get userdata in the viewmodel on click of submit it is returning undefined and the login object holds the changed value of textbox but on click it is returning black values.
please let me know
Also can you let me know how to implement definative module pattern in the same code.
The object you are returning from login.UserVM has only authenticate property and doesn't have userdata or apiUrl properties. So, instead using an IIFE to create an object, set login.UserVM to a constructor function similar to login.UserData. And then use new operator to create the viewModel object. Now the viewModel will have userdata and apiUrl properties (remove the return from the function)
Also, you need to change the HTML bindings to: data-bind="value:userdata.UserName". This looks for the userdata property inside the bound viewModel
var login = {}; //login namespace
//Constructor
login.UserData = function () {
var self = this;
self.UserName = ko.observable("");
self.Password = ko.observable("");
};
//View-Model
login.UserVM = function () {
this.userdata = new login.UserData(),
this.apiUrl = 'http://localhost:9090/',
this.authenticate = function () {
var data = JSON.parse(ko.toJSON(this.userdata));
console.log(data)
//var service = this.apiUrl + '/api/Cryptography/Encrypt';
//DBconnection.fetchdata('POST', service, JSON.stringify(data.Password), response, function () { console.log('Cannot fetch data') }, null, true);
function response(res) {
console.log(res)
}
}
}; // remove the () from here
ko.applyBindings(new login.UserVM()); /* Apply the Knockout Bindings */
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<form id="loginform" name="loginForm" method="POST">
<div id="form-root">
<div>
<label class="form-label">User Name:</label>
<input type="text" id="txtFirstName" name="txtFirstName" data-bind="value:userdata.UserName" />
</div>
<div>
<label class="form-label">Password:</label>
<input type="text" id="txtLastName" name="txtLastName" data-bind="value:userdata.Password" />
</div>
<div>
<input type="button" id="btnSubmit" value="Submit" data-bind="click: authenticate" />
</div>
</div>
</form>

Simplifying code using localStorage

I wanted to find out whether it was possible to use a loop to simplify all this rather than hard-coding the entire structure. For the second part of my Javascript where I tried to store the user inputs into localStorage using a for loop, I'm getting an error where it says
CreateEvent.js:72 Uncaught TypeError: name.push is not a function at createReplace (CreateEvent.js:72) at HTMLButtonElement.onclick (CreateEvent.html:130)
HTML:
<span class="border1">
<input class="forms" type="text" id="title" placeholder="Enter Title!">
<p id="title1"></p>
<input class="forms" type="text" id="brief" placeholder="Enter brief description!">
<p id="brief1"></p>
</span>
<div class="Hovertrees">
<p>Hover over me!</p>
<span class="Hovertrees2">
<input class="hover" type="text" id="hover" placeholder="Enter some fun facts!">
<p id="hover1"></p>
</span>
</div>
<div id="what">
<input class="forms" type="text" id="whattitle" placeholder="What is this event?">
<h2 id="whattitle1"></h2>
<input class="forms" type="text" id="whatdesc" placeholder="Enter brief description!">
<p id="whatdesc1"></p>
</div>
<div id="why">
<input class="forms" type="text" id="whytitle" placeholder="Why is this event important?">
<h2 id="whytitle1"></h2>
<input class="forms" type="text" id="whydesc" placeholder="Description of this event">
<p id="whydesc1"></p>
</div>
<div id="fun">
<input class="forms" type="text" id="funtitle" placeholder="Anything interesting you can add!">
<h3 id="funtitle1"></h3>
<input class="forms" type="text" id="fundesc" placeholder="Description of the interesting info!">
<p id="fundesc1"></p>
</div>
Javascript:
var title;
var brief;
var hover;
var whatTitle;
var whatDesc;
var whyTitle;
var whyDesc;
var funTitle;
var funDesc;
function createReplace() {
title = document.getElementById('title').value;
document.getElementById('title1').innerHTML = title;
document.getElementById('title').className = 'hidden';
document.getElementById('news').innerHTML = title;
brief = document.getElementById('brief').value;
document.getElementById('brief1').innerHTML = brief;
document.getElementById('brief').className = 'hidden';
hover = document.getElementById('hover').value;
document.getElementById('hover1').innerHTML = hover;
document.getElementById('hover').className = 'hidden';
whatTitle = document.getElementById('whattitle').value;
document.getElementById('whattitle1').innerHTML = whatTitle;
document.getElementById('whattitle').className = 'hidden';
whatDesc = document.getElementById('whatdesc').value;
document.getElementById('whatdesc1').innerHTML = whatDesc;
document.getElementById('whatdesc').className = 'hidden';
whyTitle = document.getElementById('whytitle').value;
document.getElementById('whytitle1').innerHTML = whyTitle;
document.getElementById('whytitle').className = 'hidden';
whyDesc = document.getElementById('whydesc').value;
document.getElementById('whydesc1').innerHTML = whyDesc;
document.getElementById('whydesc').className = 'hidden';
funTitle = document.getElementById('funtitle').value;
document.getElementById('funtitle1').innerHTML = funTitle;
document.getElementById('funtitle').className = 'hidden';
funDesc = document.getElementById('fundesc').value;
document.getElementById('fundesc1').innerHTML = funDesc;
document.getElementById('fundesc').className = 'hidden';
document.getElementById("create").className = "hidden";
var varNames = [
'titles',
'brief',
'hover',
'whatTitle',
'whatDesc',
'whyTitle',
'funtitle',
'fundesc'
]
for (var name in varNames) {
var value = window[name]
var obj = {name : value};
if(localStorage.getItem(name) != null) {
var tmp = JSON.parse(localStorage.getItem(name));
for(var i = 0;i<tmp.length;i++) {
name.push(tmp[i]);
}
}
name.push(obj);
localStorage.setItem(name, JSON.stringify(value));
}
}
For the first part, simplifying is not possible since you have different properties for each elements.
For the second part, you are getting error because push is a method for array object.But name is an string object declared in for loop
for (var name in varNames) {
var value = window[name]
var obj = {name : value};
if(localStorage.getItem(name) != null) {
var tmp = JSON.parse(localStorage.getItem(name));
for(var i = 0;i<tmp.length;i++) {
name.push(tmp[i]);
}
}
name.push(obj);
localStorage.setItem(name, JSON.stringify(value));
}
}
You can set item in loop
localStorage.setItem(1,'name1');
localStorage.setItem(2,'name2');
localStorage.setItem(3,'name2');
1 2 and 3 would be key that you want to set and then get according to these keys.
localStorage.key(index)
By passing index in key method it will return you the value of that key.

JS wont recognize a variable within angular controller object

Im trying to create a simple login verification, however the validation function seizes to function when the validation comparison begins, and the console sais that the variable "userName is not defined" although it clearly is.
Can enyone tell me what am i defining wrong?
the angular controller code:
var app = angular.module("LoginApp", []);
app.controller("LoginController", function ($http) {
this.userName = "";
this.password = "";
this.userNameValid = true;
this.passwordValid = true;
/*submit the form*/
this.submit = function () {
alert("submit");
this.validate();
};
/* make sure user name and password has been inserted*/
this.validate = function () {
alert("validate");
var result = true;
this.userNameValid = true;
this.passwordValid = true;
if (this.userName == "") {
alert("username="+userName);
this.userNameValid = false;
result = false;
}
if (this.password == "") {
this.passwordValid = false;
result = false;
}
alert("validuserNameValid==" + userNameValid + " passwordValid==" + passwordValid);
return result;
};
});
the HTML form:
<body ng-app="LoginApp" ng-controller="LoginController as LoginController">
<form role="form" novalidate name="loginForm" ng-submit="LoginController.submit()">
<div id="loginDetails">
<div class="form-group">
<label for="user"> User Name:</label>
<input type="text" id="user" class="form-control" ng-model="LoginController.userName" required />
<span ng-show="LoginController.userNameValid==false" class="alert-danger">field is requiered</span>
</div>
<div class="form-group">
<label for="password" >Password:</label>
<input type="password" id="password" class="form-control" ng-model="LoginController.password" required />
<span ng-show="LoginController.passwordValid==false" class="alert-danger">field is requiered</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
{{"entered information:" +"\n"+LoginController.userName+" "+ LoginController.password}}
</div>
</div>
</form>
</body>
the log:
Error: userName is not defined
this.validate#http://localhost:39191/login.js:23:13
this.submit#http://localhost:39191/login.js:11:9
anonymous/fn#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js line 231 > Function:2:292
b#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:126:19
Kc[b]</<.compile/</</e#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:274:195
uf/this.$get</m.prototype.$eval#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:145:103
uf/this.$get</m.prototype.$apply#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:145:335
Kc[b]</<.compile/</<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:274:245
Rf#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:37:31
Qf/d#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:36:486
Always use this judiciously. I would recommend you to store the reference of this in variable then use it wherever required.
var app = angular.module("LoginApp", []);
app.controller("LoginController", function ($http) {
//Store the reference of this in a variable
var lc = this;
//Use the stored refrence
lc.userName = "";
/* make sure user name and password has been inserted*/
lc.validate = function () {
if (lc.userName == "") {
alert("username="+userName);
lc.userNameValid = false;
result = false;
}
};
});
inside your alert boxes you have not mentioned this.userName try removing the alert boxes or change them.

Knockout.js enable save only if value change

I have a simple html page with value input and save button.
I want the save will be enabled only if the value is changed (somtimes is initialized and somtimes not.
I've tryied few things without any success
HTML
<input type="text"
placeholder="type here"
data-bind="value: rate,"/>
<button data-bind="click: save">Save</button>
JS
var viewmodel = function () {
this.rate = ko.observable('88').extend(required: true);
};
viewmodel.prototype.save = function () {
alert('save should be possible only if rate is changed);
};
Also on jsfiddle
Should be able to achieve this with a computed observable and the enable binding.
See http://jsfiddle.net/brendonparker/xhLrB/1/
Javascript:
var ctor = function () {
var self = this;
self.originalRate = '88';
self.rate = ko.observable('');
self.canSave = ko.computed(function(){
return self.originalRate == self.rate();
});
};
ctor.prototype.save = function () {
alert('save should be possible only if rate is changed');
};
ko.applyBindings(new ctor());
HTML:
<input type="text" placeholder="type here" data-bind="value: rate, valueUpdate: 'afterkeydown'"/>
<button data-bind="click: save, enable: canSave">Save</button>

JS Constructor Function Can't Find Global Variable

The crux of this problem is that assigning a variable to an html element is not working within a constructor function.
There must be a way around this right?
The most effective way I have found is to create a method within the constructor function that returns the element.
The problematic variable is "box".
I commented out the section at the start where I tried to make box a global variable, but the constructor couldn't find the box variable. That is the weirdest part to me.
Below is my sample code:
window.onload = function()
{
document.getElementById("sub_button").onclick = adder;
document.getElementById("scrap_it").onclick = remover;
}
//var box = document.getElementById("contact_list");
//refers to the select tag containing contact names as options
var Contacts = function()
{
this.box = function (){ return document.getElementById("contact_list");}
this.list = [];
this.contact_info = document.getElementById("contact_info");
this.find = function(personName){
var found = "missing";
for(var i = 0; i < this.list.length; i++)
{
if(this.list[i].personName == personName)
{
found = i;
}
}
return found;
}
this.addPerson = function(personName, phone)
{
if (this.find(personName) == "missing")
{
personName = personName;
contact =
{
personName: personName,
phone: phone
}
this.list.push(contact);
this.update();
}
else
{
alert("Sorry, this contact name is already in use. Please choose another.");
}
}
this.update = function()
{
this.box().innerHTML = "";
for (var i = 0; i <this.list.length; i++)
{
option_element = document.createElement("OPTION");
option_node = document.createTextNode(this.list[i].personName);
option_element.appendChild(option_node);
this.box().appendChild(option_element);
}
}
this.remove = function(name_to_delete)
{
var index_to_remove = name_to_delete;
this.list.splice(index_to_remove, 1);
this.update();
}
this.postInfo = function(contact_to_display)
{
var index_to_display = contact_to_display;
alert(this.list[index_to_display].personName);
alert(this.list[index_to_display].phone);
}
}
var myList = new Contacts();
function adder()
{
myList.addPerson(document.getElementById("contact_name").value, document.getElementById("contact_phone").value);
}
function remover()
{
myList.remove(myList.box().selectedIndex);
}
function showInfo()
{
myList.postInfo(myList.box().selectedIndex);
}
And the HTML:
<html>
<head>
<title>Address Book</title>
<script type="text/javascript" src="beta3.js"></script>
</head>
<body>
<form id="contact_form">
<label for="contact_name">Name: </label>
<input type="text" id="contact_name" /><br />
<label for="contact_phone">Phone: </label>
<input type="text" id="contact_phone" /><br />
<input type="button" name="submit" value="submit" id="sub_button" />
</form>
<br />
<div>
Delete
</div>
<br />
<div>
<select name="contact_list" id="contact_list" size="10" multiple="multiple" style="width: 450px">
</select>
</div>
<div>
<textarea id="contact_info">
</textarea>
</div>
</body>
</html>
try something like this
var box;
window.onload = function()
{
document.getElementById("sub_button").onclick = adder;
document.getElementById("scrap_it").onclick = remover;
//refers to the select tag containing contact names as options
box = document.getElementById("contact_list");
}
Your code is not working because your script is executed before our element is render in dom so your box variable get nothing.

Categories