Meteor view doesn't get updated on IE - javascript

In my application which is using MeteorJS I have a situation when I have to subscribe to "multiple aspects" of a single collection.
I have a collection called Invitations, and on the main page, I subscribe to a publication which publishes those Invitations, where the InvitedUser is the current user.
Then on a modal dialog, I want to manage those Invitations which are sent by the current user. I don't want to subscribe to the changes of the sent Invitations only on this dialog.
So I decided to manually subscribe to a publication when the dialog is shown to the user and stop this subscription when the modal gets closed.
The code behind for the modal dialog looks something like this:
var subscriptionHandle;
Template.invitationsModal.helpers({
invitations: function() {
var activeGroupId = Session.get('activeGroupId');
var filter = activeGroupId ? {invitedBy: Meteor.user()._id, group: activeGroupId} : {};
return Invitations.find(filter);
}
});
Template.invitationsModal.rendered = function() {
$('#invitationsModal').off('shown.bs.modal').on('shown.bs.modal', function(e) {
var activeGroupId = Session.get('activeGroupId');
subscriptionHandle = Meteor.subscribe('sentInvitations', activeGroupId);
});
$('#invitationsModal').off('hidden.bs.modal').on('hidden.bs.modal', function(e) {
subscriptionHandle.stop();
});
};
(I left out the unimportant parts.)
In the template I just iterate through the invitations helper:
<template name="invitationsModal">
<div id="invitationsModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<form role="form" class="form-horizontal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Invitations</h4>
</div>
<div class="modal-body container-fluid">
{{#each invitations}}
{{> invitationRow}}
{{/each}}
<div class="form-group">
<div class="col-xs-offset-2 col-xs-6">
<input type="text" class="form-control" name="name" placeholder="Name or email">
</div>
<div class="col-xs-2">
<input type="submit" class="btn btn-default button-add" value="Invite" />
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
</template>
This template then included in my main page:
{{> invitationsModal}}
When I first load the page, the Session variable activeGroupId is empty, so wrong data is loaded into the hidden modal.
When I show the modal to the user, I set the activeGroupId to some value, so:
the invitations helper is executed again because of this change, and now we return the valid list of invitations for the active group.
the DOM is updated inside the modal to reflect the change in the 1.)
Now here comes the interesting part: the whole solution works fine on Chrome and Firefox but not always on IE.
On IE there is one case when the 1.) step runs correctly, but the 2.) is simply not executed.
This is the case when I open the modal for the first time. This time the DOM contains the wrong, unfiltered collection.
When I close and open the modal for the second time (without refreshing the page in the browser), it works fine again.
I don't have any idea what could cause this behavior. Could it be a bug in Meteor, or so?
(Tested in IE11)

A call to Deps.flush() magically solved the issue - this is the event handler which shows the dialog to the user:
'click .menu-command-invitations': function(e) {
Session.set('activeGroupId', this._id);
Deps.flush(); // without this, it won't work in IE
$('#invitationsModal').modal('show');
e.preventDefault();
}
From Meteor docs:
Deps.flush forces all of the pending reactive updates to complete.
For example, if an event handler changes a Session variable that will
cause part of the user interface to rerender, the handler can call
flush to perform the rerender immediately and then access the
resulting DOM.
Although I don't really know why I need to call this and why it didn't work only under IE.
I'm reading and writing session variables inside other event handlers in the same application and those work perfectly in IE.

Related

jquery modal() not working when called from inside a function

I have a table where i put a button on the final column of some rows. This button is supposed to open a bootstrap modal using jquery through the onclick attribute. It calls a js function which has the jquery method that shows the modal, but is not working.
When I put an alert on the function and comment the jquery method it works. Also, when I call the method to open it outside of any function, it works when I load the page, as it should. So for some reason it only doesn't work when I try to call it from inside a function.
I need to call it from inside the function because I need to pass some values from the specific table row.
Button:
<button type="button" class="btn btn-success btn-sm" onclick="iniciar_produccion();">Iniciar Producción</button>
Jquery:
// This works
$("#modalIniciarProduccion").modal();
function iniciar_produccion() {
// This doesn't work
$("#modalIniciarProduccion").modal();
// alert('working');
}
Modal:
<div id="modalIniciarProduccion" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Finalizar Proyecto</h4>
</div>
<div class="modal-body">
<form action="marcar_proyecto_como_finalizado.php" id="finalizar" method="post" target="_self">
<div class="input-group">
<label> Fecha en que se entregó </label>
<input type="date" id="fechaEntrega" name="fechaEntrega" class="form-control" required>
<br><br>
</div>
</form>
</div>
<div class="modal-footer">
<input type="submit" form="finalizar" class="btn btn-default pull-right" name="action" value="Subir">
</div>
</div>
</div>
</div>
Your help is much appreciated
You put the wrong function name in the HTML.
Your function is called modalIniciar_produccion but you wrote onclick="iniciar_produccion();"
To be safe please copy&paste your function name from JS code into the HTML (note hat JS is also case dependent).
Upon further research I tracked the error the console gave me and found the solution to my problem in other post:
Bootstrap modal: is not a function
So this is a duplicate. Please mark it as such.
Anyway, the problem was conflict of the jQuery version being loaded twice. The solution is the following:
function iniciar_produccion() {
jQuery.noConflict(); // I added this
$("#modalIniciarProduccion").modal(); // This was not working
}
I just added the line jQuery.noConflict(); before the jquery method. Hope this helps someone in the future.

