How to call parent function in jquery apline js - alpine.js

I'm facing one issue when clicking on the button this.reloadDatatable() is not called. how can I call reloadDatatable() function from toggle function? below is the demo code for that. Thank you.
<button type="button" #click="addSettingContainer.toggle();"></button>
Alpine.data('initOrderGrid', () => ({
addSettingContainer: {
toggle() {
this.reloadDatatable();
}
},
reloadDatatable: function() {
console.log('a');
},
}));

You cannot access the parent object's scope from a child object without some ugly hacks. However it seem that you want to use an event system: on a button click you want to reload the data table. Alpine.js has builtin event system, we can use the $dispatch function to emit a custom event and the x-on method to capture our custom event:
<div x-data="initOrderGrid"
#reload-data-table.window="reloadDatatable">
</div>
<div x-data>
<button #click="$dispatch('reload-data-table')">Reload data table</button>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('initOrderGrid', () => ({
reloadDatatable() {
console.log('Data table reloaded');
}
}))
})
</script>

Related

jasmine test case for trigger click event of input file from external button in angular uploader component

in html
<button mat-button class="p-0" (click)="addImage.click()" data-testid="addimagebutton">
<input type="file" #addImage (change)="addImageEvt($event)" accept="image/*" multiple hidden />
spec.ts
it('should call addImageEvt method on click', () => {
spyOn(component, 'addImageEvt').and.callThrough();
fixture.detectChanges();
const addImageButton = debugElement.query(
By.css('[data-testid="addimagebutton"]')
).nativeElement;
addImageButton.click();
addImageButton.dispatchEvent(new Event('change'));
let addImageChange = debugElement.query(By.css('#addImage'));
let addImageElement = addImageChange.nativeElement;
addImageElement.triggerEventHandler('change');
fixture.whenStable().then(() => {
expect(component.addImageEvt).toHaveBeenCalled();
});
it should return true,by calling the method. i did not get where i did mistake.. please help in write test case

How to update alpinejs component from js code

I have an input name address (created by a plugin in WordPress context).
When I type some text in this input, I would like to modify an alpine component (new dropdown component used for autocompletion).
Before I used that :
address.addEventListener('input', _.debounce(event => callApi(event.target.value), 250));
Instead of calling callApi function, i need to act on the toggle.
In the dropdown component, I can add :
#set-title.window="title = $event.detail"
but how from my debounce, call the toggle ?
I should be able to do $dispatch('set-title', 'Hello World!') somewhere ?
I specify that I cannot modify my basic input (perhaps in javascript)
Thanks for help
You can create an event listener inside the Alpine.js component's init() method and mutate the title variable from there:
<div>
<input type="text" id="address" />
</div>
<div x-data="myComponent">
<div x-text="title"></div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('myComponent', () => ({
title: '',
init() {
const address = document.getElementById('address')
address.addEventListener('input', _.debounce(event => {this.title = event.target.value}, 250)
});
}
}))
})
</script>

fromEvent not fire when I put HTMLElement, and fire when I put Jquery Object

Code Here
If I put $('input') as parameter of fromEvent it will fire when I call $('input').trigger('input'). But if I put document.getElementsByTagName('input') as parameter it will not fire. It will fire only when I type, but not fire when I call $('input').trigger('input').
Can someone explain why?
Note: $('input').on('input', _ => console.log) will work in both cases.
it's because the ngOnInit hook is running before the view is built, so the document selector is querying before the element is there, but jquery selectors are actually async waiting for the document to be ready.
here's how you do it the angular way:
#ViewChild('inp')
input
// use the after view init hook
ngAfterViewInit() {
fromEvent(this.input.nativeElement, 'input') // angular way
.pipe(
tap(_ => {
console.log("tap input");
})
)
.subscribe(_ => {
console.log("subscribe input");
});
}
in your html, add this:
<input type="text" #inp>
or the even better angular way (not using fromEvent)...
<input type="text" (input)="showMe($event)">
then in component just have this:
showMe(e) {
console.log(e)
}
https://stackblitz.com/edit/angular-ivy-jfoc7d?file=src%2Fapp%2Fapp.component.html

CKEditor - get attribute of element with Onclick

