Creating a model clears the screen - javascript

This a code i have made, this is a form that takes Name and Phone Number and has a submit
button and a button to navigate to page named formentries to show the entries. I have created a view and written some HTML stuff and the entries when are input and submit is clicked an alert box shows the input. I need to create a model, collection (and 1 more view) to show all the entries on a different page. But when i create a model
FormView = backbone.Model.extend({
defaults: {
First Name: "Unknown",
Phone Number: "Not Defined
}
});
The form on the index page disappears.
The remaining code is
<html>
<meta charset="utf-8">
<title>BackboneJs Tutorial</title>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-
1.4.2.min.css">
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-
localstorage.js/1.0/backbone.localStorage-min.js" type="text/javascript"></script>
</head>
<body>
<div id="form_container">a</div>
<script type="text/template" id="form_template">
<label class="ui-hidden-accessible"><b>First Name</b></label>
<input type="text" id="input_name" placeholder="First Name"/>
<label class="ui-hidden-accessible"><b>Phone Number</b></label>
<input type = "text" id="input_phonenumber" placeholder="Phone Number" />
<input type="button" id="search_button" value="Search" />
Form Entries
</script>
<script type="text/javascript">
FormView = Backbone.View.extend({
initialize: function(){
this.render();
alert("DOM Ready.!!");
},
render: function(){
// Compile the template using underscore
var template = _.template( $("#form_template").html(), {} );
// Load the compiled HTML into the Backbone "el"
this.$el.html( template );
},
events: {
"click input[type=button]": "doAction"
},
doAction: function( event ){
// Button clicked, you can access the element that was clicked with
event.currentTarget
alert( "Form Inputs are " + $("#input_name").val() +" and " +
$("#input_phonenumber").val() );
}
});
var form_view = new FormView({ el: $("#form_container") });
</script>
</body>
</html>

#mrak is right - change First Name and Phone Number to First_Name" and "Phone_Number"
General Pointer
When some JS weirdly stops other, seemingly unrelated parts of your JS from executing, it points to an error in parsing. The V8 interpreter (in webkit at least) just stops and doesn't execute the rest. If you open up your DevTools the console should direct you to the error.
Word of advice
In this case, just remember all JS Objects are associative arrays, and there are some rules governing the characters in the keys of the array. Please see Valid javascript object property names - there are some differences between Dot Notation . and Bracket Notation []. To play safe, use the old-school rules: Avoid special characters and use underscores for spaces. Makes for better looking code as well!

Related

How to show the output of a function that takes two arguments in brython?

I have this brython script that is supposed to take in two inputs, process them in a python function imported from another python file, and generate one output into a textarea when the inputs are typed in. I can't figure out how to do that as the bind() only allows one.
Here is how the process looks like
The following code only works with one input
<textarea id="input_one"></textarea>
<textarea id="input_two"></textarea>
<textarea id="output"></textarea>
<script type="text/python">
import project
from browser import document
def function(x):
document['output'].text = project.main(x.target.value)
document['input_one'].bind('input', function)
</script>
Assign names to the fields in the document and refer to them in the bound function.
That way you can retrieve their values and pass them along to project.main.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython#3.10.7/brython.min.js">
</script>
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython#3.10.7/brython_stdlib.js">
</script>
</head>
<body onload="brython()">
<script type="text/python">
from browser import document
import project
element_x = document['input_one']
element_y = document['input_two']
element_result = document['output']
def oninput(arg):
x, y = None, None
try:
x = int(element_x.value)
y = int(element_y.value)
except ValueError:
pass
if x and y:
element_result.value = project.main(x, y)
else:
element_result.value = ''
element_x.bind('input', oninput)
element_y.bind('input', oninput)
</script>
<input id="input_one"></input>
<input id="input_two"></input>
<input id="output" disabled></input>
</body>
</html>

How to hide HTML from F12 & inspect element, sers should not be able to edit my disabled fields

