I am using Sahi to record my actions in IE8. My page contains this markup:
<td id="ButtonText" class="myClass">
<font title="unique title" onclick="CallThis()">ButtonText</font>
</td>
When I click the button defined above, Sahi records:
_click(_cell("Button Text"));
But when I play this back, the button is not clicked. However,
_assertExists(_cell("Button Text"));
returns true.
I have added the following line into the concat.js file to try to make it detect font nodes:
this.addAD({tag: "FONT", type: "null", event:"click", name: "_font", attributes: ["sahiText", "title|alt", "id", "index", "href", "className"], action: "_click", value: "sahiText"});
but this doesn't seem to have had any effect (I have restarted Sahi). I don't have any control over the page being tested and I am not sure whether the td node or the font node is being selected.
How do I fire the onclick event of the font node?
EDIT:
I have added _font to sahi/config/normal_functions.txt
Manually tweaking the page using IE tools to have the onclick even on the td results in the same steps being recorded, but it will now play it back.
<td id="ButtonText" class="myClass" onclick="CallThis()">
<font title="unique title">ButtonText</font>
</td>
Unfortunately I am unable to make any changes to the page and I still need to playback the onclick event which exists on the font node.
Both
_font("ButtonText");
_font("unique title");
give
[Exception] [object Error]
The solution to the problem was to remove the quotes around "null":
this.addAD({tag: "FONT", type: null, event:"click", name: "_font", attributes: ["sahiText", "title|alt", "id", "index", "href", "className"], action: "_click", value: "sahiText"});
Add _font to sahi/config/normal_functions.txt, restart Sahi and check.
Regards,
Narayan
Related
I am trying to convert an existing template from button clicks to a select with options. The original template looks like this:
<!-- ko foreach: {data: amounts, as: 'amount'} -->
<button type="button" data-bind="click: $parent.changeAmount.bind($parent)">
<span data-bind="text: amount.amountFormatted"></span>
</button>
<!-- /ko -->
The content of the array amounts is this:
[
{
"baseValue":"15",
"value":15,
"amountFormatted":"15,00 €",
"price":"15,00 €"
},
{
"baseValue":"25",
"value":25,
"amountFormatted":"25,00 €",
"price":"25,00 €"
},
{
"baseValue":"50",
"value":50,
"amountFormatted":"50,00 €",
"price":"50,00 €"
}
]
And this is the handler function:
changeAmount: function (amount) {
console.log(amount);
this.activeAmount(amount);
}
The console.log shows me how the return value of the button click looks like:
{
"baseValue":"50",
"value":50,
"amountFormatted":"50,00 €",
"price":"50,00 €"
}
Now I want this whole thing displayed as a select instead of buttons:
<select data-bind="options: amounts,
optionsText: 'amountFormatted',
optionsValue: 'value',
value: activeAmount,
event:{ change: changeAmount}"></select>
But with this template the select returns the entire view object instead of what a button click returns. How can I get the select to return the same object/array?
You should only be needing this as the minimal working sample:
The amounts observableArray with the options
The binding below:
<select data-bind="options: amounts,
optionsText: 'amountFormatted',
value: activeAmount"></select>
You are also using the event binding which is probably not needed on your context at all, you are binding it against the parent but instead of working with this you are also expecting the amount to be passed in, which does not work well with your click handler definition ( where you bind the function, ok, but no params are given if you go through that route ).
Rework your context and the click handler, so that it accesses activeAmount such that you dont expect a parameter. Since you are bound on the parent, just use this.activeAmount internally.
Note: you dont need to do anything to update the activeAmount if the select bind works properly. it will contain the seleced option's formattedAmount text already
When dealing with dynamically sizing the iframe in fancybox, I accidentally found that setting data-width and data-height on the [data-fancybox] is helpful after reading this answer.
Exmaple HTML element:
<a data-fancybox data-width="<?= $banner_width; ?>" data-height="<?= $banner_height; ?>" data-src="example.com" href="javascript:;">example.com</a>
and js:
$("[data-fancybox]").fancybox({
afterLoad: function ( instance, slide ) {
$('body').find('.fancybox-content').css({"width": slide.opts.width + "px", "height": slide.opts.height + "px"});
}
});
What I couldn't figure out is that there is no explanation of data-width and data-height usage on HTML element from fancybox documentation (please correct me if I'm wrong).
NOTE: these two code snippets above do work for me, but they have to work together, it wouldn't work if one of them is taken off.
Can anyone explain that a little bit for me please?
Based on fancybox 3 documentation, they do offer a way to set our own custom options by creating data-options attribute. Here is the example from the documentation:
<a data-fancybox
data-options='{"caption" : "My caption", "src : "iframe.html"}' href="javascript:;">
Open external page using iframe
</a>
You can see the value of these options by console.info( slide.opts ) from the callback function like onComplete (slide is one argument in the callback function ).
Not surprisingly, these two snippets are the same:
<a data-fancybox data-width="<?= $banner_width; ?>" data-height="<?= $banner_height; ?>" data-src="example.com" href="javascript:;">example.com</a>
<a data-fancybox data-options='{"width" : "<?= $banner_width; ?>", "height" : data-height="<?= $banner_height; ?>", "src" : "example.com" }' href="javascript:;">example.com</a>
So, in my javascript, I use slide.opts.width to get the value from data-width and slide.opts.heightto get the height from data-height, that is how my width and height value get passed from backend to frontend.
Since these two values are processed in afterLoad callback, so every iframe will be initiated with different width and height.
Properties - data-width and data-height - are used to tell the script real dimension of the image. The script then can calculate position and start zooming thumbnail while real image is still loading.
See documentation - http://fancyapps.com/fancybox/3/docs/#images
These properties are not used anywhere else.
You can use { iframe : { css : { width: '', height : '' } } } to set iframe element width/height, but there is no option to change iframe content.
I'm try to create test for my Bootstrap project. I'm use Coypu. But I ran into a some problem. I can't check my check-boxes. The problem is that I changed style form my check-box. And now standard Bootstraps check-boxes is hidden. The new check-box is hidden inside standard pattern:
<label>
<input type="checkbox" data-bind="checkedValue: key, checked: $parent.selectedCatchments, attr: { id: key }" class="catchment-checkbox" />
<span data-bind=" text: value, attr: { for: key }" class="lbl padding-8 openSans-Text catchment-checkbox-span"></span>
</label>
The problem is that Coypu can't to find the hidden element on browser. And now I can't to check selected check-box or not.
This is standard check-box:
I turned off: opacity: 0 in CSS style.
And this is new checkbox with the new style.
How can I check the number of checked items in Coypu?
I can add ConsideringInvisibleElements = true inside SetUp method, but this option will be works always for all Tests. How I can change value of ConsideringInvisibleElements option on true or false when I need inside test code?
I'm find this variant:
var catchmentsCheckboxes = Browser.FindAllXPath("id('catchmentsColumn')/div[1]/div/label/input", null, new Coypu.Options { ConsiderInvisibleElements = true });
The first parameter: xPath to element;
The second parameter is can be null;
The third parameter is ConsideringInvisibleElements. And we can change value of this parameter on true or false.
I cannot find an example to do this anywhere, although I could have sworn I've seen one in the past.
I want to add a button to a node in fancytree so that either on hovering over that node (or maybe on selecting it) the button displays (a white x on a red circle, for example) and clicking it will delete/remove that node. At all other times the delete button should be hidden for the node.
I've been unable to find any kind of example where a custom link or button is added to a fancytree node though - maybe it's not possible to do or I'm just using the wrong search terms?
Edit: I found a way to add a clickable button by appending html to the title string:
title: component.name() + "<span class='deleteButton'><a href='#' data-bind='click: myfunction'><img src='../../Content/images/deleteIcon.png' /></a></span>",
And by adding some custom css to my site file:
span.fancytree-node span.deleteButton {
display: none;
}
span.fancytree-active span.deleteButton {
margin-left: 10px;
display: inline-block;
}
But this adds the button to the title text and is therefore subject to the highlighting of the title when active. It would be better if there was a way to add this to the node OUTSIDE of the title text. Is that possible Martin?
$("#tree").fancytree({
source: [...],
renderNode: function (event, data) {
var node = data.node;
var $nodeSpan = $(node.span);
// check if span of node already rendered
if (!$nodeSpan.data('rendered')) {
var deleteButton = $('<button type="button" class="btn">delete node</button>');
$nodeSpan.append(deleteButton);
deleteButton.hide();
$nodeSpan.hover(function () {
// mouse over
deleteButton.show();
}, function () {
// mouse out
deleteButton.hide();
})
// span rendered
$nodeSpan.data('rendered', true);
}
}
});
I normally use css ':after' for such cases (https://developer.mozilla.org/de/docs/Web/CSS/::after).
If that is not enough, you can always tweak the markup in the 'renderNode' event.
How to disable HTML Clean Up while in the editor mode? I'm in a need of allowing css format & inline html in code. The idea is to disable parser and html clean up action when pasting the code and entering the Editor for editing. Thanks.
You can provide an identity function as the parser attribute upon initializing the wysihtml5 editor. The below script is a coffeescript snippet that disables the cleanup completely.
enableWysiwyg: ->
#$el.find('textarea').wysihtml5
"style": false
"font-styles": false #Font styling, e.g. h1, h2, etc. Default true
"emphasis": true #Italics, bold, etc. Default true
"lists": false #(Un)ordered lists, e.g. Bullets, Numbers. Default true
"html": true #Button which allows you to edit the generated HTML. Default false
"link": false #Button to insert a link. Default true
"image": false #Button to insert an image. Default true,
"color": false #Button to change color of font
parser: (html) -> html
JavaScript version of the above code:
$('textarea').wysihtml5({
"style": false,
"font-styles": false,
"emphasis": true,
"lists": false,
"html": true,
"link": false,
"image": false,
"color": false,
parser: function(html) {
return html;
}
});
Actually, this is what the parser rules are for.
You can attach your custom rules to the included var wysihtml5ParserRules before instantiate the editor object or just create your own rules object and give to the editor's constructor.
For example, to allow the h1 and h3 tag in addition to the tags allowed in the distributed simple example rules, you'd need to set up as follows:
<form>
<div id="toolbar" style="display: none;">
<a data-wysihtml5-command="bold" title="CTRL+B">bold</a> |
<a data-wysihtml5-command="italic" title="CTRL+I">italic</a>
<a data-wysihtml5-action="change_view">switch to html view</a>
</div>
<textarea id="textarea" placeholder="Enter text ..."></textarea>
<br><input type="reset" value="Reset form!">
</form>
<!-- The distributed parser rules -->
<script src="../parser_rules/simple.js"></script>
<script src="../dist/wysihtml5-0.4.0pre.min.js"></script>
<script>
// attach some custom rules
wysihtml5ParserRules.tags.h1 = {remove: 0};
wysihtml5ParserRules.tags.h3 = {remove: 0};
var editor = new wysihtml5.Editor("textarea", {
toolbar: "toolbar",
parserRules: wysihtml5ParserRules,
useLineBreaks: false
});
</script>
Now, when you enter/paste <title>test</title> into the editor, while you're in the editor mode, and then switch to html view, you'll get <title>test</title>. And when you switch back to editor view, you'll get <title>test</title> again.
That was the general part.
Now, in your case, I'm not sure if it's the best idea to work with 121 custom parser rules (the count of HTML tags to handle) or if it wouldn't be better to take the time and dig into the source code to find a more performant solution (doesn't make much sense to tell a parser to actualy just return the input string anyway, right?). Furthermore, you said you want to allow CSS as well. So your custom parser rules will even extend.
Anyway, as a starting point, feel free to use my custom parser rule set from here: https://github.com/eyecatchup/wysihtml5/blob/master/parser_rules/allow-all-html5.js.