SilkTest: HTML tag associated to a DomElement object - silktest

I have a SilkTest DomElement object, and I need to get the HTML tag associated to this DomElement.
How can I do this?
Thanks.
// Silk4J
DomElement column = row.getCell(i);
if (???) {
// TD case
} else {
// TH case
}
I may need it for others HTML tags too.

Related

How to query and update the DOM with yew?

Is there any way to make DOM action via use_node_ref? or alternatively, how to do document.query_selector() in Rust using yew?
use web_sys::HtmlInputElement;
use yew::{
function_component, functional::*, html,
NodeRef, Html
};
#[function_component(UseRef)]
pub fn ref_hook() -> Html {
let input_ref = use_node_ref();
let all_editables = input_ref.query_selector("[contenteditable]")
web_sys::console::(all_editables)
html! {
<div>
<input ref={input_ref} type="number" />
</div>
}
}
Goal: I have a rich text editor app. And I have a minified html in form of string like this <h1> this is title</h1><p>hello world</> and I need to get the DOM and change the innerHTML to set it to this value.
Goal2: I will also need to update the innerHtml as the user write things in the contenteditable elements. Fore example when the user type #john smith I will make a create an <a> element with href the have the link to John smith's profile.
Many things to tackle with your question.
#1 Do not set inner html
More to read about this in Alternative for innerHTML?
But instead create text nodes.
So using web-sys you would do something like:
let txtNode: Node = window()
.unwrap_throw()
.document()
.unwrap_throw()
.create_text_node("Hello")
.dyn_into()
.unwrap_throw();
myDomElement.append_hild(&txtNode).unwrap_throw();
#2 How to query data from an input
There are many ways to do this so ill just show you one of them -
controlled input
core idea is keep your input value in use_state and sync it with the input element using value and oninput attributes.
#[function_component(ControlledInputComponent)]
pub fn controlled_input_component() -> Html {
let my_text_handle = use_state(|| "".to_string());
let my_text = (*my_text_handle).clone();
let handle_input = Callback::from(move |input_event: InputEvent| {
let event: Event = input_event.dyn_into().unwrap_throw();
let input_elem: HTMLInputElement = event.target().unwrap_throw().dyn_into().unwrap_throw();
let value = input_elem.value();
my_text_handle.set(value); // update as user types
});
html! {
<div>
<input type="text" value={my_text} oninput={handle_input} />
</div>
}
}
#3 Update DOM
**External to yew as you should generally avoid updating DOM that is controlled by yew
You can then use use_effec_with_deps to react to your input changing and update your external preview there
let my_text_handle = use_state(|| "".to_string());
let my_text = (*my_text_handle).clone();
use_effect_with_deps(move |my_text| {
// run all the code from my tip #1 like:
// myDomElement.append_hild(&txtNode).unwrap_throw();
||{}
}, my_text);

Change current location programmatically