Please help me, in my application I will have enabled and disabled fields depending on conditions but when I press f12 I am able to edit disabled fields also so I have implemented a small hack kind of implementation but not sure if it is better approach
Please suggest me any better approach
<%# taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Profile</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
</style>
<script>
function divFunction(user){
event.preventDefault();
$.ajax({
type: 'POST',
url:'publicProfile.action?userNbk='+user,
dataType: 'text',
success: function(data){
var obj = jQuery.parseJSON(data);
document.getElementById("userNameHeader").innerHTML = obj.articleUserName;
document.getElementById("publicEmail").innerHTML = obj.articleUserEmail;
document.getElementById("publicNbk").innerHTML = obj.articleUserNbk;
document.getElementById("publicPid").innerHTML = obj.articleUserPersonId;
document.getElementById("publicGender").innerHTML = obj.articleUserGender;
document.getElementById("publicJob").innerHTML = obj.articleUserOccupation;
document.getElementById("publicAddress").innerHTML = obj.articleUserAddress;
document.getElementById("publicIntrests").innerHTML = obj.articleUserIntrests;
}});
}
</script>
<script type="text/javascript">
function isConsoleOpen() {
alert("hello");
var startTime = new Date();
debugger;
var endTime = new Date();
return endTime - startTime > 10;
}
$(document).ready(function() {
alert("helo");
if(isConsoleOpen()) {
/* alert("You're one sneaky dude, aren't you ?") */
document.getElementById("aaaaaa").innerHTML="You're one sneaky dude, aren't you ?";
}
})
$(document).keydown(function(event){
if(event.keyCode==123){
return false;
}
else if(event.ctrlKey && event.shiftKey && event.keyCode==73){
return false; //Prevent from ctrl+shift+i
}
});
$(document).bind("contextmenu",function(e) {
e.preventDefault();
});
</script>
</head>
<body>
<div id="aaaaaa">
<form>
<input type="text" disabled="disabled">
<input type="text" disabled="disabled">
<input type="text" disabled="disabled">
<input type="text" disabled="disabled">
</form>
</div>
</body>
</html>
To specifically answer your question, there is no way to keep users from editing your disabled fields. It is impossible to keep users from viewing and editing your HTML.
The only thing you can do to truly take care of this issue is to use server-side validation. If there is a field you don't want text passed into, you're just going to have to set up some kind of validation on the server side to not process the data from that field. Unfortunately, that's just a part of web development.
Creating "hacky" solutions is not a good idea. It leads to unmanageable code, and in this case, it does not even solve the issue.
In fact, (and yes this is opinion-based) I would even say it encourages people to mess with your fields, because if I were hunting around in your code and I saw you trying to keep me out, the first thing I'm going to do is try to get around your hacky block. And 100 times out of 100, I'm going to succeed.
Preventing HTML from being seen and/or edited is impossible.

Backbone.js: Run and display api results on keydown event

I am programming with Backbone.js I am trying to run an API request when the user types in a query in the search box. However nothing happens when I type in a query.
Here is my JAVASCRIPT:
$(function(){
var SearchList = Backbone.Collection.extend({
url: "https://api.nutritionix.com/v1_1/search/taco?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c",
initialize: function(){
this.bind("reset", function(model, options){
console.log("Inside event");
console.log(model);
});
},
//** 1. Function "parse" is a Backbone function to parse the response properly
parse:function(response){
//** return the array inside response, when returning the array
//** we left to Backone populate this collection
return response.hits;
}
});
// The main view of the application
var App = Backbone.View.extend({
initialize: function () {
this.model = new SearchList();
this.list = $('#listing');
},
el: 'document',
events: {
"keydown" : "prepCollection"
},
prepCollection: function(){
var name = $('input').val();
var newUrl = "https://api.nutritionix.com/v1_1/search/" + name + "?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c";
this.model.set("url", newUrl);
this.model.fetch({
success: function (response, xhr) {
console.log("Inside success");
console.log(response.toJSON());
},
ERROR: function (errorResponse) {
console.log(errorResponse)
}
});
this.listenTo(this.model, 'sync', this.render);
},
render: function(){
var terms = this.model;
terms.each(function (term) {
this.list.append("<li>" + term.get('field')["brand_name"] + "</li>")
}, this);
}
});
var app = new App();
});
Here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Interactive Food Guide</h1>
<div>
<input type="text" id="searchBox"> <br/><br/>
</div>
<ul id="listing"></ul>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Backbone and Underscore -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<!-- apps functionality -->
<script src="js/app.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
url is a property of the model, not an attribute. Think of attributes as things you might persist to the server.
Change:
this.model.set("url", newUrl);
To:
this.model.url = newUrl;
Note that url can also be a function which returns a string, and that there is a default function already there which works for some more typical REST cases: http://backbonejs.org/#Model-url
Also JS variables and object keys are case-sensitive, so your key should be error nor ERROR.
After running the project I noticed a couple of other things wrong:
el: 'document' - This is the whole document including the head, Backbone works with the body or things within it. Fix this by changing it to el: 'body'
You were trying to access the field attribute - it is actually called fields and you can access it like so term.get('fields').brand_name
Other bonus fixes: Clear the list before appending new results, _.throttle prepCollection so that if letters are typed fast then it will only do 2 searches (one at the beginning and one at the end of the input). Change to _.debounce to only do one search at the end of the input.
Fiddle: http://jsfiddle.net/ferahl/2nLezvmg/1/

How to load different html files in QUnit?

