Access event handler inside component - event-handling

I have a custom button component that accepts on:click event handler. Currently it looks like this:
<!-- Button.svelte -->
<button on:click>
<slot />
</button>
And I use it like this
<Button on:click={doStuff}>click me</Button>
I want to access doStuff handler inside Button component to wrap it with another function. How can I do that?
I know that I can add a custom onClick prop, but this is ugly.

You can call a function inside Button component than dispatch click event, so that will work as wrapper method.
Something like this
/* Button.svelte */
const handleClick = () => {
// your wrapper method or logic here
dispatch('click'); // this is basically doStuff()
}
<button on:click={handleClick}>
<slot />
</button>

Related

Blazor WebAssembly: How to inspect eventhandler bound to html-element in chrome?

I am currently testing Blazor WebAssembly and try the tutorial here: https://learn.microsoft.com/de-de/aspnet/core/tutorials/build-your-first-blazor-app?view=aspnetcore-3.1
In the example project, there is one page (File: Pages/Counter.razor) where an button increases the value of an counter:
#page "/counter"
<h1>Counter</h1>
<p>Current count: #currentCount</p>
<button class="btn btn-primary" #onclick="IncrementCount">Click me</button>
#code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
We can see an onclick event is bound to button and executes the eventhandler IncrementCount. When I start this page, then the page inspector of Google Chrome shows me the following button:
<button class="btn btn-primary">Click me</button>
Where can I see the bound event onclick and the eventhandler IncrementCount in Chromes developer tools for blazor?
For comparison: In the javascript-framework knockout.js can see the event and handler in the browser when I use the page inspector:
<button class="btn btn-primary" data-bind="click: function() { $root.IncrementCount(); }">
Regarding the Documentation here I assume, that I cannot see the event and handler in the HTML-Element:
The HTML markup and C# rendering logic are converted into a component class at build time.
But I hope there is there any other way to see the event and name of the handler in Chrome.

How to have one form with multiple actions

I have one doubt is it possible to have a single form(view page) with multiple actions like i want to save,update and delete on the same view page..if the user click on anyof the button then it have to call on a necessary controller function is it possible??
You have some ways to do it, but all of the them require some javascript code.
The easiest I can think of is to dynamically change the form action when clicking each button (of type button, not submit which is the default), and then submit the form.
Example:
<form id="myform" name="myform" method="post" action="">
<input id="myinput" name="myinput" type="text"/>
[..]other inputs[/..]
<button type="button" onClick="deleteAction()">DELETE</button>
<button type="button" onClick="updateAction()">UPDATE</button>
<button type="button" onClick="saveAction()">SAVE</button>
</form>
Where the JS functions are:
function deleteAction() {
changeActionAndSubmit('/action/delete');
}
function updateAction() {
changeActionAndSubmit('/action/update');
}
function saveAction() {
changeActionAndSubmit('/action/save');
}
function changeActionAndSubmit(action) {
document.getElementById('myform').action = action;
document.getElementById('myform').submit();
}
Hope I got your doubt and that this solves your issue :)
A non-JS way to achieve the same goal would be to use the name/value parameters on each button to have your backend decide what to do.
Example
<?php echo form_open('controller/method'); ?>
// form fields go here
<button type="submit" name="add" value="y">press to add</button>
<button type="submit" name="update" value="y">press to update</button>
<button type="submit" name="delete" value="y">press to delete</button>
<?php echo form_close(); ?>
then, on your controller, after validating user input, you can determine which button was pressed by reading what the buttons send about themselves to the controller (I'll assume you use CI's form helper)
if ($this->input->post('add') == 'y')
{
// the user wants to add
}
else if ($this->input->post('update') == 'y')
{
// user wants to update
}
else
{
// user wants to delete
}
// rest of code goes here
on each if structure, you can take the appropriate actions depending on which button the user pressed

How to trigger a form inside a component from VueX store

I'm calling an action in the store to send data to an API.
This call is triggered from a button in FormComponent from #click :
<button type="button" #click="$store.dispatch('saveStoreDatas')">Click me</button>
How can I submit the parent form of button (omitted code) ? I cannot use a ref because it's inside a component.
Thank you !
Do you need to dispatch an action and submit the form? Normally you can just have form data in the store and send it in the action.
If you really need to submit the form, emit an event in the child component and listen for the event in the parent component.
Child component will goes like this.
<!-- child component template -->
<button type="button" #click="handleClick">Click me</button>
// child component script
methods: {
handleClick () {
this.$store.dispatch('saveStoreDatas')
this.$emit('clickSubmit')
}
}
And this is its parent.
<!-- parent template -->
<form ref="form">
<child-component #clickSubmit="submitForm">
</form>
// parent component script
methods: {
submitForm () {
this.$refs.form.submit()
}
}
Add a separate function for the click handler:
<button type="button" #click.prevent="submitToStore">Click me</button>
...
...
methods () {
submitToStore () {
// refs can be used here - get your form data and send it to the store
let formData = this.$refs.myForm.data()
this.$store.dispatch('saveStoreDatas', formData)
...
}
...
}
Hope this helps.
just use ;
attribute #click="$store.dispatch('saveStoreDatas');$emit('clickSubmit')"
<button type="button" #click="$store.dispatch('saveStoreDatas');$emit('clickSubmit')">Click me</button>

