How to stop PNotify button click fire parent click handler
Permalink
I have an image map with a click event which places a marker on it:
then clicking the pin opens a PNotify popup with a text input and a save button, clicking on which appends the entered text to the wrapper:
I can't figure out what causes adding (doubling) new pins to the map on Save button click. I alerted 'e.target.id' and 'e.currentTarget.id' - these pop up after clicking on the map, but nothing happens (no alert) after clicking the Save button on the notice form but the pins actually append to the map...
How do I stop the Save click adding new pins to the map?
<div id="map_wrapper"> <div id="map"> <img src="map.png" /> </div> </div> ... $('#map').on('click', function(e){ alert(e.target.id); // this is the image inside 'map' alert(e.currentTarget.id); // this is the 'map' var pin = $('<div class="pin"></div>'); $('#map_wrapper').append(pin);
then clicking the pin opens a PNotify popup with a text input and a save button, clicking on which appends the entered text to the wrapper:
$('#map_wrapper').on('click', '.pin', function(e){ var id = this.id; show_notice(id); }); function show_notice(id){ notice = new PNotify({ text: form, ... }); $('form [name=save]').off('click').on('click', function(e){ e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); $('#' + id).append('<p class="pin-text hidden">' + $.trim($('#pin_text').val()) + '</p>'); notice.remove();
Viewing 15 lines of 16 lines. View entire code block.
I can't figure out what causes adding (doubling) new pins to the map on Save button click. I alerted 'e.target.id' and 'e.currentTarget.id' - these pop up after clicking on the map, but nothing happens (no alert) after clicking the Save button on the notice form but the pins actually append to the map...
How do I stop the Save click adding new pins to the map?
I'm not sure it's going to help but you could try this. Instead of appending your pin on the form's save button's click event, try doing it on the form submit event directly
Not quite what happens. A pin is appended on clicking the map. The notice is popped up on clicking the pin. The text from the notice form is appended as <p> on clicking the Save button.
If I use a submit button, where will the form submit to?
I forgot to mention, it only appends the pins if the text input field has text, if it's empty, it appends an empty <p>, but it does NOT append the pins. This is so weird! Why would it do that? I could understand if it appended pins on clicking Save regardless, but why only with text? I have no clue what may cause that.
If I use a submit button, where will the form submit to?
I forgot to mention, it only appends the pins if the text input field has text, if it's empty, it appends an empty <p>, but it does NOT append the pins. This is so weird! Why would it do that? I could understand if it appended pins on clicking Save regardless, but why only with text? I have no clue what may cause that.
in the code above I see where the text paragraph is added but I don't see where the pin is added so I can't say.
If you are not going to use a submit button then you don't really need a form. Input boxes can live outside of a form.
If, on the other hand, you want to use the form submit event then you need a form (duh!) but you don't need to submit to anything since you are going to catch the event and use it for your purpose.
If you are not going to use a submit button then you don't really need a form. Input boxes can live outside of a form.
If, on the other hand, you want to use the form submit event then you need a form (duh!) but you don't need to submit to anything since you are going to catch the event and use it for your purpose.
$(yourform).on('submit', function(evt) { evt.preventDefault(); // do your stuff });
This is where the pin is added:
I've already tried the submit event, but the pins are still added! Looks like the click event is caught by the map anyway. Weird!
Is there any way to allow appending pins ONLY if the map is clicked, nothing else?
$('#map').on('click', function(e){ alert(e.target.id); // this is the image inside 'map' alert(e.currentTarget.id); // this is the 'map' var pin = $('<div class="pin"></div>'); $('#map_wrapper').append(pin);
I've already tried the submit event, but the pins are still added! Looks like the click event is caught by the map anyway. Weird!
Is there any way to allow appending pins ONLY if the map is clicked, nothing else?
I just noticed something wrong with your code in your show_notice function you have
but e is not defined in that function so you should put those 3 lines in the click function instead
e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation();
but e is not defined in that function so you should put those 3 lines in the click function instead
Sorry, that's a typo, they're actually inside the click function, I've corrected the original post.
After further investigation, what happens is:
- pin coordinates are stored in the DB
- Add block form loads, then the map image loads, then the pins and are placed at the coordinates
- I move the pins (just for example), click on one, a notice pops up, I enter text in the form input and click the Save button
- The notice closes AND 2 new pins appear at the exact same locations as those loaded from the DB
- The new pins are added ONLY if text is entered. If the text input is empty, no pins are added
There is NO code to do that. The only 2 places where the pins are appended to the map are the map image load function and the map click function - that's it!
How can the PNotify button add the pins?
- pin coordinates are stored in the DB
- Add block form loads, then the map image loads, then the pins and are placed at the coordinates
- I move the pins (just for example), click on one, a notice pops up, I enter text in the form input and click the Save button
- The notice closes AND 2 new pins appear at the exact same locations as those loaded from the DB
- The new pins are added ONLY if text is entered. If the text input is empty, no pins are added
There is NO code to do that. The only 2 places where the pins are appended to the map are the map image load function and the map click function - that's it!
How can the PNotify button add the pins?
At this point, I have no idea. Could you share your whole block so I can test myself?
in this part
where do you get the id from since this represent the pin and the pin doesn't have an id?
$('#map_wrapper').on('click', '.pin', function(e){ var id = this.id; show_notice(id); });
where do you get the id from since this represent the pin and the pin doesn't have an id?
The id = this.id which returns the pin div id. The pin does have an id, I set it with
pin.uniqueId();
ah ok. You didn't show that bit in your original post I think.
Anyway, I just got your PM I'll have a look.
Anyway, I just got your PM I'll have a look.
in your form.php, around line 241 you have
That's not the right way to do it and as a result, any time you change anything in your whole document, that code is triggered, breaking havoc.
To test, put a breakpoint on the line right after in your browser's developer tool then open your pNotify window, enter your text then click somewhere else and that code will be triggered.
The reason we use that kind of code is when we want to hook on an event for a DOM element that doesn't exist yet. For instance, when you do it like that for your pins it makes sense because you are going to add them dynamically.
But your pictureID element is not added dinamically so just use the event stuff normally with the code below which for me solved the problem.
There are other things that seem wrong in your code. For instance, why, when you are adding to the picture your pins saved in the DB do you give them a new unique ID? you saved their original ID, why don't you re-use it?
$(document).bind('change', 'input[name="pictureID"]', function() {
That's not the right way to do it and as a result, any time you change anything in your whole document, that code is triggered, breaking havoc.
To test, put a breakpoint on the line right after in your browser's developer tool then open your pNotify window, enter your text then click somewhere else and that code will be triggered.
The reason we use that kind of code is when we want to hook on an event for a DOM element that doesn't exist yet. For instance, when you do it like that for your pins it makes sense because you are going to add them dynamically.
But your pictureID element is not added dinamically so just use the event stuff normally with the code below which for me solved the problem.
$('input[name="pictureID"]').bind('change', function() {
There are other things that seem wrong in your code. For instance, why, when you are adding to the picture your pins saved in the DB do you give them a new unique ID? you saved their original ID, why don't you re-use it?
That code didn't work for me. When I select an image from the file manager it's not loaded.
I only use the pin id while in edit mode, I don't need exact values. I only store the id for testing.
I only use the pin id while in edit mode, I don't need exact values. I only store the id for testing.
Sorry I didn't test what happens when you select the image with the manager. I followed your steps to reproduce the error so during my testing the image was already selected and I know that piece of code is responsible for the problems you're having.
Also, I believe the manager will throw an event when an image is selected and you should use that instead. Just look through the core code to see how they do it.
Also, I believe the manager will throw an event when an image is selected and you should use that instead. Just look through the core code to see how they do it.
I couldn't find any documentation on the ConcreteFileManager. Do you have a link?
https://documentation.concrete5.org/api/class-Concrete.Core.Applicat...
Uh Oh!
We couldn't find the page you were looking for.
https://documentation.concrete5.org/api/class-Concrete.Core.Applicat...
Uh Oh!
We couldn't find the page you were looking for.
Like I said look through the code. Specifically have a look a form_setup_html.php in the image_slider block, around line 39. You will see how they launch the file manager and how they use ConcreteFileManager.getFileDetails as a callback
I basically do the same thing. But the image slider form only loads thumbnails, I need to load the actual image.
I don't know why you're saying that. The point is not what you are getting, the point is how you are getting it.
The way you do it doesn't work. It creates problems, it even creates extra pins on the image if you take certain actions.
The way the slider does it ensures the code is only called when needed and it works.
What's important here is how it is called. After that feel totally free to modify what's inside to your liking.
Having said so I don't see a difference. You get your image exactly the same way it's done with the slider except you use file.url instead of file.resultsThumbnailImg. All you need to change is that nasty on change event that's being called for too often and breaks everything
The way you do it doesn't work. It creates problems, it even creates extra pins on the image if you take certain actions.
The way the slider does it ensures the code is only called when needed and it works.
What's important here is how it is called. After that feel totally free to modify what's inside to your liking.
Having said so I don't see a difference. You get your image exactly the same way it's done with the slider except you use file.url instead of file.resultsThumbnailImg. All you need to change is that nasty on change event that's being called for too often and breaks everything
I've simply replaced the lot for
and it says "ReferenceError: ConcreteFileManager is not defined"
echo '<div class="ccm-pick-slide-image ccm-pick-slide-image-' . $bID . '"></div>'; ... var attachFileManagerLaunch = function($obj) { $obj.click(function() { var oldLauncher = $(this); ConcreteFileManager.launchDialog(function(data) { ConcreteFileManager.getFileDetails(data.fID, function(r) { jQuery.fn.dialog.hideLoader(); var file = r.files[0]; oldLauncher.html(file.resultsThumbnailImg); oldLauncher.next('.image-fID').val(file.fID); }); }); }); };
Viewing 15 lines of 16 lines. View entire code block.
and it says "ReferenceError: ConcreteFileManager is not defined"
But that code above works if I put this on the form:
So looks like it's only working with the file picker on the form. I can't find how they get away without it in the slide block.
echo $al->image('picture', 'pictureID', t('Select picture') . ' <i class="fa fa-picture-o"></i>', $pic);
So looks like it's only working with the file picker on the form. I can't find how they get away without it in the slide block.
$this->requireAsset('core/file-manager');
You're the man!!! Thanks a lot! That worked )))
Would you know how to make the file manger to open the menu rather than going straight to pick a file? I need to process the clear picture event somehow.
Would you know how to make the file manger to open the menu rather than going straight to pick a file? I need to process the clear picture event somehow.
all I know is, using the image picker, when an image is selected, if you click on the picker you will see the menu instead of opening the manager. If that's not what's happening then something else is wrong.
No, clicking the picker goes straight to the file manager, no menu pops up. And this is exactly the same behavior in the Image Slider block.
Would anyone know how to show the same menu when clicking on the link as in the Image block picker (see attached image)?
Would anyone know how to show the same menu when clicking on the link as in the Image block picker (see attached image)?
the image block uses the normal core image selector
That will do what you want BUT then you don't control the JavaScript and your custom stuff might not work.
I suggest you go have a look at what's happening in the image() function in helper/concrete/asset_library and go from there
$al = $app->make('helper/concrete/asset_library'); echo $al->image('ccm-b-image', 'fID', t('Choose Image'), $bf);
That will do what you want BUT then you don't control the JavaScript and your custom stuff might not work.
I suggest you go have a look at what's happening in the image() function in helper/concrete/asset_library and go from there