looping collection in knockoutjs in to ul - asp.net-mvc

I have json collection like this
0: {FamilyDetailId:1, Name:Daniel, GenderId:1, Dob:/Date(1375554600000)/,…}
1: {FamilyDetailId:3, Name:Askar, GenderId:1, Dob:/Date(1375554600000)/,…}
var employeeFamilyModel;
function bindModel(data) {
employeeFamilyModel = ko.mapping.fromJS(data);
ko.applyBindings(employeeFamilyModel, document.getElementById("collapseOne"));
}
function loadData (employeeGuid) {
$.ajax({
url: "/HumanResource/EmployeeProfile/EmployeeProfileFamily?employeeGuid=" + employeeGuid,
type: 'post',
contentType: 'application/json',
success: function (result) {
bindModel(result);
}
});
};
view
<ul data-bind="foreach: employeeFamilyModel">
<li data-bind="text: Name"></li>
</ul>
my problems is to display each collection in new UL list
ex :
<ul>
<li> Name: Daniel </li>
</ul>
<ul>
<li> Name: Askar </li>
</ul>
how to achieve this in knockoutjs ?

Everything you have inside ko foreach block will be repeated like foreach loop. And everything you have in ko text will just output without any element around.
<!-- ko foreach: employeeFamilyModel -->
<ul>
<li>Name: <!--ko text: Name--><!--/ko--></li>
</ul>
<!-- /ko -->

To elaborate, you simply need to move your foreach binding 'up' a level, so that the <ul> is included for each data element in your view model.
JS:
employeeFamily = ko.observableArray([{Name: 'John Doe', Owner: 'John'},
{Name: 'Jane Doe', Owner: 'Jane'}])
ko.applyBindings(employeeFamily, document.getElementById("collapseOne"));
Html:
<div id = 'collapseOne' data-bind="foreach: employeeFamily">
<label data-bind="text: 'This list belongs to ' + $data.Owner"></label>
<ul>
<li data-bind="text: $data.Name"></li>
</ul>
</div>
Result:
This list belongs to John
John Doe
This list belongs to Jane
Jane Doe
I added the owner attribute to emphasize that each <ul> was bound to a different $data element. See JSFiddle example

Related

How to get descendants from current page in Umbraco 7?

I have a document type with alias dArticlesMain, and for this page I have the following structure.
dArticlesMain
dArticlesCategory1
Article1
Article2
Article3
dArticlesCategory2
Article1
Article2
Article3
dArticlesCategory3
Article1
Article2
Article3
I'm on dArticlesMain and i want to display all the descendants (Articles) and skip it's childrens (dArticlesCategory)
I have this code which display all the childrens (dArticlesCategory) and the descendants (Articles) also when i use the Article properties it's through an error.
<ul>
#foreach(var page in Model.Content.Descendants())
{
<li>#page.Name</li>
}
</ul>
I have got this code but i can't display by Article properties like articleText or articleImage.
<ul>
#foreach(var page in Model.Content.DescendantsOrSelf().OfTypes("Article"))
{
<li>#page.Name</li>
}
</ul>
I have figured it out, and here's my code...
#{
var rootNode = CurrentPage.AncestorOrSelf(1);
var articlesParent = rootNode.Children("dArticlesMain").FirstOrDefault();
<div class="row">
#foreach (var article in articlesParent.Descendants("article").Where("Visible").RandomOrder())
{
<div class="col-sm-6 col-md-3">
<div class="thumbnail">
<a href="#article.Url">
<img src="#article.articlePhoto" alt="#article.articleName" />
</a>
<div class="caption">
<a class="h4" href="#article.Url">#article.articleName</a>
#Umbraco.Truncate(article.articleFullText, 100)
</div>
</div>
</div>
}
</div>
}

Action Link in Knockout foreach data binding

I'm trying to bind data to Action Link within Knockoutjs foreach loop. This code works fine
<ul data-bind="foreach: ItemList">
<li>
<a data-bind="attr: { 'href': '#Url.Action("Items", "ItemController")' }" >
LinkText
</a>
</li>
</ul>
But I also need to bind a parameter and bind the LinkText with knockoutjs. I tried different code samples but nothing seems to work.
Final code should be something like,
<ul data-bind="foreach: ItemList">
<li>
<a data-bind="attr: { 'href': '#Url.Action("Items", "ItemController")', new { id = DataBindId)' }" >
DataBindName
</a>
</li>
</ul>
How can I make this work?
Try this...
<a data-bind="attr: { 'href': '#Url.Action("Items", "ItemController")?id=' + DataBindId }, text: DataBindName" >
</a>
Which should output something like...
<a data-bind="attr: { 'href': '/Item/Items?id=' + DataBindId }, text: DataBindName" >
</a>