alpine.js - populating form data with button

I am trying to use alpine.js to update a form's action, and am running into some confusion.
My code:
<div x-data="data=''">
<template x-if="data.url">
<div>
<form method=POST :action="data.url">
<input type="text" x-model="data.sitenumber">
<button type="submit">Submit form</button>
</form>
</div>
</template>
<input type="button" value="add data" #click="data = {url: 'www.com', sitenumber: 23}">
</div>
When I click on the button, the div form doesn't appear. My ultimate goal is to have a modal popup that is dynamically updated with an action button (delete record, etc.) when a link/button elsewhere in the document is clicked.
I tried following long with this ToDo app tutorial, but this creates a separate function, and I thought it would be possible to pass simple data variables to a different part of the div, especially since I'm not looping through an array.
Thanks!
I think the issue is that you do x-data="data=''" instead of using object initialisation syntax: x-data="{ data: '' }"

Dynamically create buttons or send data to buttons

I am dynamically trying to pass data that I get from my for loop to the buttons. I am using django to get the data in the for loop, html to make the button and jquery to pass the data. I am not sure if this is the best description though.
My code is:
{% for dogs in Dogs.Other %}
<form id="primaryDogForm" action="{% url 'personal:account:email_dog_confirm' %}" method="post">
{% csrf_token %}
<input type="hidden" id="dogId" name="dogId" value="{{ dogs }}">
<input type="button" value="Make this your primary dog" id="makePrimaryButton" class="btn btn-primary" data-toggle="modal" data-target="#makePrimary" />
</form>
{% endfor %}
Basically, people can add a list of dogs to their account and select a dog to be their primary dog. I want a modal to be called when I click on the button. And that modal should display the name of the dog that is potentially being made the primary dog.
The modal code is as follows:
<div class="modal fade" id="makePrimary" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Make Primary</h4>
</div>
<div class="modal-body">
<p>
You are about to make <span id="newDog" name="newDog"></span> your primary dog.
</p>
<hr>
Submit
</div>
</div>
</div>
</div>
The jquery for to make everything work is:
$('#makePrimaryButton').click(function() {
($('#newDog').text($('#dogId').val()));
});
$('#makePrimarySubmit').click(function(){
$('#primaryDogForm').submit();
});
The problem I am facing is that, suppose I have a list of three dogs, each with a "Make this your primary dog" button, then the button works for only the first dog. The rest of buttons dont work until the first button gets clicked.
Once the first button is clicked, all the other buttons also get the value of the first dog. Hence, the dog 2 and dog 3 in the list cant be made primary dogs.
I am pretty sure the problem is with my html and jquery. Is there a way for me to make button dynamic so that the button gets the value of the dog it is associated with? That way, any dog can be made primary dog.
Thank you so much.
The problem here is with the ID's you're placing on the initial HTML in the for loop. ID's are unique in HTML - you should only have one of them with that ID name on a page. This is also why the jquery selector only picks up the first button properly.
Instead, one way to fix this is to use classes instead of ID's, like so:
{% for dogs in Dogs.Other %}
<form class="primaryDogForm" action="{% url 'personal:account:email_dog_confirm' %}" method="post">
{% csrf_token %}
<input type="hidden" class="dogId" name="dogId" value="{{ dogs }}">
<input type="button" value="Make this your primary dog" class="btn btn-primary makePrimaryButton" data-toggle="modal" data-target="#makePrimary" />
</form>
{% endfor %}
Then you'll need to update your jquery code to reflect this change:
var lastEditedForm = null;
$('.makePrimaryButton').click(function() {
lastEditedForm = $(this).closest('form');
var dogId = lastEditedForm.find('.dogId').val();
$('#newDog').text(dogId);
});
$('#makePrimarySubmit').click(function(){
lastEditedForm.submit();
});
Note that because you've got a click event for the modal defined outside of which dog button you've clicked - which dog button got clicked last needs to be tracked for when the modal is confirmed.
Using a variable outside the two click handlers is just one way to deal with this, and potentially not the best way. Another approach is to define a temporary event handler after the initial dog button is clicked - but that also requires ensuring that the event gets cleaned up properly in the event the modal gets cancelled.
-- Edit explaining temporary event handler --
In order to have a temporary event handler created on each of your dog button clicks, you also need to ensure that the temporary handler gets removed (no matter what) each time. In this case, because you're using a bootstrap modal, we can use the close event on the modal to definitively clear out the event handler.
The javascript looks like this:
$('.makePrimaryButton').click(function() {
// note we're still placing the form in a variable here
// so we have easy reference to it in the temporary event
// handler below
var currentForm = $(this).closest('form');
var dogId = currentForm.find('.dogId').val();
$('#newDog').text(dogId);
$('#makePrimaryButton').one('click', function(){
currentForm.submit();
})
});
// hidden.bs.modal is for Bootstrap v3 or v4. If you're using
// Bootstrap v2 it's just 'hidden.'
$('#makePrimary').on('hidden.bs.modal', function(){
// clears absolutely all event handlers on the button,
// not just the ones we set. We would need a reference to
// the function we set earlier in order to take just
// that function off.
$('#makePrimaryButton').off();
})
You should add a data attribute to the button. The link below gives a good example of it's implementation:
Passing data to a bootstrap modal

Data insertion into database after clicking onto button

I would like to insert some data into my database using laravel eloquent after pressing a button.
My controller, controller method, route, js files are ready.
I just don't know how to connect these together.
Should i fire an event after clicking the button, if yes how can i do that using blade ?
I have a main page and form like this.
This is my main page :
{{ Form::open(array('action'=>'Mycontroller#myMethod')) }}
<!--Some html here !-->
<div class="row form-group">
<div class="col-sm-4">
<div class="btn btn-success" id="add" onclick="">
Here is my button
</div>
</div>
</div>
{{ Form::close() }}
I need to insert some data after clicking this button. How can i do this ? As like i said all my routes controller and function are ready for this.
Thanks in advance.
Since you already have your form set up, all you have to do is add a submit button and you will go to Mycontroller#myMethod when the submit button is called on.
// submit button
{{ Form::submit('Submit') }}
Then in your myMethod(), you can call this
$data = Input::all();
to get the form data.

Open Django template in bootstrap Modal

I'm trying to open a Django template in Twitter-Bootstrap Modal. Earlier I did it using JavaScript but it only opened once.
I read somewhere that Bootstrap Modals are more customizable, so giving it a try, I referred to an already answered question. I've the same problem and I've tried the same solution but it doesn't work for me. The only thing I get is blackened screen.
The flow goes like this:
A Django template is rendered which has several worker's details.
In that template, I've links to "Add advance" for every worker.
Clicking on which I want to open Modal.
In that Modal, I want to open another Django template containing a
form.
Filling the form, either close or press enter.
For any of these events on Modal, save the data from the form.
What I've done is here:
Template where the link is clicked: form.html
<a class="contact" href="#" data-form="/popupadvance/?worker_id={{value.worker_id}}&year={{year}}&month={{month}}" title="Advance"> Add advance</a>
<div class="modal hide" id="contactModal">
<script>
$(".contact").click(function(ev) { // for each edit contact url
ev.preventDefault(); // prevent navigation
var url = $(this).data("form"); // get the contact form url
alert(url);
$("#contactModal").load(url, function() { // load the url into the modal
$(this).modal('show'); // display the modal on url load
});
return false; // prevent the click propagation
})
</script>
The template which should open: popup.html
<div class="modal hide" id="contactModal">
<form id="form" class="well contact-form" action='/popupadvance/?worker_id={{value.worker_id}}&year={{year}}&month={{month}}' >
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
{% csrf_token %}
{{worker_id}} <br />
{% for a in old_advances %}
{{a.advance_amount}} {{a.advance_date}}<br />
{% endfor %}
<input type="integer" id="popupadvance_{{worker_id}}" placeholder="Advance ++" class="popupadvance" >
</div>
<div class="modal-footer">
<input class="btn btn-primary" type="submit" value="Save" />
<input name="cancel" class="btn" type="submit" value="Cancel"/>
</div>
</form>
Clicking on the link: "Add advance", the only thing I get is the alert I've added closing which I get blackened screen over which the Modal should appear but neither the Modal, nor the form is rendered there. But pressing forward button on browser, I get the popup.html rendered on a new page, which probably tells that the URL is working on clicking the link, but only the Modal doesn't open.
I would like to tell that the input field in pupup.html is able to save data to database with OnChange event as I did when I opened up the dialog box using JavaScript.
Any help to find the problem will be greatly appreciated. As I don't see any error on Browser console.
Thanks.

Categories

Resources