Which is better Onclick or addEventListener in javascript ? why is that? - event-handling

first solution
< button class="btn" onclick="addRow()">Sumbit < /button >
the click event is happen we run the function in the script file
function addRow(e) {
}
second solution
in script file we can create the event through the addEventListner
const btn = document.querySelector('.btn');
function addRow(e) {
}
btn.addEventListener('click', addRow);
which is the best approch why is that ?

Related

Leaflet - How to add click event to button inside marker pop up in ionic app?

I am trying to add a click listener to a button in a leaftlet popup in my ionic app.
Here I am creating the map & displaying markers, also the method I want called when the header tag is clicked is also below:
makeCapitalMarkers(map: L.map): void {
let eventHandlerAssigned = false;
this.http.get(this.capitals).subscribe((res: any) => {
for (const c of res.features) {
const lat = c.geometry.coordinates[0];
const lon = c.geometry.coordinates[1];
let marker = L.marker([lon, lat]).bindPopup(`
<h4 class="link">Click me!</h4>
`);
marker.addTo(map);
}
});
map.on('popupopen', function () {
console.log('Popup Open')
if (!eventHandlerAssigned && document.querySelector('.link')) {
console.log('Inside if')
const link = document.querySelector('.link')
link.addEventListener('click', this.buttonClicked())
eventHandlerAssigned = true
}
})
}
buttonClicked(event) {
console.log('EXECUTED');
}
When I click this header, Popup Open & Inside if are printed in the console, so I know I'm getting inside the If statement, but for some reason the buttonClicked() function isn't being executed.
Can someone please tell me why this is the current behaviour?
I just ran into this issue like 2 hours ago. I'm not familiar with ionic, but hopefully this will help.
Create a variable that keeps track of whether or not the content of your popup has an event handler attached to it already. Then you can add an event listener to the map to listen for a popup to open with map.on('popupopen', function(){}). When that happens, the DOM content in the popup is rendered and available to grab with a querySelector or getElementById. So you can target that, and add an event listener to it. You'll have to also create an event for map.on('popupclose', () => {}), and inside that, remove the event listener from the dom node that you had attached it to.
You'd need to do this for every unique popup you create whose content you want to add an event listener to. But perhaps you can build a function that will do that for you. Here's an example:
const someMarker = L.marker(map.getCenter()).bindPopup(`
<h4 class="norwayLink">To Norway!</h4>
`)
someMarker.addTo(map)
function flyToNorway(){
map.flyTo([
47.57652571374621,
-27.333984375
],3,{animate: true, duration: 5})
someMarker.closePopup()
}
let eventHandlerAssigned = false
map.on('popupopen', function(){
if (!eventHandlerAssigned && document.querySelector('.norwayLink')){
const link = document.querySelector('.norwayLink')
link.addEventListener('click', flyToNorway)
eventHandlerAssigned = true
}
})
map.on('popupclose', function(){
document.querySelector('.norwayLink').removeEventListener('click', flyToNorway)
eventHandlerAssigned = false
})
This is how I targeted the popup content and added a link to it in the demo for my plugin.
So yes you can't do (click) event binding by just adding static HTML. One way to achieve what you want can be by adding listeners after this new dom element is added, see pseudo-code below:
makeCapitalMarkers(map: L.map): void {
marker.bindPopup(this.popUpService.makeCapitalPopup(c));
marker.addTo(map);
addListener();
}
makeCapitalPopup(data: any): string {
return `` +
`<div>Name: John</div>` +
`<div>Address: 5 ....</div>` +
`<br/><button id="myButton" type="button" class="btn btn-primary" >Click me!</button>`
}
addListener() {
document.getElementById('myButton').addEventListener('click', onClickMethod
}
Ideally with Angular, we should not directly be working with DOM, so if this approach above works you can refactor adding event listener via Renderer.
Also I am not familiar with Leaflet library - but for the above approach to work you need to account for any async methods (if any), so that you were calling getElementById only after such DOM element was successfully added to the DOM.

Changing function on a button using detachPress / attachPress

I have a requirement for my app and I need to change the event handler of a common button depending on the status of the workflow.
Basically I need to change the function called when you press the button and vice-versa and was looking to achieve this by using the event handler functions detachPress and attachPress.
https://ui5.sap.com/#/api/sap.m.Button/methods/detachPress
https://ui5.sap.com/#/api/sap.m.Button/methods/attachPress
My Button (XML View):
<Button text="Edit" width="50%" id="_editButtonEmail" press="editPIN"/>
On my controller I want to change the function editPIN by cancelEditPIN.
Some things I've tried:
editPIN: function(oControlEvent) {
//change button
var editButton = this.getView().byId("_editButtonEmail");
//detach this function on press
editButton.detachPress(editButton.mEventRegistry.press[0].fFunction);
editButton.attachPress(this.cancelEditPIN());
}
cancelEditPIN: function() {
//do something else
}
Also
editPIN: function(oControlEvent) {
//change button
var src = oControlEvent.getSource();
src.detachPress(this.editPIN());
src.attachPress(this.cancelEditPIN());
}
None of these seem to work and if I check my console the function editPIN is still attached to my mEventRegistry press event.
There are few things worse than checking your GUI texts to determine what action should be done.
A different approach uses two buttons. Only one is visible at a time
<Button
text="{i18n>editPIN}"
visible="{= ${myModel>/State} === 'show' }"
press="editPIN" />
<Button
text="{i18n>editCancelPIN}"
visible="{= ${myModel>/State} === 'edit' }"
press="cancelEditPIN" />
In this case {myModel>/State} is a local JSON model where the current state of your workflow is stored.
If you really want to use your attach/detach approach: It probably didn't work because you were calling the methods while passing them as a parameter to attach/detach. So for example try src.detachPress(this.editPIN); instead of src.detachPress(this.editPIN());
Following the idea from #Jorg, I created another function checkPIN with an if statement that compares the text in the button and then fires the appropriate function depending on it.
I do have to phrase that I am using my i18n file to provide texts to my view, this way my textID will not change on whatever language the user is using.
My Button:
<Button text="Edit" width="50%" id="_editButtonEmail" press="checkPIN"/>
My Controller:
checkPIN: function(oControlEvent) {
var src = this.getView().byId("_editButtonEmail").getText();
var oBundle = this.getView().getModel("i18n").getResourceBundle();
//call cancelEditPIN
var editCancelPinText = oBundle.getText("editCancelPIN");
//call editPIN
var editPinText = oBundle.getText("editPIN");
//change button
if (src === editPinText) {
this.editPIN(oBundle);
} else if (src === editCancelPinText) {
this.cancelEditPIN(oBundle);
}
},
editPIN: function(oBundle) {
//do stuff here
//change button text
var editButton = this.getView().byId("_editButtonEmail");
editButton.setText(oBundle.getText("editCancelPIN"));
},
cancelEditPIN: function(oBundle) {
//do different stuff here
//change button text
var editButton = this.getView().byId("_editButtonEmail");
editButton.setText(oBundle.getText("editPIN"));
}
Not really the answer I was looking for because I would like to use detachPress and attachPress so if you know what I should have done in order to implement those please let me know.

jquery file upload - how to process entire queue on "basic plus" demo

Given the following demo:
jQuery File Upload Basic Plus demo
I have this working in a project as per the demo, but I'd like to remove the "Upload" button on each image and just add an "Upload All" button at the top. For the life of me I can't work out how to do it and the documentation is pretty thin...
I've tried to create a handle to the fileupload object e.g. var fileUpload = $('#fileupload').fileupload({ and call something like fileUpload.send(); but I just get "object doesn't contain a method 'send'"
The working solution is here: Start Upload all in jquery file upload blueimp
The key is unbinding the click event in the "done" option and not in the "add" option as other articles here suggest.
done: function (e, data) {
$("#uploadBtn").off('click')
$.each(data.result, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
});
},
add: function (e, data) {
$("#uploadBtn").on('click',function () {
data.submit();
});
}
Another option is to give the individual upload buttons a class, hide them from view by setting their css display to none and then binding their click to the upload_all click:
//Put this button code next to your button (or span mimicking button) that adds files to the queue.
<button id="upload_all" type="submit" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
//Give your buttons a class and set their display to none.
var uploadButton = $('<button/>', {
class:"upload",
style:"display:none"
})
.on('click', function () {
var $this = $(this),
data = $this.data();
data.submit().always(function () {
$this.remove();
});
});
//Bind their click to the click of your upload_all button.
$('#upload_all').on('click', function() {
$('.upload').click();
});
You can push all the data into an array and have your external button call a function that loops through the array and call .submit() on each.
var fileDataArray = [];
// Inside "add" event
fileDataArray.push(data);
// Inside your onClick function for your button
for (var i = 0; i < fileDataArray.length; i++) {
var data = fileDataArray[i];
data.submit();
}

