I am using the datetimepicker from http://eonasdan.github.io/bootstrap-datetimepicker/
I have a bootstrap dialogbox which contains a textfield and an ID. I have exactly copied it, but my datetimepicker does not show up... Does anyone have an idea?
Javascript/HTML:
BootstrapDialog.show({
//Set properties
draggable:true,
title: cObj.title,
message: function (dialogItself) {
var form = $('<form id="createEventForm"> </form>');
var klantNaam = $('<input id="titleDrop" type="text" />');
var description = $('<textarea id="descriptionDrop"></textarea>');
var employee = $('<select class="form-control" id="employee">');
var starttime = $('<input id="starttime" type="text" class="form-control" /><span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>');
var startTimeDiv =
$('<div/>', {
id: 'datetimepicker4',
class: 'input-group date',
html: starttime
});
var endtime = $('<input type="text" class="endtime" id="endtime"/>');
dialogItself.setData('field-klant-naam', klantNaam);
dialogItself.setData('field-description', description); // Put it in dialog data's container then you can get it easier by using dialog.getData() later.
dialogItself.setData('select-user', employee); // Put it in dialog data's container then you can get it easier by using dialog.getData() later.
dialogItself.setData('starttime', startTimeDiv); // Put it in dialog data's container then you can get it easier by using dialog.getData() later.
dialogItself.setData('endtime', endtime);
form.append('<label>Klant naam</label>').append(klantNaam);
form.append('<label>Beschrijving</label>').append(description);
form.append('<label>Medewerker</label>').append(employee);
form.append('<label>Start tijd</label>').append(startTimeDiv);
form.append('<label>Eind tijd</label>').append(endtime);
$.each(<?php echo $list?>, function(key, value) {
employee.append($("<option/>", {
value: value.key,
text: value.value
}));
});
return form;
},
})
$('#datetimepicker4').datetimepicker();
CSS:
#datepicker4{
z-index: 99999;
}
You need to call datetimepicker() on element existing in the document, in your case you are just defining the message: function() {} that is returned to the BootstrapDialog object, which means it's still in memory and hasn't been added to the DOM yet.
after taking a look on the documentation of BootstrapDialog it turns out that onShow() is invoked after the message has been added to the DOM
BootstrapDialog.show({
//Set properties
draggable:true,
title: cObj.title,
onShow: function() {
if (!this.datetime_invoked) {
this.datetime_invoked = true;
$('#datetimepicker4').datetimepicker();
}
},
message: function (dialogItself) {
var form = $('<form id="createEventForm"> </form>');
var klantNaam = $('<input id="titleDrop" type="text" />');
var description = $('<textarea id="descriptionDrop"></textarea>');
var employee = $('<select class="form-control" id="employee">');
var starttime = $('<input id="starttime" type="text" class="form-control" /><span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>');
var startTimeDiv =
$('<div/>', {
id: 'datetimepicker4',
class: 'input-group date',
html: starttime
});
var endtime = $('<input type="text" class="endtime" id="endtime"/>');
dialogItself.setData('field-klant-naam', klantNaam);
dialogItself.setData('field-description', description); // Put it in dialog data's container then you can get it easier by using dialog.getData() later.
dialogItself.setData('select-user', employee); // Put it in dialog data's container then you can get it easier by using dialog.getData() later.
dialogItself.setData('starttime', startTimeDiv); // Put it in dialog data's container then you can get it easier by using dialog.getData() later.
dialogItself.setData('endtime', endtime);
form.append('<label>Klant naam</label>').append(klantNaam);
form.append('<label>Beschrijving</label>').append(description);
form.append('<label>Medewerker</label>').append(employee);
form.append('<label>Start tijd</label>').append(startTimeDiv);
form.append('<label>Eind tijd</label>').append(endtime);
$.each(<?php echo $list?>, function(key, value) {
employee.append($("<option/>", {
value: value.key,
text: value.value
}));
});
return form;
},
})
Your ID is different in your CSS file. In your markup you have #datetimepicker4, but in your css #datepicker4
Try to change in the CSS and see if it appears.
Also, check if the datetime markup is appearing when you view the source in Firebug. If so, the above may fix it as its likely a z-index issue.
i fixed with this code:
onshown: function(dialogRef){
$('#submit_date').datepicker({
language: 'ja',
isRTL: false,
//autoclose: true,
});
},
Related
I want to update my object with values from text fields.
I think the problem is with the click eventhandler on the button but not sure. I've tried a few things, Your help would be amazing.
HTML
<form>
<label><p>Book Name: </p></label>
<input name="booktitle" id="booktitle" type="text" value="I'm a value">
<label><p>Total Pages: </p></label>
<input type="text">
<label><p>Current Page: </p></label>
<input type="text">
<button id="my-Btn" type="button">Add to List</button>
</form>
JS
(function() {
// Create book object
var book = {
name: 'JavaScript & jQuery',
totalPages: 622,
pages: 162,
pagesLeft: function() {
var total = this.totalPages - this.pages;
return total;
},
percentageLeft: function() {
var totalPercentage = this.pagesLeft() / this.totalPages * 100
return Math.round(totalPercentage);
}
};
// write out book name and pages info
var bookName, totalPages, pagesLeft, percentageLeft; //declares variables
bookName = document.getElementById('bookName'); // gets elements from document
totalPages = document.getElementById('totalPages');
pagesLeft = document.getElementById('pagesLeft');
percentageLeft = document.getElementById('percentageLeft');
bookName.textContent = book.name; // write to document
totalPages.textContent = 'Total Pages: ' + book.totalPages;
pagesLeft.textContent = book.pagesLeft();
percentageLeft.textContent = book.percentageLeft() + '%';
// pull value from text field and set to object
document.getElementById("my-Btn").addEventListener("click", function() {
book.name = document.getElementById('booktitle').value;
});
}());
Code Pen of what I have so far.
http://codepen.io/Middi/pen/pRGOVW
Thanks in advance.
Your code already updates an object's property (book.name) with a value from a text field (#booktitle). You can see this by adding alert(book.name); after the line
book.name = document.getElementById('booktitle').value;
As Jazcash noted, if you wanted to display the updated book name everytime it was changed, you'd need to add
bookName.textContent = book.name;
In your eventlistener, so it'd look something like this:
document.getElementById("my-Btn").addEventListener("click", function() {
book.name = document.getElementById('booktitle').value;
bookName.textContent = book.name;
});
The problem is you're setting your divs textContent based on book here: bookName.textContent = book.name;. But then you need to do it again in your event like so:
book.name = bookName.value;
bookName.textContent = book.name;
You'll need to do this for all your fields
I am trying to write a functionality for editing feature attributes through layer.bindPopup for Leaflet features. At this point I have pretty much everything I need, except of the one last thing: Documentation is saying that layer.bindPopup takes either HTML string or HTML element, so I need to concatenate my HTMLString with two elements: saveChanges button and speed_input input and then feed layer.bindPopup with it. Any manipulations with $.append did not help. Any suggestions on how to resolve this?
function onEachArc(feature, layer) {
// Create an input
var speed_input = L.DomUtil.create('input', 'speed');
// Set a feature property as value
speed_input.value = feature.properties.speed;
// Add a listener to watch for change on time input
L.DomEvent.addListener(speed_input, 'change', function(){
// Change the value of speed
feature.properties.speed = speed_input.value;
});
// Bind popup to layer with input
HTMLString = '<table style="width:100%">\
<tr style="background-color:grey">\
<th><b>Arc Numer: </b>' + feature.properties.linkstr + '</br></th>\
</tr>\
<tr>\
<td><b>Speed: </b> ' + feature.properties.speed + '.</div></td>\
</tr>\
</table>';
var saveChanges = document.createElement('button');
saveChanges.innerHTML = 'Save Changes';
saveChanges.onclick = function(){
$.ajax({
type:"POST",
url:"php/updateFeature.php",
data: {feature: feature},
success: function(data){
$('#test').html(data);
}
});
//return false;
}
};
/*
This did not help
var box = document.createElement("div");
box.style.width = "100px";
box.style.height = "100px";
$("#box").append("#saveChanges");
layer.bindPopup(box);
*/
layer.bindPopup(saveChanges);
};
You could use innerHTML:
The Element.innerHTML property sets or gets the HTML syntax describing the element's descendants.
var form = L.DomUtil.create('form', 'my-form');
form.innerHTML = '<input type="text" class="my-input" />';
var button = L.DomUtil.create('button', 'my-button', form);
button.textContent = 'Ok!';
http://plnkr.co/edit/DiK1zj?p=info
or use outerHTML:
On return, content contains the serialized HTML fragment describing the element and its descendants.
var inputHTML = '<input type="text" class="my-input" />';
var button = L.DomUtil.create('button', 'my-button', form);
button.textContent = 'Ok!';
var buttonHTML = button.outerHTML;
var form = '<form class="my-form">' + inputHTML + buttonHTML + '</form>';
http://plnkr.co/edit/Z6rADJ?p=preview
That said (and after reading your comment), i must say: this works but is very hacky. I wouldn't recommend doing this sort of thing this way. You either build your form with HTML elements or use a template/string and convert that into HTML elements so you can attach handlers and process stuff. Mixing things up will get you into trouble. I would approach it this way:
The template:
var template = '<form id="popup-form">\
<label for="input-speed">New speed:</label>\
<input id="input-speed" class="popup-input" type="number" />\
<table class="popup-table">\
<tr class="popup-table-row">\
<th class="popup-table-header">Arc numer:</th>\
<td id="value-arc" class="popup-table-data"></td>\
</tr>\
<tr class="popup-table-row">\
<th class="popup-table-header">Current speed:</th>\
<td id="value-speed" class="popup-table-data"></td>\
</tr>\
</table>\
<button id="button-submit" type="button">Save Changes</button>\
</form>';
Use a stylesheet, keeps the template nice and clean:
.popup-table {
width: 100%;
}
.popup-table-row {
background-color: grey;
}
In the onEachFeature function, attach a click handler:
L.geoJson(collection, {
onEachFeature: function (feature, layer) {
layer.on('click', layerClickHandler);
}
});
And handle it:
function layerClickHandler (e) {
var marker = e.target,
properties = e.target.feature.properties;
// Check if a popup was previously set if so, unbind
if (marker.hasOwnProperty('_popup')) {
marker.unbindPopup();
}
// Create new popup from template and open it
marker.bindPopup(template);
marker.openPopup();
// Now that the popup is open and the template converted to HTML and
// attached to the DOM you can query for elements by their ID
L.DomUtil.get('value-arc').textContent = properties.arc;
L.DomUtil.get('value-speed').textContent = properties.speed;
var inputSpeed = L.DomUtil.get('input-speed');
inputSpeed.value = properties.speed;
L.DomEvent.addListener(inputSpeed, 'change', function (e) {
properties.speed = e.target.value;
});
var buttonSubmit = L.DomUtil.get('button-submit');
L.DomEvent.addListener(buttonSubmit, 'click', function (e) {
// Do fancy ajax stuff then close popup
marker.closePopup();
});
}
Example on Plunker: http://plnkr.co/edit/8qVoW5?p=preview
This is cleaner, faster, it doesn't bind popups to every marker. It's more readable, extendable and less error prone. I hope that help, good luck!
Extending the example found at Autosave in MVC (ASP.NET), I wanted to create a partial to reuse in my application. I have one view with a tabbed layout, and each tab has its own form, and this is causing problems, namely that every form tries to submit every time, and only the first timestamp in the document updates. I understand why this is happening, but I don't know how I can fix it.
Partial's cshtml:
<div class="form-group">
<label class="control-label col-lg-2" for=""> </label>
<div class="col-lg-10">
<span class="help-block" id="autosaveTime">Not Autosaved</span>
</div>
</div>
#{
var autosaveString = "'" + #ViewData["autosaveController"] + "'";
if (ViewData["autosaveAction"] != null && ViewData["autosaveAction"] != "")
autosaveString += ", '" + ViewData["autosaveAction"] + "'";
}
<script type="text/javascript">
$(document).ready(function () {
autosave(#Html.Raw(autosaveString));
});
</script>
Javascript:
//methodName is optional-- will default to 'autosave'
function autosave(controllerName, methodName)
{
methodName = typeof methodName !== 'undefined' ? methodName : 'autosave'
var dirty = false;
$('input, textarea, select').keypress(function () {
dirty = true;
});
$('input, textarea, select').change(function () {
dirty = true;
});
window.setInterval(function () {
if (dirty == true) {
var form = $('form');
var data = form.serialize();
$.post('/' + controllerName + '/' + methodName, data, function () {
$('#autosaveTime').text("Autosaved at " + new Date);
})
.fail(function () {
$('#autosaveTime').text("There was a problem autosaving, check your internet connection and login status.");
});
dirty = false;
}
}, 30000); // 30 seconds
}
I have 2 ideas on how to fix it, but not sure which is more maintainable/workable:
Give each form an id, and pass that to the partial/autosave function. Add the name to the autosavetime text block for updates, and to determine which form to serialize/submit.
Somehow use jquery's closest function to find the form where the autosave block was placed, and use that to do what I was doing explicitly with #1.
First, make the URL using your Razor helper's Html extension (dynamically piecing URLs like this in JavaScript is unnecessarily risky). Take that, and stuff it in a data attribute on the tab control like so:
<div class="tab autosave" data-action-url='#Html.Action("Action", "Controller")'>
<form>
<!-- Insert content here -->
</form>
</div>
Then, you'll want something like this ONCE -- do not include it everywhere, and remove the javascript from your partial completely:
$(function() {
// Execute this only once, or you'll end up with multiple handlers... not good
$('.autosave').each(function() {
var $this = $(this),
$form = $this.find('form'),
dirty = false;
// Attach event handler to the tab, NOT the elements--more efficient, and it's always properly scoped
$this.on('change', 'input select textarea', function() {
dirty = true;
});
setInterval(function() {
if(dirty) {
// If your form is unobtrusive, you might be able to do something like: $form.trigger('submit'); instead of this ajax
$.ajax({
url : $this.data('action-url'),
data : $form.serialize()
}).success(function() {
alert("I'm awesome");
dirty = false;
});
}
}, 30 * 1000);
});
});
A little context: I'm creating a wizard, so the content of a step is hidden until you're up to that step. I'm dynamically creating the second step of the form based on your input from the first step, like so:
No Hiding, Get Input, Show Output
HTML
<p class="par">
<label for="report_cat">Category:</label>
<span class="field">
<select data-bind="options: reportTypes, optionsText: 'title', value: selectedReportType, optionsCaption: 'Report Category'" id="report_cat" class="longinput"></select>
</span>
</p>
<p class="par">
<label for="report">Report:</label>
<span class="field">
<select data-bind="options: reportPool, optionsText: 'title', value: selectedReport, optionsCaption: 'Select Report'" id="report" class="longinput"></select>
</span>
</p>
<div class="widgetcontent stdform stdform2 stdformwidget" id="tmptest" data-bind="wizardInputs: inputPool">
</div>
Relevant Javascript (ReportTypes is just an array of javascript objects)
self.inputPool = ko.computed(function() {
if (self.selectedReport() == null) return [];
//set the url
self.postUrl(self.selectedReport().postUrl);
var inputs = self.selectedReport().inputs.map(function(elem) {
var element = null;
var type = elem["type"];
var id = "wizard-elem-" + elem["title"].replace(/\s+/g, '');
if (type == "date") {
element = $("<input type =\"text\" id=\"" + id + "\" class=\"longinput wizard-dp\" style=\"display:inline-block\" />");
element.datepicker();
}
if (type == "checkbox") {
element = $("<input type =\"checkbox\" id=\"" + id + "\" />");
}
if (type == "select") {
//do something with options
element = $("<input type =\"checkbox\" id=\"" + id + "\" />");
}
elem["elem"] = element;
return elem;
});
return inputs;
});
ko.bindingHandlers.wizardInputs = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var ele = $(element);
var value = valueAccessor();
ele.children(".wizardContent").remove();
var container = $("<div class=\"wizardContent\"></div>");
for (var x in value()) {
var single = value()[x];
var id = "wizard-elem-final-" + single["title"].replace(/\s+/g, '');
var param = $("<p></p>").addClass("par");
param.append("<label for=\"" + id + "\">" + single["title"] + "</label>");
var field = $("<span></span>").addClass("field");
field.append(single["elem"]);
param.append(field);
container.append(param);
}
if (value().length > 0) {
ele.prepend(container);
}
}
};
I tossed all the code on this fiddle, I am not hiding my elements at any point. When you select any combination of Categories/Reports the second step will automatically pop up below the first. The datepicker (input 1) will appear just fine (ignore the lack of CSS for a moment).
However, when I attempt to have each step show up at the proper time by hiding and showing the containers, the datepicker will not appear. The actual input element has "hasDatePicker" class, so I know that the datepicker is still being implemented. The actual datepicker element that's hidden shows up in Firebug's HTML viewer, too; so I know it's there.
Hiding
HTML
<div class="widgetcontent stdform stdform2 stdformwidget" data-bind="slideVisible: (step() == 1)" id="tmptest1">
<p class="par">
<label for="report_name">Title:</label>
<span class="field">
<input type="text" data-bind="value: title" class="longinput" id="report_name" />
</span>
</p>
<p class="par">
<label for="report_cat">Category:</label>
<span class="field">
<select data-bind="options: reportTypes, optionsText: 'title', value: selectedReportType, optionsCaption: 'Report Category'" id="report_cat" class="longinput"></select>
</span>
</p>
<p class="par">
<label for="report">Report:</label>
<span class="field">
<select data-bind="options: reportPool, optionsText: 'title', value: selectedReport, optionsCaption: 'Select Report'" id="report" class="longinput"></select>
</span>
</p>
</div>
<div class="widgetcontent stdform stdform2 stdformwidget" id="tmptest" data-bind="wizardInputs: inputPool, slideVisible: (step() == 2)">
</div>
SlideVisible Bindings
ko.bindingHandlers.slideVisible = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var ele = $(element);
var value = ko.utils.unwrapObservable(valueAccessor());
ele.hide();
if (value) ele.slideDown();
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var ele = $(element);
var value = ko.utils.unwrapObservable(valueAccessor());
if (value) {
ele.slideDown();
}
else {
ele.slideUp();
}
}
};
I have manually played around in my console, and it seems as though the actual act of hiding and showing the containers somehow breaks my datepicker. I have been able to replicate this without the knockout through the console by hiding the element that will contain the datepicker, placing the elements in that container, and then revealing the container. The elements show up, but the datepicker will not proc.
Has anyone dealt with this before? Is there a workaround I simply have been unable to find?
Didn't read the whole thing but why don't you try to add the field to the DOM first and then attach the datepicker?
i have a input area and a button like this:
<input type="text" name="text_name" id="txt_name" size="30" maxlength="70">
<input type=button id="btnPublishAction" onclick="publishFeed()" value="Yeah" style="margin: 5px 0;" />
and a function like this:
name = oForm.elements["text_name"].value;
function publishFeed() {
var act = new gigya.services.socialize.UserAction();
act.setUserMessage(name);
act.setLinkBack("http://www.xxx.com");
act.setTitle("Check me out!");
act.setDescription("This is my Profile");
act.addMediaItem( {
src: '<?php echo $photoDiv; ?>',
href: 'http://www.exploretalent.com/<?php echo $_SESSION['talent_username'];?>',
type: 'image'
});
var params =
{
userAction:act,
scope: 'internal',
privacy: 'public',
callback:publishAction_callback
};
gigya.services.socialize.publishUserAction(conf, params);
}
what i am trying to do is when i click Yeah the value from the text_name to be set into act.setUserMessage(name); where name = oForm.elements["text_name"].value;.
i found this syntax name = oForm.elements["text_name"].value; but not sure if that works
any ideas?
Thanks
try using name = document.getElementById("txt_name").value
Assuming oForm is a reference to a form on your page. And assuming your textarea is contained in that form. And assuming your textarea has a name attribute of "text_name", then yes, that should work. Just drop that line of code into your function as the first line.
function publishFeed() {
var name = oForm.elements["text_name"].value;
var act = new gigya.services.socialize.UserAction();
act.setUserMessage(name);
...
}
With name = ... above the function, the name variable is not updated when the text changes. You want to set the value of that variable within your function so that you are getting the current text.
Edit: If you don't want to use a form on your page, then give your textarea an id and access it via that id:
<textarea id="myTextArea"></textarea>
Here's the update JavaScript:
function publishFeed() {
var name = document.getElementById("myTextArea").value;
var act = new gigya.services.socialize.UserAction();
act.setUserMessage(name);
...
}