jQuery+JS computed selector - jquery-selectors

Sorry for the bad wording of the title, but here's my problem. Suppose I have a list where every item has a class:
<ol>
<li class="chapter">Chapter 1</li>
<li class="chapter">Chapter 2</li>
...
I want to select the item which is corresponding to make the user's current chapter, which is known by javascript, in bold. So if the user is on Chapter 2 I would do something like:
$(".chapter:eq(2)").css("font-weight", "bold");
But I can't do
$(".chapter:eq("+currentChapter+")").css("font-weight", "bold");
as it gives me Uncaught SyntaxError: Unexpected identifier
Any help would be appreciated.
Edit: I'm using a template to insert the variables but I have verified that currentChapter is in fact defined and the number I expect it to be.
function fetchContent(startSlide) {ldelim}
var chapterSize = {$chapterSize};
var currentChapter = {$chapter};
var chapterName = "{$chapterName}";
alert(typeof(currentChapter)); // number
alert(currentChapter); //e.g. 3 works
alert(currentChapter + "aaa"); //e.g. 3aaa
$(".chapter:eq("+currentChapter+")").css("font-weight", "bold"); // doesn't work

Try a different approach, fetch all elements and then select only the one you want (I know it's best to select your element right in the selector, but just to try it out).
$(".chapter").eq(currentChapter).css("font-weight", "bold");
Also, looking at your code, it seems like currentChapter is a local variable inside the fetchContent function. Are you sure you can access that variable when you are calling the jQuery function? Try to check the existence and value of the currentChapter variable right before calling the jQuery function which is causing you problems.
EDIT
From the jQuery documentation jQuery :eq() selector
Because :eq() is a jQuery extension and not part of the CSS
specification, queries using :eq() cannot take advantage of the
performance boost provided by the native DOM querySelectorAll()
method. For better performance in modern browsers, use
$("your-pure-css-selector").eq(index) instead.

Related

How to select a DOM element in JavaScript?

I want the user to be able to select the contents of a element by clicking it once. The code would look like this:
<div onclick="this.xyz()">...</div>
The question is: what method goes where I wrote xyz? I've searched for things like "DOM select object," but the answer is a needle hidden in a haystack of irrelevant hits (or not).
Basically you'd want:
<div onclick="var contents = this.innerText;">foo bar</div>
which would set contents equal to foo bar. Of course, this isn't exactly cross-platform compatible. Firefox expects .textContent instead of .innerText. If you're not opposed to using jquery, then
<div onclick="var contents = $(this).text()">foo bar</div>
would do just as well and be cross-platform.

Knockout.js: Multiple ViewModel bindings on a page or a part of a page

I am wondering if it is possible to use Knockout.js's ko.applyBindings() multiple times to bind different ViewModels to one part of a page. For example, let's say I had this:
<div id="foo">...</div>
...
ko.applyBindings(new PageViewModel());
ko.applyBindings(new PartialViewModel(), $('#foo')[0]);
I am now applying two ViewModel bindings to <div id="foo>. Is this legal?
You do not want to call ko.applyBindings multiple times on the same elements. Best case, the elements will be doing more work than necessary when updating, worse case you will have multiple event handlers firing for the same element.
There are several options for handling this type of thing that are detailed here: Example of knockoutjs pattern for multi-view applications
If you really need an "island" in the middle of your content that you want to call apply bindings on later, then you can use the technique described here: http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html
This is a common road block that comes when implementing JqueryMobile-SPA.
The method : ko.applyBindings(viewmode,root dom element) accepts two arguments. The second argument comes helpful when you have multiple VM's in your page.
for example :
ko.applyBindings(model1, document.getElementById("view1"));
ko.applyBindings(model2, document.getElementById("view2"));
where view1 and view2 are the root dom element for that model. For a JqueryMobile-SPA this will be the page ids for corresponding model.
The best way to do this would be use the "with" binding construct in the div that you want the partial view model to be bound. You can find it in this fiddle
<div data-bind="with: model">
<p data-bind="text: name"></p>
</div>
<div data-bind="with: anothermodel">
<p data-bind="text: name"></p>
</div>​
var model = {
name: ko.observable('somename'),
}
var anothermodel = {
name: ko.observable('someanothername'),
}
ko.applyBindings(model);​
Also check out the "with" binding documentation on the Knockout site, to look at an AJAX callback - partial binding scenario.
My english is very bad.... =)
I use Sammy to load partial views, and Knockout to bind the Model, I try use ko.cleanNode but clean all my bindings, all DOM nodes has changed when has a bind, a property __ko__ is aggregated, then i removed that property with this code, and works !!, '#main' is my node.
var dom = dom || $("#main")[0];
for (var i in dom) {
if (i.substr(0, 6) == "__ko__") {
delete (dom[i]);
break;
}
}
after use Ggle translator:
I use Sammy for the load of partial views, and Knockout for the bind the Model, I try to use ko.cleanNode but clean all my bindings, all DOM nodes has changed when they has a bind, a property ko is aggregated, then i removed that property with this code, and works !!, '#main' is my node.

