Knockoutjs not binding to element - data-binding

I am kind of new to KnockoutJS and trying to use it.
I am having trouble binding the element using knockoutjs. Please see the fiddle below and help in resolving and correcting me.
It is basically not binding the value to the span element.
http://jsfiddle.net/EpyRA/
HTML:
<div id="taxyear">
<table style="width: 100%;" cellpadding="4" cellspacing="4">
<tr>
<td style="width: 25%">
<span>Name:</span><span data-bind="value: ReturnData.Name"></span>
</td>
</tr>
</table>
</div>
Javascript:
var myWeb = myWeb || {};
$(function () {
(function (myWeb) {
"use strict";
var serviceBase = '../Services/Data.asmx/',
getSvcUrl = function (method) { return serviceBase + method; };
myWeb.ajaxService = (function () {
var ajaxGetJson = function (method, jsonIn, callback) {
$.ajax({
url: getSvcUrl(method),
type: "GET",
data: jsonIn,
dataType: "json",
contentType: "application/json",
success: function (json) {
callback(json);
}
});
},
ajaxPostJson = function (method, jsonIn, callback) {
var test = { "Name": "testRaju", "SourceID": "ABCD" };
//just return data instead of calling for testing
callback(test);
};
return {
ajaxGetJson: ajaxGetJson,
ajaxPostJson: ajaxPostJson
};
})();
} (myWeb));
(function (myWeb) {
"use strict";
myWeb.DataService = {
getReturnData: function (jsonIn, callback) {
myWeb.ajaxService.ajaxPostJson("GetReturnData", jsonIn, callback);
}
};
} (myWeb));
//Constructor for a ReturnData object
myWeb.ReturnData = function () {
this.Name = ko.observable();
this.SourceID = ko.observable();
},
//View Model
myWeb.prdviewmodel = (function () {
var prd = ko.observable();
loadReturnDataCallback = function (jsonReturnData) {
alert(jsonReturnData.Name);
prd = new myWeb.ReturnData()
.Name(jsonReturnData.Name)
.SourceID(jsonReturnData.SourceID);
},
loadReturnData = function () {
myWeb.DataService.getReturnData("{'YearID':'" + 22 + "'}", myWeb.prdviewmodel.loadReturnDataCallback);
};
//public
return {
loadReturnData: loadReturnData,
loadReturnDataCallback: loadReturnDataCallback,
ReturnData: prd
}
})();
//hookup knockout to our viewmodel
myWeb.prdviewmodel.loadReturnData();
ko.applyBindings(myWeb.prdviewmodel);
});
Thanks in Advance,
Sam

I see a couple of minor issues:
When binding against a span, you would want to use the text binding rather than the value binding.
In the AJAX callback, you would want to set the prd observable's value by calling it as a function, rather than setting it as a new value.
In the UI, you can make use of the with binding to ensure that it does not try to bind to a property of the observable, before it has been loaded.
Here is an updated fiddle: http://jsfiddle.net/rniemeyer/Bdz5a/

Related

MVC4 Detailview from GridMvc.selectedData