Cannot get jqueryui tabs to work properly in Ember view

I'm trying to run up a little prototype in Ember.JS at the moment with a view to completely re-writing the UI of a web application as an Ember Application running against a WebAPI, but although I've managed to get Ember running OK, I cannot get jqueryui to initialise the tabs correctly.
It seems to work fine if within the view I put static data for tabs to be created from, but if I'm using dynamic data then it just doesn't work.
I have an Ember view template
<script type="text/x-handlebars" id="index">
<div id="tabs" class="ui-tabs">
<ul>
{{#each model}}
<li>
<span class="ui-icon ui-icon-person"></span>
<a {{bindAttr href="route"}} {{bindAttr title="tabTitle"}}><span>{{title}}</span></a>
</li>
{{/each}}
</ul>
{{#each model}}
<div {{bindAttr id="tabTitle"}}>
<p>
Retrieving Data - {{title}}
</p>
</div>
{{/each}}
</div>
</script>
and a view
App.IndexView = Ember.View.extend({
templateName: 'index',
didInsertElement: function () {
var tabs = $("#tabs").tabs();
}
});
and a model
App.Section = DS.Model.extend({
name: DS.attr('string'),
title: DS.attr('string'),
tabTitle: function () {
return 'tab-' + this.get('name');
}.property("name"),
route: function () {
return '#' + this.get('tabTitle');
}.property("tabTitle")
});
App.Section.FIXTURES = [
{
id: 1,
name: 'home',
title: 'Home'
},
{
id: 2,
name: 'users',
title: 'Users'
}
];
It appears to generate the HTML correctly (from checking in Firebug), but this does not work, where as if I replace the template with
<script type="text/x-handlebars" id="index">
<div id="tabs" class="ui-tabs">
<ul>
<li>
<span class="ui-icon ui-icon-person"></span>
<span>Home</span>
</li>
<li>
<span class="ui-icon ui-icon-person"></span>
<span>Users</span>
</li>
</ul>
<div id="tab-home">
<p>
Retrieving Data - Home
</p>
</div>
<div id="tab-users">
<p>
Retrieving Data - Users
</p>
</div>
</div>
</script>
it works perfectly.
I'm assuming that it's something to do with the DOM not being completely rendered by the time the tabs are initialised, but everything I can find says that didInsertElement is the place to do it, and I have had time to dig deeper yet.
I'd be grateful for any ideas.
Edit: I've managed to make this work in a fashion by doing the following:
App.IndexView = Ember.View.extend({
templateName: 'index',
didInsertElement: function () {
Ember.run.next(this, function () {
if (this.$('#tab-users').length > 0) {
var tabs = $('#tabs').tabs();
} else {
Ember.run.next(this.didInsertElement);
}
});
},
});
The problem with this is that 1) it requires me to know what one of the last elements that will be written to the view is called (and obviously with dynamic data I won't necessarily know that), so that I can keep checking for it, and 2) the inefficiency of this technique makes me want to scream!
In addition, we get a good old FoUC (Flash of Unstyled Content) after things have been rendered, but before we then get JQueryUI to style them correctly.
Any suggestions gratefully received.
It's still not nice... but this at least does work, and is reasonably efficient...
From Ember.js - Using a Handlebars helper to detect that a subview has rendered I discovered how to write a trigger, and because of the way that the run loop seems to work, inserting the trigger in the last loop on the page causes it to be called n times, but only after the loop is complete, so a quick state check "hasBeenTriggered" ensures that you only execute the delgate function once.
My code now looks like this:
<script type="text/x-handlebars" id="index">
<div id="tabs" class="ui-tabs">
<ul>
{{#each model}}
<li>
<span class="ui-icon ui-icon-person"></span>
<a {{bindAttr href="route"}} {{bindAttr title="tabTitle"}}><span>{{title}}</span></a>
</li>
{{/each}}
</ul>
{{#each model}}
<div {{bindAttr id="tabTitle"}}>
<p>
Retrieving Data - {{title}}
</p>
</div>
{{trigger "triggered"}}
{{/each}}
</div>
</script>
with the trigger
Ember.Handlebars.registerHelper('trigger', function (evtName, options) {
options = arguments[arguments.length - 1];
var hash = options.hash,
view = options.data.view,
target;
view = view.get('concreteView');
if (hash.target) {
target = Ember.Handlebars.get(this, hash.target, options);
} else {
target = view;
}
Ember.run.next(function () {
target.trigger(evtName);
});
});
and view
App.IndexView = Ember.View.extend({
templateName: 'index',
hasBeenTriggered: false,
triggered: function () {
if (!this.get("hasBeenTriggered")) {
var tabs = $('#tabs').tabs();
this.set("hasBeenTriggered", true);
}
}
});
I'd love to know if there's a better way of doing this, as this still doesn't get round the FOUC problem either (which again can be done with more JS hacks)... :(

how to disable a specific element of selectable list

I want to disable a specific element of a selectable list.
I am able to disable the whole list, but when I try with specific element, it doesn't work.
$('#disableButton').click(function(){
$('#selectable li#b ').selectable('disable');
});
http://jsfiddle.net/Komlan/RYWaZ/1/
Here is my code
//reset seats
function resetSelect(){
var options = { filter: "li.selectable" };
$( "#selectable").selectable(options);
}
//Ajax get taken seats
$('input[name="choice"]').change(function(){
resetSelect();
var sc_id = $('input:radio[name=choice]:checked').val();
$.ajax({
url: 'seatings.php',
data:{ sc_id:sc_id},
type: "POST",
dataType:'text',
success: function(data){
var id = data.split(",");
for (var i=0;i<id.length -1;i++){
alert(id[i]);
var string = "#"+id[i];
$(string).css("color","red");
$('#selectable li'+string).removeClass("selectable ui-selected");
}
var options = { filter: "li.selectable" };
$( "#selectable" ).selectable('destroy').selectable(options);
}
});
});
In summary, I'm getting a series of id and disable them one after the other, every time there is a change on my radio button group.
There is no straight way to do this (AFAIK), but here's a little hack you can use (and remember, it's just a hack and maybe not the best):
Add the css class "selectable" (or whatever you want):
<ol id="selectable">
<li class="ui-widget-content selectable" id="ok"> 1</li>
<li class="ui-widget-content selectable"> 2</li>
<li class="ui-widget-content selectable"> 3</li>
<li class="ui-widget-content selectable"> 4</li>
<li class="ui-widget-content selectable"> 5</li>
<li class="ui-widget-content selectable"> 6</li>
<li class="ui-widget-content selectable"> 7</li>
</ol>
And then use a filter on that css class:
// Create a filter to only make <li> with the specified css class, selectable.
var options = { filter: "li.selectable" };
$( "#selectable" ).selectable(options);
$('#lol').click(function(){
console.log('dsfds');
// Remove/add (toggle) the class used in the filter on the <li> you want to remove the selectable.
// (Also remove the ui-selected in case it's selected.)
$('#selectable li#ok').toggleClass("selectable").removeClass("ui-selected");
// Now destroy the selectable and re-create it with the filter again.
// We removed the css class from a <li> used in the filter, so it won't be selectable again.
$( "#selectable" ).selectable('destroy').selectable(options);
});
Updated: http://jsfiddle.net/RYWaZ/7/
References:
Selectable filter
.toggleClass()
Actually you can achieve this now.
You've got to add the class you want to your item, for example "unselectable", and use this css trick in your filter option : item:not(.unselectable)
Html :
<ul id="selectable">
<li class="unselectable"> 1</li>
<li> 2</li>
<li> 3</li>
</ul>
Jquery :
$( "#selectable" ).selectable({
filter:"li:not(.unselectable)"
});
You'll be able to select all the li children of #selectable, excepted the li which has the .unselectable class. Then you just have to toggle this class when it is necessary.

knockout.js mapping custom events

I try to build a simple blog application with knockout.js and rails.
(knockout v1.3 beta, knockout mapping plugin v2.0.2)
<h3>Posts</h3>
<ul data-bind="foreach: posts">
<li>
<input data-bind="value: title" />
</li>
</ul>
<script>
var posts = ko.mapping.fromJSON('<%= #posts.to_json.html_safe %>');
ko.applyBindings(posts);
</script>
this displays alle the posts from a rails app, no problem so far.
but now i want to add a custom event to the posts, e.g. a remove event.
i tried this:
<h3>Posts</h3>
<ul data-bind="foreach: posts">
<li>
<input data-bind="value: title" />
</li>
</ul>
<script>
var posts = ko.mapping.fromJSON('<%= #posts.to_json.html_safe %>', { remove: function() {
alert('working');
});
ko.applyBindings(posts);
</script>
but i get an error "remove is not defined"
any ideas?
you could just add the function to the posts viewModel, like this:
var posts = ko.mapping.fromJSON('<%= #posts.to_json.html_safe %>');
posts.remove = function() { alert('working'); }

Resources