ember.js: how to delete a record using a view

in ember's official guide, they say it's possible to delete a record using a view, but they don't provide an example of how to do it. i can't understand how views can get the id of the object do destroy.
maybe i didn't understand what's the view purpose? i think it's an event handler (but i see sometimes it's used to render chunks of hbl... maybe that's why i'm confusing)
is there an example of the whole process of deletion anywhere?
thank you
Generally, what you want to do is create an {{action}} in your view that sends an event to where it should actually be handled: either the controller or the route. (In my case, a little of both)
Note: Generally, you don't need to write a View class for templates, unless the view needs a particular event handler. Ember generates a generic view on-the-fly. You can see this through {{log view}}:
<script type="text/x-handlebars" data-template-name="app">
{{log view}}
</script>
If you look in the console you will find that the template app is associated with a view class:
For example, in the following view template, I'm defining a "Delete" button, which will trigger the action remove in the controller.
<script type="text/x-handlebars" data-template-name="product/remove">
<fieldset>
<legend>Remove</legend>
<div class="row-fluid">
Are you sure you want to delete <strong>{{content.name}}</strong>?
</div>
</fieldset>
<ht />
{{#linkTo products class="btn"}}Back to List{{/linkTo}}
<button {{action remove target="controller"}} class="btn btn-danger">
Delete
</button>
</script>
The controller simply gets the content property and signals the route to fire the confirmRemove event, passing its content as the argument
App.ProductRemoveController = Em.ObjectController.extend({
remove: function() {
this.get('target').send('confirmRemove', this.get('content'));
}
});
And the route actually handles it like this:
App.ProductRemoveRoute = Em.Route.extend(App.NotifyHandler, {
setupController: function(controller, model) {
var c = this.controllerFor('product');
controller.set('content', c.get('content'));
},
events: {
confirmRemove: function(record) {
record.deleteRecord();
// should commit here
// this.get('store').commit();
this.controllerFor('application').set(
'notification', 'Product has been removed'
);
this.transitionTo('products');
}
}
});
(see fiddle)
If you want to handle the event directly in the Route, without talking to the controller, in your view template, you simply omit the target="controller", and the framework will look up for a handler of that event in the controller, and if doesn't find, it will look up in the route. In this approach, you have to pass the event argument via Handlebars, if any argument is required. In this case, I know that this represents the content in that template:
<script type="text/x-handlebars" data-template-name="product/remove">
<fieldset>
<legend>Remove</legend>
<div class="row-fluid">
Are you sure you want to delete <strong>{{content.name}}</strong>?
</div>
</fieldset>
<ht />
{{#linkTo products class="btn"}}Back to List{{/linkTo}}
<button {{action confirmRemove this}} class="btn btn-danger">
Delete
</button>
</script>
With this approach, you don't need to define anything in your controller as it will fire the event directly in the route:
App.ProductRemoveController = Em.ObjectController.extend();
(see fiddle)
Update: In order to have the event handled in the object controller, the itemController property has to specify a controller, which should extend Em.ObjectController:
Depot.TransportDocumentsController = Ember.ArrayController.extend
itemController: 'transportDocument'
Depot.TransportDocumentController = Ember.ObjectController.extend
removeItem: ->
alert("aoooo")
The only thing that would be changed in a template would be the mention of the itemController in the {{each}} helper:
{{#each doc in controller itemController="transportDocument"}}
{{doc.number}}
<!-- rest of the template removed to make this short. -->
<button {{action removeItem}} class='btn btn-danger btn-small'>
<i class="icon-white icon-remove"></i>
</button>
{{/each}}
In the action, you don't need to say where the handler is located, as the framework can find the target on its own.
(see fiddle)

jquery - how to select element and all children, except specific child

I have a .mouseover() event triggered on all elements of class 'node'. It works fine, and is also triggered when user hovers over any child of .node. This works well for me, however, I do not want this event triggered if the user mouse overs a specific child, namely, an image.
Why is the selector $('.node :not(img)') not working?
Oddly enough, it does work when I try it out at http://www.woods.iki.fi/interactive-jquery-tester.html, but not in my actual implementation.
My html:
<div id="container">
<div class="node" id="abc">
<h2>Node Title</h2>
<div class="nodeChildren">
<h3 id="a1">Some text</h3>
<h3 id="a2">Some text</h3>
<h3 id="a3">Some text</h3>
</div>
<img src="diagonal-left.gif" />
</div>
</div>
My jquery:
//start with third tier not visible
$('.nodeChildren').hide();
$('.node :not(img)').mouseover(function(){
$(this).children('div').show();
});
$('.node').mouseout(function() {
$('.nodeChildren').hide();
});
});
My failed attempts
$('.node :not(img)') //no mouseover is triggered
//for the following selectors, the mouseover event is still triggered on img
$('.node').not('img')
$('.node').not($('.node').children('img'))
Thanks for any help :)
The problem is the event is "bubbling" up to the parents which triggers the mouse over. You need to add a mouseover to the img to stop this.
$(".node img").bind("mouseover", function(event) {
event.stopPropagation();
});
in the callback function of bind, you can check the target. in your case, Something like this
$(".node").bind('mouseover',function(e){
if(e.target.nodeName != 'IMG'){
$(this).children('div').show();
}
});