Below is my code which is knocokout js,i have ListviewModel which is related to two views 1st and second view as below,Both views using the class name UserDetailsView, i am binding two views 1st and second view as below,my problem is, i have click event on the 1st view "Userview" i need to get data of clicked event which is $root.UserView, when i click this it should get all related value and pass to second view so i can bind the data using knockout js ,i am getting the value but unable to bind the data when i clicked $root.UserView so i used jquery in second view for binding, but Now requirement is changed i need make another click event in second view so i can carry data to another view,before that i need to bind the second view with Knockout js how it can be done need help
function ListviewModel()
{
var self = this;
self.Listarray = ko.observableArray();
self.getUserList = function () {
var ListModel = {
userId: UserID
}
jQuery.support.cors = true;
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(ListModel),
url: serverUrl + 'xxx/xxx/xxx',
success: function (data) {
self.Listarray($.map(data, function (item) {
return new Listdata(item);
}));
}
});
};
//Click Function for UserPersonalview
self.UserView = function (Listarray) {
$("#userId").text(Listarray.userIdId());
$("#userName").text(Listarray.UserName())
document.getElementById('userProfilePic').setAttribute('src', "data:" + Listarray.ProfilePictype() + ";base64," + Listarray.ProfilePicBase64());
window.location.href = "#UserPersonalview";
}
self.UserProfile = function () {
console.log(self.Listarray());
}
}
//Model
function Listdata(data)
{
var self = this;
self.userId = ko.observable(data.userId);
self.userName = ko.observable(data.userName);
self.userProfilePicBase64 = ko.observable(data.userProfilePicBase64);
self.userProfilePictype = ko.observable(data.userProfilePictype);
self.userProfilepic = ko.computed(function () {
return "data:" + self.userProfilePictype() + ";base64," + self.userProfilePicBase64();
});
}
//1st View
<div data-role="view" id="Userview" class="UserDetailsView" data-layout="default">
<div data-role="content" style="background-color:#fff!important">
<div>
<ul style="list-style: none;" data-role="listview" id="hierarchical-listview" data-bind="foreach:Listarray">
<li style="background-color:#FFF" data-bind="click:$root.UserView">
<div style="width:100%;">
<div style="width:50%;float:left">
<span data-bind="text:$data.userId" style="display:none"></span>
<img data-bind="attr: { src:$data.userProfilepic }" onclick="Imagepopover()" />
<label style="width: 25%!important;" class="firendslisttext" data-bind="text:$data.userName"></label>
</div>
<div style="width:50%;float:left;margin: 0px -20px;">
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
//second View
<div data-role="view" id="UserPersonalview" >
<header data-role="header">
<div data-role="navbar" class="UserDetailsView">
<div class="content-header ">
<ul style="list-style: none;" >
<li data-bind="click:$root.UserProfile">
<div class="km-leftitem">
</div>
<div class="block2" >
<div class="inner" style="float:left" >
<span id="userId" style="display:none"></span>
<img data-responsive="" width="40" height="40" id="userProfilePic" src="" style="border-radius: 50%;" />
</div>
<div class="inner" style="float:left;margin-left:15px">
<label id="userName" style="width: 100%!important;"></label>
</div>
</div>
<div class="km-rightitem">
<a data-align="right"><img src="images/icon-add.png" style="height:50px" /></a>
</div>
</li>
</ul>
</div>
</div>
</header>
<div data=role="content"><div>
</div>
Related
I want to create a simple weather report website using Vue.js, I just learned this framework and had accessed public data before. But this time I am stuck.
There are two versions of methods I have tried to get data.
var app = new Vue({
el: "#weather",
data: {
city: '',
weather:[],
date: new Date().toDateString(),
greeting:''
},
methods: {
//method 1
getData: function () {
var city = this.city
$.getJSON("http://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=metric&lang=en&appid=a495404234abce9b5830b1e8d20e90a6",
function (data) {
console.log(data)
});
},
//method 2
getData: function () {
$("#search").keypress(function (e) {
if (e.which == 13) {
var city = $("#search").val();
if (city != " ") {
var url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=metric&lang=en&appid=a495404234abce9b5830b1e8d20e90a6";
console.log(url);
}
$.getJSON(url, function (data) {
this.weather = data.weather;
console.log(data);
this.returnGreeting();
})
}
})
},
}
}
});
<div class="container" id="weather">
<h1>Weather Pro</h1>
<div class="float-left"><h2>{{date}}</h2></div>
<div class="float-right" ><h3 id="time"></h3></div>
<p>{{greeting}}</p>
<div class="input-group">
<form>
<input v-model="city" class='searchbar transparent' id='search' type='text' placeholder=' enter city' />
<input id='button' #click="getData" type="button" value='GO' />
</form>
</div>
{{city}}
<div class="panel">
<div class="panel-body" v-for="d in data">
<p>
{{data}}
</p>
</div>
<ul class="list-group list-group-flush">
<!-- <li class="list-group-item">{{data.weather[0].main}}</li>
<li class="list-group-item">{{data.weather[0].description}}</li> -->
</ul>
</div>
</div>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I got an error :
[Vue warn]: Property or method "data" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Consider data to be your model. Don't reference data directly in your view, reference properties that are on the model instead.
So instead of <div>{{data.city}}</div> use <div>{{city}}</div>
var app = new Vue({
el: "#weather",
data() {
return {
city: '',
weather: [],
date: new Date().toDateString(),
greeting: ''
};
},
methods: {
getData() {
fetch("http://api.openweathermap.org/data/2.5/weather?q=" + this.city + "&units=metric&lang=en&appid=a495404234abce9b5830b1e8d20e90a6")
.then(res => res.json())
.then(data => {
this.weather = data.weather;
});
}
}
});
<div class="container" id="weather">
<h1>Weather Pro</h1>
<div class="float-left">
<h2>{{date}}</h2>
</div>
<div class="float-right">
<h3 id="time"></h3>
</div>
<p>{{greeting}}</p>
<div class="input-group">
<form>
<input v-model="city" class='searchbar transparent' id='search' type='text' placeholder=' enter city' />
<input id='button' #click="getData" type="button" value='GO' />
</form>
</div>
{{city}}
<div class="panel">
<div class="panel-body" v-for="d in weather">
<p>
{{d}}
</p>
</div>
<ul class="list-group list-group-flush"></ul>
</div>
</div>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I found out what caused the issues:
I need to define data in data, as I reference data directly in my html page, but this is optional.
Turns out there is a slim jQuery version from bootstrap that overrides the min jQuery. And $.getJSON() needs min jQuery.
looks like zero beat me to it, but here's a version using jquery call
the issue is, as mentioned in comment, that data.data is not defined. so define data inside data, and assign result to this.data. However, because it's inside a function and the scope changes, you need to store scope using var that = this and use that.data = data to assign result
dom:
<div class="container" id="weather">
<h1>Weather Pro</h1>
<div class="float-left"><h2>{{date}}</h2></div>
<div class="float-right" ><h3 id="time"></h3></div>
<p>{{greeting}}</p>
<div class="input-group">
<form>
<input v-model="city" class='searchbar transparent' id='search' type='text' placeholder=' enter city' />
<input id='button' #click="getData" type="button" value='GO' />
</form>
</div>
{{city}}
<div class="panel">
<div class="panel-body" v-for="d in data">
<p>
{{d}}
</p>
</div>
<ul class="list-group list-group-flush">
</ul>
</div>
</div>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Script:
var app = new Vue({
el: "#weather",
data: {
city: '',
weather:[],
date: new Date().toDateString(),
greeting:'',
data: null,
},
methods: {
//method 1
getData: function () {
var that = this;
var city = this.city
console.log('getData')
$.getJSON("https://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=metric&lang=en&appid=a495404234abce9b5830b1e8d20e90a6",
function (data) {
console.log(data)
that.data = data;
});
},
}
});
Here is an example fiddle.
I am trying to filter users by its data attribute , I have main div called user-append which contains users that I get from ajax get request , there can be 3 users or 100 users, its dynamical , this is my div with one user for the moment
<div id="user-append">
<div class="fc-event draggable-user" data-profesion="'+user.profesion+'" id="user_'+user.id+'" style="z-index: 9999;">
<div class="container-fluid">
<input type="hidden" value="'+user.id+'" id="user_'+ user.id + '_value" class="userId">
<div class="row" style="justify-content: center;">
<div class="col-xs-3 avatar-col">
<div class="innerAvatarUserLeft">
<img src="'+getUserImage(user.avatar)+'" width="100%" style="margin: 0 auto;">
</div>
</div>
<div class="col-xs-9 data-col">
<p class="fullName dataText">'+user.fullName+'</p>
<p class="usr_Gender dataText">Male</p>
<div style="position: relative">
<li class="availableUnavailable"></li>
<li class="usr_profesion dataText">AVAILABLE</li>
</div>
<p class="user_id" style="float:right;margin: 3px">'+user.employee_id+'</p>
</div>
</div>
</div>
</div>
</div>
as you can see I have data-profesion attribute from which I am trying to filter users depend on the profession that they have , I get the ajax request like this
$.ajax({
url: "/rest/users",
success: function (users) {
var options = [];
$user = $("#append_users");
$.each(users, function (i, user) {
options.push({
'profession': user.prof.Profession,
'gender': user.prof.Gender
});
userArr.push({
'id': user.id,
'firstName': user.prof.FirstName,
'lastName': user.prof.LastName,
'fullName': user.prof.FirstName + ' ' + user.profile.LastName,
'email': user.email,
'avatar': user.prof.Photo,
'profesion': user.prof.Profession
});
$('#filterByProfession').html('');
$('#filterByGender').html(''); // FIRST CLEAR IT
$.each(options, function (k, v) {
if (v.profession !== null) {
$('#filterByProfession').append('<option>' + v.profession + '</option>');
}
if (v.gender !== null) {
$('#filterByGender').append('<option>' + v.gender + '</option>');
}
});
});
});
and now I am trying to filter the users by its data-profesion, on change of my select option which I populate from the ajax get request , It should show only the users that contain that data-profesion value , something like this
$('#filterByProfession').change(function () {
var filterVal = $(this).val();
var userProfVal = $(".fc-event").attr("data-profesion");
if (filterVal !== userProfVal) {
}
});
You can use a CSS selector to find those users, and then hide them:
$('#filterByProfession').change(function () {
// first hide ALL users
$('.draggable-user').hide()
// then filter out the ones with the correct profession:
// (you need to escape the used quote)
.filter('[data-profesion="' + $(this).val().replace(/"/g, '\\"') + '"]')
// ... and show those
.show();
});
You're trying to get the userProfVal throughout a className selector which can return more than one element.
var userProfVal = $(".fc-event").attr("data-profesion");
^
Use the jQuery function .data() to get data attributes.
Look at this code snippet using the .each to loop over all elements returned by this selector .fc-event:
$('#filterByProfession').change(function() {
var filterVal = $(this).val();
$(".fc-event").hide().each(function() {
if ($(this).data("profesion") === filterVal) {
$(this).show();
}
});
});
Example with static data
$('#filterByProfession').change(function() {
var filterVal = $(this).val();
$(".fc-event").hide().each(function() {
if ($(this).data("profesion") === filterVal) {
$(this).show();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id='filterByProfession'>
<option>-----</option>
<option>Developer</option>
<option>Cloud computing</option>
</select>
<div id="user-append">
<div class="fc-event draggable-user" data-profesion="Developer" id="user_1" style="z-index: 9999;">
<div class="container-fluid">
<input type="hidden" value="1" id="user_1_value" class="userId">
<div class="row" style="justify-content: center;">
<div class="col-xs-3 avatar-col">
<div class="innerAvatarUserLeft">
<img src="'+getUserImage(user.avatar)+'" style="margin: 0 auto;">
</div>
</div>
<div class="col-xs-9 data-col">
Developer
<p class="fullName dataText">Ele</p>
<p class="usr_Gender dataText">Male</p>
<div style="position: relative">
<li class="availableUnavailable"></li>
<li class="usr_profesion dataText">AVAILABLE</li>
</div>
<p class="user_id" style="float:right;margin: 3px">11</p>
</div>
</div>
</div>
</div>
</div>
<div id="user-append">
<div class="fc-event draggable-user" data-profesion="Cloud computing" id="user_2" style="z-index: 9999;">
<div class="container-fluid">
<input type="hidden" value="2" id="user_2_value" class="userId">
<div class="row" style="justify-content: center;">
<div class="col-xs-3 avatar-col">
<div class="innerAvatarUserLeft">
<img src="'+getUserImage(user.avatar)+'" style="margin: 0 auto;">
</div>
</div>
<div class="col-xs-9 data-col">
Cloud computing
<p class="fullName dataText">Enri</p>
<p class="usr_Gender dataText">Male</p>
<div style="position: relative">
<li class="availableUnavailable"></li>
<li class="usr_profesion dataText">AVAILABLE</li>
</div>
<p class="user_id" style="float:right;margin: 3px">11</p>
</div>
</div>
</div>
</div>
</div>
See? the sections are being hidden according to the selected option.
Try using this
$(".fc-event[data-profesion='" + filterVal + "']").show();
$(".fc-event[data-profesion!='" + filterVal + "']").hide();
I'm using this plugin called Dragula which needs an ObservableArray as a source for the data..
HTML/Knockout-bindings
<div class="widget-container">
<div class="widget-content visible" id="team-setup">
<div class="header">
<p>Lagoppsett</p>
<p></p>
</div>
<div class="col-sm-12">
<div class="row">
<div class="widget-container">
<div class="col-xs-6 widget-content visible">
<div class="header">
<p>Tilgjengelige spillere</p>
<p></p>
</div>
<div class="player-card-container-mini" data-bind="dragula: { data: availablePlayers, group: 'playerz' } ">
<div class="player-card-mini">
<div class="player-card-left">
<div class="player-avatar" style="margin-left: 85%;">
<img src="Content/Images/player-female.png" id="imgAvatar" runat="server" />
<div class="player-shirt-no" data-bind="text: ShirtNo"></div>
</div>
</div>
<div class="player-card-subtext">
<div class="player-text">
<div class="player-card-header-small" data-bind="text: PlayerName"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-6 widget-content visible">
<div class="header">
<p>Lag</p>
<p></p>
</div>
<div data-bind="foreach: teamsetup">
<div data-bind="foreach: SubTeams">
<h1 data-bind="text: TeamSubName"></h1>
<div class="player-card-container-mini" data-bind="dragula: { data: Players, group: 'playerz' } " style="border: 1px solid red; min-height:200px">
<div class="player-card-mini">
<div class="player-card-left">
<div class="player-avatar" style="margin-left: 85%;">
<img src="Content/Images/player-female.png" id="img1" runat="server" />
<div class="player-shirt-no" data-bind="text: ShirtNo"></div>
</div>
</div>
<div class="player-card-subtext">
<div class="player-text">
<div class="player-card-header-small" data-bind="text: PlayerName"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="clear:both"> </div>
</div>
</div>
Knockout code :
var TeamSetupViewModel = function () {
var self = this;
self.teamsetup = ko.observableArray();
self.availablePlayers = ko.observableArray();
self.testPlayers = ko.observableArray();
}
var model = new TeamSetupViewModel();
ko.applyBindings(model, document.getElementById("team-setup"));
var uri = 'api/MainPage/GetTeamSetup/' + getQueryVariable("teamId");
$.get(uri,
function (data) {
model.teamsetup(data);
model.availablePlayers(data.AvailablePlayers);
model.testPlayers(data.AvailablePlayers);
console.log(data);
}, 'json');
});
The problem is... that i'm having a ObservableArray at the top node, and i do need ObservableArrays further down in the hierarchy.
model.availablePlayers works fine, but when accessing the other players in the html/ko foreach loops through teamsetup -> SubTeams -> Players it doesn't work due to Players isn't an ObservableArray. (There might be everyting from 1 to 7 SubTeams with players).
So how can i make the Players in each SubTeams an ObservableArray ?
See the image for the datastructure :
You could use Mapping plugin, but if players is the only thing you need, you can do it manually:
Simplify your view model:
var TeamSetupViewModel = function () {
var self = this;
self.availablePlayers = ko.observableArray();
self.subTeams = ko.observableArray();
}
After you get the data from the server, populate the view model converting the array of players on every team to an observable array of players:
$.get(uri,
function (data) {
model.availablePlayers(data.AvailablePlayers);
model.subTeams(data.SubTeams.map(function(t) { t.Players = ko.observableArray(t.Players); return t; }));
}, 'json');
});
Finally, remove the following line in your template (with its closing tag) - nothing to iterate over anymore:
<div data-bind="foreach: teamsetup">
... and update the name of the property in the next line, so it is camel case like in the VM:
<div data-bind="foreach: subTeams">
i have a problem when implementing pagedlist mvc in my website project. I used pagedlist mvc to show partial view. When button previous is click, the parameter doesn't complete pass, just the page number that pass and the other is null. This is my controller
public ActionResult StoreItemView(string jenis, string sorting_key, int? Page_No)
for previous button it will create link like this
localhost:20208/StoreItem/StoreItemView?Page_No=1
and has different with next button,that create link that contain all parameter
localhost:20208/StoreItem/StoreItemView?jenis=&sorting_key=&Page_No=2
why it's different call for previous and next button ?
i create the pager like this in cshtml
<div id="myPager">
#Html.PagedListPager(
Model,
page => Url.Action(
"StoreItemView",
new
{
jenis = ViewBag.jenis,
sorting_key = ViewBag.sorting_key,
Page_No = page
}
),
PagedListRenderOptions.PageNumbersOnly
)
</div>
and i use javascript too for load partial view , my javascript is
<script>
$(function () {
$('#myPager').on('click', 'a', function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
success: function (result) {
$('#container_item_store').html(result);
alert("sukses");
},
error: alert("bangsat")
});
return false;
});
});
</script>
I stuck in this problem almost 2 days. I hope the people who are here can help me. Thank you before :)
----EDIT------
#model PagedList.IPagedList<MVC_EDOLPUZ.Models.StoreItemModel>
#using System.Globalization
#using PagedList.Mvc
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
<h3><span class="label label-primary">DOLANAN PUZZLE ITEM</span></h3>
<select id="Sorting_Order" name="Sorting" onchange="reloadPartialDDL()">
<option value="0">-Urutkan Berdasarkan-</option>
<option value="nama">Nama</option>
<option value="rendah">Harga Terendah</option>
<option value="tinggi">Harga Tertinggi</option>
</select>
<div id="products" class="row list-group">
#foreach (var item in Model)
{
<div class="item col-xs-5 col-lg-3">
<div class="thumbnail">
<img class="group list-group-image img-responsive" src="#Url.Content(#item.gambar_barang)" alt="" />
<div class="caption">
<h4 class="group inner list-group-item-heading">
#item.nama_barang
</h4>
<p class="group inner list-group-item-text">
<span class="label label-warning">#item.deksripsi_barang</span>
</p>
<div class="row">
<div class="col-xs-1 col-md-6">
<input id="#item.nama_barang" type="number" class="rating" min="1" max="5" step="0.5" data-size="xs" value="#item.rating_barang">
</div>
<script>
$('##item.nama_barang').rating('refresh', { disabled: true, showClear: false, showCaption: false });
</script>
</div>
<div class="row">
<div class="col-lg-5 col-xs-4">
<p class="lead" style="font-weight: bolder; color: red;">
#string.Format(new CultureInfo("id-ID"), "{0:C}", #item.harga_barang)
</p>
</div>
<div class="col-lg-1 col-xs-2">
<a class="btn btn-success btn-responsive btn-xs" onclick="addItemToCart('#item.id_barang')" href="#">Add to cart</a>
</div>
</div>
</div>
</div>
</div>
}
</div>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#*#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))*#
<div id="myPager">
#Html.PagedListPager(
Model,
page => Url.Action(
"StoreItemView",
new
{
jenis = ViewBag.jenis,
sorting_key = ViewBag.sorting_key,
Page_No = page
}
),
PagedListRenderOptions.PageNumbersOnly
)
</div>
<script>
$(function () {
$('#myPager').on('click', 'a', function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
success: function (result) {
$('#container_item_store').html(result);
alert("sukses");
},
error: alert("bangsat")
});
return false;
});
});
</script>
that's my code for the view, and this controller that handle it's view
[HttpGet]
public ActionResult StoreItemView(string jenis, string sorting_key, int? Page_No)
{
ViewBag.jenis = jenis;
ViewBag.sorting_key = sorting_key;
List<StoreItemModel> products = StoreItemRepository.getItemList(jenis, sorting_key);
foreach (var items in products)
{
items.rating_barang = StoreItemRepository.getRatingBarang(items.id_barang);
}
int Size_Of_Page = 4;
int No_Of_Page = (Page_No ?? 1);
PagedList.PagedList<StoreItemModel> show = new PagedList.PagedList<StoreItemModel>(products, No_Of_Page, Size_Of_Page);
return PartialView("_StoreItem", show);
}
Please use like below
<div id="myPager" location="Url.Action("StoreItemView", new {jenis = ViewBag.jenis, sorting_key = ViewBag.sorting_key, Page_No = page})">
#Html.PagedListPager(
Model,
page => Url.Action("StoreItemView"),
PagedListRenderOptions.PageNumbersOnly
)
and javascript must be like
Before using the please check ViewBag.sorting_key and ViewBag.jenis is holding any value using alert in javascript. and I am not qable to see any tag with id="container_item_store". Make sure the container_item_store id must be place in some where in your view.
<script>
$(function () {
$('#myPager').on('click', 'a', function () {
var location = $(this).attr('location');
$.ajax({
url: location,
type: 'GET',
cache: false,
success: function (result) {
$('#container_item_store').html(result);
alert("sukses");
},
error: alert("bangsat")
});
return false;
});
});
I am using knockout js to get my data to display and i am also using it to bind templates. I have a page that displays the same information in two different ways: one is a grid view and the other is a list view. Currently i have both views displayed on the page load. I would like to create two buttons one for the grid and one for the list. I am not sure how to go about it with Knockout js any tips or help is appreciated.
View Page
<div data-bind="template: {name:'grid-template'}, visible: !showList()"></div>
<div data-bind="template: {name:'list-template'}, visible: showList()"></div>
<input type="button" value="Toggle" data-bind="click: toggleView"/>
<script style="float:left" type="text/html" id ="grid-template">
<section " style="width:100%; float:left">
<section id="users" data-bind="foreach: Users">
<div id="nameImage">
<figure id="content">
<img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<figcaption>
<a title="Email" id="emailIcon" class="icon-envelope icon-white" data-bind="attr:{'href':'mailto:' + Email()}"></a>
<a title="Profile" id="profileIcon" class="icon-user icon-white"></a>
</figcaption>
</figure>
<p data-bind="text:Name"></p>
</div>
</section>
</section>
</script>
<script style="float:left" type="text/html" id="list-template">
<div data-bind="foreach: Users">
<div style="width:60%; float:left; margin:10px; height:58px">
<img style="float:left; margin-right:5px" width="58" height="58" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<p style="height:58px; float:left; vertical-align:central" data-bind="text:Name"></p>
<a style="float:right" title="Profile" class="icon-user icon-black"></a>
<a style="float:right" title="Email" class="icon-envelope icon-black" data-bind="attr:{'href':'mailto:' + Email()}"></a>
</div>
</div>
</script>
#section scripts{
#Scripts.Render("~/bundles/user" + ViewBag.Layout.AppVersionForUrls)
<script type="text/javascript">
(function ($) {
$.views.User.GetUser('#url');
})(jQuery);
</script>
}
Knockout JS
$.views.User.UserViewModel = function (data) {
var self = this;
self.Name = ko.observable(data.Name);
self.Email = ko.observable(data.Email);
self.ContentRole = ko.observable(data.ContentRole);
self.MD5Email = ko.observable(data.MD5Email);
self.GravatarUrl = ko.computed(function () {
return 'http://www.gravatar.com/avatar/' + self.MD5Email() + '?s=300&d=identicon&r=G';
});
self.showList = ko.observable(true);
self.toggleView = function () {
self.showList(!self.showList());
}
};
If I understand correctly, you could bind the visible property of each div to a boolean that you flip each time a button is pressed.
HTML:
<input type="button" value="Toggle" data-bind="click: toggleView"/>
<div data-bind="visible: showGrid()">Grid</div>
<div data-bind="visible: !showGrid()">List</div>
View Model:
var ViewModel = function() {
var self = this;
self.showGrid = ko.observable(true);
self.toggleView = function() {
self.showGrid(!self.showGrid());
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
Here's a jsFiddle.