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.
CodePudding user response:
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);