Javascript "classes" - am i heading the right way? - javascript

In the past couple of years I've returned part time to programming after a 15 year gap. I was C/UNIX. So, I've picked up PHP, Java, C++ ok, but have struggled with Javascript.
Finally I think I've found a way to 'create' classes that can inherit and wondered if anyone would care to comment. Here is an example:
<!doctype html>
<head>
<title>Basic</title>
</head>
<body>
<div id="d1"></div>
<script type="text/javascript">
function Base( options ) {
var that = this;
options = options || {};
Object.keys( options ).forEach( function( item ) {
that[item] = options[item];
});
}
function Creature( options ) {
this.legs = 4;
Base.call( this, options );
console.log("New creature");
}
Creature.prototype.showNumberOfLegs = function() {
console.log( "Number legs " + this.legs );
};
function Mammal( options ) {
this.fur = true;
Creature.call( this, options );
console.log("New mammal");
}
Mammal.prototype = Object.create( Creature.prototype );
Mammal.prototype.showFur = function() {
console.log( "Fur " + this.fur );
};
var c = new Creature();
c.showNumberOfLegs();
var m = new Mammal({ legs: 6, fur: false });
m.showNumberOfLegs();
m.showFur();
</script>
</body>
</html>
Any help appreciated
Mini

Related

"jsonpointer is not defined"

I'm a university student and I'm working with JsPsych on a Jatos server. Doing an excercise I receive an error about my jspointer.
Exactly the error is:
Uncaught ReferenceError: jsonpointer is not defined at jatos.batchSession.get (jatos.js:774:13) at start:33:25
I really don't know how to solve it, cause with this kind of error I cannot retrieve my Batch Session's data to make my experiment work.
I'll show you also there my code to help you understand (it's just the specific exercise code, cause the hole set of excercises is really more vast and complex):
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title> BENVENUTO </title>
<script src="jatos.js"></script>
<script src="https://unpkg.com/jspsych#7.2.3"></script>
<script src="https://unpkg.com/#jspsych/plugin-html-keyboard-response#1.1.1"></script>
<link href="https://unpkg.com/jspsych#7.2.3/css/jspsych.css" rel="stylesheet" type="text/css" />
</head>
<body>
<style>
body {
background-color: white;
}
</style>
</body>
<script>
var jsPsych = initJsPsych ({
override_safe_mode: true,
on_finish: function(){
jatos.startComponentByPos(nextComponentPosition[componentCounter], data, JSON.stringify(data));
}
});
if (jatos.batchSession.get("level_attenzione") <= 1){
var attenzione = jsPsych.randomization.shuffle(jatos.studyInput.attenzione_1).slice(0,3)
};
if (jatos.batchSession.get("level_attenzione") == 2){
var attenzione = jsPsych.randomization.shuffle(jatos.studyInput.attenzione_2).slice(0,3)
};
if (jatos.batchSession.get("level_attenzione") > 2){
var attenzione = jsPsych.randomization.shuffle(jatos.studyInput.attenzione_3).slice(0,3)
};
if (jatos.batchSession.get("level_linguaggio") <= 1){
var linguaggio = jsPsych.randomization.shuffle(jatos.studyInput.linguaggio_1).slice(0,3)
};
if (jatos.batchSession.get("level_linguaggio") == 2){
var linguaggio = jsPsych.randomization.shuffle(jatos.studyInput.linguaggio_2).slice(0,3)
};
if (jatos.batchSession.get("level_linguaggio") > 2){
var linguaggio = jsPsych.randomization.shuffle(jatos.studyInput.linguaggio_3).slice(0,3)
};
if (jatos.batchSession.get("level_memoria_verbale") <= 1){
var memoria_verbale = jsPsych.randomization.shuffle(jatos.studyInput.memoria_verbale_1).slice(0,3)
};
if (jatos.batchSession.get("level_memoria_verbale") == 2){
var memoria_verbale = jsPsych.randomization.shuffle(jatos.studyInput.memoria_verbale_2).slice(0,3)
};
if (jatos.batchSession.get("level_memoria_verbale") > 2){
var memoria_verbale = jsPsych.randomization.shuffle(jatos.studyInput.memoria_verbale_3).slice(0,3)
};
if (jatos.batchSession.get("level_memoria_visiva") <= 1){
var memoria_visiva = jsPsych.randomization.shuffle(jatos.studyInput.memoria_visiva_1).slice(0,3)
};
if (jatos.batchSession.get("level_memoria_visiva") == 2){
var memoria_visiva = jsPsych.randomization.shuffle(jatos.studyInput.memoria_visiva_2).slice(0,3)
};
if (jatos.batchSession.get("level_memoria_visiva") > 2){
var memoria_visiva = jsPsych.randomization.shuffle(jatos.studyInput.memoria_visiva_3).slice(0,3)
};
var componentCounter = 0;
var nextComponentPosition = attenzione.concat(linguaggio).concat(memoria_verbale).concat(memoria_visiva)
nextComponentPosition = jsPsych.randomization.shuffle(nextComponentPosition)
nextComponentPosition.splice(nextComponentPosition.length/2, 0, 2)
nextComponentPosition = nextComponentPosition.concat(3);
var data = {
level_attenzione: BatchSession["level_attenzione"],
level_linguaggio: BatchSession["level_linguaggio"],
level_memoria_verbale: BatchSession["level_memoria_verbale"],
level_memoria_visiva: BatchSession["level_memoria_visiva"],
level_gradimento: BatchSession["level_gradimento"]
};
var empty = [];
sessionStorage.setItem("nextComponentPosition", nextComponentPosition);
sessionStorage.setItem("componentCounter", componentCounter);
sessionStorage.setItem('attenzione', empty);
sessionStorage.setItem('linguaggio', empty);
sessionStorage.setItem('memoria_verbale', empty);
sessionStorage.setItem('memoria_visiva', empty);
var instructions = {
type: jsPsychHtmlKeyboardResponse,
stimulus: '<h2 style="text-align-center"> Prema il tasto INVIO per proseguire </h2>',
choices: ['Enter'],
};
var timeline = [instructions];
jsPsych.run(timeline);
</script>
</html>
I've tryed to access to the JSONfile to understand where is the error about the missing jsonpointer, but what I obtained is just:
* Getter for a field in the batch session data. Takes a name
* and returns the matching value. Works only on the first
* level of the object tree. For all other levels use
* jatos.batchSession.find. Gets the object from the
* locally stored copy of the session and does not call
* the server.
* #param {string} name - name of the field
* #return {object}
*/
jatos.batchSession.get = function (name) {
var obj = jsonpointer.get(batchSessionData, "/" + name);
return cloneJsonObj(obj);
};