Chrome extension - open multiple tabs after filling in the form

I am trying to create a chrome extension - when an user clicks on a icon, the popup window with the form appears. The textarea in the form can contain more parameters which comes to URL. After filling in and clicking the GO button, multiple tabs with URLs with this parameters needs to be opened.
Example: popup.html
<form name="myform">`
<textarea id="params" name="params" style="width: 170px;height: 270px;"></textarea>`
<input id="edit" checked="checked" type="radio" name="edit" value="1" /> option 1 <input id="edit" type="radio" name="edit" value="2" /> option 2`
<div id="clicked">GO</div>`
</form>`
Then in popup.js I have:
function click(e) {
chrome.tabs.executeScript(null, {
code: "alert('starting');"
});
opener();
}
document.addEventListener('DOMContentLoaded', function () {
var divs = document.getElementById("red");
divs.addEventListener('click', click);
});
So when an user clicks on GO button, the opener() function needs to be started.
Here is the opener function - it only determines the values of textarea and radio buttons and opens as many new tabs as manz parameters are in the textarea.
function opener() {
alert('working');
var parameter = document.myform.getElementById("params").value;
for (index = 0; index < document.myform.edit.length; index++) {
if (document.myform.edit[index].checked) {
var radioValue = document.myform.edit[index].value;
break;
}
var Result = parameter.split("\n");
if (radioValue == 1) {
for (i = 0; i < Result.length; i++) {
window.open('http://mypage.com?param=' + Result[i]);
}
}
}
}
So the Result is the value of textarea splitted by \n and radio value is the value of radio button selected.
This works fine - after clicking a browser icon the popup with form comes up, but when I fill in the textarea and select the first radiobutton, then I click GO, the opener funvtion works not...
The only thing that works is the popup alert with working word and then the alert starting from the click(e) function.
So the opener function starts, writes the alert, but nothing else... no tabs will open, nothing happens...
Can someone help me please?
I've found that using the chrome.tabs.create function works much better within the extension than the window.open function does.
chrome.tabs.create({url:"https://www.facebook.com/PSChrome"});

Ajax Auto Suggest v.2 suggestion depends on radio button?

I am using auto suggest v.2.1.3 from brandspankingnew.
I have a form with two radio button and a text field and would like to know how to make the auto suggest script pointing to a different php file if one of the radio button is checked.
I tried this but it doesnt work, its always point to the same php file even if second button is checked
Could you please assist?
Many thanks in advance.
My code is as follows:
function targetvalue()
{
for (i=0;i
/>Business Street
var options = {
script:"autosuggest.php?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:10,
callback: function (obj) { document.getElementById('name').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('business', options);
var options_xml = {
script: function (input) { return "autosuggest.php?input="+input+"&testid="+document.getElementById('testid').value; },
varname:"input"
};
var as_xml = new bsn.AutoSuggest('business', options_xml);
As for me, the easiest solution is to pass the the button state to the one script eg only one script but can return different results depending on button state. Otherwise you need to rewrite options each time someone clicks on the radio button. The second solution an lead to unpredictable behavior of auto suggest component.
Sample script:
var selectedValue = getRadioSelectedValue("radioGroupName");
var options_xml = { script: function (input) { return "autosuggest.php?input="+input+"&testid="+document.getElementById('testid').value+"&mode="+selectedValue; },
Write getRadioSelectedValue by yourself to get selected radio button value or set some flag on click. Mode param in GET request will indicates the state of the button, so you can return proper response.