I'm using QUnit for unit testing js and jquery.
My HTML looks like this:
<!DOCTYPE html>
<html>
<head>
<title>QUnit Test Suite</title>
<script src="../lib/jquery.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.16.0.css" type="text/css" media="screen">
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<!--This is where I may have to add startPage.html--->
<script src="../login.js"></script>
<script src="../test/myTests.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
Currently, I'm adding login.js as shown and I'm getting references correctly to objects defined in login.js.
However, functions in login.js contains references to some dom elements defined in startPage.html which is located elsewhere.
So, if I say $('#login-btn'), it is throwing an error. Is there any way to fix this?
Can I
(a) refer to startPage.html to my qunit page given above?
(b) refer to or load startPage.html in the file where I'm running tests (myTests.js):
QUnit.test( "a test", function( assert ) {
assert.equal( 1, "1", "String '1' and number 1 have the same value" );//works
assert.equal( login.abc, "abc", "Abc" );//works with attributes
assert.equal(($("#userid").val()),'', 'Userid field is present');//fails
assert.equal( login.ValidUserId(), true, "ValidUserId" );//fails with functions
});
Does QUnit provide any method to load Html/php files so they'll be defined prior to testing. Like 'fixtures' in jasmine?
EDIT: Please also tell what to do in case I have startPage.php
There are a couple of ways you can do this. The simplest is just to use the built-in QUnit "fixtures" element. In your QUnit HTML file, simply add any HTML you want in the div with the id of qunit-fixture. Any HTML you put in there will be reset to what it was on load before each test (automatically).
<html>
...
<body>
<div id='qunit'></div>
<div id='qunit-fixture'>
<!-- everything in here is reset before each test -->
<form>
<input id='userid' type='text'>
<input id='login-btn' type='submit'>
</form>
</div>
</body>
</html>
Note that the HTML in the fixture doesn't really have to match what you have in production, but obviously you can do that. Really, you should just be adding the minimal necessary HTML so that you can minimize any side effects on your tests.
The second option is to actually pull in the HTML from that login page and delay the start of the QUnit tests until the HTML loading is complete:
<html>
<head>
...
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<script>
// tell QUnit you're not ready to start right away...
QUnit.config.autostart = false;
$.ajax({
url: '/path/to/startPage.html',
dataType: 'html',
success: function(html) {
// find specific elements you want...
var elem = $(html).find(...);
$('#qunit-fixture').append(elem);
QUnit.start(); // ...tell QUnit you're ready to go
}
});
</script>
...
</head>
...
</html>
Another way to do this without using jquery is as follows
QUnit.config.autostart = false;
window.onload = function() {
var xhr = new XMLHttpRequest();
if (xhr) {
xhr.onloadend = function () {
if(xhr.status == 200) {
var txt = xhr.responseText;
var start = txt.indexOf('<body>')+6;
var end = txt.indexOf('</body>');;
var body_text = txt.substring(start, end);
var qunit_fixture_body = document.getElementById('qunit-fixture');
qunit_fixture_body.innerHTML = body_text;
}
QUnit.start();
}
xhr.open("GET", "index.html");
xhr.send();
} else {
QUnit.start(); //If getting the html file from server fails run tests and fail anyway
}
}

How to retrieve an input's value without the browser interpreting html special entities?

Is there a way in JavaScript or MooTools to retrieve the actual text in the value from an input element without the browser interpreting any html special entites? Please see the example included below. My desired outcome is:
<div id="output">
<p>Your text is: <b>[<script>alert('scrubbed');</script>]</b></p>
</div>
Note that it works if I type/copy <script>alert('scrubbed');</script> directly into the text input box, but fails if I insert right after loading the page.
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>scrubtest</title>
</head>
<body id="scrubtest" onload="">
<script type="text/javascript" language="JavaScript" src="/js/mootools-core.js"></script>
<input type="text" name="scrubtext" value="<script>alert('scrubbed');</script>" id="scrubtext"/><br />
<input type="button" value="Insert" onclick="insertText();"/><br />
<input type="button" value="Get via MooTools" onclick="alert($('scrubtext').get('value'));"/><br />
<input type="button" value="Get via JavaScript" onclick="alert(document.getElementById('scrubtext').value);"/><br />
<div id="output">
</div>
<script type="text/javascript" charset="utf-8">
function insertText()
{
var stext = $('scrubtext').get('value');
var result = new Element( 'p', {html: "Your text is: <b>["+stext+"]</b>"} );
result.inject($('output'));
}
</script>
</body>
</html>
{html: "Your text is: <b>["+stext+"]</b>"}
That's your problem: you're taking a plain text string and adding it into HTML markup. Naturally any < characters in the text string will become markup, and you give yourself a potential client-side cross-site-scripting vulnerability.
You can HTML-escape, but there's no built-in function to do it in JS, so you have to define it yourself, eg.:
// HTML-encode a string for use in text content or an attribute value delimited by
// double-quotes
//
function HTMLEncode(s) {
return s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}
...
var result = new Element('p', {html: "Your text is: <b>["+HTMLEncode(stext)+"]</b>"});
However, it is generally simpler to use DOM methods to add plain text without the bother of string hacking. I believe Moo would do it like this:
var bold= new Element('b', {text: stext});
var result= new Element('p', {text: 'Your text is: '});
bold.inject(result);
escape & like this: &
<input type="text" name="scrubtext" value="&lt;script&gt;alert('scrubbed');&lt;/script&gt;" id="scrubtext"/>
You can change the & characters into &amp by using
var result = new Element( 'p', {html: "Your text is: <b>["+stext.replace(/&/g,'&amp')+"]</b>"} );
Addition: I would go with bobince on the benefit of using the DOM node properties, instead of injecting arbitrary HTML.
function htmlspecialchars_decode(text)
{
var stub_object = new Element('span',{ 'html':text });
var ret_val = stub_object.get('text');
delete stub_object;
return ret_val;
}

Categories