"removed" event in Meteor - events

I want to trigger an event when an element is removed from the DOM.
In one of my templates I show a checkbox only when a condition is met:
{{#if some.thing}}
<input type="checkbox" class="checkbox">
{{/if}}
This checkbox later then is converted to a Bootstrap Toggle component.
What it does is, it hides the original checkbox and adds some markup to the document. All OK with that.
Now, if my collection changes and the condition, which previously was met, now evaluates to false, the checkbox is removed from the DOM. The node created from Bootstrap Toggle though stays present. So I want to remove the nde when the checkbox is removed.
I thought I could to this with the DOMNodeRemoved event but have some issues there:
Template.myTemplate.events({
"DOMNodeRemoved input.checkbox": function(el) {
$(el.currentTarget).bootstrapToggle('destroy');
}
});
The event fires, but somehow it ends in a cascade when I call bootstrapToggle('destroy') and the browser freezes. Also the event fires multiple times before and it makes me think this is not the correct way to watch for removed nodes in the first place.
Is there any better way to watch for removed elements and fire an event before they are deleted?
I know I could simply call a helper from my template, manually check if the node exists and delete the node with jQuery. But I'd like to see if this is possible with Meteor.events instead.

If you place the input (and the new bootstrap node/s) inside a child template, this should "just work" out of the box.
<template name="parent">
{{#if some.thing}}
{{> child}}
{{/if}}
</template>
<template name="child">
<input type="checkbox">
<!-- additional bootstrap nodes get instantiated in child -->
</template>
In the above, if some.thing === false the input and the new node/s will be removed from the DOM by Meteor automatically.

Related

Livewire Alpinejs Emit/Dispatch variables across files

How can I emit and recognise changes from child components (in separated files) using AlpineJS?
I'm trying to build a form in Livewire/alpinejs that would only show the next step after selected a value in the previous step.
I know I can use livewire model/emitUp to catch changes from the selectfield child component and then use x-show accordingly. However, emitting up is rather slow, waiting around 5 seconds after selecting each select field isn't a good user experience. Hence the user of AlpineJs.
The issue is that x-data is scoped locally and I cannot pass down a variable and assign that as the x-model. AlpineJS has $dispatch, but it seems to only work within a file. So I can't dispatch when the x-model changed and then catch that change in Livewire Main Form.
Livewire Main Form
<div>
<form>
<livewire:selectfield />
{{-- Only show this div when livewire:selectfield has selected a value (Incomplete code)--}}
<p>
Should see this only when a select-field value has been selected
</p>
</form>
<div>
Livewire Select Field
<div x-data="{ selectedField: '' }">
<label> Form Label </label>
<select x-model="selectedField">
<option value="1">Opt 1</option>
<option value="2">Opt 2</option>
<option value="3">Opt 3</option>
</select>
</div>
Is there any way of showing/hiding div elements when the child component input fields have a selected input? Preferably with AlpineJS due for user experience and less network bombardments.
EDIT
Turns out I just didn't use the functions properly! Ignore this
Must of read the docs wrong. Using Livewire/AlpineJS can emit values from child to parent, similar to VueJS.
The child component HTML should have
<button type="button" #click="$dispatch('custom-event')">Test Model Update Upwards</button>
The parent component has this html. In your case, just add the custom event where it makes sense.
<p #custom-event.window="console.log('Workign emit function cross child/parent')"></p>

Inconsistent click event from v-switch

I'm trying to catch the click of a v-switch prior to it flipping to see if a preexisting condition has been met. While logging e.target of the event I am getting
<div class="v-input--selection-controls__ripple primary--text"></div>
as the result but every now and then I get
<input aria-checked="true" id="input-24" role="switch" type="checkbox" aria-disabled="false" value="Arizona">
Am I missing something in this or is this unexpected behavior?
Codepen Example
What is happening is that you're clicking on two different elements.
When you click on the ball or around it in the grey area you click on this element:
But when you click outside it but still inside the input you click on this other element:
However, both of then capture you click.
You could change your implementation to capture the change event:
<template v-slot:item.ia="{ item }">
<v-switch
v-model="ia_array"
:key="item.id"
:label="item.state"
:value="item.state"
#change="onChange"
></v-switch>
</template>

How do I check a child element in protractor?

I need to know how to check a child element of a parent object
I am trying to check that a checkbox in my application is being deselected. All of my checkboxes have the same value in the code. My parent has a 100% unique name. I need to know if there is a way to check that the checkbox for my parent element is deselected without it just checking the first element with the checkbox code.
<div ng-repeat="k in model.keys" class="Filter__item ng-scope">
<a ng-click="toggleSentiment(k)" pt-id="POSITIVE-filter-toggle"
class="btn btn-default">
<fa type="far" icon="check-square"
ng-class="{'text-success':!model.sentiment[k].on}"
class=ng-isolate-scope text-success">
<svg class="svg-inline--fa fa-check-square fa-w-14"
aria-hidden="true" data-prefix="far" data-icon="check-square"
role="img" xmlns="w3.org/2000/svg"
viewbox="0 0 448 512" data-fa-i2svg>
//for the selected checkbox
icon="check-square"
//for the deselected checkbox
icon="square"
//for my parent
pt-id="POSITIVE-filter-toggle"
the pt-id is unique, but all the check boxes have same icon attribute value.
I can click on the filter using the pt-id but the checkbox is the same everywhere
Buddy the only way to check whether the checkbox/radio button is selected or not is via getAttribute('attributte's name') but it totally depends on your UI designed by dev team i.e. there should be a flag selected with values true and false.
So, my opinion is better to check you HTML from browser's Dev tool that is their any kind of flag is present or not. Else check with dev team for what to do with this case.
Also, every HTML tag shows some property attributes in the devtool, here is the image
But this Attribute "checked:false" you will not be able to fetch it via getAttribute method.
You can use css selector: parent selector > child selector to find child element of specific parent.
Then use getAttribute('icon') to get the value of icon for comparing.
element(by.css('a[pt-id="POSITIVE-filter-toggle"] > fa'))
.getAttribute('icon')
.then(function(value){
expect(value).toEqual('square');
})

Meteor multiple event handlers attached when showing and hiding templates

I'm having an issue with nested templates in Meteor.
If I have a template like this, with a child template inside it:
In parentTemplate.js
{{#if showParentTemplate}}
{{> parentTemplate}}
{{/if}}
<template name="parentTemplate">
{{> childTemplate}}
</template>
In childTemplate.js:
<template name="childTemplate">
<a class="someItem" href="#"></a>
</template>
When I register a click event on the element(anchor in this example), then show/hide the parent template on the DOM, I end up with an extra event listener on the anchor for each time I show the parent back on the DOM. I checked the Template.parentTemplate.onDestroy() and it is firing. That should mean the template and its events are being destroyed. I would imaging that includes destroying the child template and its events as well.
Here is a simple handler for the click event
Template.childTemplate.events({
'click .someItem' :(e,template)=>{
console.log('got it');
}
})
And to clarify, I am attaching the event listeners in the onCreated method, not the onRendered method.
I'm seeing that each time the parentTemplate is shown, the childTemplate fires the onCreated event, then multiple onRendered events. A new onRendered is added with each hide/show of the parentTemplate.
Is there something basic I'm missing here. It seems almost like there are multiple instances of the template on the DOM or the events are never destroyed. is there a correct way to destroy a Meteor template when it is hidden or removed form the DOM?

CakePHP Prototype Ajax Checkbox disable onCreate onComplete events

I have two checkboxes in my code as mentioned below:
<input type="checkbox" id="event_id" name="data[Noncompetitor][event_id][]" value="1">
<input type="checkbox" id="event_id" name="data[Noncompetitor][event_id][]" value="2">
Now I am doing Ajax function like onCreate and onComplete, where I want to disable checkboxes when its initiated and want to enable again as completed request. I am not sure how that can be achieved in Prototype JS and both above checkboxes have same id.
onCreate: function(){
document.getElementById("event_id").setAttribute("disabled", "disabled");
Element.show('loading_message');
},
onComplete: function(){
document.getElementById("event_id").removeAttribute("disabled");
Element.hide('loading_message');
},
My Above code works, but it disables only first checkbox, so please help me here.
Thanks !
You can't have two ids of the same in a HTML page, nothing is stopping you from putting two ids of the same in a HTML page you can but you kill a kitten everytime you do that, and furthermore having two ids will confuse yourself in cases like this. document.getElementById would return the first id it finds and stop caring about the other everytime you have two ids of the same in a HTML page, thus why it only works for one checkbox.
You can either assign classes to your checkboxes, or you can reference your checkbox using name attribute if your form is also named.
http://jsfiddle.net/Q5qNg/7/

Resources