How can disable the selected link when clicking another in wicket ? - java

i have a bunch of links like this :
<li wicket:id="LIlink">Link name</li>
in wicket , the <li> is a WebMarkupContainer and <a> is a Link
when i am clicking a link , i want to change the li's class to active , and i'm doing this with a class made by me like in the following example :
Link link= new Link("link")
{
#Override
public void onClick() {
WMK.add(CssClassManagement.addAttribute("active"));
}
};
considering that WMK is the WebMarkupContainer containing the link .
Until here ,everything works , the problem is i can't figure out how i remove the class active from the <li> when another link is clicked ?

if your links point to different pages you can just check if the current page is one pointed by a given link and then decide to add or remove the active attribute.

The problem is in CssClassManagement.addAttribute("active").
This adds a permanent Behavior to the component that contributes "active" CSS class for each render of the component. If the Behavior is temporary (see Behavior#isTemporary()) then it will be used just once and removed immediately from the component. So next repaint of the page will not mark the link as active.
Another approach is to remove the CSS class when the click event happens:
$(function() {
$(document).on('click', 'a', function() {$('li.active').removeClass('active');});
});
This will remove the CSS class when the user clicks on an anchor. The repaint of the page will come with the new link selected as active.

Related

Selenium Webdriver with Java - Click on an hyperlinked Dropdown Container

I need to click on an element inside a Dropdown container. I've tried several searchs but I haven't been able to find the correct solution. The select method doesn't work, and I still don't know how to work with Selectors when there's no ID, Name or Class related to it. Here's the HTML code:
Account<span class="caret"></span>
<div class="account-dropdown__container">
<ul>
<li>Account</li>
<li>Invite Friends</li>
<li>Zola Store Credit</li>
<li>Registry Settings</li>
<li>Orders You've Placed</li>
<li><a>Log out</a></li>
</ul>
</div>
The first piece of code is a button, but if I put my mouse over it, it will show the Dropdown container that I am talking about. If I put my mouse over it without clicking, it will show the list of the Dropdown Container. (And I would also like to know how to hover an element to show the list without clicking it, because its hidden).
My question is, then: how can I click on Registry Settings?
It doesn't have an ID, nor a class (although it is inside the class account-dropdown__container). I think I can use By.name("Registry Settings"), but since is not visible unless the Dropdown list is open, it won't click and it will show Css Selector not found error. Care to help? Thanks!
Also, I am using Cucumber + Selenium + Java in IntelliJ IDEA, the synthaxis changes just a bit, but it is still different from the codes I tend to find in this forum. Hence, why I am asking for a specific solution to my problem.
You have to make the dropdown visible first.
As in Selenium you can't just hover an element, you will have to do it all in one go.
Check this: How to perform mouseover function in Selenium WebDriver using Java?
Actions action = new Actions(webdriver);
WebElement button = webdriver.findElement(By.class("account-link"));
action.moveToElement(button).moveToElement(webdriver.findElement(By.linkText("Registry Settings")).click().build().perform();
You may have to wait in between for the dropdown to appear. I have not tested the code, you will probably have to fix it before it works.
As you have mentioned when you put your mouse over to a button, it will show the Dropdown container.
Same can be automated with the help of selenium like this : (I am assuming account is a button )
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.linkText("Account"))).build().perform();
Now your drop-down is expanded or visible in UI, and you want to click on Registry Settings . Since your drop down is not made using Select options tags which are available in HTML. You can't use Select class from Selenium.
You will have to store every elements which are present in drop down to a list. and then based on some condition , you can click on your desire element.
Code:
List<WebElement> options = driver.findElements(By.cssSelector("div.account-dropdown__container ul li"));
for(WebElement option : options) {
if(option.getText().trim().contains("Registry Settings")) {
option.click();
}
}
Hope this will help.

Bootstrap (actually JQuery) DatePicker does not hide on blur in Wicket modal

