jQuery Traversing + Live Event Handlers - jquery-selectors

I'm having some issues with attaching live event handlers to particular rows.
What I have and what I'm after:
I have some HTML that will be generated dynamically after page load as follows:
<table>
<tr>
<td></td>
</tr>
<tr>
<td class="bonus"></td>
</tr>
<tr>
<td></td>
</tr>
</table>
I would like to have two click events:
One for rows that aren't a "bonus row"
One for rows that have a "bonus row" after them
What I've tried and the problem:
However, I cannot work out how to use a selector to select "element that has a particular element after it" (i.e. a "previous" selector). As such, the best I can arrive at is:
Rows that aren't a "bonus row": $('tr:not(:has(.bonus))')
Rows that have a "bonus row" after them: $('tr + tr:has(.bonus)').prev()
This is all well and good, except whenever I use the live() method on a jQuery object that was obtained through traversal, rather than pure selection i.e.
$('tr:has(.bonus)').prev().live('click', function() {
alert('hello');
});
I get this error:
uncaught exception: Syntax error,
unrecognized expression: )
The issue as an even more minimal example:
I was hoping this was localised to some script I am using, but I've isolated this to a minimal jsFiddle example which still replicates the issue for me: http://jsfiddle.net/ptvrA/
HTML:
<div></div>
<div id="target"></div>
JS:
$('#target').prev().live('click', function () {
alert('f');
});
It seems from this answer that this is a known limitation of live.
My workarounds
For reference, my workarounds are either:
Mark the rows that have a "bonus row" after them in some way
Bind the click to all rows, and do a check to see if there is a "bonus row" after them within the handler.
But if I can get a "nicer" solution, even out of curiosity in case I run into this problem in a different situation, I'd appreciate it.
Cheers

$('tr + tr:has(.bonus) ~ tr') //for row whose next sibling is a bonus row
Will do what you want with the .live method.
For all the people who get here in the future using google.
uncaught exception: Syntax error, unrecognized expression: )
That is happening because .live() uses the original selector that was given to the first call in the jQuery chain. It doesn't no consider additional methods used after the initial $('selector').

To be honest, I'd just use your second idea and bind click to all rows, then check to see if next row has a bonus td in it, like this:
$('tr:not(:has(.bonus))').live('click', function () {
if ($(this).next().children('td').hasClass('bonus')) {
alert('next row has bonus td');
}
else {
alert('next row does not have bonus td');
}
});
fiddle located here: http://jsfiddle.net/7gdqc/2/
I don't think there's a pure selector way to do it, and this isn't really a workaround - I'd call it a valid solution to your problem.

Related

How to do a regexp in a waitForPopUp Command in Selenium IDE?

I have popups with this name structure:
static_dynamic_static
The dynamic part changes each time I log in so my test cases fail each time. I thought about solving the problem with a regular expression like this:
Command: waitForPopUp
Target: regexp:static_.+_static
But this doesn't work. What do I do wrong? Is this even working. If not, is there another way to solve this problem?
From my experience you don't need to declare it as a regex within the target field, you should just be able to have the target as:
static_*_static
and that should do it
If you've got only one popup window you can use null as a target and test will take the first popup:
waitForPopup | null
The other option is to get dynamic part before popup opening. It is very likely that the dynamic part could be retrieved from the page. If so you can get it using storeEval, and than use like:
waitForPopup | javascript{'static'+storedVars['dynamic']+'static'}
If you can't store the dynamic part please provide an html of your page or only the part where the dynamic part mentioned.
I see that theoretically it could be possible to get all the names of your windows and than to use pattern in a loop to get the one.
Also (theoretically) it is possible to expand default waitForPopup function.
But the second way and especially the first are much cheaper.
The best way to handle this might be to run a snippet of javascript to handle this:
<tr>
<td>storeEval</td>
<td>var myRe = new RegExp("^prefix.+", "g"); var mywin; windows=selenium.getAllWindowNames();for (i = 0; i < windows.length; i++) { if(myRe.test(windows[i])) { mywin=windows[i]} }; mywin;</td>
<td>x</td>
</tr>
<tr>
<td>selectWindow</td>
<td>name=${myWindow}</td>
<td></td>
</tr>
That javascript isn't fully function (no null checking) but should help get you on the right track.

Meteor: record in db updating, but data not changing on screen

