Materialize Modal and Dropdown Problems with Meteor Blaze - meteor

I recently ran into some problems when trying to use the Materialize modal and dropdown features with Blaze, specifically when there are multiple instances of each.
I have this template called cadcall:
<template name="cadcall">
<tr>
<td class="truncate">{{id}}</td>
<td>FRI</td>
<td>{{time}}</td>
<td>{{type}}</td>
<td>{{location}}</td>
<td>{{notes}}</td>
<td>
<i class="material-icons call-dropdown-button" data-activates="cadcallactions">more_vert</i>
</td>
</tr>
<div id="call-details-modal" class="modal">
<div class="modal-content">
<h4>Call Details</h4>
<div class="row">
<form class="new-call col s12">
<div class="row">
<div class="input-field col s6">
<input id="call-id" type="text" class="validate" disabled>
<label for="call-id">ID</label>
</div>
<div class="input-field col s6">
<input id="call-time" type="text" class="validate" disabled>
<label for="call-time">Time</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input id="call-location" type="text" autocomplete="off">
<label for="call-location">Location</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<textarea id="call-notes" class="materialize-textarea" length="100000" autocomplete="off"></textarea>
<label for="call-notes">Notes</label>
</div>
</div>
<div class="modal-footer">
<button type="submit" href="#!" class="modal-action modal-close waves-effect waves-grey btn-flat center">Submit</button>
</div>
</form>
</div>
</div>
</div>
<ul id='cadcallactions' class='dropdown-content'>
<li><a class="callupdate" href=""><i class="material-icons">update</i>Update</a></li>
<li><a class="callresolve" href=""><i class="material-icons">check</i>Resolve</a></li>
</ul>
</template>
Here is the cadcall events:
Template.cadcall.events({
'click .callresolve'(e) {
Calls.remove(this._id);
},
});
Here is the cadcall onRendered:
Template.cadcall.onRendered(function() {
$(document).ready(function () {
$('.call-details').leanModal();
});
$('.call-dropdown-button').dropdown({
inDuration: 300,
outDuration: 225,
constrainWidth: false, // Does not change width of dropdown to that of the activator
hover: false, // Activate on hover
gutter: 0, // Spacing from edge
belowOrigin: true, // Displays dropdown below the button
alignment: 'right', // Displays dropdown with edge aligned to the left of button
stopPropagation: false // Stops event propagation
});
});
Essentially, for each call there is in the Mongo database, I iterate each call entry. However, if there are multiple calls, the modal doesn't function correctly. If I try to close the modal (by clicking the class callupdate after opening it, the gray area behind it stays.
In addition to the modal not working correctly, the dropdown menu also acts funky, specifically when I try to delete a field (by clicking the class callresolve). Whenever I try to delete a call entry it works, but thereafter the dropdown menus on the other call entries stop working altogether. Furthermore, for some reason when I add an entry then delete it, an error pops up in the Chrome console:
blaze.js:650 Uncaught Error: Must be attached
at Blaze._DOMRange.DOMRange.containsElement (blaze.js:650)
at Blaze._DOMRange.<anonymous> (blaze.js:2612)
at HTMLAnchorElement.<anonymous> (blaze.js:863)
at HTMLTableSectionElement.dispatch (jquery.js:4723)
at HTMLTableSectionElement.elemData.handle (jquery.js:4391)
Presumably, since these problems only occur when I have multiple call entries, I think the HTML may be conflicting with each iteration of the call entry. Is there a way to remedy this issue?

Related

Use checkboxes to add and remove items from a list

I'm working with asp.net core mvc and I have two views, one to edit a profile and another to show the profile. The view to edit the profile has checkboxes and the view to show the profile has a list with the items that got selected in the edit view. Whenever I edit the profile, all the checkboxes are unselected. I want that whenever I'm on the EditProfile view, the items that were on the ShowProfile view get selected and the others unselected. If I select a checkbox, that item gets added to the list and if I unselect a previous selected item, that item gets removed from the list. Since I'm a beginner, I have no idea how to do this working with both views. I did multiple things and it didn't work
Part of the ShowProfile view
#model ModifyProfile
#{
}
<div class="card">
<div class="card-body">
<a class="btn btn primary"href="\ProfileDetails\EditProfile">Edit</a>
</div>
</div>
<div class="card-body">
<h3 class="mb-3">Interests</h3>
<div class="mb-3">
<div class="text">Interests:</div>
#if (Model.InterestProfile != null){
<ul>
#foreach(InterestProfile interestProfile in Model.InterestProfiles{
<li class="mb-3">
#interestProfile.Interest.InterestName
</li>
}
</ul>
}else
{
#:No interests
}
</div>
</div>
Part of the EditProfileView
#model ProfileViewModel
#{
}
<form action="EditProfile" method="post">
<div class="card">
<div class="card-body">
<button class="btn btn-primary" type="submit">Submit changes</button>
</div>
</div>
<div class="card">
<div class="card-body">
<div>
<label class="form-label">Interested in</label>
<div class="checkbox">
#foreach (Interest interest in Model.Interests)
{
<label><input type="checkbox" name="interestId" value="#interest.InterestId">
#interest.InterestName </label>
}
</div>
</div>
</div>
</div>
Is there a way to do it with checkboxes? I think that a dropdown list could be helpful here but I don't know if it's worth deleting all the code I have already to make that change

Ngbootstrap: how to position dropdown under search input

I'm following this documentation cause I would like to create a
Gmail like 'search bar' where beside the input there's a dropdown button that opens a dropdown with filter options.
Unfortunately in the docs the examples don't cover the input + dropdown button scenario.
I started with this:
<!-- Search bar-->
<div class="input-group mb-3">
<input type="text" class="form-control">
<div class="input-group-append" ngbDropdown role="group" aria-label="Button group with nested dropdown">
<button class="btn btn-outline-success" ngbDropdownToggle></button>
<div class="dropdown-menu" ngbDropdownMenu>
<button class="dropdown-item">One</button>
<button class="dropdown-item">Two</button>
</div>
</div>
</div>
Everything is shown correctly, but the dropdown is not. It is opened under its parent (the button), while I'd like to have it for the whole length of the input. Pretty sure it could be solved with some CSS rule.
From the documentation under Manual Triggers, you could attach the dropdown menu to the input group and trigger the open/close with the appended button on click event.
<!-- Search bar-->
<div class="container">
<div class="input-group mb-3" #myDrop="ngbDropdown" ngbDropdown>
<input type="text" class="form-control" >
<div class="input-group-append" role="group" >
<button (click)="$event.stopPropagation(); myDrop.open();" class="btn btn-outline-success" >Hi</button>
</div>
<div class="dropdown-menu" ngbDropdownMenu>
<button class="dropdown-item">One</button>
<button class="dropdown-item">Two</button>
</div>
</div>
</div>

Navbar with search box - MaterializeCss

I'm trying to create a functional search bar inside my nav bar with materializecss. I can put the search icon and write text inside it but it doesn't work. I only have the design part. I'm not being able to find the jquery to initialize the search box and make it work.
<ul class="right hide-on-med-and-down">
<li>
<div class="input-field col s6 s12 white-text">
<i class="white-text small material-icons prefix">search</i>
<input type="text" placeholder="search" id="autocomplete-input" class="white-text">
</div>
</li>
</ul>
You have not initialized autocomplete and it's options in JS file.
You can check JS code below.
Try to run the demo below, a search bar with implemented autocomplete.
You can get Apple, Microsoft and Google in the search bar autocomplete.
For more options add them in the data object under autocomplete initialization.
var myData={
"Apple": null,
"Microsoft": null,
"Google": 'https://placehold.it/250x250'
};
$(document).ready(function() {
$('input.autocomplete').autocomplete({
data: myData,
limit: 20, // The max amount of results that can be shown at once. Default: Infinity.
onAutocomplete: function(val) {
// Callback function when value is autcompleted.
},
minLength: 1, // The minimum length of the input for the autocomplete to start. Default: 1.
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">search</i>
<input type="text" id="autocomplete-input" class="autocomplete">
<label for="autocomplete-input">Search</label>
</div>
</div>
</div>
</div>

how do i use same sidenav in multiple pages

So i created a sidenav on one of my page and its working properly there
what i want to do is on another page i want to use that same sidenav.
My side nav code:
<form id="keyword-form" class="side-nav rt-side-nav">
<div>
<center><h5>KEYWORDS</h5></center>
<textarea rows="10" cols="50" id="txtarea" class="keyword-text" placeholder="enter comma seperated values for the products" contenteditable="true">{{keywords}}</textarea>
</div>
<div class="keyword-submit">
<center><button type="submit" class="key-submit btn waves-effect waves-light col m12">SUBMIT</button></center>
</div>
</form>
<a data-activates="keyword-form" class="button-collapse"></a>
<div hidden class="keyword">
</div>
Wrap your navbar code in a template then use that template on each page. See example in the Meteor Todo app tutorial. Or if you are using Iron Router put it in your app body template.
Template example:
<template name="sidenav">
<form id="keyword-form" class="side-nav rt-side-nav">
<div>
<center><h5>KEYWORDS</h5></center>
<textarea rows="10" cols="50" id="txtarea" class="keyword-text" placeholder="enter comma seperated values for the products" contenteditable="true">{{keywords}}</textarea>
</div>
<div class="keyword-submit">
<center><button type="submit" class="key-submit btn waves-effect waves-light col m12">SUBMIT</button></center>
</div>
</form>
<a data-activates="keyword-form" class="button-collapse"></a>
<div hidden class="keyword">
</div>
</template>
Then every time you want to show your sidenav:
{{> sidenav}}

Handling form submittion

I have a form within modal and I don't seem to be able to catch the submit event.
Let's say we have a html page defined as (for the sake of simplicity leaving out any templates defined by me)
<body>
<button class="ui button">Open modal</button>
<div class="ui small modal">
<div class="header">
Enter your email
</div>
<div class="content">
<form class="ui form">
<div class="field">
<div class="ui left icon input">
<i class="at icon"></i>
<input type="email" name="email" placeholder="Email">
</div>
</div>
<div class="ui error message">
</div>
</form>
</div>
<div class="actions">
<div class="ui negative button">
Cancel
</div>
<div class="ui positive primary loadable button">
Reset password
</div>
</div>
</div>
</body>
and registred template events
Template.body.events({
'click button': function () {
$('.modal').modal('show');
},
'submit form': function () {
alert('called');
}
});
When I submit the form it doesn't get cought by the handler. Why and what's the best approach?
I got something similar working by defining the inner content of modal as template, but it makes things much harder. Is there any other way?
EDIT: Here's meteorpad that demostrates the issue
The reason behind this behavior is that modal is detached from the DOM. This behavior can be overriden by setting detachable: false
Here's working meteorpad
Credits

Resources