Angular UI Datepicker. Enable only 5 days from today excluding weekends - datepicker

I am using Angular UI Bootstrap datepicker directive in my project. I have this specific need like I need to enable only 5 days from current day. In case of weekend, I need to disable them and enable the remaining days. for eg, If current day in Friday, I need to enable fri, mon, tue, web, thurs. I am using dateDisabled property to achieve this. Problem is all past month dates are also getting enabled. Also I think the solution I came up is not elegant. Below is my markup and code. Kindly help me. Thank you in advance.
<input show-weeks="false" ng-click="vm.openDate()" name="quotedate" type="text" class="form-control" ng-model-options="{timezone:'UTC'}" uib-datepicker-popup="dd/MM/yyyy" ng-model="vm.quote.date" is-open="vm.quotedate.opened" datepicker-options="vm.dateOptions" required close-text="Close" readonly="true"/>
vm.dateOptions = {
dateDisabled: disabled,
minDate: today
};
function disabled(data) {
var date = data.date,
mode = data.mode;
if (today.getDay() === 0 || today.getDay() === 6) {
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6 || date.getDate() > today.getDate() + 5 );
}else if (today.getDay() === 1) {
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6 || date.getDate() > today.getDate() + 4 );
}else {
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6 || date.getDate() > today.getDate() + 6 );
}
}

