How can I change the dataSource for Alchemy.js - alchemy.js

I have an alchemy graph displayed.
new Alchemy(config);
How can I change the config.dataSource and then redisplay the graph with the new data?

You could create an new configuration and then reload it in javascript. Something like this:
<script type="javascript">
var config = {
dataSource: "data/data.json",
...
...
}
var newConfig = {
dataSource: "data/new_data.json",
...
...
}
function changeData(){
alchemy = new Alchemy(newconfig);
}
</script>
<body>
<button onclick="changeData()">Click me</button>
</body>

Related

jCryption ASP.Net MVC

Our security team asked me to not submit plain text passwords in my log in page, we use HTTPS though. so I thought that I need to do client side encryption before submit, I searched for solution and decided to implement jCryption.
However the example presented there is PHP/python, after a few google found this. I did whatever was explained in the link but I don't know how to retrieve form data that user submitted in form.
I only see a key returns in my login post back action and the LoginModel that should contain username, password is null.
Login.cshtml
#model Portal.Model.Membership.LoginModel
#using jCryption
#{
Layout = null;
jCryption.HandleRequest(Request);
}
<html>
<head>
<script src="~/Assets/global/plugins/jquery.min.js" type="text/javascript"></script>
<script src="~/Assets/global/plugins/jquery-migrate.min.js" type="text/javascript"></script>
#jCryption.RenderScriptFor("form", src: #Url.Content("~/Assets/admin/scripts/jquery.jcryption.3.1.0.js"))
</head>
<body>
#using (Html.BeginForm(null, null, FormMethod.Post, new { #autocomplete = "off" }))
{
<div class="form-body">
<div class="form-group">
#Html.LabelFor(x => x.Username, new { #class = "placeholder" })
#Html.TextBoxFor(x => x.Username, new { #class = "form-input", autocomplete = "off" })
<span></span>
</div>
<div class="form-group">
#Html.LabelFor(x => x.Password, new { #class = "placeholder" })
#Html.PasswordFor(x => x.Password, new { #class = "form-input", autocomplete = "off" })
<span></span>
</div>
</div>
<div class="form-group">
<button id="btnLogin">Login</button>
</div>
}
</body>
<!-- END BODY -->
</html>
Update
I put break point on login post action and it popup twice, one with key and another with jCryption:
For MVC 5, you need to adjust a little bit.
at login.cshtml
#using jCryption
#{
jCryption.HandleRequest(Request);
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="/Scripts/jquery.jcryption.3.1.0.mod.js"></script>
<script type="text/javascript">
// tweak for compatibility with jquery.validate
(function($){
var _jCryption = $.jCryption;
var jCryptionMod = function(el,options){
var form = $(el), hasValidator = !!form.data('validator');
if (hasValidator){
var v = form.validate();
var prev_handler = v.settings.submitHandler;
v.settings.submitHandler = function (_form, event) {
if( prev_handler ) prev_handler.apply(this, arguments);
var form = $(_form);
if (!form.hasClass('jc-before-submit')) {
v.settings.submitHandler = prev_handler;
form.addClass('jc-before-submit');
setTimeout( function(){ form.trigger('_jc_submit', event); }, 100 );
}
};
_jCryption.call(this, form, $.extend(options, {
submitElement: form,
submitEvent: '_jc_submit',
beforeEncryption: function(){
form.removeAttr('disabled');// form element hack ( IE11 )
return true;
}
}));
} else {
return _jCryption.call(this,el,options);
}
}
$.extend(jCryptionMod, $.jCryption);
$.jCryption = jCryptionMod;
})(jQuery);
</script>
<script type="text/javascript">
$(document).ready(function(){
var form = $('form');
var url = form.attr('action') || '/Account/Login';
form.jCryption({
getKeysURL: url + '?getPublicKey=true',
handshakeURL: url + '?handshake=true'
});
});
</script>
}
AccountController, you should follow JakeJP's documentation (exact same code).
At IE F12 Developer Tools (Network-->go to detail view-->Request body), it showns &jCryptionKey= but not &UserName= and &Password=.
You lack the jCryptionHandler attribute in your action method. The attribute is responsible for handling the jCryption handshake and decryption.
[jCryptionHandler]
public ActionResult Login(LoginModel model)
{
return View();
}