How can I programmatically change the current location ?
The app-location is on parent element and I want change it from the child element.
here is parent excerpt
dom-module(id='test', assetpath='/')
template
app-location(route='{{route}}')
app-route(route='{{route}}', pattern='/:page', data='{{rootData}}', tail='{{rootTail}}')
...
login-page(name='login', route='[[rootTail]]')
...
script.
Polymer({is: 'test');
and the child
dom-module(id='login-page')
template
div(class='layout horizontal center-justified mh400')
div(class='layout vertical center-justified')
form(is='iron-form', id='login-form', method='post', action='/api/auth/login', on-iron-form-response='onResponse')
...
script.
Polymer({
is: 'login-page',
onResponse: function (event) {
var resp = event.detail.response;
if (resp.success) {
// Change here the location
}
}
})
Sorry by the Jade instead of html but give to understand i think.
app-location simply interfaces with the location bar of the browser. It uses iron-location internally. There's nothing stopping you from including it in the child element as well. It's role here would be to update the location bar (instead of listening to changes). In your JavaScript, select the element and update its path.
The app-location in the parent element will detect the change in the location bar and update route
dom-module(id='login-page')
template
app-location
div(class='layout horizontal center-justified mh400')
div(class='layout vertical center-justified')
form(is='iron-form', id='login-form', method='post', action='/api/auth/login', on-iron-form-response='onResponse')
...
script.
Polymer({
is: 'login-page',
onResponse: function (event) {
var resp = event.detail.response;
if (resp.success) {
// TODO: Update with your new path
this.shadowRoot.querySelector('app-location').path = '';
}
}
})

Angular: manipulating trusted HTML before binding

In my Angular app, I receive some HTML as a string from an API and then I want to render it in the page. So I do:
var myHtml = $sce.valueOf(inputString);
return myHtml;
And then I include it in my template:
<div ng-bind-html="myHtml"></div>
This works fine. But before I render it, I also want to make some changes to the text content of the HTML nodes. (I don't want to do this to the original inputString because it's hard to avoid affecting HTML tags.) So I tried:
var myHtml = $sce.valueOf(inputHtml);
// myHtml is an object of type TrustedValueHolderType
// now I want to access the HTML nodes inside it so I do:
for (var i = 0; i < myHtml.length; ++i) {
if (myHtml[i].nodeType === 3) {
myHtml[i].nodeValue = myHtml[i].nodeValue.replace(/a/, 'b');
}
}
return myHtml;
And then include it in my template:
<div ng-bind-html="myHtml"></div>
But this doesn't work because myHtml is not a list of nodes but an object of type TrustedValueHolderType and I cannot access the HTML nodes inside it.

Change HTML input field to label by defining custom angular directive

I have lots of input, textarea and select on some pages (angular templates).
I want to redefine "input" directive such that It will take a value like ViewMode = true from either localStorage and convert all inputs as label. If I change the ViewMode then on page refresh input should behave properly.
But I do not want to edit any input tag on any angular template.
Means I want to override input, textarea and select as my own angular directive.
I am not able to start. Where from should I start? (I have experience of custom directive with new name, but not with any exciting HTML tag name)
Note: I do not want to use readonly (with proper style) since it requires editing all input tag. Not only that I have custom directives with isolated scope, so I need to pass the ViewMode value to all custom directives. More over if user press CTRL+A content readonly field is not being selected.
I am looking for a solution kind of as follows
ViewButtonClickEvent () {
set localStorage.viewMode = true;
callExistingEditMethod();
}
EditButtonClickEvent () {
set localStorage.viewMode = false;
callExistingEditMethod();
}
editPagesModule.directive('input', {
if(localStorage.viewMode != true)
//Keep all existing functionality with ng-model
}
else {
//replace input with span or label.
}
})
You could create directives called input, select and textarea, which would automatically be compiled without having to change your existing markup.
Working examples: JSFiddle & Plunker
It would look something like this:
angular.module('myApp', [])
.directive('input', inputDirective)
.directive('select', inputDirective)
.directive('textarea', inputDirective)
.factory('$editMode', editModeFactory)
;
inputDirective.$inject = ['$editMode'];
function inputDirective($editMode) {
return {
link: postLink
};
function postLink(scope, iElement, iAttr) {
scope.$watch($editMode.get, function(edit) {
if (iElement[0].nodeName === 'SELECT') {
if (edit === 'true') iElement.removeAttr('disabled');
else iElement.attr('disabled', true);
}
else {
if (edit === 'true') iElement.removeAttr('readonly');
else iElement.attr('readonly', true);
}
});
}
}
editModeFactory.$inject = ['$window'];
function editModeFactory($window) {
return {
get: function() {
return $window.localStorage.getItem('editMode');
},
set: function(value) {
$window.localStorage.setItem('editMode', value);
}
};
}
I did use the readonly attribute (disabled for select), because the only other option I can think of would be to replace the entire input element with something like a div. You would also have to cache the original element, so you can restore it later...and doing that sort of thing would break your bindings so you'd have to recompile every input, every time. That just seems like a horrible idea.

combine string and html string and display in ui-bootstrap popover

I am using restangular to get a collection of items from a server. each item has a description, which is a normal string and a longDescription which contains html describing how it should be formatted.
I am trying to display this information in a single ui-bootstrap popover
I have added a restangule response interceptor like so
var addTrustedDesc = function(room) {
var result;
var desc = room.description;
var longDesc = room.longDescription;
if(desc && longDesc) {
result = desc + ' </br> ' + longDesc;
} else if(desc) {
result = desc;
} else if(longDesc) {
result = longDesc;
}
room.trustedDesc = $sce.trustAsHtml(result);
return room;
};
RestangularConfigurer.addResponseInterceptor(function(data) {
return _.map(data, function(room) {
return addTrustedDesc(room);
});
});
and then much later I try to use the trustedDesc in the popover like so
popover="{{ row.data.trustedDesc }}"
but the popover just displays {}
if I change the line above to
room.trustedDesc = $sce.getTrustedHtml($sce.trustAsHtml(result));
or simply
room.trustedDesc = result;
then the popover displays the full string including the html elements
is it possible to get the popover to render the html and display it?
Your problem is most likely that the bootstrap ui popover cannot handle custom template. I would try to use the custom popover of angular strap instead http://mgcrea.github.io/angular-strap/#popovers

Resources