Here is the exact copy of my code: jsFiddleCode
As you can see I have a two sortable connected lists and when some item is dropped to them they execute functions subFunction and unsubFunction respectively. Now, I also have the code for doubleclicking one of the items so that then they are put in the opposite list (the function switchLists() takes care of that.
Now, what I would like to accomplish here is the same behavior as when the items are dragged and dropped (the alert box appearing and saying exactly (for example): "Item 6 just subed".
My lack of understanding is how can it be that I have the ui available when the function subFunction is called, and not when I call the switchLists. ( I did try to add ui to the call of switchLists like this:
switchLists(e, ui){
//same code as before...
//this code doesn't execute
var itemText= ui.item.text();
alert(itemText + " just subed");
}
But I get an error in FireBug in Firefox saying that the ui is undefined.
You are free to edit the code on fiddle and post it here as a link.
As a more general questions: how does jquery pass variables to other functions? I mean, the code:
receive: subFunction
is called without any arguments, so how does the subFunction get event and ui? If you have some good tutorial on all this, it's appreciated.
Thank you for your help.
After a long day playing with this I finally came to the answer and did it like this: jsFiddle link
In short, I separated the previous function to two functions and I also read a little more about jQuery and found out that in the function I can do $(this) and so access the text of the element.
OK, just for reference the whole code is here:
$(function() {
$( "#sortable1" ).sortable({
connectWith: ".connectedSortable",
receive: subFunction
});
$( "#sortable2" ).sortable({
connectWith: ".connectedSortable",
receive: unsubFunction
});
$(".ui-state-default").dblclick(function() {
$(this).removeClass().addClass("ui-state-highlight");
var litem = $(this).clone();
litem.appendTo($('#sortable2'));
$(this).remove();
$.jGrowl($(this).text() + " successfully unsubed!", {header:"Subscription Status", life: 1000});
});
$(".ui-state-highlight").dblclick(function() {
$(this).removeClass().addClass("ui-state-default");
var litem = $(this).clone();
litem.appendTo($('#sortable1'));
$(this).remove();
$.jGrowl($(this).text() + " successfully subed!", {header:"Subscription Status", life: 1000});
});
function subFunction(event, ui) {
ui.item.toggleClass("ui-state-default");
ui.item.toggleClass("ui-state-highlight");
$.jGrowl(ui.item.text() + " successfully subed!", {header:"Subscription Status", life: 1000});
}
function unsubFunction(event, ui) {
ui.item.toggleClass("ui-state-default");
ui.item.toggleClass("ui-state-highlight");
$.jGrowl(ui.item.text() + " successfully unsubed!", {header:"Subscription Status", life: 1000});
}
});
Related
I have a question regarding how protractor handles the locating of elements.
I am using page-objects just like I did in Webdriver.
The big difference with Webdriver is that locating the element only happens when a function is called on that element.
When using page-objects, it is advised to instantiate your objects before your tests. But then I was wondering, if you instantiate your object and the page changes, what happens to the state of the elements?
I shall demonstrate with an example
it('Change service', function() {
servicePage.clickChangeService();
serviceForm.selectService(1);
serviceForm.save();
expect(servicePage.getService()).toMatch('\bNo service\b');
});
When debugging servicePage.getService() returns undefined.
Is this because serviceForm is another page and the state of servicePage has been changed?
This is my pageobject:
var servicePage = function() {
this.changeServiceLink = element(by.id('serviceLink'));
this.service = element(by.id('service'));
this.clickChangeService = function() {
this.changeServiceLink.click();
};
this.getService = function() {
return this.service.getAttribute('value');
};
};
module.exports = servicePage;
Thank you in advance.
Regards
Essentially, element() is an 'elementFinder' which doesn't do any work unless you call some action like getAttribute().
So you can think of element(by.id('service')) as a placeholder.
When you want to actually find the element and do some action, then you combine it like element(by.id('service')).getAttribute('value'), but this in itself isn't the value that you are looking for, it's a promise to get the value. You can read all about how to deal with promises elsewhere.
The other thing that protractor does specifically is to patch in a waitForAngular() when it applies an action so that it will wait for any outstanding http calls and timeouts before actually going out to find the element and apply the action. So when you call .getAttribute() it really looks like
return browser.waitForAngular().then(function() {
return element(by.id('service')).getAttribute('value');
});
So, in your example, if your angular pages aren't set up correctly or depending on the controls you are using, you might be trying to get the value before the page has settled with the new value in the element.
To debug your example you should be doing something like
it('Change service', function() {
servicePage.getService().then(function(originalService) {
console.log('originalService: ' + originalService);
});
servicePage.clickChangeService();
serviceForm.selectService(1);
serviceForm.save();
servicePage.getService().then(function(newService) {
console.log('newService: ' + newService);
});
expect(servicePage.getService()).toMatch('\bNo service\b');
});
The other thing that I'm seeing is that your pageObject appears to be a constructor when you could just use an object instead:
// name this file servicePage.js, and use as 'var servicePage = require('./servicePage.js');'
module.exports = {
changeServiceLink: element(by.id('serviceLink')),
service: element(by.id('service')),
clickChangeService: function() {
this.changeServiceLink.click();
},
getService: function() {
return this.service.getAttribute('value');
}
};
Otherwise you would have to do something like module.exports = new servicePage(); or instantiate it in your test file.
When you navigate another page, the web elements will be clear, that you selected. So you have to select again. You can select all elements that is in a page of HTML. You can click that you see. So the protactor + Selenium can decide what is displayed.
You have a mistake in your code, try this:
expect(servicePage.getService()).toMatch('\bNo service\b');
I have an XML view that contains a TileContainer which is bound to a model that is used to create StandardTiles. The XML snippet is:
<TileContainer id="tilelist" tiles="{Applications}">
<tiles>
<StandardTile name="{ID}" icon="{Icon}" title="{Name}" press="doNavigation" info="{Description}"
number="{path : 'Number', formatter: 'linxas.com.fiori.launchpad.util.Formatter.formatUsingURL'}"
numberUnit="{NumberUnit}"/>
</tiles>
</TileContainer>
This is working perfectly, the correct tiles are getting displayed etc. When I click on a tile, there is navigation that occurs and I want to "remember" which tile was clicked (by index) so when returning I can scroll to that tile. This is done on the tile's press event handler (doNavigation function) and stores the index in sessionStorage. This is also working properly.
doNavigation : function (evt) {
if (sessionStorage && this.getView().byId('tilelist')) {
sessionStorage.setItem("selected_tile", this.getView().byId('tilelist').indexOfTile(evt.getSource()));
}
...
}
The proper value is stored. So when navigating back, within the onAfterRendering function of the page that contains the TileContainer I have the following code. It is attempting to see if there is a "selected_tile" value stored in sessionStorage, if so it calls scollIntoView passing in the tile index. The issue is that this code is executed, but doesn't work and I suspect it is because at the time of calling this function, the TileContainer's tiles aggregation is returning 0 length.
onAfterRendering : function (evt) {
var theList = this.getView().byId("tilelist");
if (sessionStorage && theList) {
var tile_index = sessionStorage.getItem("selected_tile");
console.log(tile_index + " of " + theList.getTiles().length);
if (tile_index) {
theList.scrollIntoView(+tile_index, true);
sessionStorage.removeItem("selected_tile");
}
}
}
My console output looks something like this (based on the tile that was clicked):
5 of 0
Any help would be appreciated. I assume that there is somewhere else that I need to execute this last bit of code as the TileContainer does not seem to be finished processing its tiles at this point, at least that is my assumption of why the tiles aggregation is 0.
Are you using Routing in your project?
If yes, you can try to register a method to handle the routePatternMatched event of the router. This method will be called after the onAfterRendering method - if the proper route pattern is matched.
To achieve this, just create the following:
onInit: function() {
sap.ui.core.UIComponent.getRouterFor(this).getRoute("NameOfYourCurrentRoute").attachPatternMatched(this._routePatternMatched, this);
},
_routePatternMatched: function(oEvent) {
//do your stuff here
},
Hopefully the TileList is ready at this point to navigate to the correct tile.
I am having one issue with document.ready jQuery function.
On load the document.ready function is working fine. When I click on the button or href link, I want to reconnect with the document.ready function where I have set of code in JavaScript file.
Here is the actual scenario. Please find below sample JS code:
$(document).ready(function() {
var title = "This is your title";
var shortText = jQuery.trim(title).substring(0, 10).split(" ").slice(0, -1).join(" ") + "...";
alert(shortText );
});
After clicking submit button i am adding the input fields data in the below table row. In which description texts are also added in one of table row columns. If description field has more than 100 character, I am pushing the above mentioned JavaScript code from external .JS file. How can i refresh the Java script function without refreshing the page? Anyone have idea?
Please share your opinion.
Create a function, that you can call both in document.ready, and also anywhere else, such as a buttons click event:
function myfunc(){
var title = "This is your title";
var shortText = jQuery.trim(title).substring(0, 10).split(" ").slice(0, -1).join(" ") + "...";
alert(shortText );
}
$(document).ready(function() {
//call when document is ready
myfunc();
//call again when button is clicked
$('#button').click(myfunc());
});
I try to use good lib jstree but i have some strange problem with dblclick binding.
Here is my code
$("#basic_html").jstree({
themes: {
url: "http://mywork/shinframework/shinfw/themes/redmond/css/jstree/default/style.css"
},
"plugins" : ["themes","html_data","ui","crrm","hotkeys", "core"],
});
$("#basic_html").bind("dblclick.jstree", function (e, data) {
alert(e);
alert(data);
});
When this code runs and i make dblclick for some node i can see 2 alerts. The first is object -right, the second is undefined - BUT i want receive data information.
Please, if some specialist solve this problem give me right way for correct use dblclick and receive "data" information about node who is i clicked.
Thanks
I recommend this approach . . .
$("#basic_html li").live("dblclick", function (data) {
//this object is jsTree node that was double clicked
...
});
First, you usually only need to know if the li was clicked so monitoring the event on the li will give you everything you need. Secondly, use live or delegate for the event binding so you can manipulate the tree without breaking the event.
Once you have the node that was double clicked (the this object) you can then use the built-in functions like this . . .
if (!jsAll.is_selected(this)) { return false; } //cancel operation if dbl-clicked node not selected
Where . . .
jsAll = $.jstree._reference("basic_html")
$("#basic_html").bind("dblclick.jstree", function (event) {
var node = $(event.target).closest("li");//that was the node you double click
});
that's the code you want.
I try to use good lib jstree but i have some strange problem with dblclick binding.
Here is my code
$("#basic_html").jstree({
themes: {
url: "http://mywork/shinframework/shinfw/themes/redmond/css/jstree/default/style.css"
},
"plugins" : ["themes","html_data","ui","crrm","hotkeys", "core"],
});
$("#basic_html").bind("dblclick.jstree", function (e, data) {
alert(e);
alert(data);
});
When this code runs and i make dblclick for some node i can see 2 alerts. The first is object -right, the second is undefined - BUT i want receive data information.
Please, if some specialist solve this problem give me right way for correct use dblclick and receive "data" information about node who is i clicked.
Thanks
I recommend this approach . . .
$("#basic_html li").live("dblclick", function (data) {
//this object is jsTree node that was double clicked
...
});
First, you usually only need to know if the li was clicked so monitoring the event on the li will give you everything you need. Secondly, use live or delegate for the event binding so you can manipulate the tree without breaking the event.
Once you have the node that was double clicked (the this object) you can then use the built-in functions like this . . .
if (!jsAll.is_selected(this)) { return false; } //cancel operation if dbl-clicked node not selected
Where . . .
jsAll = $.jstree._reference("basic_html")
$("#basic_html").bind("dblclick.jstree", function (event) {
var node = $(event.target).closest("li");//that was the node you double click
});
that's the code you want.