I am trying to get the selected row of a MVCGrid and display the details in an modal dialog using a partialview.
I am getting the selected row via ajax:
$(document).ready(function(){
var selectedRow;
$(document).on('click', '.grid-mvc', function () {
pageGrids.PersonGrid.onRowSelect(function (e) {
// $.prompt(e.row.ID);
SendData(e.row);
});
});
});
The 'SendData'-function is:
function SendData(i) {
var data= i.ID;
$.ajax({
url: '/Home/Person',
contentType: "application/html; charset=utf-8",
type: "GET",
data: { "id": daten },
dataType: "html"
, success: function () {
ShowPersonDetails(data);
}
});
}
and the ShowPersonDetails(data) is like that:
function ShowPersonDetails(data) {
$(document).ready(function () {
$('#PersonDiv').load("Person?id=" + data);
$("#PersonDiv").prompt(
$("#PersonDiv").html(),
{
title: "some title",
buttons: { OK: 'true', Abbruch: 'false' },
position: { width: 800, height: 600 }
});
});
}
The controller:
[HttpGet]
public ActionResult Person(int id)
{
var pS = new DbAccess(MvcApplication.Connection).GetUserData(id);
var p = new Person();
if (pS.Rows.Count < 0)
{
return PartialView("Person");
}
p.Alter = pS.Rows[0].ItemArray[0].ToString();
p.Nachname = pS.Rows[0].ItemArray[5].ToString();
return PartialView("Person", p);
}
Any advice would be nice!
Greetings
PP
i did something like you are trying to do, so hope my code helps
in the grid, table, i put a link for details
<tr>
<td>
#Html.ActionLink("Details", "ActionDetails", new { id = Model.LstItems[x].ID }, new { #class = "detailsLink" })
</td>
</tr>
the javascript
$('#detailsDialog').dialog({
autoOpen: false,
width: 400,
resizable: false,
modal: true,
buttons: {
"Cancel": function () {
$(this).dialog("close");
}
}
});
$(".detailsLink").button();
$(".detailsLink").click(function () {
linkObj = $(this);
var dialogDiv = $('#detailsDialog');
var viewUrl = linkObj.attr('href');
$.get(viewUrl, function (data) {
dialogDiv.html(data);
//open dialog
dialogDiv.dialog('open');
});
return false;
});
in somewhere in the view
<div id="detailsDialog" title="Offer Details">
</div>
the controller
public ActionResult ActionDetails(int id)
{
ItemEntity model = ItemEntity .GetBy(id);
return PartialView(model);
}
the partial view
#model YourNameSpace.Entities.ItemEntity
#using (Ajax.BeginForm("ActionDetails", "YourController", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "updateSuccess",
OnFailure = "showErrorMessage"
}, new { #id = "detailForm" }))
{
//your details for your item
}
hope this help you

jQuery Autocomplete Component

I'm facing a strange issue with autocomplete.
First issue:
based on the tutorial found here, only the first letter of the found items is showing in the list of autocomplete items
Here is an illustration:
My action at debug time
Dummy data returned, always the same regardless of the search pattern just for testing
In the rendered view, this is what happens:
The Javascript for autocomplete of this scenario is as follows:
$("#Email").autocomplete('#Url.Action("FindEmail", "Administration")',
{
dataType: 'json',
parse: function(data) {
var rows = new Array();
for (var i = 0; i < data.length; i++) {
rows[i] = {
data: data[i].Value,
value: data[i].Value,
result: data[i].Value
};
}
return rows;
},
width: 300,
minLength: 3,
highlight: false,
multiple: false
});
Second issue:
I've changed my code to work with a more comfortable Ajax call for me that depends on Model mapping rather than sending a q and limit parameters as in the previous tutorial, and as I've seen in many other tutorials, but the Ajax call isn't firing, not even giving me an error.
My code for this scenario is based on this Stack Overflow Answer
Here is my controller and view code related:
//[HttpPost]
[SpecializedContextFilter]
[Authorize]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public JsonResult FindEmail(RegistrationModel model) //Notice the use of model instead of string q and string limit
{
//Just a dummy implementation
var rez = new List<ValueModel>
{
new ValueModel {Description = "atest1#test.com", Value = "atest1#test.com"},
new ValueModel {Description = "atest2#test.com", Value = "atest2#test.com"},
new ValueModel {Description = "atest3#test.com", Value = "atest3#test.com"},
new ValueModel {Description = "atest4#test.com", Value = "atest4#test.com"}
};
//var retValue = rez.Select(r => new { email = r.Value }).OrderBy(x => x).Take(10);
//return Json(retValue, JsonRequestBehavior.AllowGet);
return Json(rez, JsonRequestBehavior.AllowGet);
}
View JavaScript:
$("#Email").autocomplete({
source: function(request, response) {
$.ajax({
url: '#Url.Action("FindEmail", "Administration")',
type: "POST",
dataType: "json",
data: { email: $("#Email").val(), conferenceId: $("#ConferenceId").val() },
success: function(data) {
response($.map(data, function(item) {
return { label: item.Value, value: item.Value, id: item.Value };
}));
},
select: function(event, ui) {
$("input[type=hidden]").val(ui.item.id);
}
});
}
});
Firefox console view:
I've tried a lot of codes for the second scenario, most of them are Stack Overflow answers, but nothing is happening!
I'm my missing anything ?
Note: jQuery plugins are included, Ajax is already working in the same page, so I'm not sure whats the problem
Thanks for any help.
Here is a full working example, see screen grab.
These are the steps that I had take to get the second example working.
Script-references/Markup/Js
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-ui-1.8.24.min.js"></script>
<input id="ConferenceId" value="1" />
<div class="ui-widget">
<label for="Email">Email: </label>
<input id="Email">
</div>
<script type="text/javascript">
$("#Email").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("FindEmail", "Administration")',
type: "POST",
dataType: "json",
data: { email: $("#Email").val(), conferenceId: $("#ConferenceId").val() },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Value, value: item.Value, id: item.Value };
}));
},
select: function (event, ui) {
$("input[type=hidden]").val(ui.item.id);
}
});
}
});
</script>
Models
public class RegistrationModel
{
public string Email { get; set; }
public string ConferenceId { get; set; }
}
public class ValueModel
{
public string Description { get; set; }
public string Value { get; set; }
}
Controller Action
I had to add the [HttpPost] attribute.
[HttpPost]
public JsonResult FindEmail(RegistrationModel model) //Notice the use of model instead of string q and string limit
{
//Just a dummy implementation
var rez = new List<ValueModel>
{
new ValueModel {Description = "atest1#test.com", Value = "atest1#test.com"},
new ValueModel {Description = "atest2#test.com", Value = "atest2#test.com"},
new ValueModel {Description = "atest3#test.com", Value = "atest3#test.com"},
new ValueModel {Description = "atest4#test.com", Value = "atest4#test.com"}
};
return Json(rez, JsonRequestBehavior.AllowGet);
}
Screen grab