Does anyone know the location of detailed documentation covering the use of watir with html tags such as li ul td to navigate the DOM?

I have encountered unexpected results from the following code.
I'm getting -list- values from the -unordered list- located after the one I target
with "Employee_error_list"
why doesn't the response confine itself to the content
between the -unordered-list- and /-unordered-list- ?
theList = browser.ul(:id, "Employee_error_list")
theList.lis.each do |li|
puts li.text
end
To answer the question about documentation
The list type elements you mention are ElementCollection objects.
The best documentation I've found is the Watir-Webdriver RDoc Documentation.
A list of these can be found here.
A full list of elements supported by Watir is here
You can traverse an ElementCollection by using the code example you give:
theList = browser.ul(:id, "Employee_error_list")
theList.lis.each do |li|
puts li.text
end
As far as why the elements returned are not confined to the ul you specify, I'm not sure without seeing an example of the page HTML. The way you are doing it should work, but if you're seeing unexpected behavior it could be a bug.

jQuery: Select all 'select' elements with certain val()

Does anyone know of an easy way, using jQuery, to select all <select> elements whose val() attribute yields a certain value?
I'm trying to do some validation logic and would like to just select all those elements with a single selector, then apply a warning class to each of their parents. This I know how to do once I select all the elements, but I didn't see a selector that handles this case.
Am I going to have to select all of the <select> elements into a selector, then iterate through them and check each of their values? I was hoping there would be a simpler way.
Thanks.
Why doesn't select[value=x] work? Well firstly because <select> doesn't actually have a value attribute. There is not a single value of a select box: there may be no selected options (there shouldn't normally be, but there can be in at least IE), and, in a <select multiple>, there can be any number of selected options.
Even input[value=x] doesn't work, even though <input> does have a value attribute. Well, it does work, it just doesn't do what you think. It fetches the value of the value="..." attribute in the HTML, not the current value you have entered into the form. The value="..." attribute actually corresponds to the defaultValue property and not value.
Similarly, option[value=x][selected] doesn't work because it is checking the <option selected> attribute from the HTML source (selected attribute -> defaultSelected property) and not the current selectedness of the option (selected property not attribute) - which might have changed since the page was loaded.
Except in IE, which gets the value, selected etc form attributes wrong.
Except (again): Tesserex's example may seem to work, and the reason for that is that that it's using a non-standard jQuery-specific selector, :has. This causes the native querySelectorAll methods of modern browsers to fail, and consequently jQuery falls back to its own (native JavaScript, slow) selector engine instead. This selector engine has a bug where it confuses properties for attributes, allowing [value=x] to do what you expected, and not fail like it should! (Update: this is probably no longer the case in newer jQuery versions.)
Summary: form field state checking and selectors don't mix. Apart from these issues, you also have to worry about escaping issues - for example, what if the value you want to test against contains quotes or square brackets?
So instead, yes, you should check it manually. For example using a filter:
$('select').filter(function() {
return $(this).val()==='the target value';
}).parent().addClass('warning');
(There is a value property in HTML5 and supported by modern browsers, that when you read it gives you the value of the first selected <option>. jQuery's val() is safe to use here because it provides the same method of getting the first selected option even on browsers that don't support this.)
The existing answers don't work on select tags, but I found something that does. Ask for a select that has a selected option.
$("select:has(option[value=blah]:selected)")
You can use :
$("select[value=X]");
where X is the value against which you want to check the select's value.
Attribute selectors Is what you're looking for I believe.
Something like $+('element[attribute="value"]')
See also:
*= anywhere
^= starts with
$= ends with
~= contains word
etc.
You can create a change event that puts the value in a custom attribute on the select element whenever the value changes. You can then use a simple selector to find all of the select elements that have that value. For example:
$("select").on("change", function (e) {
var $select = $(e.currentTarget);
$select.attr("select-value", $select.val());
});
And then you can do this:
var $matches = $("select[select-value='" + searchVal + "']");
$matches will have all of your matching selects.
This is a lot easier than having to iterate through elements. Remember to set select-value to the initial value when rendering the page so you don't need to trigger a change event for each select so the select-value is set.

Access select using div/span id

In jquery is it possible to access a select element by simply using the div or span id plus the "select" selector? I ask because i have a series of auto-generated forms meaning I can't assign an id to the form elements plus the names are weird like "w24", I'd like to access a form element specifically a select using the surrounding span id and "select" selector example:
$("#hiv_care select").attr("disabled",true);
I've tried this but it doesn't work, forcing me to explicitly use the dropdown name.
Seems I was using the wrong div id. SLaks thanks for the link to jsfiddle.net it exposed my ways and is really helping me with testing out my jquery code.