I need to have multiple data bindings on one element. For example, I want a href as well as a html data-binding on one a tag. I have tried this,
<a data-bind="html: name"
data-bind="attr: { href: url }"
data-bind="attr: { 'data-prop': xyz }">
</a>
But this doesn't work. It seems knockout only supports binding one data-bind property? How to bind both the href, the inner html, and a custom "data-prop" attribute on one element?
Like this:
<a data-bind="html: name, attr: { href: url }">
You use comma-separated bindings - the attribute is the same as passing an object:
{
html: name,
attr: { href: url }
}
Or, if you're asking about multiple attr bindings at once:
<a data-bind="html: name, attr: { href: url, 'data-prop': FullName }">
This is how I implemented the source attribute and click event using data-bind. You may find it useful.
<img data-bind="{click: function(data, event) {ESVendorWidget.loadFunction(data,event)},
attr: {src: $data.Photo.PhotoUrl }}"
alt="package pic" class="big" />
I simply use:
<input type="checkbox"
data-bind="click: callFunction(), checkedValue: 0, checked: Card.Days">
for a checkbox element.
you can use multiple properties using , like below
<a data-bind="attr: { href: url, id: id , class: classvalue}">
object like this
{ url: 'http://stackoverflow.com', id:'newid' , classvalue: 'classname' }
you can use like below
data-bind="text: method.method_title, attr: {'id': 'label_method_' +
method.method_code}"
Related
There is a code I'm working on - https://jsfiddle.net/md_bender/pj6a1akz/3/. I need to create new elements and append them to the existing element ul. With creating elements and appending everything is OK.
But I don't know how to create child element in the created element. I need to create
<img src="path"/>
In the div I have created earlier in script. It must be like that
<div class="img-w js-popup">
<img src="path"/>
</div>
Delete
But only I can do is create as next sibling to the div
<div class="img-w js-popup"></div>
<img src="path"/>
Delete
Who can help me and solve my problem?
You can append img to div before you append that div to li. You can also write the same code like this Fiddle
$('<li/>')
.append($('<div/>', {
'class': 'img-w js-popup',
}).append($('<img/>', {
'src': '//www.gravatar.com/avatar/9142888a2ae6160f2faec90134eeafa3/?default=&s=80'
})))
.append($('<a/>', {
href: 'delete.php',
text: 'Delete'
}))
.appendTo('ul');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<div>
<img src="//www.gravatar.com/avatar/9142888a2ae6160f2faec90134eeafa3/?default=&s=80" alt="" />
</div>
Delete
</li>
</ul>
The issue is because your append() call is on the li itself, not the div you just added. Try this:
var $div = $('<div/>', {
'class': 'img-w js-popup'
});
$('<img/>', {
'src': '//www.gravatar.com/avatar/9142888a2ae6160f2faec90134eeafa3/?default=&s=80'
}).appendTo($div)
$('<li/>').append($div).append($('<a/>', {
href: 'delete.php',
text: 'Delete'
})).appendTo('ul');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<ul>
<li>
<div>
<img src="//www.gravatar.com/avatar/9142888a2ae6160f2faec90134eeafa3/?default=&s=80" alt="" />
</div>
Delete
</li>
</ul>
With that said, you're using the most verbose method of creating HTML. As you're hard-coding all attributes, it can be simplified by just providing the plain string - or even by just cloning the previous li and appending that.
If do not need single DOMs (li, div, img) its easier to create static string and append whole into list, just like that (remember about backslashes):
$('ul').append("<li><div><img src=\"//www.gravatar.com/avatar/9142888a2ae6160f2faec90134eeafa3/?default=&s=80\" alt=\"\"/></div>Delete</li>");
$('<li/>')
.append($('<div/>', {
'class': 'img-w js-popup',
}))
.append($('<div/>', {
'id': 'idOFDiv'
}))
.append($('<a/>', {
href: 'delete.php',
text: 'Delete'
}))
.appendTo('ul');
$("#idOFDiv").append($('<img/>', {
'src': '//www.gravatar.com/avatar/9142888a2ae6160f2faec90134eeafa3/?default=&s=80'
}));
I just started using knockout and having some problems using foreach.
I need to dynamically populate a list with "collapsing" div.
I cant figuer out how to set the
"data-target=""" with the according div id.Is there a kind of $index as in Angular.How do i declare it inside of the data-target?
Thank for the help.
<ul class="nav navbar-nav side-nav">
<li data-bind="foreach: { data: categories, as: 'category' }">
<div id="??" class="collapse">
<h1>Some text</h1>
</div>
</li>
</ul>
Do it within the data-bind:
<a href="javascript:;" data-toggle="collapse" data-bind="attr: { 'data-target': ... }">
<div class="collapse" data-bind="attr: { id: ... }">
Knockout does have a $index context property, too:
<div data-bind="attr: { id: 'foo' + $index() }">
What's data-target being used for? I don't think you not need that in the first place.
If you want to toggle a section, I recommend using a more natural way to solve this. In the context of knockout this means: write a binding handler that encapsulates the behavior you want.
Expressed in simplest terms: You want to click on something and it should toggle something else. For example the visibility of the following <h1>
The minimal thing to do would be: Toggle a CSS class and use that to influence visibility.
Here is a binding handler that switches a CSS class on and off. Together with the simplest CSS you get collapse/expand behavior.
ko.bindingHandlers.toggleClass = {
init: function (element, valueAccessor) {
ko.utils.registerEventHandler(element, 'click', function () {
var cssClass = valueAccessor(),
shouldHaveClass = element.className.indexOf(cssClass) < 0;
ko.utils.toggleDomNodeCssClass(element, cssClass, shouldHaveClass);
});
}
}
ko.applyBindings({
categories: [
{title: 'Category A'},
{title: 'Category B'},
{title: 'Category C'},
{title: 'Category D'}
]
});
.collapsed+.collapse {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: categories">
<li>
<div class="collapse">
<h1>Some text</h1>
</div>
</li>
</ul>
Of course you can use all kinds of more advanced techniques, but the principle would stay the same. Define a behavior, attach that behavior to an element via a binding handler.
This is my Razor Page containing multiple divs with each div containing either follow or unfollow button with NeighbourhoodName and other stuff.
<p class="lead" style="display: none" data-bind="visible: profiles().length == 0">No neighbourhood found...</p>
<ul data-bind="visible: profiles().length > 0, foreach: profiles">
<li class="media" style="border-top: solid 1px lightgrey; padding-top: 15px;">
<div class="media-body">
<h4 class="media-heading">
<a class="btn pull-right" data-bind="visible: !IsFollowed, attr: { href: followAction }">Follow</a>
<a class="btn btn-danger pull-right" data-bind="visible: IsFollowed, attr: { href: unfollowAction }">Unfollow</a>
</h4>
<em data-bind="text: NeighbourhoodName"></em>
<em data-bind="text: NeighbourhoodId"></em>
//stuck at this line
</div>
</li>
I want to Generate a new page with click on any of the div. So,I want to send id of the neighbourhood to action method with click on respective div. Right now, i am able to get NeighbourhoodId with data-bind attribute but dont know how to send this id to action method with click on any area of div means how to mix this anchor tag. something like that.
This is my follow action url in a knockout code which send neighbourhoodId on follow button click:
self.followAction = location.protocol + "//" + location.host + '/Neighbourhood/Follow?uid=' + data.NeighbourhoodId;
But, i dont want any button. simple click on div should send id to action method.
how to achieve this. please suggest me something.
You simply have to use the click binding on the div, and bind it to a function in your viewmodel.
The function in your viewmodel receives as parameter the knockout context available in the bound element. So, you can directly access the desired data from that function.
<div class="media-body" data-bind="click: yourViewModelFunction">
In your viewmodel, your function should be implemented like this:
yourViewModelFunction = function(data) {
// here you can use data.NeighbourhoodId
}
hi this is my code snippet:
<div class="showtimes" data-bind="visible: showHide">
<div data-bind="template: { name: 'movie-grouped-showtimes-template', data: $data }"></div>
</div>
I want to toggle showHide off and on using the following:
<a class="icon arrow" data-bind="click: $parent.showtimes">
can't I just set up a variable showHide in my view Model, like the following:
self.showHide = ko.observable(false) ... Hide
showHide(true); ... show
and can I set it using the click : $parent.showtimes, like in the following:
<a class="icon arrow" data-bind="click: $parent.showtimes"></a>
You just have to set a function in the viewmodel that binds to the button's click (or modify an existing one, like showTimes in this case) to toggle the value of showHide.
Here's a simple example: http://jsfiddle.net/EfrainReyes/LNzDL/
var vm = {
showHide: ko.observable(false),
toggle: function() {
this.showHide( !this.showHide() );
}
};
ko.applyBindings(vm);
I didn't add any other elements to the example because the question seems to be targeted more towards showing/hiding the div.
Let's say i have,
<span class="cls1 cls2" data-bind="title: title" ></span>
I want to add another class via JSON object,
{ title: 'a', clas: 'cls3' }
This work's,
<span class="cls1 cls2" data-bind="attr:{title: title,'class': 'cls1 cls2'+clas}" ></span>
But the problem is that it will add two class attributes. I need the cls1 and cls2 class on beginning. But need cls3 class after some event.
You should use css binding instead of attr for this. Read more about it in the documentation: http://knockoutjs.com/documentation/css-binding.html.
You code will look something like this:
<span class="cls1 cls2" data-bind="text: title, css: myClass" ></span>
Here is working fiddle: http://jsfiddle.net/vyshniakov/gKaRF/
Using multiple classes:
<span
class="yourClass"
data-bind="css: { myClass: (true == true), theirClass: (!true == false), ourClass: true }"
>Thine Classes</span>
You can use the css binding to do this:
<span class="cls1 cls3" data-bind="css: clas"/>
This adds the value of your "clas" property to the current class collection of the element