Observables initialized/attached to Observable in extender not initialized at page load

I
I have created a text counter to tell the user how many characters of they have typed and how many they have remaining available. This should show when the text area has focus and disappear then the text area loses focus.
I have created a binding handler that uses an extender to extend the observable object that is being passed into it. The problem is that it works only after entering text, navigating off of the text area, and then navigating back to the text area.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div class="question" >
<label for="successes" data-textkey="successes">This is a question</label>
<textarea data-bind="textCounter: successes, hasFocus: successes.hasFocus, maxLength:200, event: { keyup:successes.updateRemaining }"></textarea>
<div class="lengthmessage edit" data-bind="visible:successes.hasFocus()">
<div >
<em>Length:</em> <span data-bind="text:successes.currentLength"></span>
<em>Remaining:</em> <span data-bind="text:successes.remainingLength"></span>
</div>
</div>
</div>
<script src="../Scripts/knockout-2.3.0.debug.js" type="text/javascript"></script>
<script type="text/javascript">
(function (ko) {
ko.extenders.textCounter = function (target, options) {
options = options || {};
options.maxLength = options.maxLength ? parseInt(options.maxLength) : 2000;
target.maxLength = ko.observable(options.maxLength);
target.currentLength = ko.observable(target().length);
target.remainingLength = ko.observable(target.maxLength() - target.currentLength());
target.hasFocus = ko.observable(false);
target.hasFocus.subscribe(function () {
target.currentLength(target().length);
target.remainingLength(target.maxLength() - target.currentLength());
});
target.updateRemaining = function (data, event) {
if (event.target == undefined && event.srcElement.value == "") {
target.currentLength(0);
}
else {
var e = $(event.target || event.srcElement);
target.currentLength(e.val().length);
if (target.currentLength() > target.maxLength()) {
e.val(e.val().substr(0, target.maxLength()));
target.currentLength(target.maxLength());
}
}
target.remainingLength(target.maxLength() - target.currentLength());
};
return target;
};
ko.bindingHandlers.textCounter = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var val = ko.utils.unwrapObservable(valueAccessor());
var observable = valueAccessor();
observable.extend({ textCounter: allBindingsAccessor() });
ko.applyBindingsToNode(element, {
value: valueAccessor()
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var val = ko.utils.unwrapObservable(valueAccessor());
var observable = valueAccessor();
ko.bindingHandlers.css.update(element, function () { return { hasFocus: observable.hasFocus }; });
}
};
var viewModel = function () {
this.successes = ko.observable("");
//this.successes.hasFocus = ko.observable();
}
ko.applyBindings(new viewModel());
} (ko));
</script>
</body>
</html>
If I uncomment:
//this.successes.hasFocus = ko.observable();
The page will behave the way that I want it to, from the very beginning, but it defeats the whole purpose of using the extender since my view model now has one of the objects from the extender in it.
I have got to believe that there is something relatively simple that I am missing here.
Thanks for your help..
The issue is that hasFocus has not been defined when the binding string here is parsed:
<textarea data-bind="textCounter: successes, hasFocus: successes.hasFocus, maxLength:200, event: { keyup:successes.updateRemaining }"></textarea>
So, when the binding string is parsed successes.hasFocus is undefined.
One option would be to apply the hasFocus binding inside of your textCounter binding after your hasFocus property is available.
Also, in Knockout 3.0 (released today), the parsing of the binding string happens when the value is accessed in the binding itself. So, your code actually works property in KO 3.0 already.

Can i call a JS script in knockout databinding?

I need to invoke a JS function inside a foreach loop in knockout data-bind.
I need to do something like:
<div data-bind="foreach:items()">
.....
<script>
jQuery(function () { jQuery('#myid').rateit({ value:$data.value }); })
</script>
....
</div>
Obviously it doesn't work, i've not found a way to apply data binding inside a script tag ... is there a way to do it?
No, you can't.
If you want to execute something for every item in a collection (or on any observable) you can use a computed observable.
This would work in your scenario:
ko.computed(function () {
var items = this.items();
for (var i = 0; i < items.length; i++) {
jQuery(function () { jQuery('#myid').rateit({ value: item[i].value }); })
}
}, viewModel);