I have a wicket bootstrap DateTextField on a panel inside modal. When datepicker is shown from click, datepicker is attached to the root page, not the modal.
That causes a problem: without adding some z-index to datepicker, I cannot see it on top of modal.
When I blur from the picker, it should close. Somehow, due the fact the picker is not child of modal, clicking outside datepicker closes it only, if it is clicked outside the modal. Inside modal nothing happens.
I can tweak this by autoclose, but when you go to input and manually use backSpace to clear the value, there is no a way to close datepicker by clicking somewhere inside the modal.
Some html to make it clear:
<html>
<panel>
<modal>
<input>datefield is here</input>
</modal>
<panel>
<datepicker comes here>
</html>
How to get datepicker attached to modal, or somehow else fix the issue of blur inside the modal?
I have tried to attach the panel a click event that hides datepicker, but it hides the datepicker right away when it opens.
Edit:
Click to modal does nothing, although html is moved artificially there and is placed correctly in DOM tree. Thanks to #Gavriel about insight to moving stuff between DOM elements, though.
Edit2:
Code to reproduce situation:
class MyPanel extends Panel {
DateTextField field = new DateTextField("foo");
(...)
add(field);
}
class MyPage extends WebPage {
(...)
ModalWindow modal = new ModalWindow("modal");
modal.add(new MyPanel());
(...)
}
html for the panel, containing the dateTextField
<html>
..
<input wicket:id="foo"></input>
..
</html>
As you see from snippet, java code generates the jQuery part.
Edit3:
I speak about this creature:
[DateTextField sources] https://github.com/l0rdn1kk0n/wicket-bootstrap/blob/master/bootstrap-extensions/src/main/java/de/agilecoders/wicket/extensions/markup/html/bootstrap/form/DateTextField.java
Edit4:
Hmm.. I added in Javascript a blur event listener inside the input in modal and that blur even did not work. So it turns out that the real question in hand is how to get onblur work inside modal. Because that is what is broken!!
Edit5:
Sorry, cannot give fiddle. From Edit3 you see sources I use for picker and what I really call is this function:
protected CharSequence createScript(final DateTextFieldConfig config) {
return $(this).chain("datepicker", config).get();
}
which is inside java class, so not JavaScript at all although syntax is looking so similar. For my understanding fiddles take no java code inside them. Wicket needs the java part, I am sorry about it.
For fiddle askers I found similar situation on this fiddle: http://jsfiddle.net/VytfY/227/ - works 100% ok, similar technologies I mention here, no use to my problem.
Last edit:
$('html').on('click',function(e){
if(e.target.className.indexOf('datepicker') == -1 &&
e.target.className != 'next' && e.target.className != 'prev' &&
e.target.className != 'year' && e.target.className != 'month'){
if ($('.datepicker').get(0) != undefined){
$('.datepicker').get(0).remove();
}
}
});
Thanks #Mathew you made my day, above is what it ended to be. I added to input element a class datepickerContainer so clicking it does not hide picker.
Thanks folks, this is done!
One more: for IE, use:
var canvas = $('.datepicker').get(0);
canvas.parentNode.removeChild(canvas);
instead of direct remove. Remove not yet supported, even IE11.
The idea is to move the div created by datepicker.
Use http://api.jqueryui.com/datepicker/#option-beforeShow You can see an example how it is used in a slightly different use case: How to add a custom class to my JQuery UI Datepicker
When you append an element to the DOM that was already inside the DOM, it is removed from the original place, in other words if you use $("#dst").append("#src"), then src element is moved to dst.
Update: I think there's a more straightforward way: You provide the id of the div you want it to use. This way you can have this div inside your modal dialog.
$("#button").on('click', function(){
$("#datepicker").datepicker();
});
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button id="button">choose date</button>
<div id="datepicker"></div>
<div>footer</div>
$("#button").on('click', function(){
var dt=$("#datepicker").show();
dt.datepicker().on('change', function (ev) {
$(dt).hide();
});
$('html').on('click',function(e){
if(e.target.id !='button'){
$(dt).hide();
}
});
});
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button id="button">choose date</button>
<div id="datepicker"></div>
<div>footer</div>

JavaScript only loads once per tab? (Multiple "pages" with tables in single page)