I'm trying to get the value of the attribute data-time-start when I click on the span.
My FIDDLE : http://jsfiddle.net/zagloo/7hvrxw2c/20/
HTML :
<textarea id="editor1"> <span class="sub" id="sub1" data-time-start="0">Hello </span>
<span class="sub" id="sub2" data-time-start="2">My </span>
<span class="sub" id="sub3" data-time-start="6">Name </span>
<span class="sub" id="sub4" data-time-start="8">Is </span>
<span class="sub" id="sub5" data-time-start="12">Zoob</span>
</textarea>
My JS:
var textarea;
$(document).ready(function () {
textarea = $('#ckeditor_block').find('textarea').attr('id');
ckeditor_init();
});
function ckeditor_init() {
CKEDITOR.replace(textarea, {
language: 'fr',
allowedContent: true
});
}
I tried with this:
CKEDITOR.on('click', function (e) {
var element = $(e.target);
console.log(element);
var cursor = element.data("timeStart");
console.log(cursor);
});
But nothing appened ...
How to do that please ? thank you !!
You can't (or better you shouldn't) use the default jQuery event/element handling in this case, because the CKEditor comes with its very own event/ element system.
Update: Based on the comments below, to avoid CKEditor's quirky behaviour, it is better to use attachListener instead of jQuery's 'on' to bind an event listener
Step one: Bind the click event:
var editorInstance = CKEDITOR.instances['editor1'];
editorInstance.on('contentDom', function() {
editorInstance.editable().attachListener(
this.document,
'click',
function( event ) {
// execute the code here
}
);
});
Step two: Find and access the data attribute:
var editorInstance = CKEDITOR.instances['editor1'];
editorInstance.on('contentDom', function() {
editorInstance.editable().attachListener(
this.document,
'click',
function( event ) {
/* event is an object containing a property data
of type CKEDITOR.dom.event, this object has a
method to receive the DOM target, which finally has
a data method like the jQuery data method */
event.data.getTarget().data('time-start');
}
);
});
For more info check the CKEditor docs.
Updated fiddle is here

Mixedup ajax response on mutliple Form.Request mootools

I have 2 Form.Request in 2 functions that are executed on 2 different buttons clicks
here is fiddle
http://jsfiddle.net/RtxXe/38/
seems like I did not set the events in right order in my functions since they are mixing up the responses. if you hit Clear cache and than Send you still get response from clear cache and vice versa. Unless you reload the page and click again you cant get the right response for each button as it should be .
Since this is not my original form and *I can only change it with js * , i added the clear cache button with new Element. I cant figure out as to why is this happening and any help is appreciated.
this is original html:
<div id="toolbar">
<ul>
<li id="adminsubmit">Send</li>
</ul>
</div>
<div id="response"></div>
<form action="http://www.scoobydoo.com/cgi-bin/scoobysnack" method="post" name="editform" id="myform">
<fieldset>
<!-- form elements go here -->
</fieldset>
<input type="hidden" name="task" value="">
</form>
​ and here is js:
var AdminForm = {
start: function() {
var toolbar = $$('#toolbar ul');
var addbtn2 = new Element('li', {
'id': 'cache',
'class': 'button',
html: 'Clear Cache'
});
addbtn2.inject(toolbar[0], 'top');
var btn1 = $('adminsubmit').getElement('a');
var btn2 = $('cache').getElement('a');
btn1.addEvent('click', function(event) {
event.preventDefault ? event.preventDefault() : event.returnValue = false;
AdminForm.formChange();
});
btn2.addEvent('click', function(event) {
event.preventDefault ? event.preventDefault() : event.returnValue = false;
AdminForm.clearCache();
});
},
formChange: function() {
var adminform = $('myform');
var target = $('response');
var adminsend = new Form.Request(adminform, target, {
onSend: function() {
target.set('html', 'formChange sending');
},
onComplete: function() {
target.set('html', 'formChange sent');
}
});
adminsend.send();
},
clearCache: function() {
var adminform = $('myform');
var target = $('response');
var clearingcahe = new Form.Request(adminform, target, {
onSend: function() {
target.set('html', 'clearCache sending');
},
onComplete: function() {
target.set('html', 'clearCache sent');
}
});
clearingcahe.send();
}
}
window.addEvent('domready', AdminForm.start);​
The Form.Request in Mootools inherits Class.Occlude, see http://mootools.net/docs/more/Class/Class.Occlude
But the Class.Occlude will prevent that several Objects are created and applied to the same DOM Element. That is, it works like a singleton, so the first time you do new Form.Request(adminform, ...) it will return a new instance of Form.Request.
However, the second time you call new Form.Request(adminform, ...) the previous object will be returned instead.
Your fiddle actually demonstrates this very good, because the first one that is clicked of "Clear Cache" or "Send" will be the one that initiates the object. The second time it will discard your options and just return the old object.
So there are two ways to solve this:
Create the Form.Request but don't set the event handlers through the options but through
adminsend.removeEvents('complete'); adminsend.addEvent('complete', ....)
Don't forget to remove the old event handlers before applying the new! otherwise you will just apply more and more eventhandlers.
There are two "buttons" so make two forms, which would be much more semantically correct as well.

Resources