What you are looking for are the min-date, max-date, and date-disabled attributes, as described in the docs. The date-disabled function in this example is pulled directly from the docs, and in order to confine the available date range, simply set the min-date attribute to the current datetime:
vm.dt = new Date();
vm.minDate = angular.copy(vm.dt);
...and the max-date to five days from now:
var fiveDaysFromNow = angular.copy(vm.dt);
fiveDaysFromNow.setDate(fiveDaysFromNow.getDate() + 5);
vm.maxDate = fiveDaysFromNow;
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('DatepickerDemoCtrl', function ($scope) {
var vm = this;
function today() {
vm.dt = new Date();
}
today();
vm.opened = false;
vm.openDatePopup = function() {
vm.opened = true;
};
// Disable weekend selection
vm.disabled = function(date, mode) {
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
};
vm.minDate = angular.copy(vm.dt);
var fiveWeekdaysFromNow = angular.copy(vm.dt);
fiveWeekdaysFromNow.setDate(fiveWeekdaysFromNow.getDate() + 7);
vm.maxDate = fiveWeekdaysFromNow;
vm.dateOptions = {
formatYear: 'yy',
startingDay: 0
};
vm.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
vm.format = vm.formats[0];
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.1.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<style>
.full button span {
background-color: limegreen;
border-radius: 32px;
color: black;
}
.partially button span {
background-color: orange;
border-radius: 32px;
color: black;
}
</style>
<div ng-controller="DatepickerDemoCtrl as demo">
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<p class="input-group">
<input type="text"
class="form-control"
uib-datepicker-popup="{{demo.format}}"
ng-model="demo.dt"
show-weeks="false"
is-open="demo.opened"
min-date="demo.minDate"
max-date="demo.maxDate"
datepicker-options="demo.dateOptions"
date-disabled="demo.disabled(date, mode)"
ng-required="true"
close-text="Close"/>
<span class="input-group-btn">
<button type="button"
class="btn btn-default"
ng-click="demo.openDatePopup()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
</div>
</div>
</div>
</body>
</html>
Hope this helps!

Related

The date changes automatically (days with months)

I use fomantic-ui/semantic.
I choose the date from the popup - everything is fine.
I am correcting the date "manually" - days with months change (yyyy-mm-dd to yyyy-dd-mm)
I want format date: yyyy-mm-dd (Day: 01-31, month 01 - 12).
I give "if" for days less than 10 to add '0' and for months less than 10 to add '0'
Video problem: https://www.screencast.com/t/y3pnvvZVqL
$('#rangestart').calendar({
type: 'date',
firstDayOfWeek: 1,
monthFirst: false,
ampm: false,
formatter: {
date: function (date, settings) {
if (!date) return '';
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
if (month<10) var month = ("0" + (date.getMonth() + 1)).slice(-2);
else var month = date.getMonth() + 1;
if(day<10) var day = ("0" + (date.getDate())).slice(-2);
else var day = date.getDate();
return year + '-' + month + '-' + day;
}
},
endCalendar: $('#rangeend'),
text: {
days: ['Nd', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'Sb'],
months: ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'],
monthsShort: ['Sty', 'Luty', 'Mar', 'Kwi', 'Maj', 'Czer', 'Lip', 'Sierp', 'Wrz', 'Paz', 'List', 'Grud'],
today: 'Dziś',
now: 'Teraz'
}
});
$('#rangeend').calendar({
type: 'date',
firstDayOfWeek: 1,
monthFirst: false,
ampm: false,
formatter: {
date: function (date, settings) {
if (!date) return '';
var year = date.getFullYear();
var month = ("0" + (date.getMonth() + 1)).slice(-2);
var day = ("0" + (date.getDate())).slice(-2);
return year + '-' + month + '-' + day;
}
},
startCalendar: $('#rangestart'),
text: {
days: ['Nd', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'Sb'],
months: ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'],
monthsShort: ['Sty', 'Luty', 'Mar', 'Kwi', 'Maj', 'Czer', 'Lip', 'Sierp', 'Wrz', 'Paz', 'List', 'Grud'],
today: 'Dziś',
now: 'Teraz'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Date</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/jquery#3.3.1/dist/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui#2.7.2/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui#2.7.2/dist/semantic.min.js"></script>
<!-- jQuery Modal -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.css" />
<body>
<div class="ui">
<div class="ui segment">
<label>Zakres dat:</label>
<div class="ui calendar" id="rangestart" style="font-size: 10px; width: 48%;">
<div class="ui input left icon" style="font-size: 10px; width: 48%;">
<i class="calendar icon"></i>
<input type="text" name="build_daytime_start" placeholder="Od" style="font-size: 10px; width: 48%;">
</div>
</div>
<div class="ui calendar" id="rangeend" style="font-size: 10px; width: 48%;">
<div class="ui input left icon" style="font-size: 10px; width: 48%;">
<i class="calendar icon"></i>
<input type="text" name="build_daytime_end" placeholder="Do" style="font-size: 10px; width: 48%;">
</div>
</div><br>
</div>
</div>
<script src="index.js"></script>

Owl Curasol Not working in my date picker

Hi I have Date picker on select Date Month & Year it will show all Date in that Moth it working Fine
Now I want to add a Slider On that so that i used Owl Curasol after adding Curasol Date picker Stopped Working.
My Full code
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="http://www.jqueryscript.net/demo/Powerful-Customizable-jQuery-Carousel-Slider-OWL-Carousel/owl-carousel/owl.carousel.css">
<script type="text/javascript">
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";
$(function() {
$('.date-picker').datepicker( {
changeMonth: true,
changeYear: true,
showButtonPanel: true,
dateFormat: 'MM yy',
minDate: 0,
onClose: function(dateText, inst) {
$d = new Date(inst.selectedYear, parseInt(inst.selectedMonth)+1, 0).getDate();
$(this).datepicker('setDate', new Date(inst.selectedYear, inst.selectedMonth, 1));
html='';
for(i=1;i<=$d;i++){
console.log(inst.selectedYear+'-'+(parseInt(inst.selectedMonth)+1)+'-'+i);
d = new Date(inst.selectedYear+'-'+(parseInt(inst.selectedMonth)+1)+'-'+i);
console.log(d);
n = weekday[d.getDay()];
html += '<div class="datediv">div-'+i+'<br>'+n+'</div>';
}
$('#datecontent').html(html);
}
});
$(document).ready(function() {
$(document).live('click', '.datediv', function() { alert("hello"); });});
});
</script>
Html Code
<label for="startDate">Date :</label>
<input name="startDate" id="startDate" class="date-picker" />
<div id="datecontent" id="owl-demo">
</div>
Owl Script
<script src="http://www.jqueryscript.net/demo/Powerful-Customizable-jQuery-Carousel-Slider-OWL-Carousel/assets/js/jquery-1.9.1.min.js"></script>
<script src="http://www.jqueryscript.net/demo/Powerful-Customizable-jQuery-Carousel-Slider-OWL-Carousel/owl-carousel/owl.carousel.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#owl-demo").owlCarousel({
items : 10, //10 items above 1000px browser width
itemsDesktop : [1000,5], //5 items between 1000px and 901px
itemsDesktopSmall : [900,3], // betweem 900px and 601px
itemsTablet: [600,2], //2 items between 600 and 0;
itemsMobile : false // itemsMobile disabled - inherit from itemsTablet option
});
});
</script>
I got This error TypeError: $(...).datepicker is not a function
How to fix this issue. I think because of Jquery Conflict Only
How to over come on this??
Hope this helps!
You should use the add method in carousel to append items inside carousel.Also use refresh to run the slider after appending.
owl.trigger('add.owl.carousel', ['<div class="datediv">div-'+i+'<br>'+n+'</div>']).trigger('refresh.owl.carousel');
use remove method to remove items from carousel before appending new items.
for (var i =0; i< $('.owl-item').length; i++) {
owl.trigger('remove.owl.carousel', [i]).trigger('refresh.owl.carousel');
}
$(document).ready(function() {
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";
$('.date-picker').datepicker( {
changeMonth: true,
changeYear: true,
showButtonPanel: true,
dateFormat: 'MM yy',
minDate: 0,
onClose: function(dateText, inst) {
$d = new Date(inst.selectedYear, parseInt(inst.selectedMonth)+1, 0).getDate();
$(this).datepicker('setDate', new Date(inst.selectedYear, inst.selectedMonth, 1));
for (var i =0; i< $('.owl-item').length; i++) {
owl.trigger('remove.owl.carousel', [i]).trigger('refresh.owl.carousel');
}
for(i=1;i<=$d;i++){
console.log(inst.selectedYear+'-'+(parseInt(inst.selectedMonth)+1)+'-'+i);
d = new Date(inst.selectedYear+'-'+(parseInt(inst.selectedMonth)+1)+'-'+i);
console.log(d);
n = weekday[d.getDay()];
owl
.trigger('add.owl.carousel', ['<div class="datediv">div-'+i+'<br>'+n+'</div>'])
.trigger('refresh.owl.carousel');
}
}
});
$(document).on('click', '.datediv', function() { alert("hello"); });
var owl = $(".owl-demo");
owl.owlCarousel({
margin: 20,
items : 10, //10 items above 1000px browser width
itemsDesktop : [1000,5], //5 items between 1000px and 901px
itemsDesktopSmall : [900,3], // betweem 900px and 601px
itemsTablet: [600,2], //2 items between 600 and 0;
itemsMobile : false // itemsMobile disabled - inherit from itemsTablet option
});
});
.owl-item {
-webkit-tap-highlight-color: transparent;
position: relative;
min-height: 1px;
float: left;
-webkit-backface-visibility: hidden;
-webkit-touch-callout: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.0.0-beta.3/owl.carousel.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.0.0-beta.3/assets/owl.theme.default.min.css" rel="stylesheet"/>
<link href="https://owlcarousel2.github.io/OwlCarousel2/assets/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.0.0-beta.3/assets/owl.theme.default.min.css" rel="stylesheet"/>
<label for="startDate">Date :</label>
<input name="startDate" id="startDate" class="date-picker" />
<div id="datecontent" class="owl-demo">
</div>

SharpSpring - Prevent form from automatically appearing if user has filled out form (without relying on cookies)

Ok, this is related to the question I asked a short while ago: Silverstripe/PHP/jQuery - Once form has been filled out by user, prevent it from automatically appearing for each visit
Something has changed since then. Per request of the client, the form must not automatically appear if the user has already filled it out and has thus been placed into SharpSpring. Originally, I was creating a cookie on successful form submission using JavaScript. However, the latest concern is that it's not effective enough as cookies are registered only to certain devices and browsers, and users can clear their cookies at any time.
Essentially, the desired result is to prevent the form from automatically appearing if the user has been registered in SharpSpring (a separate domain) without having to rely on cookies.
Has anyone ever attempted something like this, checking to see if a user has submitted a form to another domain?
For reference, here is the form code I have setup:
<?php
/*
Plugin Name: SharpSpring Form Plugin
Description: A custom form plugin that is SharpSpring-compatible and uses HTML, CSS, jQuery, and AJAX
Version: 1.0
*/
define('SSCFURL', WP_PLUGIN_URL . "/" . dirname(plugin_basename(__FILE__)));
define('SSCFPATH', WP_PLUGIN_DIR . "/" . dirname(plugin_basename(__FILE__)));
function sharpspringform_enqueuescripts()
{
wp_enqueue_script('jquery-src', SSCFURL . '/js/jquery.js', array('jquery'));
wp_enqueue_script('jquery-ui', SSCFURL . '/js/jquery-ui.js', array('jquery'));
wp_enqueue_script('boootstrap', SSCFURL . '/js/bootstrap.js', array('jquery'));
wp_localize_script('sharpspringform', 'sharpspringformajax', array('ajaxurl' => admin_url('admin-ajax.php')));
}
add_action('wp_enqueue_scripts', 'sharpspringform_enqueuescripts');
function sharpspringform_show_form()
{
wp_enqueue_style( 'boilerplate', SSCFURL.'/css/boilerplate.css');
wp_enqueue_style( 'bootstrapcss', SSCFURL.'/css/bootstrap.css');
wp_enqueue_style( 'bookregistration', SSCFURL.'/css/Book-Registration.css');
wp_enqueue_style( 'formstyles', SSCFURL.'/css/styles.css');
?>
<div class="mobile-view" style="right: 51px;">
<a class="mobile-btn">
<span class="glyphicon glyphicon-arrow-left icon-arrow-mobile mobile-form-btn"></span>
</a>
</div>
<div class="slider register-photo">
<div class="form-inner">
<div class="form-container">
<form method="post" enctype="multipart/form-data" class="signupForm" id="browserHangFormPV">
<a class="sidebar">
<span class="glyphicon glyphicon-arrow-left icon-arrow arrow"></span>
</a>
<a class="closeBtn">
<span class="glyphicon glyphicon-remove"></span>
</a>
<h2 class="text-center black">Sign up for our newsletter.</h2>
<p class="errors-container light">Please fill in the required fields.</p>
<div class="success">Thank you for signing up!</div>
<div class="form-field-content">
<div class="form-group">
<input class="form-control FirstNameTxt" type="text" name="first_name" placeholder="*First Name"
autofocus="">
</div>
<div class="form-group">
<input class="form-control LastNameTxt" type="text" name="last_name" placeholder="*Last Name"
autofocus="">
</div>
<div class="form-group">
<input class="form-control EmailTxt" type="email" name="email" placeholder="*Email"
autofocus="">
</div>
<div class="form-group">
<input class="form-control CompanyTxt" type="text" name="company" placeholder="*Company"
autofocus="">
</div>
<div class="form-group submit-button">
<button class="btn btn-primary btn-block button-submit" type="button">SIGN ME UP</button>
<img src="/wp-content/plugins/sharpspring-form/img/ajax-loader.gif" class="progress" alt="Submitting...">
</div>
</div>
<br/>
<div class="privacy-link">
<a href="[privacy policy link]" class="already" target="_blank"><span
class="glyphicon glyphicon-lock icon-lock"></span>We will never share your information.</a>
</div>
</form>
<input type="hidden" id="gatewayEmbedID" value="<?php echo get_option( 'pv_signup_sharpspring_ID' ); ?>" />
<script type="text/javascript">
var embedID = document.getElementById("gatewayEmbedID").value;
var __ss_noform = __ss_noform || [];
__ss_noform.push(['baseURI', 'https://app-3QNAHNE212.marketingautomation.services/webforms/receivePostback/[redacted]']);
__ss_noform.push(['form', 'browserHangFormPV', embedID]);
__ss_noform.push(['submitType', 'manual']);
</script>
<script type="text/javascript" src="https://koi-3QNAHNE212.marketingautomation.services/client/noform.js?ver=1.24" ></script>
</div>
</div>
</div>
<?php
}
function sharpspringform_shortcode_func( $atts )
{
ob_start();
sharpspringform_show_form();
$output = ob_get_contents();
ob_end_clean();
return $output;
}
add_shortcode( 'sharpspringform', 'sharpspringform_shortcode_func' );
The form submission code with generates a cookie using JS:
;
(function ($) {
$(document).ready(function () {
var successMessage = $('.success');
var error = $('.errors-container');
var sharpSpringID = $('#gatewayEmbedID').val();
var submitbtn = $('.button-submit');
var SubmitProgress = $('img.progress');
var formdata = {};
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
submitbtn.click(function (e) {
resetErrors();
postForm();
});
function resetErrors() {
$('.signupForm input').removeClass('error-field');
}
function postForm() {
$.each($('.signupForm input'), function (i, v) {
if (v.type !== 'submit') {
formdata[v.name] = v.value;
}
});
submitbtn.hide();
error.hide();
SubmitProgress.show();
$.ajax({
type: "POST",
data: formdata,
url: '/wp-content/plugins/sharpspring-form/sharpsring-form-submission.php',
dataType: "json"
}).done(function (response) {
submitbtn.show();
SubmitProgress.hide();
if (response.errors) {
error.show();
var errors = response.errors;
errors.forEach(function (error) {
$('input[name="' + error + '"]').addClass('error-field');
})
}
else {
__ss_noform.push(['submit', null, sharpSpringID]);
setCookie('SignupSuccess', 'NewsletterSignup', 3650);
$('#browserHangFormPV')[0].reset();
$('.form-field-content').hide();
successMessage.show();
$('.button-submit').html("Submitted");
}
});
}
});
}(jQuery));
The jQuery code that sets up the form sliding animation and popup feature, as well as checks for the existence of the JS cookie created on successful form submit:
jQuery.noConflict();
(function ($) {
$(document).ready(function () {
//This function checks if we are in mobile view or not to determine the
//UI behavior of the form.
checkCookie();
window.onload = checkWindowSize();
var arrowicon = $(".arrow");
var overlay = $("#overlay");
var slidingDiv = $(".slider");
var closeBtn = $(".closeBtn");
var mobileBtn = $(".mobile-btn");
//When the page loads, check the screen size.
//If the screen size is less than 768px, you want to get the function
//that opens the form as a popup in the center of the screen
//Otherwise, you want it to be a slide-out animation from the right side
function checkWindowSize() {
if ($(window).width() <= 768) {
//get function to open form at center of screen
if(sessionStorage["PopupShown"] != 'yes' && !checkCookie()){
setTimeout(formModal, 5000);
function formModal() {
slidingDiv.addClass("showForm")
overlay.addClass("showOverlay");
overlay.removeClass('hideOverlay');
mobileBtn.addClass("hideBtn");
}
}
}
else {
//when we aren't in mobile view, let's just have the form slide out from the right
if(sessionStorage["PopupShown"] != 'yes' && !checkCookie()){
setTimeout(slideOut, 5000);
function slideOut() {
slidingDiv.animate({'right': '-20px'}).addClass('open');
arrowicon.addClass("glyphicon-arrow-right");
arrowicon.removeClass("glyphicon-arrow-left");
overlay.addClass("showOverlay");
overlay.removeClass("hideOverlay");
}
}
}
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function checkCookie() {
var user = getCookie("SignupSuccess");
if (user != "") {
return true;
} else {
return false;
}
}
/*
------------------------------------------------------------
Functions to open/close form like a modal in center of screen in mobile view
------------------------------------------------------------
*/
mobileBtn.click(function () {
slidingDiv.addClass("showForm");
slidingDiv.removeClass("hideForm");
overlay.addClass("showOverlay");
overlay.removeClass('hideOverlay');
mobileBtn.addClass("hideBtn");
});
closeBtn.click(function () {
slidingDiv.addClass("hideForm");
slidingDiv.removeClass("showForm");
overlay.removeClass("showOverlay");
overlay.addClass("hideOverlay")
mobileBtn.removeClass("hideBtn");
sessionStorage["PopupShown"] = 'yes'; //Save in the sessionStorage if the modal has been shown
});
/*
------------------------------------------------------------
Function to slide the sidebar form out/in
------------------------------------------------------------
*/
arrowicon.click(function () {
if (slidingDiv.hasClass('open')) {
slidingDiv.animate({'right': '-390px'}, 200).removeClass('open');
arrowicon.addClass("glyphicon-arrow-left");
arrowicon.removeClass("glyphicon-arrow-right");
overlay.removeClass("showOverlay");
overlay.addClass("hideOverlay");
sessionStorage["PopupShown"] = 'yes'; //Save in the sessionStorage if the modal has been shown
} else {
slidingDiv.animate({'right': '-20px'}, 200).addClass('open');
arrowicon.addClass("glyphicon-arrow-right");
arrowicon.removeClass("glyphicon-arrow-left");
overlay.addClass("showOverlay");
overlay.removeClass("hideOverlay");
}
});
});
}(jQuery));
I'm confused by the WordPress code here, rather than SilverStripe, it's not clear in your question which platform you're using.
Basically, if you want something more robust than cookies, you'll need to store the registration in the database and check it there (assuming the registration form is on your site). This means you handle the form submission on your site, send the data to the remote site and check the responses, and if all goes well, save the fact that the user has registered remotely into your database where you can check when deciding whether to show the form or not, next time.
If you don't have access to the registration form, or you want to also notice registrations made independently of your site, then you need to have an API you can query on the remote site in order to see if the user is registered.
I found a sharpspring API, but I'm not sure if it's relevant.

Meteor: Subscribed Colletion doesn't update automatically (Reactivity)

I'm facing the problem that adding data to a subscribed Collection doesn't automatically refresh the shown elements of a collection. If I add a new element the element show's up for a second and then disappears! Refreshing the browser (F5) and the new element shows up.
I put the subscription into Meteor.autorun but things kept beeing the same.
lists.html (client):
<<template name="lists">
<div class="lists col-md-12" {{!style="border:1px red solid"}}>
<!-- Checklist Adder -->
<form id="list-add-form" class="form-inline" role="form" action="action">
<div class="col-md-6">
<input class="form-control" id="list-name" placeholder="Neue Liste" required="required"/>
</div>
<button type="submit" class="btn btn-primary" id="submit-add">
<span class="glyphicon glyphicon-plus-sign"></span>
Neue Liste
</button>
</form>
<!-- Checklist Ausgabe -->
<ul>
<br/>
{{#each lists}}
<li style="position: relative;" id="{{this._id}}" data-id="{{_id}}" class="clickOnList">
<!--<input type="button" class="deleteLists" id="{{this._id}}" value="-" style="z-index: 999;"/> -->
<span id="{{this._id}}" data-id="{{_id}}" style="padding-left: 10px; vertical-align:middle;">{{this.name}}</span>
<form id="changerForm_{{_id}}" class="changeList-name-form" data-id="{{_id}}" style="visibility: hidden; position: absolute; top:0;">
<input id="changerText_{{_id}}" type="text" class="list_name" data-id="{{_id}}" value="{{this.name}}" />
</form>
{{#if ownerOfList this._id}}
<a data-toggle="modal" class="userForListModal" id="{{this.name}}" data-id="{{this._id}}" data-target="#userForListModal">
<span class="glyphicon glyphicon-user" id="{{this.name}}" style="color:black;"data-id="{{this._id}}"></span><span style="color:black;" id="{{this.name}}" data-id="{{this._id}}" style="font-size: small; vertical-align: super">{{memberCount this._id}}</span></a>
<div class="deleteLists" id="dLBtn_{{_id}}" data-id="{{this._id}}" style="float: right; padding-right: 5px; padding-top: 1px; visibility: hidden;">
<span class="deleteLists glyphicon glyphicon-minus-sign" data-id="{{this._id}}"></span>
</div>
{{else}}
<a class="userForListModal">
<span class="glyphicon glyphicon-user" style="color:black;"></span><span style="color:black;" style="font-size: small; vertical-align: super">{{memberCount this._id}}</span></a>
{{/if}}
<!-- <button type="submit" class="deleteLists btn btn-default btn-xs" id="dLBtn_{{_id}}" data-id="{{this._id}}" style="float: right;" > -->
</button>
</li>
{{/each}}
</ul>
</div>
<div class="modal fade" id="userForListModal" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="userForListModalLabel"></h4>
</div></template>
<div class="modal-body col-md-12">
<div id="userForListModalUsers">
</div>
<p>Neuen Benutzer zur Checkliste hinzufügen:</p>
<form id="list-addUser-form" class="form-inline" role="form" action="action">
<div class="col-md-12">
<div class="col-md-6">
{{inputAutocomplete settings id="name-list-addUser" class="input-xlarge" placeholder="Benutzer Name" required="required"}}
</div>
<div class="col-md-6">
<button type="submit" class="btn btn-secondary" id="submit-list-addUser">
<span class="glyphicon glyphicon-plus-sign"></span>
Benutzer hinzufügen
</button>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<div id="userForListModalerrorMessage" style="color:red; display: none; text-align:left"></div><button type="button" class="btn btn-default" data-dismiss="modal">Schließen</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</template>
<template name="userPill">
<span class="label" style="color:black">{{username}}</span>
lists.js (client):
Template.lists.lists = function(){ return Lists.find(); }
Lists = new Meteor.Collection("lists");
Deps.autorun(function() {
Meteor.subscribe('lists');
})
lists.js
var activeListName = "";
var activeListID = "";
Template.lists.lists = function()
{
return Lists.find();
}
Template.lists.memberCount = function(id)
{
var count = "";
Meteor.call("listMemberCount", id, function(error,result)
{
if (error) {
console.log("List not initialized:" + error.reason);
}
else
{
Session.set("countMember_"+id,result);
}
});
return Session.get("countMember_"+id);
}
Template.lists.ownerOfList = function(id)
{
return ( Meteor.userId() == Lists.findOne({_id : id}).owner);
}
Template.lists.settings = function()
{
return {
position: "top",
limit: 5,
rules: [
{
token: '',
collection: Meteor.users,
field: "username",
template: Template.userPill
}]
}
}
Template.lists.events({
'submit #list-add-form' : function(e, t) {
/* Checklisten ausgeben */
e.preventDefault();
var name = t.find('#list-name').value;
var id = new Meteor.Collection.ObjectID().valueOf();
var id_block = new Meteor.Collection.ObjectID().valueOf();
Lists.insert({_id : id, name : name, owner : Meteor.userId()});
Meteor.users.update({_id : Meteor.userId()}, {$addToSet :{lists : id}});
Listitems.insert({_id : id_block, name : "", items: []});
Lists.update(id, {$addToSet : {items : id_block}});
},
'click .clickOnList' : function(e)
{
/* Eventhandler fuer klick auf Checkliste */
Session.set("activeListId", e.target.id);
$("#"+e.target.id).siblings('li').removeClass("active");
$("#"+e.target.id).addClass("active");
},
'mouseover .clickOnList' : function (e,t) {
$( ".deleteLists" ).each(function( index, item ) {
if ( item.getAttribute("data-id") == e.target.getAttribute("data-id")) {
item.style.visibility = 'visible';
} else {
item.style.visibility = 'hidden';
}
});
},
'mouseleave .clickOnList' : function (e,t) {
$( ".deleteLists" ).each(function( index, item ) {
item.style.visibility = 'hidden';
});
},
'click .deleteLists' : function(e, t)
{
/* Eventhandler zum loeschen einer Checkliste */
var id = e.target.getAttribute("data-id");
Meteor.call("removeList", id);
console.log("test");
},
'click .changeListnameButton' : function(e,t) {
var id = e.target.getAttribute("data-id");
document.getElementById("changerForm_" + id).style.visibility = 'visible';
document.getElementById(id).style.visibility = 'hidden';
document.getElementById("changerText_" + id).focus();
},
'dblclick .clickOnList' : function(e,t){
var id = e.target.getAttribute("data-id");
document.getElementById("changerForm_" + id).style.visibility = 'visible';
document.getElementById(id).style.visibility = 'hidden';
document.getElementById("changerText_" + id).focus();
},
'submit .changeList-name-form' : function(e,t) {
e.preventDefault();
var id = e.target.getAttribute("data-id");
var text = document.getElementById("changerText_" + id).value;
if(text != '') {
Meteor.call("changeListName", id, text);
}
if (Session.get("activeListId", e.target.id) == id ) {
Session.set("activeListName", text);
}
document.getElementById("changerForm_" + id).style.visibility = 'hidden';
document.getElementById(id).style.visibility = 'visible';
},
'blur .list_name' : function(e,t) {
e.preventDefault();
var id = e.target.getAttribute("data-id");
var text = document.getElementById("changerText_" + id).value;
if((text != '') && (document.getElementById(id).style.visibility == 'hidden')) {
Meteor.call("changeListName", id, text);
}
if (Session.get("activeListId", e.target.id) == id ) {
Session.set("activeListName", text);
}
document.getElementById("changerForm_" + id).style.visibility = 'hidden';
document.getElementById(id).style.visibility = 'visible';
},
'click .userForListModal' : function(e,t) {
e.preventDefault();
activeListName = e.target.id;
activeListID = e.target.getAttribute("data-id");
//console.log(activeListID + " " + activeListName);
//console.log("New user for Liste" + Lists.findOne({_id : activeListID}).name);
userForList(activeListID);
$("#userForListModalLabel").html("Benutzer der Liste '"+ activeListName+ "'");
},
'submit #list-addUser-form' : function(e,t) {
e.preventDefault();
var newUser = $('#name-list-addUser').val();
Meteor.call("addUserToList", newUser, activeListID, function(error,result)
{
if (error) {
console.log(error.reason);
}
else
{
if (result == 1) {
$('#userForListModalerrorMessage').fadeIn(1000, function() {$(this).delay(1000).fadeOut(1000);});
$('#userForListModalerrorMessage').html("<div class=\"alert alert-danger\">Benutzer wurde nicht gefunden...</div>");
}
else if (result == 2) {
$('#userForListModalerrorMessage').fadeIn(1000, function() {$(this).delay(1000).fadeOut(1000);});
$('#userForListModalerrorMessage').html("<div class=\"alert alert-warning\">Benutzer ist Besitzer der Liste...</div>");
}
}
});
}
});
function userForList(id)
{
try
{
var owner = Lists.findOne({_id : id}).owner;
var members = Lists.findOne({_id : id}).member;
}
catch(e){
}
output = "<ul>";
output += "<li> Besitzer der Liste: <ul><li>" + owner + "</li></ul></li>";
output += "<li>Mitarbeiter der Liste: <ul>"
if (members != undefined) {
for(i=0; i<members.length; i++)
{
output+= "<li>" + members[i] + "</li>";
}
}
output += "</ul></li></ul>";
$('#userForListModalUsers').html(output);
}
main.js (server):
Lists = new Meteor.Collection("lists");
Meteor.publish("lists", function(){
var ListsOfUser = Meteor.users.findOne({_id : this.userId}).lists;
return Lists.find({_id :{ $in : ListsOfUser}});
});
Lists.allow({
insert : function(userID, list)
{
return (userID && (list.owner === userID));
},
//todo
update : function(userID)
{
return true;
},
//todo
remove : function(userID)
{
return true;
}
});
Thanks in advance!
I believe this is happening because the ListsOfUser variable in your Meteor.publish "lists" function is not a reactive data source. ListsOfUser is an array drawn from your result set, not a reactive cursor. Therefore it is not being invalidated server side when a user adds a new list on the client. From the Meteor docs (note the last sentence especially):
If you call Meteor.subscribe within a reactive computation, for example using
Deps.autorun,the subscription will automatically be cancelled when the computation
is invalidated or stopped; it's not necessary to call stop on subscriptions made
from inside autorun. However, if the next iteration of your run function subscribes
to the same record set (same name and parameters), Meteor is smart enough to skip a
wasteful unsubscribe/resubscribe.
ListsOfUser is not changing when a user adds a new list, so you are not being unsubscribed and resubscribed to the lists publication. (Note also that Meteor.users.findOne() is also not a reactive data source - you might want to switch it to Meteor.users.find() depending on how you go about making ListsOfUser reactive).
There are a few ways you could go about making the user lists reactive.
First, you could publish both the user cursor and the lists cursor, either separately or as an array in the same publish function, place both subscriptions in your Deps.autorun, and then fish out the user lists client side in a helper.
Meteor.publish("userWithLists", function(){
return Meteor.users.find(
{_id: this.userId},
{fields: {'lists': 1}}
);
});
Second, you could publish the static array of user lists as its own Collection and then use cursor.observe or cursor.observeChanges to track when it changes. While my understanding is that this is closest to the "correct" or "Meteor" way of doing it, it is also apparently quite verbose and I have not tried it. This tutorial goes into great detail about how you would tackle something like this: https://www.eventedmind.com/feed/aGHZygsphtTWELpKZ
Third, you could simply stick the user lists into your Session object, which is already reactive, and then publish your Lists.find() based on the Session, i.e.:
Meteor.publish("lists", function(lists){/* find code goes here */});
and
Deps.autorun(function(){
Meteor.subscribe("lists", Session.get("listsOfUser"));
});
This last one is probably an overuse / abuse of the Session object, particularly if your listsOfUser grows large, but should work as a hack.
I know this question is old, but still someone might be seeking for the answer. And the answer is Meteor.publishComposite available with a publish-composite package - https://atmospherejs.com/reywood/publish-composite
And there's an example there
Meteor.publishComposite('topTenPosts', {
find: function() {
// Find top ten highest scoring posts
return Posts.find({}, { sort: { score: -1 }, limit: 10 });
},
children: [
{
find: function(post) {
// Find post author. Even though we only want to return
// one record here, we use "find" instead of "findOne"
// since this function should return a cursor.
return Meteor.users.find(
{ _id: post.authorId },
{ limit: 1, fields: { profile: 1 } });
}
},
{
find: function(post) {
// Find top two comments on post
return Comments.find(
{ postId: post._id },
{ sort: { score: -1 }, limit: 2 });
},
children: [
{
find: function(comment, post) {
// Find user that authored comment.
return Meteor.users.find(
{ _id: comment.authorId },
{ limit: 1, fields: { profile: 1 } });
}
}
]
}
]
});
I am rather new to meteor but, in your server code, should it not be:
var ListsOfUser = Meteor.users.findOne({_id : Meteor.userId}).lists;
rather than:
var ListsOfUser = Meteor.users.findOne({_id : Meteor.userId}).lists;

Multiple forms in one page using jQuery-File-Upload

I am trying to add multiple forms which associates different types of document but when I try to add a file from second form it shows up in primary form submission and also for process event. Please advise what could be wrong here.
<form accept-charset="UTF-8" action="/docs/1" class="documents" enctype="multipart/form-data" id="new_document" method="post">
<div class="input-append" >
<input class="filestyle" did="pdoc" id="document_doc_file" name="document[doc_file]" type="file" uid="template-upload-1" />
</div>
<input id="document_doc_type" name="document[doc_type]" type="hidden" value="1" />
</form><script id="template-upload-1" type="text/x-tmpl">
<div class="upload">
{%=o.name%}<span class="pull-right" id="pbar">Uploading 0%</span></span>
<div class="progress"><div class="bar" style="width: 0%"></div></div>
</div>
</script>
<div id="pdoc"></div>
<form accept-charset="UTF-8" action="/docs/1" class="documents" enctype="multipart/form-data" id="new_document" method="post">
<div class="input-append" >
<input class="filestyle" did="ldoc" id="document_doc_file" name="document[doc_file]" type="file" uid="template-upload-2" />
</div>
<input id="document_doc_type" name="document[doc_type]" type="hidden" value="2" />
</form><script id="template-upload-2" type="text/x-tmpl">
<div class="upload">
{%=o.name%}<span class="pull-right" id="pbar">Uploading 0%</span></span>
<div class="progress"><div class="bar" style="width: 0%"></div></div>
</div>
</script>
<div id="ldoc"></div>
<script type="text/javascript">
$(function () {
$('.documents').fileupload({
dropZone: $(this).find('input:file'),
dataType: 'script',
fileInput: $(this).find('input:file'),
singleFileUploads: true,
add: function(e, data) {
var file, types;
types = /(\.|\/)(pdf|xls|xlsx)$/i;
file = data.files[0];
if (types.test(file.type) || types.test(file.name)) {
uid = $(this).find(':file').attr('uid');
if ($('#' +uid).length > 0) {
data.context = $(tmpl(uid, file).trim());
}
did = $(this).find(':file').attr('did');
$('#' + did).append(data.context);
data.submit();
} else {
alert("" + file.name + " is not a pdf or an excel file.");
}
},
progress: function (e, data) {
if (data.context) {
var progress = parseInt(data.loaded / data.total * 100, 10);
data.context.find('.bar').css('width', progress + '%');
if (progress < 100) {
data.context.find('#pbar').html('Uploading ' + progress + '% ...');
} else {
data.context.find('#pbar').html('Upload Complete');
}
}
}
});
$(document).bind('drop dragover', function (e) {
e.preventDefault();
});
});
</script>
The variable 'this' that you use is ambiguous and might be the cause for the problem.
The simplest solution would be to initiate each form separately - in a for loop over the results of $('.documents') or if you are expecting only two forms just give each of them an id doc1 and doc2 and build the fileupload for each.