Knockout observables not binding and applyBindings firing twice

I had earlier asked this question here which worked in a html file. Now I am trying to put the same in the ASP.NET webform but does not seem to work.
What happens here the first time the page loads ajax call fires which I do not want except when the cursor is moved away from the text box
On Blur I have a popup window that I want to show the data returned from the ajax call. The data does not bind either. What am I doing wrong here.
My Javascript:
<script type="text/javascript">
var self = this;
function showPopUp() {
var cvr = document.getElementById("cover")
var dlg = document.getElementById("dialog")
var SName = document.getElementById("<%=txtSurname.ClientID%>").value
document.getElementById("txtSurnameSearch").value = SName
cvr.style.display = "block"
dlg.style.display = "block"
if (document.body.style.overflow = "hidden") {
cvr.style.width = "1024"
cvr.style.height = "100;"
}
this.SurnameViewModel(SName) //<= here I pass the surname to the ViewModel
}
function closePopUp(el) {
var cvr = document.getElementById("cover")
var dlg = document.getElementById(el)
cvr.style.display = "none"
dlg.style.display = "none"
document.body.style.overflowY = "scroll"
}
function SurnameViewModel(Surname) {
var self = this;
self.Surnames = ko.observableArray();
$.ajax({
crossDomain: true,
type: 'POST',
url: "http://localhost/GetSurnames/Name/ChurchID",
dataType: 'json',
data: { "Name":Surname, "ChurchID": "17" },
processdata: true,
success: function (result) {
alert(result.data);
ko.mapping.fromJSON(result.data, {}, self.Surnames);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Failure!");
alert(xhr.status);
alert(thrownError);
}
});
}
$(document).ready(function () {
ko.applyBindings(new SurnameViewModel());
});
</script>
My HTML
<!-- Grey Background -->
<div id="cover"></div>
<!-- Surname Popup -->
<div id="dialog" style="display:none">
My Dialog Content
<br /><input ID="txtSurnameSearch" type="text" />
<br /><input type="button" value="Submit" />
<br />[Close]
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre> //<= just shows the header
<table>
<thead>
<tr>
<th>ID</th>
<th>Family Name</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: Surnames">
<tr>
<td data-bind="value: id"></td>
<td data-bind="value: homename"></td>
</tr>
</tbody>
</table>
</div>
TextBox where the onBlur is called:
<asp:TextBox ID="txtSurname" MaxLength="50" runat="server" Width="127px" class="txtboxes" placeholder="Last Name" onblur="showPopUp();" />
JSON Data returned by the ajax call
{"data":"[{\"id\":3,\"homename\":\"D\\u0027Costa\"}]"}
Edit 1:
If I hard code the values in the ajax call it seems to bind but still fires on page load
data: { "Name":"d", "ChurchID": "17" },
In your view model your Ajax call is inline, not inside a method, so as an instance of its contstructed your AJAX gets fired off. See this code, we create a global variable to hold the instance of your model and then wrap the AJAX call into its on function (method) in your JS. Then you can just call the method on your instance when you need to in your popup code.
var self = this;
var model = new SurnameViewModel();
function showPopUp() {
var cvr = document.getElementById("cover")
var dlg = document.getElementById("dialog")
var SName = document.getElementById("<%=txtSurname.ClientID%>").value
document.getElementById("txtSurnameSearch").value = SName
cvr.style.display = "block"
dlg.style.display = "block"
if (document.body.style.overflow = "hidden") {
cvr.style.width = "1024"
cvr.style.height = "100;"
}
model.GetSurname(SName) //<= here I pass the surname to the ViewModel
}
function closePopUp(el) {
var cvr = document.getElementById("cover")
var dlg = document.getElementById(el)
cvr.style.display = "none"
dlg.style.display = "none"
document.body.style.overflowY = "scroll"
}
function SurnameViewModel() {
var self = this;
self.Surnames = ko.observableArray();
self.GetSurname = function(Surname){
$.ajax({
crossDomain: true,
type: 'POST',
url: "http://localhost/GetSurnames/Name/ChurchID",
dataType: 'json',
data: { "Name":Surname, "ChurchID": "17" },
processdata: true,
success: function (result) {
alert(result.data);
ko.mapping.fromJSON(result.data, {}, self.Surnames);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Failure!");
alert(xhr.status);
alert(thrownError);
}
});
}
}
$(document).ready(function () {
ko.applyBindings(model);
});
</script>

