Popover with MeteorJS - javascript

Try to use bootstrap popover with MeteorJS and have 2 troubles:
Can't assign some value that coming from collection to input value
I try to get one popover on html,body but have every popover on every template, it's normal, but I try to do only 1 popover on 1 screen
I have collection Posts with such documents Posts.insert({title:"Loli Pop"});
Meteor.publish("posts_levels", function(){
return Posts.find();
});
<template name="www">
{{#each level}}
{{> one}}
{{/each}}
</template>
Template.www.onCreated(function(){
var self = this;
self.autorun(function() {
self.subscribe('posts_levels');
});
});
<template name="one">
<div class="popover-markup">
<div class=" trigger ">
Edit
</div>
</div>
<div class="content-popover hide">
<form class="form">
<input name="title" id="post_edit_title" value="{{title}}" />
</form>
</div>
</template>
Template.one.onRendered(function(){
$('.popover-markup > .trigger').popover({
html : true,
content: function() {
return $('.content-popover').html();
},
container: 'body',
placement: 'right'
});
EDIT: 2 problem solved for 50%, I add this, and now it's hide when I open another popover, but then I must click 2x on .trigger to show new popover
$('.popover-markup > .trigger').popover({
html : true,
content: function() {
return $('.content-popover').html();
},
container: 'body',
placement: 'right'
}).on("click", function(e){
$('.trigger').not(this).popover('hide');
});

Here's an anwser for your question 1 (assign value from collection to input).
The input in the template gets the value of title. When you remove the hide class you can see the title from the collection. But a popover inserts new elements into the DOM. And those new elements are rendered by Bootstrap and not rendered by Blaze, so the input is not filled with the value of title.
What you can do is attach an event handler to the popover when it is shown. Something like this:
Template.one.onRendered(function(){
$('.popover-markup > .trigger').popover({
html: true,
content: function () {
return $('.content-popover').html();
},
container: 'body',
placement: 'auto top'
}).on('shown.bs.popover', function () {
$('.popover-content #post_edit_title').val(this.data.title);
}.bind(this));
});
As you can see the event shown.bs.popover can be used to do some initialization. In the event handler the value for the input is set.
It is important to have the jquery selector find your input in the popped form, that's why the selector starts with .popover-content. Otherwise it would set the value to the first input that was defined in the template.
Another thing to note is the use of bind(this). That attaches this and makes it usable inside the event handler so you can get the value of title.
BTW, there is also a hidden.bs.popover event when the popover is closing.

Related

Is there any method in Fullcalendar v5 which rerenders event?

I have bootstrap popover initialized on events, inside popover content i have button (on click button calls function which changes the extendedProp.status of related event using event.setExtendedProp() method)
//above of my code FullCalendar has rendered and set as variable var = calendar
eventDidMount: function (info) {
$(info.el).popover({
html: true,
content: PopoverHtml(info.event),
container: 'body',
animation: true,
})
}
Since popover is initialized right after the event element has been added to the DOM i need to rerender event to change popover's content
eventChange: function (changeInfo) {
event_source = calendar.getEventSourceById(changeInfo.event.id);
event_source.refetch();
},
I also tried dynamic content setting method of bootstrap setContent()
I use popover with eventClick without problems:
function event_click(info) {
$('.popover_show').popover('dispose');
$(info.jsEvent.srcElement).popover({
container: 'body',
animation: false,
title: 'Zeitraum: '+fc_date_print(info.event.start, true)+" - "+fc_date_print(info.event.end, false)+
"<a href='#' class='float-right' onclick='form_cancel()' ><img src='/icon/x.svg' width='23' height='23' > </a>",
placement: 'bottom',
boundary: 'window',
sanitize: false,
trigger : 'manual',
popperConfig: {eventsEnabled: false },
"html": true,
content: function(){ a = get_form(info.event.extendedProps['id']); return a; }
});
$(info.jsEvent.srcElement).popover('show');
$(info.jsEvent.srcElement).addClass('popover_show');
}
I create the popover-content dynamicly in get_form() (currently in 2 way, one by javascript from extentedProbs, second I load content from popover dynamicly via ajax. This is much more efficent, than creating a popover for every event in advance.
Works fine for me.
The line
$(info.jsEvent.srcElement).popover('show');
do the magic, that you don't need a second click.
I add the class popover_show to the sourceElement, so $('.popover_show').popover('dispose');
will close all popover. (I do that before open a new popover)
But there are plenty other ways for that.

jQuery display property not changing but other properties are

I'm trying to make a text editable on clicking it. Below is the code I'm trying. When the title is clicked it shows an input box and button to save it.
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
I have changed other properties like color or changing the text of the elements and its working, but it is not applying the display property or .show()/.hide() function on the title or edit elements.
Below is my jQuery
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(){
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
$(title).show();
$(edit).hide();
}
function editTitle(){
$('.title-edit', this).show();
$('.title', this).hide();
}
Here's the jsfiddle
https://jsfiddle.net/ywezpag7/
I've added
$(title).html('abcd');
to the end to show that other properties/functions are working, but just not the display.
For checking the html change on title element you will have to check the source through developer tools cause the title element is hidden.
Where am I going wrong?
Your problem is in the function saveTitle. The first line must stop the event propagation otherwise after this function the editTitle function is called.
The snippet:
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(e){
// this line
e.stopPropagation();
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
title.show();
edit.hide();
title.text($('.title-edit input').val());
}
function editTitle(e){
$('.title-edit', this).show();
$('.title', this).hide();
}
.title-edit{
display:none
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
The issue as mentioned already is that your click events are fighting. In your code, the title-edit class is within the block, so when you click on the save button it triggers events for both clicks.
The easiest and, imho, cleanest way to resolve this is to switch your click event to be called on .title, and .title-edit button. You can also simplify the code beyond what you've got there.
$(function(){
$('.title').click(editTitle);
$('.title-edit button').click(saveTitle);
});
function saveTitle(){
$('.title').show();
$('.title-edit').hide();
$(title).html('abcd');
}
function editTitle(){
$('.title-edit').show();
$('.title').hide();
}
https://jsfiddle.net/ywezpag7/7/
I tried debug your code, and I had seen, that then you click to "Save" button, handled both functions, saveTitle() and editTitle(), and in that order. Therefore, the elements initially hidden, and then shown.

Can Bootstrap popovers not be destroyed?

Is it possible to have a bootstrap (v3) popovers to have it's div loaded right at the start of pageload and not be destroyed when it is being toggled?
I have a popover content in a div:
<div id="popoverContent">
<h1>Stuff</h1>
<p>I'm in a popover!</p>
</div>
And a button that toggles the popover:
<a id="floating_tab" data-toggle="popover" data-placement="left">Button</a>
Here is my Javascript code that handles the button pushes:
<script>
var x = false;
$('[data-toggle=popover]').popover({
content: $('#popoverContent').html(),
html: true
}).click(function() {
if (x) {
$(this).popover('hide');
x = false;
}
else {
$(this).popover('show');
x = true;
}
});
</script>
The thing is, that when $(this).popover('show'); is called, a div is created. Something like this shows up in the inspect element (chrome):
<div class="popover fade left in" role="tooltip" id="popover460185" style="top: 430.5px; left: 2234px; display: block;"><div class="arrow" style="top: 50%;"></div><h3 class="popover-title" style="display: none;"></h3><div class="popover-content">
<h1>Stuff</h1>
<p>I'm in a popover!</p>
</div></div>
But when the button is clicked again, the whole div itself is removed and obliterated from the page.
Is it possible to have the popover div to be created during pageload (hidden though) and can be toggleable without having the div to be deleted?
As stated in the comments, it is not presently possible with Bootstrap 3. The Popover (which is an extension of the Tooltip) is dynamically created on show and detached (using jQuery.detach) from the DOM on hide.
It is probably best to roll your own JavaScript and simply utilize Bootstrap's CSS. However, you could easily patch the functionality using the Popover's event API -the following can be used as a starting place:
$(function () {
var content = $('#popover-content'), // Pre defined popover content.
popover = $('#popover-anchor').popover();
popover.on('inserted.bs.popover', function () {
var instance = $(this).data('bs.popover');
// Replace the popover's content element with the 'content' element
instance.$tip = content;
});
popover.on('shown.bs.popover', function () {
var instance = $(this).data('bs.popover');
// Remove the reference to 'content', so that it is not detached on hide
instance.$tip = null;
});
popover.on('hide.bs.popover', function () {
// Manually hide the popover, since we removed the reference to 'content'
content.removeClass('in');
content.addClass('out');
});
});
Codepen

ResponsiveTabs add onclick in js file

I am working with the ResponsiveTabs module from PeteLove.com.
http://www.petelove.com/responsiveTabs/
I would like to make a change into it because I need an onclick event added to the tabs. Now this should be done I believe in the following code section.
// CREATE TAB ITEMS (VISIBLE ON DESKTOP)
//create tab list item from heading
//associate tab list item with tab panel
var $tabListItem = $('<li/>', {
'class': 'responsive-tabs__list__item',
id: 'tablist' + tablistcount + '-tab' + tabcount,
'aria-controls': 'tablist' + tablistcount +'-panel' + tabcount,
'role': 'tab',
tabindex: 0,
text: $tabHeading.text(),
keydown: function (objEvent) {
if (objEvent.keyCode === 13) { // if user presses 'enter'
$tabListItem.click();
}
},
click: function() {
//Show associated panel
Now I expected to see somewhere <li> so that I could do <li onclick="setBrowserFrameSource(); return false;"> but there is no <li> anywhere just the closing brackets. So I should add it to the code above. I have tried to add it as follows:
'role': 'tab',
'onclick="setBrowserFrameSource(); return false;"',
tabindex: 0,
But this broke the entire thing. Any help would be appreciated. Thanks in advance.
According to the instructions from the website petelove.com (full link in original question) you need to start the tabs with:
<div class="responsive-tabs">
Then the plugin will do the rest. So I thought instead of adding for each <li> an onclick event why not add it to the container element. Which I did and it is working. So I now have the following.
<div class="responsive-tabs" onclick="setBrowserFrameSource(); return false;">
Now every time a tab is clicked it does its functions.

Meteor JS: How do I preserve cursor position on contenteditable field between renders?

Problem:
I have several contenteditable elements. When a user focuses on an element, an editing class name is added to the element. I am using Session object to do this, instead of jQuery. The problem is that everytime I focus on the element, it rerenders, and both the cursor position and focus is lost.
I am trying to use the preserve method on the element to prevent it from getting updated when the element is being edited, but cannot get this to work. Any suggestions?
Here's my code:
// Collection
Forms = new Meteor.Collection('forms');
// Fixtures
if (Forms.find().count() === 0) {
Forms.insert({
description: "form 1"
});
Forms.insert({
description: "form 2"
});
}
if (Meteor.isClient) {
// Helpers
Template.forms.helpers({
editState: function() {
return Session.equals("fieldEditing", this._id) ? "editing" : "";
},
forms: function() {
return Forms.find();
}
});
// Preserve
Template.forms.preserve(['.editing']);
// Event handler
Template.forms.events({
'focus .form-field' : function (e, template) {
e.preventDefault();
Session.set("fieldEditing", this._id);
}
});
}
// Template
<head>
<title>testproject</title>
</head>
<body>
{{> forms}}
</body>
<template name="forms">
{{#each forms}}
<p class="{{editState}} form-field" contenteditable>
{{description}}
</p>
{{/each}}
</template>
This is caused by Spark not considering the content of the contenteditable node a value that should be kept. Hence each render resets the content of the div, moving the cursor to the beginning.
I found closed issue that is similar https://github.com/meteor/meteor/issues/171 , but I don't think using {{#constant}} regions is a great solution in your case.
I would suggest:
Trying one of the new preview-rendering engines.
Creating an issue at https://github.com/meteor/meteor with your specific example.
Note, I changed your code to the following to test easier:
if (Meteor.isClient) {
// Collection
Forms = new Meteor.Collection(null);
// Fixtures
if (Forms.find().count() === 0) {
Forms.insert({
description: "form 1"
});
Forms.insert({
description: "form 2"
});
}
// Helpers
Template.forms.helpers({
timer: function(){
return Session.get("timer");
},
forms: function() {
return Forms.find();
}
});
// Preserve
Template.forms.preserve({
".form-field":function(n){return n.id}
});
Session.set("timer",+new Date())
Meteor.setInterval(function(){
Session.set("timer",+new Date())
},2000);
}
// Template
<head>
<title>testproject</title>
</head>
<body>
{{> forms}}
</body>
<template name="forms">
{{timer}}
{{#each forms}}
<p class="form-field" contenteditable id="form-{{_id}}">
{{description}}
</p>
{{/each}}
</template>

Categories

Resources