I have 2 datepickers which use bootstrap and knockout to bind data.
The below is my html template for datepickers and I have added the options
<div class="clearfix form-inline marginBottom10px row col-md-12 fontWeightNormal" role="form">
<span class="col-md-2 col-xs-12 pull-left paddingLeft0px">
<label class="control-label paddingTop5px" for="datespanFromfilter">
From
</label>
</span>
<div class="form-group col-md-3 paddingLeft0px paddingRight0px">
<span class="date input-group" id="datespanFromfilter" data-date-format="DD/MM/YYYY" data-bind="datetimepicker :dateSpanFrom, datePickerOptions : {todayBtn : true, pickTime: false, format: 'DD/MM/YYYY', maxDate : new Date(), orientation: 'left'}, enable: !refreshingPage()">
<input class="form-control" id="datespanFromfilterinput" placeholder="DD/MM/YYYY" data-bind="value: dateSpanFrom, enable: !refreshingPage()" disabled />
<span class="input-group-addon" data-bind="enable: !refreshingPage()">
<span class="glyphicon glyphicon-calendar" data-bind="enable: !refreshingPage()"></span>
</span>
</span>
</div>
<div class="col-md-1 ">
<label class="control-label paddingLeft0px paddingTop5px" for="datespanTofilter">
To
</label>
</div>
<div class="form-group col-md-3 paddingLeft0px paddingRight0px">
<span class="date input-group" id="datespanTofilter" data-date-format="DD/MM/YYYY" data-bind="datetimepicker : dateSpanTo, datePickerOptions : {todayBtn : true, pickTime: false, orientation: 'left', format : 'DD/MM/YYYY', maxDate : new Date()}, enable: !refreshingPage()">
<input class="form-control" placeholder="DD/MM/YYYY" data-bind="value: dateSpanTo, enable: !refreshingPage()" disabled />
<span class="input-group-addon" data-bind="enable: !refreshingPage(), disabled: !refreshingPage()">
<span class="glyphicon glyphicon-calendar" data-bind="enable: !refreshingPage()"></span>
</span>
</span>
</div>
</div>
This is how I handle the Datepicker in knockout
ko.bindingHandlers.datetimepicker = {
/// <summary>The customized event handler datepicker.</summary>
init: function (element, valueAccessor, allBindingsAccessor) {
allBindings = allBindingsAccessor();
var options = allBindings.datePickerOptions || {};
ko.utils.extend(options, allBindings.datePickerOptions)
$(element).datetimepicker(options).on("change.dp", function (evntObj) {
self.errorMessage("");
var observable = valueAccessor();
if (evntObj.timeStamp !== undefined) {
var picker = $(this).data("DateTimePicker");
var d = picker.getDate();
if (d != null && d != '') {
observable(d.format(picker.format));
}
else {
observable(moment(settings.defaultUtcDate).format("DD/MM/YYYY"));
}
}
});
},
update: function (element, valueAccessor) {
self.errorMessage("");
var thisFormat = 'DD/MM/YYYY';
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).data("DateTimePicker").setDate(moment(value).format(thisFormat));
}
};
but in options only Format and pickTime seems to be working fine, I also need to show TodayButton and correct the orientation.
But these to options are not working if i change the value
Will someone help me to solve the issue
Related
I have a problem again and do not really get on with it.
I would like to know that you can enter an appointment and I already have the following script.
Unfortunately, no entries are entered in the calendar :-( can someone help me there?
I've already asked quite a bit about google and co. Unfortunately, I come to no real point of help.
can it be that I already use the eventRender and then want to use it again below?
here once my code:
<link rel='stylesheet' href='kalender2/fullcalendar.css' />
<script src='kalender2/fullcalendar.js'></script>
<script src='kalender2/locale/de.js'></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="kalender2/lib/hour.js"></script>
<script>
var CalenderEvent;
var datenPruefenDatenSenden;
var terminPruefenDatenSenden;
var datenPruefenDatenVerarbeiten;
var termin_nachberechnung;
var TerminAddZeit;
var AddEventToCalener;
$(document).ready(function() {
function DeleteEvent(id){
SendFormData(id,'',"delete");
$('#calendar').fullCalendar('removeEvents',id);
}
var initialLocaleCode = 'de';
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listWeek'
},
dayClick: function(date, jsEvent, view) {
$('#calenderAdEvent').modal('show');
$('#start_date_add_day').val(date.format('DD.MM.YYYY'));
$('#start_date_add_time').val(date.format('HH:mm'));
},
eventRender: function(eventObj, $el) {
$el.popover({
title: eventObj.title,
content: eventObj.description,
trigger: 'hover',
placement: 'top',
container: 'body'
});
$el.html(eventObj.title + '<span class="removebtn" onclick="DeleteEvent('+eventObj.id+');" id="Delete">X</span>');
$el.find(".removebtn").click(function() {
$('#calendar').fullCalendar('removeEvents',eventObj.id);
});
},
businessHours: [
<?php echo $Offen;?>
],
eventDrop: function( event, delta, revertFunc, jsEvent, ui, view ) {
var Alertback = SendFormData(event.id,$.fullCalendar.moment(event.start._d), $.fullCalendar.moment(event.end._d),"update");
alert(Alertback);
},
eventResize: function( event, delta, revertFunc, jsEvent, ui, view ) {
var Alertback = SendFormData(event.id,$.fullCalendar.moment(event.start._d), $.fullCalendar.moment(event.end._d),"update");
alert(Alertback);
},
timezone: 'Europe/Berlin',
nowIndicator: true,
now: '<?php echo date("Y-m-d", time() ) .'T'. date("H:i:s");?>',
locale: 'de',
buttonIcons: true, // show the prev/next text
defaultView: 'agendaWeek',
defaultDate: '<?php echo date("Y-m-d", time() );?>',
navLinks: true, // can click day/week names to navigate views
editable: true,
eventLimit: true, // allow "more" link when too many events
allDaySlot: true,
droppable: true,
events: [
<?php echo $aus;?>
],
timeFormat: 'H(:mm)',
eventClick: function(event, jsEvent, view) {
CalenderEvent = event;
$('#id_termin').val(event.id);
$('#name').val(event.title);
$('#Time_Event').val(event.TimeEvent);
$('#description').val(event.description);
$('#start_date_day').val(moment(event.start).format('DD.MM.YYYY'));
$('#start_date_time').val(moment(event.start).format('HH:mm'));
if(event.end) {
$('#end_date_day').val(moment(event.end).format('DD.MM.YYYY'));
$('#end_date_time').val(moment(event.end).format('HH:mm'));
} else {
$('#end_date_day').val(moment(event.end).format('DD.MM.YYYY'));
$('#end_date_time').val(moment(event.end).format('HH:mm'));
}
$('#event_id').val(event.id);
$('#calenderEditEvent').modal();
}
});
datenPruefenDatenSenden = function(){
var start = $('#start_date_day').val()+'//'+$('#start_date_time').val();
var end = $('#end_date_day').val()+'//'+$('#end_date_time').val();
var erg = SendFormData($("#id_termin").val(),start,end,'TerminEditSave');
$('#calenderEditEvent').modal('hide');
CalenderEvent.start = moment($('#start_date_day').val()+' '+$('#start_date_time').val(), "DD.MM.YYYY HH:MM");
CalenderEvent.end = moment($('#end_date_day').val()+' '+$('#end_date_time').val(), "DD.MM.YYYY HH:MM");
$('#calendar').fullCalendar('updateEvent', CalenderEvent);
}
datenPruefenDatenVerarbeiten = function (daten){
if(daten == 1){$('#submit_erg').html('<div class="alert alert-danger">Terminüberschneidung</div><button class="btn btn-info" onclick="terminPruefenDatenSenden();">Erneut prüfen</button>');}
$('#submit_button').html('<button type="button" class="btn btn-warning" onclick="datenPruefenDatenSenden();">Termin Speichern</button>');
}
terminPruefenDatenSenden = function (){
$('#submit_erg').html('');
var start = $('#start_date_day').val()+'//'+$('#start_date_time').val();
var end = $('#end_date_day').val()+'//'+$('#end_date_time').val();
var erg = SendFormData($("#id_termin").val(),start,end,'pruefen');
}
termin_nachberechnung = function (){
var TimePlus = new Hour($('#Time_Event').val());
var zeit = new Hour($('#start_date_time').val()+':00');
$('#end_date_time').val(zeit.add(TimePlus));
}
TerminAddZeit = function (){
var erg = SendFormData($("#id_termin_add").val(),$('#start_date_add_time').val(),'','TimePlus');
$('#start_date_add_time_end').val(erg);
}
AddEventToCalener = function(){
var Start = moment($('#start_date_add_day').val()+' '+$('#start_date_add_time').val(), "DD.MM.YYYY HH:MM");
var End = moment($('#start_date_add_day').val()+' '+$('#start_date_add_time_end').val(), "DD.MM.YYYY HH:MM");
var event = new Object();
event = {
title: 'Testtermin',
start: Start,
end: End,
allDay: false,
};
console.log(event);
$('#calendar').fullCalendar('renderEvent', event);
}
});
$(function() {
$('[data-toggle="datepicker_bearbeiten"]').datepicker({
autoHide: true,
format: 'dd.mm.yyyy',
zIndex: 2048,
});
});
function SendFormData(id,start,end,aufruf){
var erg;
if(aufruf == 'update'){start = start/1000;end = end/1000;}
$.ajax({type: "post",url: "kalender2/kalender.class.php",data : {id : id,sta : start,end : end,aufruf : aufruf}
}).done(function( dataEnd ){if(aufruf == 'pruefen'){datenPruefenDatenVerarbeiten(dataEnd);}erg = dataEnd;});
return erg;
}
</script>
<div id='calendar'></div>
<div class="modal" id="calenderAdEvent" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Termin eintragen</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Datum</span>
</div>
<input type="text" id="start_date_add_day" name="start_date_add_day" class="form-control">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Dienstleistung</span>
</div>
<select class="custom-select" id="id_termin_add">
<option selected>bitte wählen</option>
<?php echo $dienst;?>
</select>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Termin von</span>
</div>
<input type="text" id="start_date_add_time" name="start_date_add_time" class="form-control">
<div class="input-group-append">
<span class="input-group-text">-</span>
</div>
<input type="text" name="start_date_add_time_end" id="start_date_add_time_end" class="form-control">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Kundenname</span>
</div>
<input type="text" list="kunden" id="KundenName" name="KundenName" class="form-control" onkeyup="KundenListe();">
<datalist id="kunden">
<?php echo $KundenListe;?>
</datalist>
<div class="input-group-append">
<span class="input-group-text">oder KN</span>
</div>
<input type="text" name="KIDTerminBuchen" id="KIDTerminBuchen" class="form-control">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="AddEventToCalener();">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal" id="calenderEditEvent" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Termin bearbeiten</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">Start</span>
</div>
<input type="text" name="termin" id="start_date_day" class="form-control" data-toggle="datepicker_bearbeiten">
<input type="text" id="start_date_time" onkeyup="termin_nachberechnung('Hallo');" class="form-control datetimepicker-input" data-target="#datetimepicker3" data-target-input="nearest"/>
<div class="input-group-append">
<span class="input-group-text">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHfSURBVEhLzZW9L91hFMcvaby0HUi9VKJNE2ZbvWxERQdTO5h0YLCQWLAykehUJAYWIWZSjBJtojqQog1TUyotwl8g+HyfU7fXffm9Mfgkn+ScJzf3/J7n+Z3zi90HHuBrnMBveITneIhfcRhrMDJvcA8/Yw9W4RPMxqdYiwP4A1cwVLFcnMYNrNdCAtrZOwvjqGgb7mOfFvzIwU84g3laSOI5/rIwhTJcw1GXeaAdqECWy1LxKiIeok6gy2VpeIubmG4H1/gVEeX4FytcloDOehcbXJaZIEWE7mbOwv/oNV210JOgRXQap1jisn+oD/Sa+hG0iJjFDguNLVQf+BGmiApMWmgcoxrNDz3dBfa7zJsmXLbQ0KhQU3mhJlWBS9zWgg/VqL6J8wdLLcxIJ+p3O9iqBR9acN5CYx01izKhAj/xhcuCoYYct9AYwkELU4hSQHxEDdk4Or/vmHwvypcwbIFiPMPHLktA4zp5wkblA45YeBPtRuNa0/Q26G41uwpdloZe/IKPXBYeNetvbHSZB2Oocf3MZcGpwwO8MUq80Oun77l2lq8FD4pQD6bv/isthKESNa5PUB+ydmzGl6hG68ZF1LR9jwUYGY1rHcEU6k/VuAuoRlMfRL2/uyQWuwKiRlWN6WWKKwAAAABJRU5ErkJggg==">
</span>
</div>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">Ende</span>
</div>
<input type="text" name="termin" id="end_date_day" class="form-control" data-toggle="datepicker_bearbeiten">
<input type="text" id="end_date_time" class="form-control datetimepicker-input" data-target="#datetimepicker3" data-target-input="nearest"/>
<div class="input-group-append">
<span class="input-group-text">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHfSURBVEhLzZW9L91hFMcvaby0HUi9VKJNE2ZbvWxERQdTO5h0YLCQWLAykehUJAYWIWZSjBJtojqQog1TUyotwl8g+HyfU7fXffm9Mfgkn+ScJzf3/J7n+Z3zi90HHuBrnMBveITneIhfcRhrMDJvcA8/Yw9W4RPMxqdYiwP4A1cwVLFcnMYNrNdCAtrZOwvjqGgb7mOfFvzIwU84g3laSOI5/rIwhTJcw1GXeaAdqECWy1LxKiIeok6gy2VpeIubmG4H1/gVEeX4FytcloDOehcbXJaZIEWE7mbOwv/oNV210JOgRXQap1jisn+oD/Sa+hG0iJjFDguNLVQf+BGmiApMWmgcoxrNDz3dBfa7zJsmXLbQ0KhQU3mhJlWBS9zWgg/VqL6J8wdLLcxIJ+p3O9iqBR9acN5CYx01izKhAj/xhcuCoYYct9AYwkELU4hSQHxEDdk4Or/vmHwvypcwbIFiPMPHLktA4zp5wkblA45YeBPtRuNa0/Q26G41uwpdloZe/IKPXBYeNetvbHSZB2Oocf3MZcGpwwO8MUq80Oun77l2lq8FD4pQD6bv/isthKESNa5PUB+ydmzGl6hG68ZF1LR9jwUYGY1rHcEU6k/VuAuoRlMfRL2/uyQWuwKiRlWN6WWKKwAAAABJRU5ErkJggg==">
</span>
</div>
</div>
<input type="hidden" id="id_termin">
<input type="hidden" id="Time_Event">
</div>
<div class="modal-footer">
<span id="submit_erg"></span>
<span id="submit_button"><button type="button" class="btn btn-info" onclick="terminPruefenDatenSenden();">Prüfen</button></span>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
I have done some more tests. As soon as I take the eventRender: function (eventObj, $ el) { ........ }, out, I use the function AddEventToCalener = function () { $ ('# calendar'). fullCalendar ('renderEvent', { title: 'dynamic event', start: '2018-11-26', allDay: true }); } successfully.
But as soon as I insert eventRender again, I get the following message:
Error: TOOLTIP: Option "content" provided type "undefined" but
expected type "(string | element | function)"
So the problem is still that the event is not entered in the calendar. the console gives me the following with console.log
{…} allDay: false end: Object { _isAMomentObject: true, _i: "26.11.2018 12:00", _f: "DD.MM.YYYY HH:MM", … } start: Object { _isAMomentObject: true, _i: "26.11.2018 11:30", _f: "DD.MM.YYYY HH:MM", … } title: "Testtermin" <prototype>: Object { … }
Your code is failing to add the event because of a missing field.
In the eventRender function you create a popover, and the popover tries to read a property called "description" from the event:
content: eventObj.description
However, your AddEventToCalener() function defines an event like this:
event = {
title: 'Testtermin',
start: Start,
end: End,
allDay: false,
};
In this event there is no "description" field specified. This means it's undefined, and therefore when eventRender runs and tries to create the popover, it crashes because it can't read that field. (I know this from the error message - it appears the popover code is programmed to check the type of the value given in the "content" option, and will only accept strings, HTML elements, or functions - it will not accept undefined variables.)
For the eventRender/popover code to work you need to specify something for the field, even if it's just an empty string:
event = {
title: 'Testtermin',
start: Start,
end: End,
allDay: false,
description: ""
};
Also, your momentJS parsing string is incorrect - instead of
"DD.MM.YYYY HH:MM"
it should be
"DD.MM.YYYY HH:mm"
because MM signifies months, whereas mm signifies minutes. See http://momentjs.com/docs/#/parsing/string-format/ for documenation.
Fullcalendar v5
let calendarEl = document.getElementById('calendar');
let calendar = new FullCalendar.Calendar(calendarEl, {
dateClick: function(date) {
console.log(date);
console.log(date.jsEvent);
console.log(date.view);
},
})
When i'm trying to locate 'datepicker' in protractor, i found every time a new date the instance/object of 'datepicker' created with same class='.datepicker' with incremented value of z-index, but i want to handle the single object or at least old object/instance should get destroyed to locate new object.
Following code/snippets will depicts the above explanation.
<!-- HTML CODE -->
<div class="form-group">
<label>Start Date</label>
<div class="input-group date form_datetime"
data-date- format="yyyy-mm-dd hh:ii"
data-link-field="dtp_input1">
<input class="form-control" size="16" ng-class="submitted:myScheduleForm.submitted}" ng-model="pollConfigInfo.startTime" readonly="" type="text" required=""/>
<span class="input-group-addon">
<i class="fa fa-times" style="cursor: pointer"></i>
</span>
<span class="input-group-addon">
<i class="fa fa-calendar" style="cursor: pointer"></i>
</span>
</div>
<input id="dtp_input1" value="" type="hidden"/>
</div>
JAVASCRIPT CODE:
<script>
$('.form_datetime').datetimepicker({
//language: 'fr',
weekStart: 1,
todayBtn: 1,
autoclose: 1,
todayHighlight: 1,
startView: 2,
forceParse: 0,
showMeridian: 1
});
</script>
Protractor Snippet to select datepicker
selectStartTimeAndDate:
{
value : function()
{
var picker = element(by.css('.fa-calendar'));
picker.click();
browser.driver.sleep(2000);
var day = element(by.cssContainingText('div.datetimepicker-days > table.table-condensed > tbody > tr > td.day','1'));
day.click();
var hour = element(by.cssContainingText('span.hour_am','12'));
hour.click();
var min = element(by.cssContainingText('span.minute','12:00'));
min.click();
}
},
I'm not able to locate the 'picker' class due to this:
I got answer by making some changes in the protractor snippet like this:
var picker = element(by.css('.fa-calendar'));
picker.click();
browser.driver.sleep(2000);
var day = element.all(by.cssContainingText('div.datetimepicker-days > table.table-condensed > tbody > tr > td.day','1')).last();
day.click();
var hour = element.all(by.cssContainingText('span.hour_am','12')).last();
hour.click();
var min = element.all(by.cssContainingText('span.minute','12:00')).last();
min.click();
In the code below when I click edit the other boxes loose the edited icon until cancel is clicked.
Is there away that I can have it so that if a box is not being edited it keeps the normal state of code?
The library I am using is: https://vitalets.github.io/x-editable/
Normal State:
When an edit button is clicked:
jQuery:
/* X-Editable */
$(function(){
$.fn.editable.defaults.mode = 'inline';
$.fn.editable.defaults.params = function (params) {
params._token = $("#_token").data("token");
return params;
};
var dataURL = $('.updateField').data('url');
var inputName = $('.updateField').attr("name");
$('.updateField').editable({
type: 'text',
url: dataURL,
name: inputName,
placement: 'top',
title: 'Enter public name',
toggle:'manual',
send:'always',
ajaxOptions:{
dataType: 'json'
}
});
$('.edit').click(function(e){
var container = $(this).closest('.input-group'); // !!
var input = container.find('.updateField');
var inputName = input.attr('name');
var dataURL = input.data('url');
console.log(inputName);
e.stopPropagation();
container.find('.updateField').editable('toggle'); // !!
container.find('.edit').hide(); // !!
});
$(document).on('click', '.editable-cancel, .editable-submit', function(e){
$(e.target).closest('.input-group').find('.edit').show(); // !!
})
//ajax emulation. Type "err" to see error message
$.mockjax({
url: '/post',
responseTime: 100,
response: function(settings) {
if(settings.data.value == 'err') {
this.status = 500;
this.responseText = 'Validation error!';
} else {
this.responseText = '';
}
}
});
});
Normal State HTML:
<input name="__RequestVerificationToken" type="hidden" value="{{ csrf_token() }}" />
<div class="box-body">
<div class="form-group">
<label class="col-sm-2 control-label" for="siteName">Website Name</label>
<div class="col-sm-3">
<div class="input-group">
<input class="form-control updateField" data-url="{{ route('generalDataSubmit', 1)}}" data-title="Website Name" name="siteName" placeholder="Email" type="input" value="{{ old('siteName', $siteSettingsData->siteName)}}"> <span class="input-group-btn"><button class="btn btn-default edit" type="button"><span class="glyphicon glyphicon glyphicon-pencil"></span></button></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="siteEmail">Website E-Mail Address</label>
<div class="col-sm-3">
<div class="input-group">
<input class="form-control updateField" data-url="{{ route('generalDataSubmit', 1) }}"data-title="Website E-Mail Address" name="siteEmail" placeholder="Site E-Mail" type="email" value="{{ old('siteEmail', $siteSettingsData->siteEmail) }}"> <span class="input-group-btn"><button class="btn btn-default edit" type="button"><span class="glyphicon glyphicon glyphicon-pencil"></span></button></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="siteCopyright">Website Copyright</label>
<div class="col-sm-3">
<div class="input-group">
<input class="form-control updateField" data-url="{{ route('generalDataSubmit', 1)}}" data-title="Website Copyright" name="siteCopyright" placeholder="Site Copyright" type="input" value="{{ old('siteCopyright', $siteSettingsData->siteCopyright)}}"> <span class="input-group-btn"><button class="btn btn-default edit" type="button"><span class="glyphicon glyphicon glyphicon-pencil"></span></button></span>
</div>
</div>
</div>
</div>
<!-- /.box-body -->
try changing the following line:
container.find('.edit').hide();
to
$(this).hide();
It seems like you are using some bootstrap design template.From my point of view the code
$('.edit').click(function(e){
var container = $(this).closest('.input-group'); // !!
var input = container.find('.updateField');
var inputName = input.attr('name');
var dataURL = input.data('url');
console.log(inputName);
e.stopPropagation();
container.find('.updateField').editable('toggle'); // !!
container.find('.edit').hide(); // !!
});
seems ok.I don't understand the line container.find('.updateField').editable('toggle'); // !! in the function.Are you using some kind of library. My suggestion is to remove that line from your code and test.Also check whether you are getting the correct value of inputName outputted.And finally check in the console for any errors when you click the edit button.
Try using $(e) instead of $(this) in the following code:
$('.edit').click(function(e){
//var container = $(this).closest('.input-group');
var container = $(e).closest('.input-group');
var input = container.find('.updateField');
var inputName = input.attr('name');
var dataURL = input.data('url');
console.log(inputName);
e.stopPropagation();
container.find('.updateField').editable('toggle'); // !!
container.find('.edit').hide(); // !!
});
I have situation where I would like user to select start date and restrict the end date to either selected start date of the day next to selected start date.
How can I do this on boostrap datepickers for start and end date
Download bootstrap-datepicker.js from here
HTML Code
<div class="col-md-6 ">
<div class="form-group">
<label>Start Date</label>
<div class='input-group date'>
<input type='text' id='datecheckin1' class="form-control" placeholder="DD/MM/YYYY" data-date-format="dd/M/yyyy" readonly />
<span class="input-group-addon" ><span class="glyphicon glyphicon-calendar"></span></span>
</div>
</div>
</div>
<div class="col-md-6 ">
<div class="form-group">
<label>End Date</label>
<div class='input-group date'>
<input type='text' id='datecheckout1' class="form-control" placeholder="DD/MM/YYYY" data-date-format="dd/M/yyyy" readonly />
<span class="input-group-addon" ><span class="glyphicon glyphicon-calendar"></span></span>
</div>
</div>
</div>
Java Script code
var nowTemp = new Date();
var now = new Date(nowTemp.getFullYear(), nowTemp.getMonth(), nowTemp.getDate(), 0, 0, 0, 0);
var checkin2 = $('#datecheckin1').datepicker({
onRender: function (date) {
//Here we restrict the date date of start datepicker
return date.valueOf() < now.valueOf() ? 'disabled' : '';
}
}).on('changeDate', function (ev) {
var newDate = new Date(ev.date);
newDate.setDate(newDate.getDate() + 1);
//Here we set the date of end datepicker
checkout2.setValue(newDate);
checkin2.hide();
$('#datecheckout1')[0].focus();
}).data('datepicker');
var checkout2 = $('#datecheckout1').datepicker({
onRender: function (date) {
//Here we restrict the date of enddatepicker
return date.valueOf() <= checkin2.date.valueOf() ? 'disabled' : '';
}
}).on('changeDate', function () {
checkout2.hide();
}).data('datepicker');
Hope this will help you.
$('#dtpicker').datepicker({
endDate: '-1d'
}).on(....
I have a form where there is a need for me to have 2 or more date fields for different things. I tried the Angular UI Bootstrap which works fine when I have only 1 date field in the form. But it stops working if I have multiple date fields and I dont know the easier method to get this to work.
This is my HTML sample:
<label>First Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" name="dt" ng-model="formData.dt" is-open="opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
<label>Second Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" name="dtSecond" ng-model="formData.dtSecond" is-open="opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
My JS is:
myApp.controller('DatePickrCntrl', function ($scope) {
$scope.today = function() {
$scope.formData.dt = new Date();
};
$scope.today();
$scope.showWeeks = true;
$scope.toggleWeeks = function () {
$scope.showWeeks = ! $scope.showWeeks;
};
$scope.clear = function () {
$scope.dt = null;
};
// Disable weekend selection
$scope.disabled = function(date, mode) {
return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
};
$scope.toggleMin = function() {
$scope.minDate = ( $scope.minDate ) ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'shortDate'];
$scope.format = $scope.formats[0];
});
I implemented based on the sample here. The problem I have here is:
1) When one of the date field is clicked, the pop-up datepicker is messed up and seems to show 2 datepicker in 1.
2) When I remove is-open="opened" attribute, the pop-up window seems to work fine. But without is-open="opened", the ng-click="open($event) for the button doesnt work.
3) Since each of the date fields have different ng-models, I am unable to set default dates for any date fields except for the first one with ng-model="formData.dt"
The only long way to resolve this that I can think of is to separate the controller for each date field.
I would like to know how others implement multiple date fields in 1 form itself when using Angular UI Bootstrap.
I have 30 in one form one controller no problem. use the same concept if you need it on ng-repeat.
<label>First Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}"
name="dt" ng-model="formData.dt" is-open="datepickers.dt"
datepicker-options="dateOptions" ng-required="true"
close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event,'dt')">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
<label>Second Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}"
name="dtSecond" ng-model="formData.dtSecond"
is-open="datepickers.dtSecond" datepicker-options="dateOptions"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event,'dtSecond')">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
myApp.controller('DatePickrCntrl', function ($scope) {
$scope.datepickers = {
dt: false,
dtSecond: false
}
$scope.today = function() {
$scope.formData.dt = new Date();
// ***** Q1 *****
$scope.formData.dtSecond = new Date();
};
$scope.today();
$scope.showWeeks = true;
$scope.toggleWeeks = function () {
$scope.showWeeks = ! $scope.showWeeks;
};
$scope.clear = function () {
$scope.dt = null;
};
// Disable weekend selection
$scope.disabled = function(date, mode) {
return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
};
$scope.toggleMin = function() {
$scope.minDate = ( $scope.minDate ) ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event, which) {
$event.preventDefault();
$event.stopPropagation();
$scope.datepickers[which]= true;
};
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'shortDate'];
$scope.format = $scope.formats[0];
});
// ***** Q2 ***** somemodel can be just an array [1,2,3,4,5]
<div ng-repeat="o in somemodel">
<label>Date Label</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}"
name="dt{{o}}" ng-model="datepickers.data[o]"
is-open="datepickers.isopen[o]" datepicker-options="datepickers.option"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event,o)">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
myApp.controller('DatePickrCntrl', function ($scope) {
$scope.datepickers = {
data: {},
options: {
'year-format': "'yy'",
'starting-day': 1
},
isopen: {}
}
$http.get("get/data/for/some/model", function(result) {
$scope.somemodel = result;
for (var i = 0; i < result.length; i++) {
$scope.datepickers.isopen[result] = false;
$scope.datepickers.data[result] = new Date(); //set default date.
}
});
// fill in rest of the function
});
Simpler Solution. Requires only modding the HTML and can be used in a ng-repeat if you like. Just be creative with what you name the opened
Stick this in your Controller:
$scope.calendar = {
opened: {},
dateFormat: 'MM/dd/yyyy',
dateOptions: {},
open: function($event, which) {
$event.preventDefault();
$event.stopPropagation();
$scope.calendar.opened[which] = true;
}
};
HTML:
<div class="form-group row">
<div class="col-lg-6">
<label for="formDOB">Date of Birth</label>
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{calendar.dateFormat}}" ng-model="record.birthDate" is-open="calendar.opened.dob" datepicker-options="calendar.dateOptions" close-text="Close" placeholder="Date of Birth" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="calendar.open($event, 'dob')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-lg-6">
<label for="formWinDate">Win Date</label>
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{calendar.dateFormat}}" ng-model="record.winDate" is-open="calendar.opened.win" datepicker-options="calendar.dateOptions" close-text="Close" placeholder="Win DAte" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="calendar.open($event, 'win')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
wayne's answer is great. I would only add, that you can make the function 'open()' better:
$scope.open = function ($event, datePicker) {
$event.preventDefault();
$event.stopPropagation();
$scope.closeAll();
datePicker.opened = true;
};
And then you have to use it like that:
ng-click="open($event, dateFrom)"
Where dateFrom is your ng-model (i.e. you use $scope.dateFrom).
EDIT: $scope.closeAll(); is a function that closes all the datePickers. It can be written like that:
$scope.closeAll = function() {
$scope.dateFrom.opened = false;
$scope.dateTo.opened = false;
};
I'd prefer not to mix ng-model with UI info.For this purpose, is necessary to define an array to store the opening flags, as well as checking if the datePicker is opened or not.
Moreover, I have changes the 'open' behavior to 'toggle' instead, in order to allow closinf the datePicker with the button.
Here is my controller:
$scope.toggleOpenDatePicker = function($event,datePicker) {
$event.preventDefault();
$event.stopPropagation();
$scope[datePicker] = !$scope[datePicker];
};
Then it can be used as:
<input type="text" class="form-control" ng-model="model.date1" is-open="date1" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="toggleOpenDatePicker($event,'date1')"><i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
The $scope idea was borrowed from here:
I solved my problem by use this plunker with minor changes.
HTML
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="openDatePickers[0]" min-date="minDate" max-date="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, 0)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<h4>Popup</h4>
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="openDatePickers[1]" min-date="minDate" max-date="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, 1)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
and in controller
$scope.openDatePickers = [];
$scope.open = function ($event, datePickerIndex) {
$event.preventDefault();
$event.stopPropagation();
if ($scope.openDatePickers[datePickerIndex] === true) {
$scope.openDatePickers.length = 0;
} else {
$scope.openDatePickers.length = 0;
$scope.openDatePickers[datePickerIndex] = true;
}
};
my changes
instead numbers (0 or 1) i use $index in angular ng-repeat.
like this:
is-open="openDatePickers[**$index**]"
ng-click="open($event, **$index**)"
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="openDatePickers[$index]" min-date="minDate" max-date="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close">
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, $index)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
i used it in a different way and it looks a bit easier to me. I was using one of the mentioned approaches, but i was to lazy to create tons of calendars since i was running i a loop without having any static identifier.
So this solution is just valid for you, if you want to create lots of calendars inside of a ng-repeat. Hope it helps!
That is the controller
$scope.datepickers = {
data: {},
isopen: {}
}
// setting the defaults once
for (var i = 0; i < $scope.array.length; i++) {
$scope.datepickers.isopen[i] = false;
$scope.datepickers.data[i] = new Date();
}
// aso..
$scope.valuationDatePickerOpen = function($event, index) {
if ($event) {
$event.preventDefault();
$event.stopPropagation();
}
$scope.datepickers.isopen[index] = true;
};
And this is the HTML snipped inside my loop
<!-- ng-repeat="entry in array track by $index" -->
<input type="text" class="form-control"
datepicker-popup="dd-MMMM-yyyy"
is-open="datepickers.isopen[$index]"
ng-click="valuationDatePickerOpen($event, $index)"
ng-model="entry.date" />