knockout.js with binding

This is probably a really basic question but in the following view model I am populating self.userData from an ajax call. I want to display this information in the UI and I figured the 'with' binding is the way to go.. however since self.userData is empty until the ajax function is called I get an error from the with binding
HTML
<div data-bind="with: userData">
<div data-bind="text: userId"></div>
...
</div>
Model
var viewModel = function () {
var self = this;
self.userData = {};
self.login = function(data) {
var postData = { ..trimmed out.. };
$.ajax({
type: "POST",
url: "myService",
data: postData
}).done(function (data, status) {
self.userData = ko.mapping.fromJS(data, userData);
console.log(self.userData);
}).fail(function (data, status) {
alert('Could Not Login');
});
}
};
ko.applyBindings(new viewModel());
Initialize userData with an empty observable, an then set it with the object created by the the mapping plugin once the call return. I.e. change
self.userData = {};
with
self.userDara = ko.observable();
and change
self.userData = ko.mapping.fromJS(data, userData);
with
self.userData(ko.mapping.fromJS(data,userData));
You need to initialize userData as an empty observable (single object from ajax call) or observable array (multiple objects) first:
self.userData = ko.observableArray([]);
or
self.userData = ko.observable();

Jquery AutoComplete Load Problem

Not Work
Jquery Code:
$('[id$=Name]').autocomplete('CallBack.aspx',{formatItem: function(item){return item.Name;}}).result(function(event, item) {
location.href = item.AGE;
});
Json:
var data = [{NAME:"John",AGE:"57"}];
Work
Jquery Code:
var data = [{NAME:"John",AGE:"57"}];
$('[id$=Name]').autocomplete(data,{formatItem: function(item){return item.Name;}}).result(function(event, item) {
location.href = item.AGE;
});
alt text http://img11.imageshack.us/img11/119/38235621.jpg
Help me pls how its make ? callback.aspx return json not work
Try changing your data to this:
var data = [{id:"John",value:"57"}];
EDIT
Here's a sample of what I think you're trying to do:
var data = [{NAME:"John",AGE:"57"}];
$('[id$=Name]').autocomplete('CallBack.aspx', {
formatItem: function(item) {
return item.NAME;
}}).result(function(event, item) {
location.href = 'somepage.aspx?age=' + item.AGE;
});
Basically you needed to capitalise return item.Name to return item.NAME.
Try This
<script type="text/javascript">
$(document).ready(function () {
$("#TextboxId").autocomplete({
source: function (request, response) {
$.ajax({
url: "URL",
type: "POST",
dataType: "json",
data: { ids: idstopass },
success: function (retrieveddata) {
alert(retrieveddata);
var dData = JSON.parse(retrieveddata);
alert(dData.Name);
},
error: function (request, status, error) {
console.log("Error! " + request.responseText);
}
})
},
});
})
</script>

Resources