Why is my method called twice in Framework7 on click? - javascript

I'm using Framework7 and I'm trying to just make a fairly simple button click setup that triggers an alert window. The setup is as follows:
<div class="col-100">
<div class="list no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Custom Message</div>
<div class="item-input-wrap">
<input id="custom-message-input" type="text" placeholder="Your message here..." />
<span id="custom-message-clear" class="input-clear-button"></span>
</div>
</div>
</li>
</ul>
<a id="custom-message-button" class="button button-raised button-fill">Send Custom Message</a>
</div>
</div>
And the click event is initialized like so:
app.on('pageInit', function (page) {
$('#custom-message-button').on('click', () => {
$('#custom-message-clear').click();
app.dialog.alert('Message was successfully sent.', 'Information');
});
...
But for some reason, when I click the button, it triggers twice. The alert appears once, I click it away, then it appears again, and I click it away. Then it stays gone.
What might I be missing here?

If anyone should stumble upon this in the future; It's because "pageInit" is called for every page that is found in the router. Use the "name" property to figure out what page is currently being initialised.

Related

<autofocus> unable to get focus repeatedly until the page is refreshed

I am designing a footnote at the bottom of an article to annotate following up status;
<article class="col-md-12">
</article>
<div class="col-md-12 footnote">
add a footnote
</div>
When the "add a footnote" link is hidden after being clicked and prompt the "footnote form" which I set autofocus which textarea. The "autofucus" works properly.
$('.footnote-link a').on('click', function (e) {
e.preventDefault();
...
var $footnoteForm = $(`
<form class="article-footnote-form footnote-form" style="margin-top:10px" >
<div class="form-group row">
<div class="col-md-9">
<textarea class="form-control" name="footnote" rows="3" autofocus></textarea>
</div>
<div class="col-md-3">
<button class="btn btn-primary" type="submit" id="articleFootnoteBtn">Add Annotation</button>
</div>
</div>
</form>`);
$articleFootnoteLink.parent().hide();
$articleFootnoteLink.parent().after($footnoteForm);
The form is submitted to server using Ajax then I cleared the forms by
$footnotesTop.find(".footnote-form").html(""). Now the page displays the article and the newly added footnote.
However, if I click the "add footnote" again, it unable to get focus automatically as it does at first time until I refresh the page to click.
How could I get the form focus during the second click event.
You need to use a delegated eventHandler. The js code $('.footnote-link a').on('click', function (e) { is only applied to the elements jQuery finds using that selector when the page is loaded.
Try $( document ).on('click', '.footnote-link a', function (e) {. You can use a tighter selector rather than document - it seems like .footnote would work based on what I see.
jQuery delegated events tutorial

How do I change a variable in a child element that has ng-click in the parent element.

Consider this code:
<section class="page-section about-us" scroll-bookmark="about-us" ng-click="activeSection=true" ng-init="activeSection=false">
<div class="page-content sub-content active-section">{{activeSection}}
<div class="page-border">
<a href="#" class="close-section"><img src="public/images/go-back-icon.png" />
<div class="back-button" ng-click="activeSection=false">CLOSE</div>
</a>
</div>
</div>
</section>
I have an ng-click in the that element which changes the value of 'activeSection' to true. Inside of it, I have another button that can switch this back to it's initial value (false).
In the actual app, it would show or hide this child button based on a class added to the element,just to give you a little background what I'm trying to achieve.
When I click on the element, it does as I expect it to be: switch the value to 'true'. But when I click on the .back-button element with the other ng-click, it fails to register the changed value.
Why is that?
They're both inside the same controller, btw. If there's a solution that doesn't involve creating a new controller, it would be better.
If you click on your back button, activeSection will be false but then your event will be propagated to its parent so the ng-click of Section will be executed too and activeSection will be true again.
In order to make your code work, you should stop the propagation of the ng-click event after changing the value of your variable in your back-button.
Your code would look like this:
<section class="page-section about-us" scroll-bookmark="about-us" ng-click="activeSection=true" ng-init="activeSection=false">
<div class="page-content sub-content active-section">{{activeSection}}
<div class="page-border">
<a href="#" class="close-section"><img src="public/images/go-back-icon.png" />
<div class="back-button" ng-click="activeSection=false; $event.stopPropagation();">CLOSE</div>
</a>
</div>
</div>
</section>
What you are doing wrong is that you are putting the close button inside the element which have already ng-click, that's why when you are clicking the close button, it executes the parent ng-click and stop propagation for all other click events happening simultaneously.
So, the possible solution is making another super parent of the elements and taking the close button out of the element which is making it visible when clicked and adding a ng-show directive to the close button.
Checkout the following snippet
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<section class="page-section about-us" scroll-bookmark="about-us" ng-init="activeSection=false">
<div ng-click="activeSection=true" class="page-content sub-content active-section">{{activeSection}}
<div class="page-border">
<a href="#" class="close-section"><img src="public/images/go-back-icon.png" />
</a>
</div>
</div>
<div ng-show="activeSection" class="back-button" ng-click="activeSection=false">CLOSE</div>
</section>
</div>

append a div with class "modal-trigger" using jquery.append() not working

i have a modal named "modalcreatelist" using materializecss. the modal will triggered when some div is clicked using an a href tag.
<div id="modalcreatelist" class="modal">
<div class="modal-content">
<div class="col s12 m6 l12">
<div class="row">
<h6><b>Create a list..</b></h6>
<div class="divider"></div> <p>Title</p>
<input type="text" placeholder="Title.." id="listTitle">
<input type="hidden" id="hiddenListId" value="<?php foreach($board as $r) {echo $r->boardId;}?>">
</div>
</div>
</div>
<div class="modal-footer"> <a class="waves-effect waves-red btn-flat modal-action modal-close">Close</a> <a class="waves-effect waves-red btn-flat modal-action modal-close" onclick="createList()">Save</a>
</div>
</div>
so i use this html code to trigger the modal, this works perfectly fine
<div id="invoice-line" class="left-align white-text">
<a href="#modalcreatelist" class="modal-trigger white-text">Add a List..
</a>
</div>
however when i move the code to my javascript file, i try to append the div using jquery .append()
and it is not working
the class "modal-trigger" is not loaded at all
the url is showing like 'localhost/project#modalcreatelist'
$("#divCreateList").append'(<div id="invoice-line" class="left-align white-text">Add a List..</div>')
You need to rebind modal-trigger after adding it to DOM. It works the first time cause the bind is done based on class name on document.ready. You need to add an event listener for click on modal-trigger and add the logic that opens your modal.
That means, after adding the content through JavaScript. You have to write something like.
$('.modal-trigger').on('click', function() { open modal; })
replace 'open modal' with your logic.

Loading Placeholder tag in FORM when variables are set

I have a simple user settings form written in HTML5 which commits user defined settings to local storage.
I want it so that if someone access the settings page again, and the user settings are defined the placeholders and/or values prefill the form with those settings.
I have tried using window.load, document.ready at the end and the beginning, but I can only get the form to load thre values if I click reload. I need these value to prefil if the page is visited.
Here is my version of the form which loads the values if you RELOAD the page
Script first
function loadUserSettings() {
$("#full_name").attr("placeholder", db_user.full_name);
$("#mobile_number").attr("placeholder", db_user.mobile_number);
$("#email_address").attr("placeholder", db_user.email_address);
$("#full_name").attr("value", db_user.full_name);
$("#mobile_number").attr("value", db_user.mobile_number);
$("#email_address").attr("value", db_user.email_address);
}
and now the form
<body>
<div data-role="page" data-control-title="Settings" data-theme="b" id="settings" class="global_page">
<div data-theme="b" data-role="header" data-position="fixed" class="global_topbar">
<a data-role="button" data-transition="flip" href="index.html" data-icon="back" data-iconpos="left" class="ui-btn-left global_button">
Back
</a>
<a data-role="button" data-transition="flip" href="help_settings.html" data-icon="info" data-iconpos="left" class="ui-btn-right global_button">
Help
</a>
<h3 class="global_header">
Settings
</h3>
</div>
<div data-role="content" style="padding: 1%">
<form id="postSettings" action="" class="global_form">
<div data-role="fieldcontain" data-controltype="textinput" class="full_name">
<label for="full_name">
Name
</label>
<input name="full_name" id="full_name" type="text" data-mini="true"/>
</div>
<div data-role="fieldcontain" data-controltype="textinput" class="email_address">
<label for="email_address">
Email Address
</label>
<input name="email_address" id="email_address" type="email" data-mini="true"/>
</div>
<div data-role="fieldcontain" data-controltype="textinput" class="global_text_input">
<label for="mobile_number">
Mobile Number
</label>
<input name="mobile_number" id="mobile_number" type="tel" data-mini="true"/>
</div>
<input id="store_posting" type="submit" data-icon="plus" data-iconpos="left" value="Store Information" class="global_button" onclick="dbGoUser()"/>
</form>
</div>
</div>
</body>
<script language="JavaScript">
document.ready = loadUserSettings();
</script>
I have managed a workaround using a function that I attach to my settings buttons which basically
function loadSettingsPage() {
window.location.href = "settings.html";
}
and this works everytime prefilling the placeholders / values no problem, however I am using a datatransition link of 'FLIP' which is lost using the above function.
SO ideally I want to either fix injection of the placeholders when I click a normal link (which I suspect is just a page refresh type option that does not loop) or make my loadSettingsPage use the JQuery flip transition.
Thanks in advance for any assistance.
OK, I was able to get around the issue with some custom functions. I had to lose the flip effect, and move to a simple fade but I ended up using
function fadeIn() {
$("body").hide();
$("body").fadeIn(500);
}
function loadPageSettings(urlvar) {
$("body").fadeOut(500, function(){ window.location.href = urlvar; });
}
for the custom functions
All hyperlinks used something like this
<a id="home_new_journey" data-role="button" onclick="loadPageSettings('journey_info.html')" data-icon="plus" data-iconpos="left" class="global_button">New Journey</a>
and at the footer of every page I just had
<script language="javascript">
window.onload = fadeIn();
</script>
So now I have pages loading properly with all dynamic content an a consistent fading effect.

jQuery click function exclude children except for one

I have this piece of HTML:
<div class="pop-up rooster-toevoegen">
<div class="pop-up-container">
<div class="pop-up-header clearfix">
<div class="pop-up-title">
Rooster toevoegen
</div>
<div class="sprite close"></div>
</div>
<div class="pop-up-content clearfix">
<form id="rooster-toevoegen-form" class="form rooster-toevoegen-form">
<div class="afdeling-container">
</div>
<div class="date-container">
</div>
<div class="button-container clearfix">
<button value="" name="rooster-toevoegen-button" class="rooster-toevoegen-button button-green">Toevoegen</button>
</div>
</form>
</div>
</div>
</div>
Now I want a click function on .rooster-toevoegen and exclude all children from this click function EXCEPT the button. Also the button has already a function(submitting the form), this must stay the buttons event handler.
CONTEXT:
This is a pop-up with a form inside. When the user clicks next to the pop-up the pop-up has to close. Not when clicking on the pop-up which happens when I don't exclude the children from the click event. BUT when the user clicks on the button the form has to submit. So the button should not be excluded from the click and perform his own action.
How do I do this?
You can prevent from bubbling to all elements using e.preventDefault(), and manually trigger click on button.
Better way is to bind one more click event only to button.

Categories