I have the following code:
foreach (var interest in Model.Interests)
{
<div>
<span>#interest.SubjectName</span>
#if (interest.Description.Length > 2)
{
<a data-bind="click(DATA)" href="#" title="View Details">details</a>
}
</div>
}
I'm using Razor because I need to allow users without javascript to have read-only access to the site, so using a knockout/JS loop here isn't an option.
In this line:
<a data-bind="click(DATA)" href="#" title="View Details">details</a>
I'd like to take the current interest (razor object) and send it into the click function. I just don't know the syntax.
How can this be achieved?
Depends on what representation of the object you want to pass to your function. If JSON will suffice, try this:
<a data-bind='#String.Format("click({0})", Newtonsoft.Json.JsonConvert.SerializeObject(interest))'
href="#" title="View Details">details</a>
Then in your click function you can get the object like this:
function click(data) {
var interest = JSON.parse(data);
}
Related
I'm looking for live search for ASP.NET and entity framework. I'm a little bit green with it. I read that it needs to use ajax, but I never used it before and can't get good example. Here is a piece of code, cshtml (part of textbox)
<div class="form-horizontal">
<hr />
<h4>Search for a client: </h4>
<div class="input-group">
<span class="input-group-addon" id="Name">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</span>
#Html.TextBox("Name", "", new { #class = "form-control", placeholder = "Name" })
</div>
<div><h6></h6></div>
<div class="input-group">
<span class="input-group-addon" id="Surname">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</span>
#Html.TextBox("Surname", "", new { #class = "form-control", placeholder = "Surname" })
</div>
<div><h6></h6></div>
<button type="submit" class="btn btn-default" data-toggle="modal" data-target="#infoModal">Search</button>
</div>
this is a part of controller:
public ActionResult Index(string Name, string Surname)
{
var SearchList = from m in db.Klienci
select m;
if (!String.IsNullOrEmpty(Name))
{
SearchList = SearchList.Where(s => s.Name.Contains(Name));
}
if (!String.IsNullOrEmpty(Surname))
{
SearchList = SearchList.Where(s => s.Nazwisko.Contains(Surname));
}
return View(SearchList);
}
So it search for me clients by name and surname, but it refresh full page when it lost focus or after clicking the button. How to solve it, to get live search? after each keystroke search through database? I'm a little bit green, would you Help me?
You can listen to the keyup event on your input element, read the value and send it to the server using ajax. Return the results and in the ajax call's success callback, update the ui with the results.
$(function() {
$("#Name,#SurName").keyup(function(e) {
var n = $("#Name").val();
var sn = $("#SurName").val();
$.get("/Home/Index?Name="+n+"&SurName="+sn,function(r){
//update ui with results
$("#resultsTable").html(r);
});
});
});
The code basically listens to the key up event on the two input textboxes and read the values and send to the /Home/Index action method using jquery get method asynchronously.When the action method returns the response, we update the DOM.
Assuming resultsTable is the Id of the table where we list the results.
Also, since you are returning the partial view result ( without layout headers), you should use return PartialView() instead of return View()
if(Request.IsAjaxRequest())
return PartialView(SearchList);
return View(SearchList);
Here is nice example/tutorial how to use Ajax with ASP.NET MVC
http://www.itorian.com/2013/02/jquery-ajax-get-and-post-calls-to.html
EDITED: 2016-07-20
Example:
$(function () {
$("searchField").keyup(function () {
$.ajax({
type: "POST",
url: "/Controller/Action",
data: data,
datatype: "html",
success: function (data) {
$('#result').html(data);
}
});
});
You have to visit the server to get data from server and without ajax it is not possible. Now the question is how to make ajax call, you can use jQuery js lib to do but I would recommend you to try angular as data binding in angular will fulfill your needs.
Take a look at followings links
Angular Ajax Service -
jQuery Ajax
I am experimenting with Knockout with TypeScript and am trying to send a view model that contains another model as parameters to a function like:
TypeScript:
export interface IEmployee {...}
export interface ICompany {...}
export class ViewModel() {
constructor(company : ICompany) {}
public setAsOwner(parent : ViewModel, person : IEmployee) {
parent.company.updateOwner(person.id);
}
}
// In a different file
ko.applyBindings(new ViewModel(new ICompany()));
HTML:
<ul data-bind="foreach: employees">
<li>
#*Employee details...*#
<button data-bind="click: $root.setAsOwner.bind($parent, $data)">
Set as new owner
</button>
</li>
</ul>
However I keep getting an error saying that parent.company is undefined. What is the right way to pass the view model as a parameter to its own function?
The click binding handler function automatically receives the current employee item as the first parameter, and if you call $parent.setAsOwner from a wrapper function, the parent view model is available to the method via this.
So change the setAsOwner method to:
public setAsOwner(person : IEmployee) {
this.company.updateOwner(person.id);
}
and the HTML to:
<ul data-bind="foreach: employees">
<li>
#*Employee details...*#
<button data-bind="click: function(employee) { $parent.setAsOwner(employee); }">
Set as new owner
</button>
</li>
</ul>
I have a knockout Observable which is populated during some interaction with my page. This Observable is a comma-separated value (i.e. "a,b,c"). What I need now is to pass this as an argument to #Url.Action. See below:
<input type="button" onclick="window.location.href='#Url.Action("Benefits", "Employee", new { ids = "a,b,c" })';" />
How can I do this?
You could use the click binding.
<button data-bind="click: function () { myFunction('#Url.Action("Benefits", "Employee")'); }">
Click me
</button>
//then in your view model:
self.myFunction = function (actionURL) {
window.location.href = (actionURL + '?ids=' + this.ids());
};
or just the attribute binding directly on a link
<a data-bind="attr: { 'href': '#Url.Action("Benefits", "Employee")?ids=' + ids() }">
Click
</a>
you will need to build your url as a query string manualy
suppose ids = ko.observable('a,b,c');
then you'll build your url
<input type="button" onclick="window.location.href='#(Url.Action("Benefits", "Employee"))' + '?ids=' + $data.ids()" />
that will generate a url like http://localhost:5248/Employee/Benefits?ids=a,b,c
or try this
<button data-bind="click: function() { window.location.href='#(Url.Action("Benefits", "Employee"))' + '?ids=' + ids() }">
Click me
</button>
JSFiddler DEMO
You could set the url ahead of time with a piece you replace with the actual values, it's kinda hacky, but since the MVC code is executed on the server, any MVC code would require at least a round-trip to the server to reload something.
urls = {
EmployeeBenefits: '#Url.Action("Benefits", "Employee", new {ids="==ids=="})'
};
window.location.href = urls.EmployeeBenefits.replace('==ids==', "a,b,c");
I thought about writing an MVC action that would return javascript creating a Url object with the site's routes that could be used just like this but started using other ways before I got around to it.
I have the following snippet JQuery inside an HTML file:
$.getJSON("/events/", function (data) {
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
});
The code is executed when, for example, the user presses a button and returns JSON like:
{"Events":[{"Name":"Event1"},{"Name":"Event2"},{"Name":"Event3"}]}
This result is linked (using KnockoutJS) to:
<ul data-bind="foreach: Events">
<li><span data-bind="text: Name"></span></li>
</ul>
Everything works fine with the first call to $.GetJSON. I get what I want, which is (browser output):
Event1
Event2
Event3
But in subsequent calls to "$. GetJSON" I get the following error in Firebug:
NotFoundError: Node was not found.
containerNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling);
And I get no list item.
What I can be doing wrong?
Thank you very much in advance.
The whole point of Knockout is to handle the interaction between your view and view model. In this case, you're trying to update a list of events in response to a button click. The button click should be linked to a function in your view model, while the list should be linked to an observable array that's updated when you click the button. I've put this together in a fiddle here: http://jsfiddle.net/mbest/uZb3e/ and the important parts are below:
<button type=button data-bind="click: updateEvents">Update</button>
<ul data-bind="foreach: data.Events">
<li><span data-bind="text: Name"></span></li>
</ul>
Javascript:
var viewModel = {
data: ko.mapping.fromJS({"Events":[]}),
updateEvents: function() {
var self = this;
$.getJSON("/events/", function (data) {
ko.mapping.fromJS(newData, self.data);
});
}
};
ko.applyBindings(viewModel);
My friend Thomas Brattli found the solution:
<ul data-bind="template: { name: 'template', foreach: Events }"></ul>
<script id="template" type="text/html">
<li><span data-bind="text: Name"></span></li>
</script>
Thanks !
I've been looking at the:
data-filter="true"
option for filtering a list based on what is entered into a search box using Jquery mobile.
I'd like to do the same except hook in the ability to use an ajax get() to populate the list. Does anyone know how to go about doing this or an example anywhere of it being achieved. I've not seen anything on the JQ mobile site.
Thanks.
I couldn't find anything built in that does what you ask, but I was able to achieve this using a simple ajax request and manually filling the list. I started with a text box for the search field, and an empty ul
<div data-role="fieldcontain">
<label for="search">Search:</label>
<input type="search" name="search" id="search" value=""/>
</div>
<ul id="results" data-role="listview">
</ul>
This script block will send an ajax request after each key press, it might be better to add a delay though. It will abort the previous request if still loading and the person types another key. Not perfect, but its a start.
<script>
var last, last_xhr;
var x = $('#search').live('keyup change', function () {
if (last == $(this).val()) return;
last = $(this).val();
$.mobile.showPageLoadingMsg();
if (last_xhr) {
last_xhr.abort();
}
last_xhr = $.get('/Search', { q: last }, function (data) {
last_xhr = undefined;
var list = $('#wines').empty();
$.each(data, function (i, val) {
var el = $('<li data-theme="c" />');
el.append($('' + val.Name + ''));
list.append(el);
});
list.listview('refresh');
$.mobile.hidePageLoadingMsg();
});
});
</script>
The most important bit is calling refresh otherwise it doesn't apply the theme.
list.listview('refresh');