-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The right way to use meteor-semantic-ui's modal? #25
Comments
I dont know how to answer this correctly, as there are multiple ways to tackle a problem like this. The first thing that popped into my mind was using http://docs.meteor.com/#/basic/tracker Untested code... Tracker.autorun(function () {
if (Session.get("modal_is_open")) {
$('.ui.modal').modal('show')
} else {
$('.ui.modal').modal('hide')
}
}); You could also try to use multiple modals and talk to them individually.. Tracker.autorun(function () {
if (Session.get("modal_1_is_open")) {
$('#modal1').modal('show')
} else {
$('#modal1').modal('hide')
}
if (Session.get("modal_2_is_open")) {
$('#modal2').modal('show')
} else {
$('#modal2').modal('hide')
}
}); Or maybe you could avoid using Sessions for opening and closing, i dont know. Totally depends on your project. |
The problem I met is if I use $('.ui.modal').modal('show') to open modal, there is no logic on the modal which meteor template did not render it but jquery did. If I have a form in modal, I will only see the form but can not summit the form. I am sorry that I am not a professional programmer. I just want to write a personal site. But this simple problem frustrated me. |
<head>
<title>semantic-modal-example</title>
</head>
<body>
{{> hello}}
</body>
<template name="hello">
<button class="openModal">Click Me</button>
<p>Form value: {{formValue}}</p>
<div id="modalView" class="ui modal">
<div class="content">
<div class="ui fluid input">
<input id="modalInputValue" placeholder="form value here" type="text" value="{{formValue}}">
</div>
</div>
<div class="actions">
<div class="ui button cancel">Cancel</div>
<div class="ui button ok">OK</div>
</div>
</div>
</template> if (Meteor.isClient) {
Session.setDefault("formValue", 'something');
Template.hello.helpers({
formValue: function () {
return Session.get("formValue");
}
});
Template.hello.events({
'click .openModal': function () {
$('#modalView')
.modal({
onDeny : function(){
console.log('canceled')
return false;
},
onApprove : function() {
var modalInputValue = $('#modalInputValue').val();
Session.set("formValue", modalInputValue);
}
})
.modal('show')
;
}
});
} |
You might want to consider using Approve / Deny Callbacks. |
I see. It works! Thank you very very much! |
Great :) |
In the example above, how do I access the context of the template? Say I want to save some data from the modal and I require the _id of the hello template context and there are multiple form elements. Is it really best to set 5 session variables? And then where to I place the actual meteor call method (or with insecure simply add the insert function)? |
Instead of Sessions you could use it like this too... <head>
<title>semantic-modal-example</title>
</head>
<body>
{{> carsView}}
</body>
<template name="carsView">
{{#each cars}}
{{> carButton}}
{{/each}}
</template>
<template name="carButton">
<button class="openModal">{{name}}</button>
<div class="ui modal">
<div class="content">
<div class="ui fluid input">
<input class="carname{{_id}}" placeholder="car name here" type="text" value="{{name}}">
</div>
</div>
<div class="actions">
<div class="ui button cancel">Cancel</div>
<div class="ui button ok">OK</div>
</div>
</div>
</template> Cars = new Mongo.Collection('cars');
if (Meteor.isClient) {
Template.carsView.helpers({
cars: function () {
return Cars.find();
}
});
Template.carButton.events({
'click .openModal': function (event,template) {
var self = this;
template.$('.modal')
.modal({
onDeny : function(){
console.log('canceled')
return false;
},
onApprove : function() {
var name = $('.carname'+self._id).val();
console.log(self._id,name);
Cars.update({_id:self._id},{$set:{name:name}});
}
})
.modal('show')
;
}
});
}
if (Meteor.isServer){
Meteor.startup(function(){
if (!Cars.findOne()){
Cars.insert({'name':'dodge'});
Cars.insert({'name':'fiat'});
Cars.insert({'name':'mercedes'});
}
})
} |
Ah, var self = this. Totally forgot about that fundamental trick. I worked around it with global variables but that is much nicer, thanks! |
I just found out that Blaze events doesn't work for Semantic UI modal templates. |
@sanjo Can you elaborate a little more on how to structure the workaround? Thanks! |
@joryphillips Here is an example of a modal with form, based on my use case. Node: I use the template extensions package for the hooks instead of onCreated, onRendered (https://github.com/aldeed/meteor-template-extension). This is not necessary. The modal template<template name="modal">
<div class="ui small modal">
<i class="close icon"></i>
<div class="header">
{{header}}
</div>
<div class="content">
{{> modalForm}}
</div>
<div class="actions">
<div class="ui deny button">Cancel</div>
<div class="ui {{#unless isFilledOut}}disabled{{/unless}} primary approve button">
{{approveText}}
</div>
</div>
</div>
</template> var template = Template.modal;
template.hooks({
created: function () {
var self = this;
_.defaults(self.data, {
header: 'My modal header',
approveText: 'Submit'
});
self.form = new ReactiveVar(null);
self.getForm = function () {
return self.form.get();
};
},
rendered: function () {
var self = this;
self.form.set(
Blaze.getView($('form', self.firstNode).get(0)).templateInstance()
);
var modal = self.$('.ui.modal');
modal.modal({
onApprove: function () {
self.getForm().submit();
},
onHidden: function () {
Blaze.remove(self.view);
}
});
modal.modal('show');
}
});
template.helpers({
isFilledOut() {
var self = Template.instance();
var formInstance = self.getForm();
return formInstance && _.every(formInstance.form, function (field) {
return !!field.get();
});
}
}); The modal content template (in this case the form)<template name="modalForm">
<form class="ui form">
{{!-- TODO: Add form inputs --}}
</form>
</template> var template = Template.modalForm;
template.hooks({
created: function () {
var self = this;
self.form = {
// myInput: new ReactiveVar(null)
};
self.submit = function () {
// TODO: Implement form submit action
};
}
}); Service to show modalsModal = {
show: function (templateName, data = {}) {
var template = Template[templateName];
var parentNode = document.body;
Blaze.renderWithData(template, data, parentNode);
}
}; |
@sanjo thank you very much for the quick response! Just wondering, what event fires the modal in your use case? |
This callback is called by semantic ui when the user clicks the approve button. onApprove: function () {
self.getForm().submit();
},
|
Just reminding you guys of the new location of this package ;)
|
I've found a pretty clean solution for using Semantic UI's modals; you can see the code here: A lengthier explanation of the pattern can be found here: (Incidentally, applying the pattern to Foundation modals is even simpler: |
@dalgard That hackpad was very well written and taught me everything I needed to know. Thanks!! |
I'm glad :) |
@dalgard I have a couple of questions that I believe you will be able to answer:
Thanks |
Both your requests are met by the pattern I've outlined. In fact, I consider them central to the pattern. |
@dalgard |
These days, I'm using a custom openModal binding with the |
@sanjo Great tip! I have been banging my head in the wall for 30 minutes! |
I had problem too. When you have modal template and {{> modalTemplate}} in a parent template and do .modal('show') on onRendered of the parent template. Other jquery initializations on the modal template's onRendered doesn't run second time when you open the modal even in tracker.autorun environment. If someone has a solution to this problem, can share please? thanks. |
If you want to use Meteor events with semantic ui modal, try to initiate the modal with "detachable: false". It works for me :) |
Yeah but kinda kills all the good stuff :) This post thread has been really helpful. Thanks alot. |
@sanjo Dude thank you for that great tip of putting the modal content in a separate template! @nooitaf maybe we want to put this in the package's readme? #25 (comment) |
@dalgard Just wanted to say thanks for that hackpad -- especially the onHidden callback method of blaze removal! |
if you wanna to use with meteor-blaze template events inside semantic model, you can separate all modal content to another template, and it worked perfectly. this didn't workHTML <template name="firstModal">
<div id="firstModal" class="ui wide modal">
<i class="close icon"></i>
<input type="button" class="ui button" value="click me">
</div>
</template> JS Template.firstModal.events({
'click .button': function(event, template){
alert('click !!!!!!!')
}
}); but this is perfect!!HTML <template name="firstModal">
<div id="firstModal" class="ui wide modal">
<i class="close icon"></i>
{{>firstModalContent}}
</div>
</template>
<template name="firstModalContent">
<input type="button" class="ui button" value="click me">
</template> JS Template.firstModalContent.events({
'click .button': function(event, template){
alert('click !!!!!!!')
}
}); |
just by change I have a modal in a page and sometimes it works fine... Uncaught TypeError: $(...).modal is not a function any of you have any idea regarding this? somehow there are problems in loading jquery and semantic ui but this is the only place where I have problems with semantic ui related features. |
@dalgard I read that your solution is very good but too bad both of your link (sample and explanation) are broken now. Do you still have the solution and explanation? Thanks. Regards, |
When I use modal, I found if I open it with meteor template, I mean, rendering when a session variable is true, there is event binding but transition animation, else if I open modal with jquery $('.ui.modal').modal('show'), there is transition animation but event bindings. So I think there is other ways to use modal which keep functions from Blaze and animations from Semantic-ui at the same time. Dynamic part for integration of these two frameworks is not so straightforward. Would you like to point out the right way to use meteor-semantic-ui's modal? Thank you very much.
The text was updated successfully, but these errors were encountered: