How to add an attribute to the finish button within jQuery-Steps? - jquery-steps

TLDR: How would one add an 'id' attribute to the finish button within jQuery.Steps.js?
When the finish button is called it looks like this within HTML:
Finish
This is what I want it to look like:
Finish
Any ideas?

Add this it works
onInit :function (event, current) {
$('.actions a[href=#finish]').attr('id', 'example1');
}

You can define a class for this element and choose a selector for that class in below statement to add id named example1 to Finish element.
$('.some_selector').attr('id', 'example1');

Try this:
onInit :function (event, current) {
$('.actions a[href=\\#finish]').attr('id', 'FinishButton');
}

Add the following in your steps
onInit: function (event, currentIndex) {
$('.actions a[href="#finish"]').attr('id', "example1");
},

Related

Value is not applied to Ng-Class on window resize

I have the following controller:
function PlansController($scope) {
var vm = this;
vm.plan = null;
vm.show = function (plan) {
vm.plan = plan;
}
$scope.$on("match", function (event, mq) {
if (mq === "mobile") {
vm.plan = "free";
console.log(vm.plan);
}
});
})();
The $scope.$on match fires when the media query "screen and (max-width: 31.9375em)" matches. Then I have the following:
<table class="plans" data-ng-class="vm.plan">
When I load the page with a width that matches the media query I can see that vm.plan class is applied to the table ...
The problem is when open the page in a large width. When I resize it to mobil I see in the console that the vm.plan becomes "free", so the Match condition fires and vm.plan is defined, but the CSS class is not applied to the table.
UPDATE
I just added an example in https://jsfiddle.net/g3wzayp3/11/
Just increase the HTML preview pane and you will see on console the value "true" when the width matches the media query ... But the class is not applied to the text ...
Any idea why?
Are you trying to apply the class called "free" on resize? If yes, this is not the way to do it. ng-class is used like {free: vm.plan} where vm.plan becomes true or false
Example:
<div ng-class="{free: should_apply}">Hello</div>
where free is the class that you want to apply, should_apply is a variable that evaluates to true or false
Here's a fiddle example:
https://jsfiddle.net/a7u1m3n6/
UPDATE:
You need to call $scope.$apply(); in the $on method. Here's the fiddle - https://jsfiddle.net/g3wzayp3/12/

AngularJS addClass isn't working

I have been trying to addClass through AngularJS and the code doesn't seem to work, weird thing is addClass is working on Parent Menu Item but doesn't work on Sub item.
I have a nested UL and LI, when I click on the Parent LI ParentLi function gets called and it adds a "focused" class to the Clicked LI, this works fine but when I click on Nested LI's I call childLi and I do the same operation as done for the Parent but class doesn't get added. I am new to Angular and I hope I am doing this in the right way.
$scope.parentLi = function(event) {
var liElement = angular.element(event.target.parentNode);
var allParentLiElements = document.getElementsByClassName('parent-dropdown');
if (!liElement.hasClass('focused')) {
angular.element(allParentLiElements).removeClass('focused');
liElement.addClass('focused');
} else
liElement.removeClass('focused');
};
$scope.childLi = function(event){
var liElement = angular.element(event.target.parentNode);
var allParentLiElements = document.getElementsByClassName('child-dropdown');
if(!liElement.hasClass('focused')){
angular.element(allParentLiElements).removeClass('focused');
$(event.target).closest('.parent-dropdown').addClass('focused');
liElement.addClass('focused');
} else
liElement.removeClass('focused');
}
Note that i have edited my jsfiddle code based on the answer given by Jiam30.
adding focused class should work like active class i.e the menu that i just clicked should have focused class other should not, same way if i have hover on menu item and click on subitem, both the subitem and the parent item should have focused class.
Fiddle
Manipulating elements in a controller should be avoided.
Use ng-class instead (also use ng-repeat to avoid HTML repetition). For instance:
<li class="dropdown parent-dropdown" ng-click="parentLi()" ng-class="{'focused': isDropdownFocused}"></li>
With this function in the controller:
$scope.parentLi = function() {
$scope.isDropdownFocused = !$scope.isDropdownFocused;
};
Updated Fiddle: http://jsfiddle.net/6be56/127/

How to test if an element has class using Protractor?

I'm trying out Protractor to e2e test Angular app and haven't figured out how to detect if an element has a specific class or not.
In my case, the test clicks on submit button and now I want to know if form[name="getoffer"] has class .ngDirty. What may be the solutions?
describe('Contact form', function() {
beforeEach(function(){
browser.get('http://localhost:9000');
element(by.linkText('Contact me')).click();
});
it('should fail form validation, all fields pristine', function() {
element(by.css('.form[name="getoffer"] input[type="submit"]')).click();
expect(element(by.name('getoffer'))).toHaveClass('ngDirty'); // <-- This line
});
});
One gotcha you have to look out for with using toMatch(), as in the accepted answer, is partial matches. For instance, let's say you have an element that might have the classes correct and incorrect, and you want to test that it has the class correct. If you were to use expect(element.getAttribute('class')).toMatch('correct'), that will return true even if the element has the incorrect class.
My suggestion:
If you want to only accept exact matches, you can create a helper method for it:
var hasClass = function (element, cls) {
return element.getAttribute('class').then(function (classes) {
return classes.split(' ').indexOf(cls) !== -1;
});
};
You can use it like this (taking advantage of the fact that expect automatically resolves promises in Protractor):
expect(hasClass(element(by.name('getoffer')), 'ngDirty')).toBe(true);
If you're using Protractor with Jasmine, you could use toMatch to match as a regular expression...
expect(element(by.name('getoffer')).getAttribute('class')).toMatch('ngDirty');
Also, note that toContain will match list items, if you need that.
Simplest is:
expect(element.getAttribute('class')).toContain("active");
Based on the answer from Sergey K, you could also add a custom matcher to do this:
(coffeescript)
beforeEach(()->
this.addMatchers({
toHaveClass: (expected)->
#message = ()->
"Expected #{#actual.locator_.value} to have class '#{expected}'"
#actual.getAttribute('class').then((classes)->
classes.split(' ').indexOf(expected) isnt -1
)
})
)
Then you can use it in tests like this:
expect($('div#ugly')).toHaveClass('beautiful')
And you'll get the following error if it doesn't:
Message:
Expected div#ugly to have class beautiful
Stacktrace:
Error: Expected div#ugly to have class 'beautiful'
Have you tried this?
const el = element(by.name('getoffer'));
expect(el.getAttribute('class')).toBe('ngDirty')
or a variation of the above...
I made this matcher, I had to wrap it in a promise and use 2 returns
this.addMatchers({
toHaveClass: function(a) {
return this.actual.getAttribute('class').then(function(cls){
var patt = new RegExp('(^|\\s)' + a + '(\\s|$)');
return patt.test(cls);
});
}
});
in my test i can now do stuf like this:
var myDivs = element.all(by.css('div.myClass'));
expect(myDivs.count()).toBe(3);
// test for class
expect(myDivs.get(0)).not.toHaveClass('active');
this also works when an element has multiple classes or when an element has no class attribute at all.
function checkHasClass (selector, class_name) {
// custom function returns true/false depending if selector has class name
// split classes for selector into a list
return $(selector).getAttribute('class').then(function(classes){
var classes = classes.split(' ');
if (classes.indexOf(class_name) > -1) return true;
return false;
});
}
This is how I do it at least, without the need to use the expect function. This function simply returns true if the class is inside the element and false if not. This also uses promises so you would use it like:
checkHasClass('#your-element', 'your-class').then(function(class_found){
if (class_found) console.log("Your element has that class");
});
Edit: I just realized this is essentially the same as the top answer
Here a Jasmine 1.3.x custom toHaveClass matcher with negation .not support plus wait up to 5 seconds (or whatever you specify).
Find the full custom matcher to be added on your onPrepare block in this gist
Sample usage:
it('test the class finder custom matcher', function() {
// These guys should pass OK given your user input
// element starts with an ng-invalid class:
expect($('#user_name')).toHaveClass('ng-invalid');
expect($('#user_name')).not.toHaveClass('ZZZ');
expect($('#user_name')).toNotHaveClass('ZZZ');
expect($('#user_name')).not.toNotHaveClass('ng-invalid');
// These guys should each fail:
expect($('#user_name')).toHaveClass('ZZZ');
expect($('#user_name')).not.toHaveClass('ng-invalid');
expect($('#user_name')).toNotHaveClass('ng-invalid');
expect($('#user_name')).not.toNotHaveClass('ZZZ');
});
One way to achieve this would be to use xpath and use contains()
Example:
var expectElementToHaveClass = function (className) {
var path = by.xpath("//div[contains(#class,'"+ className +"')]");
expect(element.all(path).count()).to.eventually.be.eq(1);
};
You can use the CSS parser to handle this by checking if an element with the given class exists:
expect(element(by.css('.form[name="getoffer"].ngDirty')).isPresent()).toBe(true);
Essentially, you're solving a few problems:
how to get class. class is an html attribute and thus can be retrieved by this command (await is the recommended way these days)
let class = await element.getAttribute('class')
Once you got the value of a class, you want to assert it
// for exact value
expect(class).toBe("active");
// for partial match
expect(class).toContain("active");
// or
expect(class.includes("active")).toBe(true);
// BUT, keep in mind
expect('male').toContain('male');
expect('female').toContain('male');
// BOTH pass

How to get current button`id in extjs?

Let's suppose I have this this simple button:
{
xtype :'button',
text :'button',
id:'address'+counter.no,
handler : function() {}
}
How can I get access to the current button and get access to its properties such as name, id, etc?
I'm aware of Ext.getCmp('compid') but I need to get access to CURRENT button, and I don't know its id.
Do you mean inside the handler function?
See docs at description for handler.
As first parameter this button object is passed, so you could do the following:
{
xtype :'button',
text :'button',
id:'address'+counter.no,
handler : function(thisButton, eventObject) {
//Do something with thisButton like:
alert(thisButton.getId());
}
}

Add class to DIV if checkbox is checked onload

I need help with a script to add an "active" class to a div when a hidden checkbox is checked. This all happening within a somewhat complex form that can be saved and later edited. Here's the process:
I have a series of hidden checkboxes that are checked when a visible DIV is clicked. Thanks to a few people, especially Dimitar Christoff from previous posts here, I have a few simple scripts that handle everything:
A person clicks on a div:
<div class="thumb left prodata" data-id="7"> yadda yadda </div>
An active class is added to the div:
$$('.thumb').addEvent('click', function(){
this.toggleClass('tactive');
});
The corresponding checkbox is checked:
document.getElements("a.add_app").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_select_p" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
Now, I need a fourth ( and final ) function to complete the project (using mootools or just plain javascript, no jQuery). When the form is loaded after being saved, I need a way to add the active class back to the corresponding div. Basically reverse the process. I AM trying to figure it out myself, and would love to post an idea but anything I've tried is, well, bad. I thought I'd at least get this question posted while I work on it. Thanks in advance!
window.addEvents({
load: function(){
if (checkbox.checked){
document.getElements('.thumb').fireEvent('click');
}
}
});
Example: http://jsfiddle.net/vCH9n/
Okay, in case anyone is interested, here is the final solution. What this does is: Create a click event for a DIV class to toggle an active class onclick, and also correlates each DIV to a checkbox using a data-id="X" that = the checkbox ID. Finally, if the form is reloaded ( in this case the form can be saved and edited later ) the final piece of javascript then sees what checkboxes are checked on page load and triggers the active class for the DIV.
To see it all in action, check it out here: https://www.worklabs.ca/2/add-new/add-new?itemetype=website ( script is currently working on the third tab, CHOOSE STYLE ). You won't be able to save/edit it unless you're a member however, but it works:) You can unhide the checkboxes using firebug and toggle the checkboxes yourself to see.
window.addEvent('domready', function() {
// apply the psuedo event to some elements
$$('.thumb').addEvent('click', function() {
this.toggleClass('tactive');
});
$$('.cbox').addEvent('click', function() {
var checkboxes= $$('.cbox');
for(i=1; i<=checkboxes.length; i++){
if(checkboxes[i-1].checked){
if($('c_'+checkboxes[i-1].id))
$('c_'+checkboxes[i-1].id).set("class", "thumb tactive");
}
else{
if($('c_'+checkboxes[i-1].id))
$('c_'+checkboxes[i-1].id).set("class", "thumb");
}
}
});
// Add the active class to the corresponding div when a checkbox is checked onLoad... basic idea:
var checkboxes= $$('.cbox');
for(i=1; i<=checkboxes.length; i++){
if(checkboxes[i-1].checked){
$('c_field_tmp_'+i).set("class", "thumb tactive");
}
}
document.getElements("div.thumb").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_tmp_" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
});

Resources