Here's a simplified version of what I have in one of my templates:
{{#each dataRecord}}
{{#if editingNow}}
<tr class="dataRow">
<td><button class="updateRecord" id="{{this._id}}">SAV</button></td>
<td><input type="text" id="{{this._id}}" value="{{this.f}}"></td></td>
</tr>
{{else}}
<tr class="dataRow">
<td><button class="edit" id="{{this._id}}">EDIT</button></td>
<td>{{this.f}}</td>
<td><button class="deleteRecord" id="{{this._id}}">DEL</button> </td>
</tr>
{{/if}}
{{/each}}
editingNow returns the value of boolean session variable which starts out as false. So when the page loads, the user sees the value of the 'f' field for each record and the EDIT button. The EDIT button flips the session variable to true and then the data is shown using an input element. The user can edit the data and click the button, which is now a SAVE button. That button updates the record using the _id and flips the session variable back to false.
The works as far as editing the data goes -- the record is definitely getting updated. I can check the value in the console and see that it has been changed. But the data that gets displayed in the table reverts back to the original value. I can see the change displayed in that field very briefly and then it flips back. Even weirder, if I click the EDIT button again, the table still displays the old value. The only way to see the updated data in that field is to restart the app.
This problem never occurred when I was using my local mongo db or when I was linking to my database on meteor.com. This has only started happening since I moved my app to modulus.io. Any ideas?
UPDATE
Although I could not figure out what was causing the reactive update problem in the template, with Ethaan's help, I was able to get a better understanding of the issue and find a work-around, so I've accepted the answer and hopefully we will get to the bottom of this eventually.
Seems like you have some allow/deny problems maybe?
Try with
Collection.allow({
insert:function(){return true;},
remove:function(){return true;},
update:function(){return true;},
})
Or check the connection with the database is succefull, go to the admin panel on modulus
Option 2
Clean the database and make a dummy insert on the server side.
First on the meteor shell run meteor reset.
OR If you have the application is on modulus.io use the mongo shell, and use this piece of code.
db.getCollectionNames().forEach(function(name) {
if (name.indexOf('system.') === -1) {
db.getCollection(name).drop();
}
})
Now when you are sure the database is empty, put this on the server side.
//Server Code.
Meteor.startup(function(){
if(Collection.find().count() == 0){
Collection.insert({serverInsert:"test from server"},function(err,result){
if(!err){
console.log("insert succefull")
}
})
}
})

Selenium IDE, selecting muliple text using same class

I have a page with lots of text using the same class. I am wanting to select and store all the text with that same class. Is this possible? All advice & comments appreciated!
I have HTML code like this:
<p class="foo">Some sample text</p>
<p class="foo">Some more sample text</p>
I have tried this:
<tr>
<td>storeText</td>
<td>//p[#class=foo']</td>
<td>var1</td>
</tr>
I expected var1 to be:
Some sample text
Some more sample text
Alternatively do I need to set up a while statement and gather each individually?
This page talks about a similar exercise, but uses Selenium for Python: Get the text from multiple elements with the same class in Selenium for Python?
//gather all p[class=foo]
List<WebElement> ele = driver.findElements(By.cssSelector("p.foo"));
Iterator<WebElement> iter = ele.iterator();
// initialize array, map, whatever
While(iter.hasNext()) {
// insert text into map
// print to log
// store in array
//whatever you need
var.add( iter.next().text() );
}
I didn't get to try out the answer from #bcar because I am not a javascript expert nor am I sure I could put the answer into IDE. I found another way however. I discovered that the text is stored in tables, so I am using the following code to extract the entire table (which includes the text I need).
<tr>
<td>storeText</td>
<td>//div/h2[text()="Elements and Performance Criteria"]/following::table</td>
<td>Content</td>
</tr>
Now I have to work out how to replace the new lines with as this is plain text. Another question for stackoverflow! Thanks.
Quite easy:
Just loop through the stored elements.
Whenever you use find_elements_by_class_name, it returns the list of selenium web elements. Hence you just need to iterate with a loop, like this.
names = driver.find_elements_by_class_name("_xEcR")
for i in names:
print(i.text)

Angular 1.2.0: Error: "Referencing private fields in Angular expressions is disallowed" when attempting to access Mongo _id fields

When attempting to read a mongo _id field from an angular expression:
<tr ng-repeat="person in people">
<td>{{person._id}}</td>
<td>{{person.name}}</td>
<td>{{person.location}}</td>
<td>{{person.active}}</td>
</tr>
the following error is thrown:
"Referencing private fields in Angular expressions is disallowed"
plunker link: http://plnkr.co/edit/dgHNP2rVGPwAltXWklL5
EDIT:
This change has been reverted in Angular 1.2.1: https://github.com/angular/angular.js/commit/4ab16aaaf762e9038803da1f967ac8cb6650727d
The Current Solution
This is due to a breaking change in Angular 1.2.0 ( discussed here: https://github.com/angular/angular.js/commit/3d6a89e )
There's an easy, if not annoying, fix to this.
In your app.run function, you can add a $rootScope level accessors object that contains a function to return the correct Mongo ID.
app.run(function($rootScope) {
$rootScope.accessors = {
getId: function(row) {
return row._id
}
}
});
Then, in your markup, use that method instead of directly accessing the data point:
<tr ng-repeat="person in people">
<td>{{accessors.getId(person)}}</td>
<td>{{person.name}}</td>
<td>{{person.location}}</td>
<td>{{person.active}}</td>
</tr>
A plunker with the fix: http://plnkr.co/edit/NcRrKh
Discussion:
This will allow you to progress forward with your development, but know that it does come with more overhead than if you could just access the variable directly. For small projects, this should not impact performance at any perceptible level, though you might see some measurable amount on larger apps. However, this concern is, as of right now, purely academic.

Zend Cycle within Partials

Is there an alternative to using 'Cycle' when creating zebra tables in Zend. ( My version does not have Cycle helper and don't really want to have to upgrade.
Using a partial loop and need each table to put out different bg color. However the partial loop doesn't seem to act as a standard loop with no repeat
I'd use javascript, as long as that's not crutial ;)
$('#table row:even').addClass('even');
I think you're right, the cycle helper seems to reset for every iteration of partialLoop()... which would be consistent with the documentation.
I've gotten round this by using the partial loop's counter, like so:
<tr class="<?php print ($this->partialCounter%2) ? "odd" : "even"; ?>">
<td>Test</td>
<td>Test</td>
<td>Test</td>
</tr>