Dynamic binding of li items click event - javascript

I have durandal and knockout web application.
I have a html as follows:
<ul id="header">
</ul>
In .js function I am adding li dynamically as:
$("#header).append('<li id="btn"> <span class="name">Test</span></li>')
ko.applyBindingsToNode(ul);
I am aware of the fact that I am binding the li after applyBindings has been called. To add it dynamically I am using
ko.applyBindingsToNode(ul); , but still no luck.
Can anyone please tell me whats the syntax/alternative solution for this?

// begins a JavaScript comment. This means that everything after <a href="javascript: is commented out, and the resulting code will look something like this:
$("#header).append('<li id="btn"><a href="javascript:
ko.applyBindingsToNode(ul);
Furthermore, the ko.applyBindingsToNode call will be part of the ' string opened just after the opening brackets on the append call.
To resolve this, you need to escape those comments by placing backslashes before them:
href="javascript:\/\/"

Refer to the demo here.
Please find the code below:
HTML:
<ul id="header">
</ul>
JS:
$(function() {
$("#header").append('<li id="btn">' + ' <span class="name">Test</span></li>');
//ko.applyBindingsToNode(ul);
});

using foreach:
var DemoPage = (function() {
function DemoPage() {
var _this = this;
_this.buttons = ko.observableArray([]);
_this.debug = ko.observable('');
_this.testmethod = function(data, event) {
_this.debug('Clicked LI: ' + data.buttonId);
}
_this.addHeadingRow = function() {
_this.buttons.push({
buttonId: Math.floor(Math.random() * 100)
});
}
}
return DemoPage;
})();
var demoApp = new DemoPage();
ko.applyBindings(demoApp);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul id="header" data-bind="foreach: buttons">
<li id="btn">
<a data-bind="click: $root.testmethod">
<span class="name">Test</span>
</a>
</li>
</ul>
<button data-bind="click: addHeadingRow">add heading row</button>
<p data-bind="text: debug"></p>

I would like to answer my own question.
The solution is very simple .
In the .js file define an observable array
self.arraysample = ko.observableArray([]);
In a method populate the array with data
self.arraysample.push(data)
In the html page , we can do this:
<ul id="head" data-bind:"foeach:arraysample">
<li>
<a id="btn">
<span data-bind="text:$data.arrayelement"></span>
</a>
</li>
</ul>
Thats it whenevr the data in the "self.arraysample" changes, automatic updating will take place because of knockout js properties.
I hope it helps someone because ,I have seen so many examples in the web advising to use ko.applyBindings() once again which doesnt work at all.

Related

In JavaScript, or jQuery, how do I accurately grab an attribute to manipulate the active selector?

Ultimately I'm wanting the user to click on the Landing Page next to an image on either Print or Mug. Then on the Order Page have the button for Print/Mug be active and then the image that's associated be marked as well.
So I have in Landing Page the following code:
<ul class="dropdown-menu">
<li>
Print
</li>
<li>
Mug
</li>
</ul>
Then in the Order Page the following code:
<div class="img-container1 image-container" image_var="main_image.jpg">
<%= image_tag('main_image.jpg') %>
<div class="wk-after">
<div class="centered-wk">
<span class="fa fa-check-circle check-circle"></span>
</div>
<div class="centered-wk wk-select">
SELECTED
</div>
</div>
</div>
My thought process was to then grab from the Order Page the image_var attribute and make it active.
So far I've been using:
<script>
function toggleActive() {
var activeElements = document.querySelectorAll('image_var');
activeElements.forEach(function (el) {
el.classList.remove('active');
});
btn.classList.add('active');
}
</script>
This isn't working. I don't know what the best way to grab the image_var or a url parameter. What am I missing?
I've also tried:
<script>
function toggleActive() {
var activeElements = document.querySelectorAll('[image-var]');
activeElements.forEach(function (el) {
el.classList.remove('active');
});
btn.classList.add('active');
}
</script>
With an update to the div on the container to be image-var to match. Still not touching the image.
I feel like this should be working with jQuery:
<script>
$(function(){
$.url.attr('image')
$.url.attr('type')
});
</script>
Wouldn't this be pulling out the main_image.jpg and then the print from type?

JavaScript /Jquery : A for loop function with some special usage

This application have 2 components, a HTML page which contain some element and a JavaScript to generate buttons.
I will try to give out a simplify example in the question for now, but if there's something unclear then i would upload the full code later.
I am using HandleBar.js to generate different contents in the html but don't worry if you don't have any idea about this plugin i will make another non-handlebar.js version.
Consider the Html part looks like below:
HandleBar.js version
//example:
//{{feedId}} = 0t454g465754754h456
//{{url}} = www.jegdo.co.uk
{{each}}
<div class="feedIdChecker">{{feedId}}</div>
<div class="{{feedId}}-EditRegionUrl" >{{url}}</div>
<button class="output-{{feedId}}">Output</button>
{{/each}}
Then i have a JQuery function which would output the url
var feedId = $(".feedIdChecker").html();
$('".output-'+feedId+'"').click(function(){
var postUrl = $('".'+feedId+'-EditRegionUrl"').html();
console.log(postUrl );
});
});
}
I found there's no way to identify which button is which. Since i need to declare the var feedID outside the button, it would always get the first feedID it founds and append to all buttons, how may i solve it? Please tell me if this question is confuse, i will try to explain it in a better way.
There's lots of people trying to help me but it seem i need to give out some more details in order for better understanding:
Javascript:
var initRegionEdit = function(){
var feedId = $(".feedIdChecker").html();
$(".CTHK").click(function(){
var postUrl = ($(this).prev('div').html());
})
}
HTML
<div class="EditRegionUrl" >{{url}}</div>
<div class="feedIdChecker">{{feedId}}</div>
{{#if region}}
<span class="dropdown"><i class="fa fa-map-marker" aria-hidden="true" style="color:gray;"></i>
<span class="result-date result-date-region" type="button" data-toggle="dropdown">{{region}}
<span class="caret"></span></span>
<ul class="dropdown-menu" style="min-width:100px;text-align:center;">
<li class="CTHK" data-url="{{url}}" style=" margin-top: 0px !important;margin-bottom: 0px !important;">Hong Kong</li><div class="divider"></div>
<li class="CTTW" style=" margin-top: 0px !important;margin-bottom: 0px !important;">Taiwan</li><div class="divider"></div>
</ul>
</span>
{{/if}}
I wish above information can help
So when you select $(".feedIdChecker") you actually get an array of all matching elements, but as soon as you call .html it only gets you the first. So to solve your issue we need to loop over all the $(".feedIdChecker")s like so:
$(".feedIdChecker").each(function(i, e) {
var feedID = $(e).html();
$('.output-'+feedID).click(function(){
var postUrl = $("." + feedID + "-EditRegionUrl").html();
console.log(postUrl);
});
});
This will attach the click handler to each of the buttons.
You could use the handlebars.js each/index feature to do this:
<button id="whatever-{{#index}}"
class="output-{{feedId}}">
Output
</button>
I'm assuming you need an answer on how to apply a unique id to each button, not how to bind click handlers to them (which other people have answered anyway)
May this version be quicker and with less code.
$('[class*=output-]').click(function() {
var feedId = this.className.split("-")[1];
var postUrl = $('.EditRegionUrl-' + feedId).html();
alert(postUrl);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="feedIdChecker">1</div>
<div class="EditRegionUrl-1" >URL1</div>
<button class="output-1">Output1</button>
<div class="feedIdChecker">2</div>
<div class="EditRegionUrl-2" >URL2</div>
<button class="output-2">Output2</button>
Can you just put url in the button and a generic class:
<button class="output-{{feedId}} btn-class" data-url="{{url}}">Output</button>
and then
$('.btn-class').click(function(){
console.log($(this).data('url') );
});
Or even just without changing your markup at all
$("button").click(function(){
console.log($(this).prev('div').text());
});

toggle() scope in a jquery script

I'm building a skilltree composed by node containing an hidden description
the single node is like this
<div class="node inactive-node root">
Example Skill
<div class="info">
<p class="cost">30</p>
<div class="dropdown">
<b class="caret"></b>
<div class="dropdown-menu">
Example description
</div>
</div>
</div>
</div>
the following script make obviusly show all the dropdown-menu in the page
var main = function() {
$('.dropdown-toggle').click( function() {
$('.dropdown-menu').toggle();
});
};
but the fix i tried
var main = function() {
$('.dropdown-toggle').click( function() {
$(this).children('.dropdown-menu').toggle();
});
};
is ineffective and i cant figure why.I'm tryng to select the single dropdown-menu under the clicked dropdown-toggle, but i'm failing to understand how.
It's not a child element. It's a sibling. Try using next().
$(this).next().toggle();
Or
$(this).parent().find('.dropdown-menu').toggle();
$('+.dropdown-menu',this).toggle();
Or
$('+.dropdown-menu',this).slideToggle();

Appending angularjs in Html

OK this is the code. Here once the button is clicked i want to show value of list in ul .
js file
$('#myBox').append("<li ng-repeat='name in event'>"{{name}}"</li>");
html file
<ul id='myBox'></ul>
<button class="btn btn-default" ng-click="sometask()">Click me</div>
Once Click is clicked i want to display value of list in ul but i am unable to see the result .
if i need to append simple value then i would have done this
var name = "Hello World";
$('#myBox').append("<li>"+name+"</li>");
But using ng-repeat i couldnt use this thing. So please help me .
Thank
You need to compile your html before inserting it to DOM.
var myApp = angular.module('myApp', []);
myApp.controller('AngularCtrl',['$scope','$compile',function($scope,$compile){
$scope.event = ['one','two','three','four','five'];
$scope.sometask = function(){
var html = $compile("<li ng-repeat='name in event'>{{name}}</li>")($scope);
angular.element(document.querySelector('#myBox')).append(html);
}
}]);
Your list should just live inside your controller somewhere, then your code should just append an item to the list and angular will take care of rendering it for you.
<div ng-controller="listCtrl">
<ul id='myBox' >
<li ng-repeat='name in event'>
name
</li>
</ul>
<button class="btn btn-default" ng-click="sometask()">Click me</div>
then in your controller you should have something like:
$scope.sometask = function() {
event.push("new name") ;
}

Clearing push notifications onClick button

I've got a notifications button in a rails app that lists friends' recent activity. It has a count badge that appears over the button. Once a user views those notifications I want to clear the current badge so the count can restart with new notifications. Any suggestions?
var renderActivities = function() {
var source = $('#activities-template').html();
var template = Handlebars.compile(source);
var html = template({
activities: window.loadedActivities,
count: window.loadedActivities.length
});
I was trying something like this:
$('#notifications-button').click(function(event) {
count: = 0;
});
Source code (outside of body):
<script id="activities-template" type="text/x-handlebars-template">
<button class="btn btn-default" class="dropdown-toggle notifications-button" data-toggle="dropdown"><i class="fa fa-bell-o fa-2x"><span class="badge notifications-count">{{count}}</span></i></button>
<ul class="dropdown-menu pull-right notifications-menu">
{{#each activities}}
{{activityLink}}
{{/each}}
<li class="divider"></li>
<li>See All</li>
</ul>
</script>
I'm really not all that familiar with Javascript but really need this feature to work.
You're going to want to grab the selector that contains the count and set the text to 0. Something like so...
$('#notifications-button').on('click', function() {
$('.notifications-count').text('0');
});

Categories