Get start and end indices of multiple divs of a sentence in jQuery

I have an input text box which accepts sentences from the user and after accepting it from the user splits it using Regex and makes a div of each tokenized word and appends it into the table.
I want to enable clickable links, based on the div(s) I made in the earlier step, on the press of control key on the keyboard and left mouse click I want to select multiple div(s) like in this screenshot and consequently get the start and end indices of the selected word, and the word selected in that sentence.
Here is the code which I tried:
#{
ViewData["Title"] = "Index";
}
<style>
#editor {
padding: 5px;
border: solid green 1px;
}
</style>
<h2>AnnotationView</h2>
<h2>Enter text to annotate</h2>
<input type="text" id="myInput" />
<button id="btnAddUtterance" class="btn btn-info">Add Utterance</button>
<table id="tblText" class="table table-hover">
<thead>
<tr>
<th>Select</th>
<th>User Utterance</th>
</tr>
</thead>
<tbody></tbody>
</table>
<button id='btnDeleteRow' class='btn btn-danger'>Delete Utterance</button>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
$( function ()
{
$( '#btnAddUtterance' ).click( function ()
{
populateUtterance();
} );
function populateUtterance()
{
debugger;
let userUtterance = $( '#myInput' ).val();
let splittedUtterance = tokenizeUtterance( userUtterance );
let markup = "<tr><td><input type='checkbox' name='record'></td><td name = 'utterance'>" + splittedUtterance + "</td></tr>";
$( "#tblText tbody" ).append( markup );
$( '#myInput' ).val( '' );
}
$( "#myInput" ).keyup( function ( event )
{
if ( event.keyCode === 13 )
{
populateUtterance();
}
} );
function splitCharacters( utterance )
{
return utterance.split( '' );
}
function findSpacesIndex( utterance )
{
let index = 0;
let spacesIndex = [];
while ( ( index = utterance.indexOf( ' ', index + 1 ) ) > 0 )
{
spacesIndex.push( index );
}
return spacesIndex;
}
var lookUpObject = [];
function tokenizeUtterance( utterance )
{
debugger;
let spilittedUserText = utterance.toString().match( /[\w-']+|[^\w\s]+/g );
let div = '';
let wordStart = 0, wordEnd = 0;
let spacesIndex = [];
spacesIndex = findSpacesIndex( utterance );
let splittedUtteranceChars = [];
splittedUtteranceChars = splitCharacters( utterance );
$.each( spilittedUserText, function ( index, item )
{
div += '<div style="display: inline-block;margin:5px;" class="spilittedDiv">' + item + '</div>';
} );
console.log( lookUpObject );
return div;
}
$( document ).on( "click", "#tblText > tbody > tr > td:nth-child(2)", function ()
{
console.log( "Selected" );
} );
// Find and remove selected table rows
$( document ).on( 'click', '#btnDeleteRow', function ( e )
{
$( "#tblText tbody" ).find( 'input[name="record"]' ).each( function ()
{
if ( $( this ).is( ":checked" ) )
{
$( this ).parents( "tr" ).remove();
}
} );
} );
} );
</script>
Here's how it looks now:
An example would be user inputting an sentence like:
HELLO, WORLD which would give me an output of the sort on splitting of div(s).
<div>
<div> HELLO </div>
<div> , <div>
<div> WORLD </div>
</div>
for which I have written a function:
function tokenizeUtterance( utterance )
{
let spilittedUserText = utterance.toString().match( /[\w-']+|[^\w\s]+/g );
let div = '';
let wordStart = 0, wordEnd = 0;
let spacesIndex = [];
spacesIndex = findSpacesIndex( utterance );
let splittedUtteranceChars = [];
splittedUtteranceChars = splitCharacters( utterance );
$.each( spilittedUserText, function ( index, item )
{
div += '<div style="display: inline-block;margin:5px;" class="spilittedDiv">' + item + '</div>';
} );
return div;
}
So, if the user selects the div(s) which range from HELLO to WORLD, I should get an JSON object of the following sort:
{
"start": 0,
"end": 11,
"value": "HELLO, WORLD"
}
If the user selects the word HELLO and , I must get the JSON object like:
{
"start": 0,
"end": 5,
"value": "HELLO,"
}
Any help is appreciated, thank you.
I think HTML data-* Attributes can help you.
You just need to embed the start and end ndice of every word in the relative div in the tokenizeUtterance() function, I mean :
For the word Hello, the div would be like this :
<div style="display:inline-block;margin:5px;"
class="spilittedDiv"
id="divX"
data-start="0"
data-end="4"
data-value="Hello">Hello
</div>
So, to get the start, end and the value, you need to add this to your tokenizeUtterance():
var wordIndex = 0;
$.each( spilittedUserText, function ( index, item ){
divId = "div"+index;
divStart = wordIndex;
divEnd = wordIndex + item.length;
divValue = item;
div += '<div style="display:inline-block;margin:5px;"
class="spilittedDiv"
id="'+divId+'"
data-start="'+divStart+'"
data-end="'+divEnd+'"
data-value="'+divValue+'"
>' + item + '</div>';
wordIndex = wordIndex + item.length;
});
And after that, you can get these data using this :
var start = $("#divX").data("start");
var end = $("#divX").data("end");
var value = $("#divX").data("value");
If the user select the another div, you just set the var end to the second div data-end :
end = $("#div2").data("end");
value = value + $("#div2").data("value");

How can I merge an Array with an object in javascript

I'm having an array of object
var todos= [
{
id: 1,
name: test,
description: test
}
]
How can I insert an object with properties stored in different variable say
var newTodos={id:2,name:test2,description:test2,purpose:NA}
so that the final arrray looks like
var todos=
[
{
id: 1,
name: test,
description: test
},
id: 2,
name: test2,
description: test2,
purpose: NA
]
var todos= [
{
id: 1,
name: test,
description: test
}
]
var newTodos={id:2,name:test2,description:test2,purpose:NA};
todos.push(newTodos);
The answer you accepted is the right answer to the wrong question.
If you really want to add the properties of newTodos (which is misnamed; it is just a single todo) then you can do what the answer says, or more easily, just do
$.extend (todos, newTodos);
_.extend (todos, newTodos);
Object.assign(todos, newTodos);
or use your other favorite property merging utility.
However, I cannot imagine what you are going to usefully do with such a mutant object, which is an array with a single element which is a todo, and now is sort of a todo itself with the todo properties directly on it.
I'm guessing that what you want to do is add another todo to your array of todos, in which case as others have suggested you can just push it.
todos.push(newTodos)
If you actually mean newTodos to be an array of todos, as its name suggests, in other words, if its format is actually
var newTodos = [ {id:2,name:test2,description:test2,purpose:NA}, ... ];
Then to add it to todos you would concatenate:
todos = todos.concat(newTodos);
This is how you do it:
for (var index in newTodos) {
todos[index] = newTodos[index];
}
You can check the values of your array like this:
for (var index in todos) {
console.log(index + ": " + todos[index]);
}
EDIT: In conform with the asked fiddle, I add the fiddle and code:
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo</title>
<script type="text/javascript" src="/js/lib/dummy.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<style type="text/css">
</style>
<script type="text/javascript">//<![CDATA[
var VanillaRunOnDomReady = function() {
var todos= [
{
id: 1,
name: 'test',
description: 'test'
}
];
var newTodos={id:2,name:'test2',description:'test2',purpose:'NA'};
for (var index in newTodos) {
todos[index] = newTodos[index];
}
var output = "";
for (var index in todos) {
if (typeof todos[index] === "object") {
output += index + ": {";
var first = true;
for (var innerIndex in todos[index]) {
if (!first) {
output += ", ";
} else {
first = false;
}
output += innerIndex + ": " + todos[index][innerIndex];
}
output += "}<br>";
} else {
output += index + ": " + todos[index] + "<br>";
}
}
document.getElementById("output").innerHTML = output;
}
var alreadyrunflag = 0;
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", function(){
alreadyrunflag=1;
VanillaRunOnDomReady();
}, false);
else if (document.all && !window.opera) {
document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>');
var contentloadtag = document.getElementById("contentloadtag")
contentloadtag.onreadystatechange=function(){
if (this.readyState=="complete"){
alreadyrunflag=1;
VanillaRunOnDomReady();
}
}
}
window.onload = function(){
setTimeout("if (!alreadyrunflag){VanillaRunOnDomReady}", 0);
}//]]>
</script>
</head>
<body>
<div id="output">a</div>
</body></html>

javascript array to string conversion

I have this array in javascript:
[div.parts, div.editor, div.inside-1, div.container-2, div.inside-wrapper, div#content, div.whitebgpan, div, div#maindiv, body, html]
How can I convert it into string, so that the output will be:
div.parts div.editor div.inside-1 div.container-2 div.inside-wrapper div#content div.whitebgpan div div#maindiv body html
here is my code:
jQuery(document).on('click', function(e){
var ClickedParents = jQuery(e.target).parents(); //Get all parents of clicked element
var ClickedParents_array = jQuery.makeArray(ClickedParents); //Make array
console.log(ClickedParents_array); //Show output in colsole
});
You can use a combination of the jQuery each function and JavaScript's Array.Join function to solve this problem.
DEMO: http://jsfiddle.net/zay015ex/1/
I've artificially retrieved an array of jQuery objects to show how you can solve this, but the concept is common to your problem.
HTML
<div id="parent">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
<div id="child4"></div>
<div id="child5"></div>
</div>
JavaScript
var arrayOfObjects = $('#parent').children();
var ids = [];
$.each(arrayOfObjects, function(i, val)
{
ids.push(val.id);
});
var idString = ids.join(' ');
You can read up more on the jQuery each function here.
You can read up more on the JavaScript's Array.Join function
here.
===== Update =====
Ok, the following code is tested, just open a console and paste this. it selects all div tags and convert into selector string.
$.map($('div'),function toSelector(elem){
var jqObj = $(elem)
var tag = jqObj.prop('tagName').toLowerCase()
var classes = jqObj.attr('class') ? '.' + jqObj.attr('class').split(' ').join('.') : ''
var ids = jqObj.attr('id') ? '#' + jqObj.attr('id').split(' ').join('#'): ''
return tag + classes + ids
})
===================
Supposing they're jquery objects, you have to build the string manually.
For example, do something like following. (not tested)
function toSelector(jqObj){
var tag = jqObj.prop('tagName').toLowerCase()
var classes = jqObj.attr('class') ? '.' + jqObj.attr('class').split(' ').join('.') : ''
var ids = jqObj.attr('id') ? '#' + jqObj.attr('id').split(' ').join('#'): ''
return tag + classes + ids
}
array.map(toSelector)
I think below code is helpful for you.
<script type="text/javascript">
String.prototype.replaceAll = function ( token, newToken, ignoreCase ) {
var _token;
var str = this + "";
var i = -1;
if ( typeof token === "string" ) {
if ( ignoreCase ) {
_token = token.toLowerCase();
while( (
i = str.toLowerCase().indexOf(
token, i >= 0 ? i + newToken.length : 0
) ) !== -1
) {
str = str.substring( 0, i ) +
newToken +
str.substring( i + token.length );
}
} else {
return this.split( token ).join( newToken );
}
}
return str;
};
try{
var arr = [];
arr.push('div.parts', 'div.editor', 'div.inside-1', 'div.container-2', 'div.inside-wrapper', 'div#content', 'div.whitebgpan', 'div', 'div#maindiv', 'body', 'html');
var stringData = arr.toString();
stringData = stringData.replaceAll(",", " ");
console.log(stringData);
}catch(e){
alert(e)
}
</script>

problem in calling object.method.method, Javascript

//////////////////////////////////////////////////////////////////////////////
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
// 3 constructor functions of Person, Book, and Library
function Person(fname,lname)
{
this.firstName = fname;
this.lastName = lname;
}
function Book(booktitle,pages,price)
{
this.bookTitle = booktitle;
this.pages = pages;
this.price = price;
this.authors = new Array(arguments.length-3);
for(i=0;i<arguments.length-3;i++)
{
this.authors[i] = arguments[i+3];
}
}
function Library()
{
this.books = new Array(arguments.length);
for(i=0;i<arguments.length;i++)
{
this.books[i] = arguments[i];
}
this.totalPrice = function(){
var totalCost = 0;
for(i=0;i<this.books.length;i++)
{
totalCost += this.books[i].price;
}
return totalCost;
}
this.averagePrice = new Function("return this.totalPrice()/this.books.length");
var flag;
this.getBook = function(name){
for(i=0;i<this.books.length;i++)
{
if(this.books[i].bookTitle == name )
{
this.flag = i;
}
}
}
this.getAuthors = function(){
var toSay = "";
for(j=0;j<this.books[this.flag].authors.length;j++){
var authName =
this.books[this.flag].authors[j].lastName + " " +
this.books[this.flag].authors[j].firstName + "\t";
if(toSay.indexOf(authName)!=-1)
continue;
toSay+=""+authName;
}
return toSay;
}
}
var john = new Person("Smith", "John");
var jack = new Person("Simpson", "Jack");
var bobby = new Person("Franklin", "Bobby");
var albert = new Person("Camus", "Albert");
var java = new Book("Dummy Java", 1000, 29.95, john, jack);
var php = new Book("Dummy PHP", 300, 19.95, john);
var xml = new Book("Dummy XML", 150, 9.95, bobby, albert);
var js = new Book("Dummy JavaScript", 2000, 49.95, albert);
var lib = new Library(java, php, xml, js);
alert(lib.totalPrice()); // output 109.8
alert(lib.averagePrice()); // output 27.45
lib.getBook("Dummy XML");
alert(lib.getAuthors()); // output John Smith, Jack Simpson
</script>
</head>
<body>
</body>
</html>
/////////////////////////////////////////////////////////////////////
Instead of using the below two statements
lib.getBook("Dummy XML");
alert(lib.getAuthors()); // output John Smith, Jack Simpson
it works fine to produce the above output. but i want to produce the abouve output using nested methods.
i want to use a single statement alert(lib.getBook("Dummy XML").getAuthors()); to produce the same output ( // output John Smith, Jack Simpson)
Please help me on how to call a method in a method.
Thanks
It's called method chaining. Have the functions return this.
this.getBook = function(name){
for(i=0;i<this.books.length;i++) {
if(this.books[i].bookTitle == name ) {
this.flag = i;
}
}
return this;
}
then you can call another method on the return of lib.getBook("Dummy XML")....
You'll need to redefine the getBook() function to return a reference to 'lib' in order for your idea to work.

Categories

Resources