Trying to deal XML with Ajax

I Wrote a code that takes a generates XML file from Harvard Uni, and put it in a dropdown, next you can choose a course from the list and it will generates a table with the course details.
<script type="text/javascript" src="Script/jquery-1.7.2.js"></script>
<script type="text/javascript">
$('#button').click(function () {
document.getElementById("span").style.visibility = "visible";
document.getElementById("button").style.visibility = "hidden";
$.ajax({
type: "GET",
url: "Harvard.aspx?field=COMPSCI",
success: function (data) {
var courses = data.documentElement.getElementsByTagName("Course");
var options = document.createElement("select");
$(options).change(function () {
ShowCourseDetails(this);
});
for (var i = 0; i < courses.length; i++) {
var option = document.createElement("option");
option.value = $(courses[i]).find("cat_num").text();
option.text = $(courses[i]).find("title").text();
options.add(option, null);
}
document.getElementById("selectDiv").appendChild(options);
document.getElementById("span").style.visibility = "hidden";
}
});
});
function ShowCourseDetails(event) {
// get the index of the selected option
var idx = event.selectedIndex;
// get the value of the selected option
var cat_num = event.options[idx].value;
$.ajax({
type: "GET",
url: "http://courses.cs50.net/api/1.0/courses?output=xml&&cat_num=" + cat_num,
success: function (data) {
$("#TableDiv").html(ConvertToTable(data.documentElement));
}
});
}
function ConvertToTable(targetNode) {
targetNode = targetNode.childNodes[0];
// first we need to create headers
var columnCount = 2;
var rowCount = targetNode.childNodes.length
// name for the table
var myTable = document.createElement("table");
for (var i = 0; i < rowCount; i++) {
var newRow = myTable.insertRow();
var firstCell = newRow.insertCell();
firstCell.innerHTML = targetNode.childNodes[i].nodeName;
var secondCell = newRow.insertCell();
secondCell.innerHTML = targetNode.childNodes[i].text;
}
// i prefer to send it as string instead of a table object
return myTable.outerHTML;
}
</script>
and the body:
<div id="main">
<div class="left">
<input id="button" type="button" value="Get all science courses from HARVARD"/>
<br />
<span id="span" style="visibility: hidden">Downloading courses from harvard....</span>
<div id="selectDiv"></div>
<div id="TableDiv"></div>
</div>
</div>
and What I get in the dropdown is only "undefined" on all the rows in the dropdown, can someone can see the problem with the code I wrote?
10x alot in advance :)
Working jsFiddle: http://jsfiddle.net/3kXZh/44/
Well, I found a couple of issues..
First, I'd stay away from setting "onclick" in the HTML. You want to separate your action layer from your content layer.
Since you're using jQuery anyway, try this:
$('#button').click(function() {
/* function loadXMLDoc contents should go here */
});
And change:
<input id="button" type="button" onclick="loadXMLDoc()" value="Get all sci..."/>
To:
<input id="button" type="button" value="Get all sci..." />
To solve your immediate problem in the JavaScript, change the loadXMLDoc function from this:
option.value = courses[i].getElementsByTagName("cat_num")[0].text;
option.text = courses[i].getElementsByTagName("title")[0].text;
to this:
option.value = $(courses[i]).find("cat_num").text();
option.text = $(courses[i]).find("title").text();
That should be enough to get you on to creating your tables from there.

Calling ASP.NET MVC Controller explicitly via AJAX

I know that I can use following piece of code to refresh a div:
<%=Ajax.ActionLink( "Update", "Administration", new AjaxOptions { UpdateTargetId = "grid", LoadingElementId = "grid-wait" } ) %>
But this creates a link; user will have to click on it to get the view refreshed.
How can I make it automatic, i.e., like say if I want the grid to be refreshed after every five seconds?
Try this:
<p id="CurrentDateTime"></p>
<script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.setInterval(updateDateTime, 5000);
function updateDateTime() {
$.get("GetCurrentDate?rnd=" + Math.random(1000), {}, function (r) {
$("#CurrentDateTime").html(r);
}, "text");
}
</script>
public ActionResult GetCurrentDate()
{
return Content(DateTime.Now.ToString("U"));
}

Resources