Alright, so I'm creating a script to avoid activating a link in a parent div. I've added an image of the website to give you an idea of what it looks like and to make it easier for me to explain. The white tabs are controlled by Ajax and all of them are loaded when the Orders/Subscriptions page is loaded.
All the rows in the table are clickable, and the blue cogwheel shows a dropdown when you hover over it. This dropdown contains several links that need the javascript/jquery code to not activate the row link instead. The problem is that when you switch tabs, the js code won't run unless you reload the page (the active tab stays when reloaded), but the users of the website shouldn't have to reload the page every time they switch between the tabs.
I have absolutely no idea why the .js file only works on the active tab. Everything is written in Wicket/Java using a lot of Ajax events for this page.
JavaScript:
$(document).ready( function () {
$('.dropdown-menu > li > a').on('click', function(event) {
event.stopPropagation();
alert('Propagination Stopped');
});
EDIT:
Alright, so I now know it works if I add
location.reload();
when the tabs are clicked, but I kinda want to avoid this since that adds unnecessary loading time.
I figured out what the problem was. Since I use Ajax for the tabs I had to add
$(document).ajaxComplete(function { myFunction });
and put the onClick in there. That way it would load properly every time I switched tabs.
The invisible tables in the inactive tabs had display: none; which mean when they are set to display: visible; it isn't part of the DOM. So the script won't run unless page is reloaded.
Don't like answering my own question, but felt like the info should be shared.
Thanks for the help anyways guys!
You haven't shown how your script elements are defined and added to the DOM, so it's hard to be specific.
Once a script element has been added to the DOM (directly, or via markup), it is run once. If you want any functions defined by that script to be run again, you have to run them. So in your tab-switching code, add code to call a function if you want it to be run for that tab.
You also haven't shown how you're loading the tab content, or whether the tab content defines script tags. It's best not to have the tab content contain any more script than necessary. Instead, have a main script file loaded with the page that defines the main functions, and then at most have a single script in the dynamically-loaded tab content that executes a single function call to that already-loaded code. If you're loading via jQuery's load, it'll call the scripts for you unless you use a fragment identifier with load. (If you use a fragment identifier with load, it disregards scripts in the content entirely.)
I think this will help you!
the html code example
<ul id="ajaxContainer">
<li>the default content in your app</li>
</ul>
<nav id="pagination">
<ul>
<li><a class="active" href="/ajaxpath1">1</a></li>
<li>2</li>
<li>2</li>
</ul>
</nav>
<script src="jquerypath/jquery.js"></script>
<script src="appjspath/app.js"></script>
Code in your app.js as bellow
$(function() {
var $ajaxContainer = $('#ajaxContainer'),
CLSA = "active",
DOT = ".",
$pagination = $('#pagination'),
hasElMakeShow = function($el) {
//just make elment show hide
$el.show().siblings().hide();
},
appendNewEl = function($el) {
//new data requested should be append to container element
$ajaxContainer.append($el);
hasElMakeShow($el);
},
initBindEl = function(){
//init bind first active pagination el with its data elment
var $li = $ajaxContainer.find('>li'),
$active = $pagination.find(DOT + CLSA);
$active.data('el', $li);
},
switchNavA = function($el) {
//do some pagination switch active class work
$el.addClass(CLSA).closest('li').siblings().removeClass(CLSA);
};
initBindEl();//first bind current pagination
$pagination.delegate('>li a', 'click.page', function(e){
e.preventDefault();//prevent default jump
var $me = $(this),
isActive = $me.is(DOT + CLSA),
$targetEl = $me.data('el');
if(!isActive) {
if($targetEl.length) {
hasElMakeShow($targetEl);
} else {
var url = $me.attr('href');
$.get(url, function(data){
var $respondEl = $(data);
$me.data('el', $respondEl);
appendNewEl($respondEl);
switchNavA($me);
});
}
}
});
});

commandLink disabled via javascript can still be clicked

I need to disable the button based on the selected row of t:dataTable.
This is the javascript method I'm calling on the row selection event
(the button should be disabled if an item in the selected row has a tooltip... it's ugly, but it was the easiest thing to do):
function processUpdateButton() {
if (!$(".selectedRow").length
|| $(".selectedRow").children().find(".tooltip").length){
$(".Update").button({disabled:true});
} else {
$(".Update").button({disabled:false});
};
}
This is the JSF commandLink:
<h:commandLink id="update" styleClass="Update iconButton"
action="#{myBB.update}"
value="#{gui['button.update']}"
tabindex="301"/>
Setting disabled attribute to the button works. The button is greyed out and if I hover the mouse over it, the cursor doesn't change as it does for other links. The problem is, that I can still click it and the method in the backing bean is called. Is there some way to prevent that?
Here's the rendered disabled button:
<a id="mainForm:update"
class="iconButton ... ui-button-disabled ui-state-disabled"
onclick="return myfaces.oam.submitForm('mainForm','mainForm:update');"
href="#" role="button" aria-disabled="true" disabled="disabled">
<span class="ui-button-text">Update</span>
</a>
I should probably remove the onClick attribute, but I don't know how I would be able to reenable it again.
Of course I can check the condition on the server after clicking the Update button, but that's the last resort. It would be nice if I could completely disable the button generated by JSF only from javascript without call to the server.
So I've found the solution. I copied the onclick attribute to another attribute on disabling button and vice versa:
var onclick;
if (!$(".selectedRow").length
|| $(".selectedRow").children().find(".tooltip").length){
$(".Update").button({disabled:true});
onclick=$(".Update").attr('onclick');
$(".Update").attr('onclick2',onclick);
$(".Update").removeAttr('onclick');
} else {
$(".Update").button({disabled:false});
onclick=$(".Update").attr('onclick2');
$(".Update").attr('onclick',onclick);
$(".Update").removeAttr('onclick2');
};
As you can see the generated html code is not a button but hyperlink. So you need to remove the link from link tag. Could try follows:
$(".Update").removeAttr('href');

Refresh only update panel on parent from pop-up window

I have a button which opens a pop-up window and an Ajax update panel. Inside that window I have another button.
What code do I have to run if I want that update panel to be refreshed, when I press the button from the parent page, without refreshing the whole page?
I sow this code on a web which refreshes the page:
<div id="Container" onclick="__doPostBack('UpdatePanel1', '');">
I am such a good friend with Java.
You need to utilize window.opener object.
window.opener.document.getElementById('Container').onclick();
I'd suggest using jQuery to ensure cross-browser compatibility. And also adding some null-checks of course.
Use Jquery :
If the DIV ID remains static :
$("#Container").click(function() {
// REFRESH CONTAINER HERE
});
If the Div ID is dynamic then make use of class instead of ID:
$(".Container").click(function() {
// REFRESH CONTAINER HERE
});

Categories

Resources