In my webapp i am creating three viewmodel which are nested like first viewmodel is parent of second , second is parent of third. now if i want to display value of third view model it is giving me error that it is not define . In my code LoanRateViewModel is parent whose child is Term and Tier is child of Term.
function Tier(data){
var self = this;
self.tierValue = ko.observable(data.tierValue || "");
self.rate = ko.observable(data.rate || "121212");
self.simplerate = ko.observable(data.simplerate || "121212");
self.compoundrate = ko.observable(data.compoundrate || "12212");
}
function Term(data) {
var self = this;
self.Tiers = ko.observableArray([]);
self.loanterm = ko.observable(data.loanterm || "12");
self.termIdentifier = ko.observable(data.termIdentifier || "12");
};
here is jsfiddle link DEMO
How can i call the grand child is it possible through knockout js ?
The problem is unfortunately not in the code you posted*, but in the fiddle.
What you want is certainly possible, though as mentioned in comments you'd need proper nesting to reach grand-children, because they will always be in the context of a certain parent (Term). I've (mostly) fixed your jsfiddle, fixing issues until there were no errors left. Some things that would answer your "question" are:
Make sure you properly close DOM elements (e.g. table and tbody);
Make sure you refer to $root for methods that are on the root (e.g. addTier);
In tables, make sure each row has equal number of cells (or use colspan), or your results will look weird.
* It'd be nice if you edit your question, and included the relevant (preferably well-formatted) code, so the question can remain useful for others with a similar problem.
Related
I am trying to access child element of an ng-repeat element but I am having troubles doing that.
I have searched around about the problem and the solutions that I have found did not work for me. One of those solutions was to do something like this:
var parent = element(by.repeater(''));
var child = parent.element(by.....);
When I try the child line I cant see the element function on the parent element..
http://prikachi.com/images/11/8338011u.png
If you see the screenshot above you will see the structure of the code of the page that I am trying to test.
I need to access the alt attribute of the image of the avatar and get its value (thats the Username of the User).
One thing that came to my mind is to use .getInnerHTML() on the ng-repeat row which will return a string with all that code. From there I can find the alt attribute and its value with string manipulation but this seems too brute and I am sure that there has to be a better way.
Simply I want to be able to get row 4 from the repeater and get the Username of the user at row 4, that's all I wanna do actually.
Try this,
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).first()
(or)
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).get(0)
You can get it directly using element.all() and get() locator in protractor. Here's how -
var child = element.all(by.repeater('parent_locator')).get(3); //gets 4th element in repeater. Its a 0 based index.
child.getAttribute('alt').then(function(user){
var username = user; //username contains the alt text
});
Hope this helps.
In Protractor element documentation it gives an example like this to find child elements, which is same as chaining element find:
// Chain 2 element calls.
let child = element(by.css('.parent')).
$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = element(by.css('.parent')).
$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
// Or using the shortcut $() notation instead of element(by.css()):
// Chain 2 element calls.
let child = $('.parent').$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = $('.parent').$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
https://www.protractortest.org/#/api?view=ElementFinder.prototype.$
this example could help :
return element(by.css('select.custom-select:nth-child(1) option[value="12"]'));
you can use nth-child() selector to access to a child element.
In my example i used a plugin with 2 select with same classes and i wanted to click on a defined option in the select 1, and a second in the select 2.
I'm fairly new to javascript and jQuery. I've searched for answers to this question, but have had no luck, though I bet there are some in here. So advance apologies if this is a dup.
Markup has 3 checkboxes with different classes, and one class in common. I want to notice when the number of boxes checked in either of two classes changes, or rather when there is a transition between at least one box in two of the classes being checked or unchecked. The two interesting classes are named "professional" and "vendor", and the class in common is "account_type_checkbox".
When the page is ready, I count the number of checked "professional" and "vendor" boxes with:
jQuery("input.professional[checked='checked'], input.vendor[checked='checked']").length
This appears to work correctly. I have a "change" event handler on checkboxes in the common class that does the same count when it triggers. But when the event triggers, it gets the same count as it did on page load - i.e. it doesn't see the updated DOM with the modified checked attribute.
I've put a jsfiddle for this at http://jsfiddle.net/cm280s9z/1
Could someone please help me fix this, and/or explain why my code doesn't work the way I expected it to?
http://jsfiddle.net/cm280s9z/3/
Use alert($(":checkbox:checked").length); to get the sum of all marked checkboxes.
There are several other ways of doing this too, as pointed out in this thread, such as doing it by classes on a checkbox:
calculate the number of html checkbox checked using jquery
Maybe you will find this useful: http://jsfiddle.net/cm280s9z/6/
Here's a cleaned up version (not saying it's the best ever) of what you had, showing the :checked.
Reasons why this code is good:
storing the jQuery object checkboxes means it won't have to re-jquery-objectify it every time.
grabbing objects by certain [vague or lengthy] selectors can be more strenuous on jQuery. Grabbing by this class means it'll be more specific as well. We can further filter out checked using .filter. Extra Tip: If traversing the DOM, I like to grab a container that's fairly unique and use .find() to help me get at the descendants.
functions can bring some order and organization to what you're doing.
comments are your friend.
Hope this helps!
var GLOB = GLOB || {};
jQuery(document).ready(function () {
// Define
var checkboxes = jQuery('.account_type_checkbox');
var get_checkbox_count = function(checkboxes){
return checkboxes.filter(':checked').length;
};
var do_business = function(){
alert('transitioned to business');
};
var do_personal = function(){
alert('transitioned to personal');
};
// Initialize
GLOB.business_count = get_checkbox_count(checkboxes);
alert('GLOB.business_count = ' + GLOB.business_count);
// Events
checkboxes.change(function(){
var cur_count = get_checkbox_count(checkboxes);
var add_business = (cur_count > 0);
var no_business = (GLOB.business_count < 1);
// If any are selected it's business, where previously none were checked.
var transition_business = (add_business && no_business);
// If none are selected it's personal, if previously any were checked.
var transition_personal = (!add_business && !no_business)
if (transition_business)
do_business();
if (transition_personal)
do_personal();
});
});
Sorry for bad wording in the question but it's hard to explain for me. I'm using several bxsliders on a page and some are placed in hidden divs. Unfortunately images are not shown in the slider after making the parent div visible unless the slider is reloaded (See here: bxSlider within show/hide divs). So let's say I initiate the sliders at the beginning with:
var slider_0=$("#slider_0 .bxslider").bxSlider({
//bxslider options here
});
var slider_4=$("#slider_4 .bxslider").bxSlider({
//bxslider options here
});
var slider_7=$("#slider_7 .bxslider").bxSlider({
//bxslider options here
});
The sliders are not consecutively numbered but there is a navigation and if I click the 7th element it leads to slider_7. So I could get the index of the clicked item with:
$(this).index();
When I call slider_7.reloadSlider(); it would work but I don't know which slider the user clicks and which number it has. So would it be possible to call that with a created string like this:
slider_name='slider_'+$(this).index();
slider_name.reloadSlider();
works not of course. Is there a way to do it?
I would create a dictionary with strings as keys and functions as values. Then, you could have O(1) lookup of the functions you're targeting.
In general, you can do it like so:
// set up your dictionary
var dictionary = {};
// add your functions
dictionary['methodName'] = function() {};
// call the functions
dictionary['methodName']();
So, for your example, you could do:
dictionary['slider_7'] = slider_7.reloadSlider;
dictionary['slider_'+$(this).index()]();
You could trigger it with
window["slider_" + $(this).index()].reloadSlider()
Although, I'm not sure whether your approach is the best. I think I'd go with arrays or with object (as a key-value pairs)
Try this:
slider_name='slider_'+$(this).index();
$("#" + slider_name + " .bx_slider").reloadSlider();
Found a working solution:
eval("slider_" + $(this).index()).reloadSlider();
Its not entirely clear here what you want/are trying to do. What it seems like you want to do is get a programmatic handle on a specific slider when a user clicks a specific part of your page. You do not accomplish this by eval()ing a string...that's what event handlers are for. So create a click event handler and in that event handler
$('#idOfWhatTheUserClicksOn').click(function(event) {
var slider = document.getElementById('#idOfRelatedSlider');
$(slider).bxSlider();
//if you need the current value of the slider you can get that too
var value = slider.value;
});
You could achieve the same with fewer LOC by using a class instead of id's with different handlers, but the concept is the same.
var slider_cache = [
$("#slider_0 .bxslider").bxSlider(),
$("#slider_1 .bxslider").bxSlider(),
$("#slider_2 .bxslider").bxSlider()
];
...
slider_cache[$(this).index()].reloadSlider();
This is my fiddle. http://jsfiddle.net/aaScC/
Please check in the example, the Score property has 3.5 value but it is being displayed as 1. I know the score property is bound to dropdown value so its coming as 1. But i want 3.5 to be displayed. Please help.
var GoalsModel = function (goals) {
var self = this;
self.goals = ko.observableArray(ko.utils.arrayMap(goals, function (goal) { return new Goal(goal) }));
};
The problem is that you just make the select element invisible. You don't want the element at all. You can use bindings if or ifnot to control this.
Here is an updated example: http://jsfiddle.net/waxwing/aaScC/1/ . I wrapped the select inside a span to make it work, but you can also use virtual bindings if you don't like to change your DOM structure.
I'm writing a small jQuery plugin that binds to 8 divs on a page, each of which contains a form. There are two links for each widget that increment or decrement a field within the form and then POSTs the form. The problem is that all 16 links on the page all submit the first form on the page.
The source code is here:
http://pastie.org/657045
I'm a jQuery/JS newb and figure this is probably a variable scope issue, but I've tried everything and can't get the elements to operate independently.
At the very beginning, you need to iterate through the results of the $(containerobj) and run the rest of the code through that, replacing each reference, like this:
jQuery.RankWidget = function(containerobj, options) {
return $(containerobj).each(function() {
var $container = $(this);
var $form = $container.find('.rank_buttons form');
var $rank_up = $container.find('.rank.up');
var $rank_down = $container.find('.rank.down');
var $value_field = $container.find('input.rank_value');
var $comment_score = $container.find('.comment_score');
var $comment_rank = $container.find('.comment_rank');
...
};
};
At the moment, you're applying all the events to all of the links, rather than scoping it to each container object in turn.
I solved my problem by using .click() instead of .live()
Anyone know if there is away to use .live() and get the scope for each widget correct? I even tried passing in the variable as an argument to the clickRank() function, but it was still referencing the wrong form.