Data binding not working but works fine in tutorial - data-binding

I am new to knockout.js. I am following this tutorial. It is working fine on knockout site but not for me. Error console is also not showing any error.
Below is my code
View:
Tasks
<form data-bind="submit: addTask">
Add task: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
<button type="submit">Add</button>
</form>
<div >
<ul data-bind="foreach: tasks, visible: tasks().length > 0" id="testing">
<li>
<input type="checkbox" data-bind="checked: isDone" />
<input data-bind="value: title, disable: isDone" />
Delete
</li>
</ul>
</div>
View Model:
<script>
function Task(data) {
this.title = ko.observable(data.title);
this.isDone = ko.observable(data.isDone);
}
function TaskListViewModel() {
// Data
var self = this;
self.tasks = ko.observableArray([]);
self.newTaskText = ko.observable();
self.incompleteTasks = ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() });
});
// Operations
self.addTask = function() {
self.tasks.push(new Task({ title: this.newTaskText() }));
self.newTaskText("");
};
self.removeTask = function(task) { self.tasks.remove(task) };
}
ko.applyBindings(new TaskListViewModel(),document.getElementById("testing"));
</script>

The problem is that the ko.applyBindings doesn't apply to all data-bind attributes. Move your "testing" id to a place where it covers all the HTML code with the relevant "data-bind" attributes.

Related

Close modal with search results when clicking outside?

I'm trying to close a modal div with AJAX search results, but nothing works.
I have tested several solutions on SO but nothing works?!
This is the code I have right now:
<form action="/search" method="get">
<input type="hidden" name="qt" value="main">
<div class="searchBox" id="search">
<input type="text" name="q" id="find" placeholder="Search here..." class="mainSearchField" />
<div class="searchBoxResults" id="search_items"></div>
</div>
</form>
<script>
$(document).ready(function() {
$( "#find" ).keyup(function(){
fetch();
});
});
function fetch() {
var val = document.getElementById("find").value;
$.ajax({
type: 'post',
url: '/include/functions/searchFetch.php',
data: {
q:val
},
success: function (response){
document.getElementById("search_items").innerHTML = response;
}
});
}
</script>
UPDATE
This is what I have tried to add, to the above:
window.onclick = function(event) {
if (event.target.id != "search_items") {
$("search_items").hide();
}
}

How to add validation on a dynamic textbox based from the model?

Say I have this Jquery code:
$('.additems').click(function () {
$table = $('.item');
$table.append('<tr> <td> <input type="textbox" name="test"> </td> </tr>');
});
And I want to enable the validation from the [Required] attribute of my model who contains the property test
I tried adding the autogenerated html from the #Html.ValidationMessageFor which is
<span class="field-validation-valid" data-valmsg-for="test" data-valmsg-replace="true"></span> but it's not working.
How do I do it?
You can try different solution
$('.additems').click(function () {
$table = $('.item');
$table.append('<tr> <td> <input type="textbox" class="myReq" name="test"> </td> </tr>');
});
function foo() {
$(".myReq").each(function () {
//Your Control
});
}

Add or remove element on knockout validation error or succes

I have a konockout validation:
define([
"jquery",
"knockout",
"knockout.validation",
"inte/accdevice"
], function ($, ko, validation) {
return function (model, getzipcodeurl) {
$(function () {
ko.validation.registerExtenders();
function ViewModelprofile() {
var self = this;
self.firstName = ko.observable(model.FirstName).extend({ required: { message: errors} });
self.updating = ko.observable(true);
};
var vms = new ViewModelprofile();
vms.errors = ko.validation.group(vms);
ko.applyBindingsWithValidation(vms, document.getElementById('infosBlocEdit'), { messagesOnModified: true });
});
};
});
This is my HTML:
<input id="FirstName" name="FirstName" type="text" value="#Model.FirstName" data-bind="value: firstName" maxlength="19" />
<span class="errorMsg" data-bind="validationMessage: firstName"></span>
Actually when there is an error i show:<span class="errorMsg" data-bind="validationMessage: firstName">errors</span>
I need to personalize css on error and on success on each element validation:
On error i need to show this:<span class="invalidLine">
<span class="bble"> </span>
<span class="bbleTxt">errors</span>
</span>
and on succes:<span class="validLine"></span>
How can I do this?
If I understand the question correctly and from what I see you use knockout validation, you need something like:
<span class="invalidLine" data-bind="visible: !firstName.isValid()">
<span class="bble"> </span>
<span class="bbleTxt">errors</span>
</span>
<span class="validLine" data-bind="visible: firstName.isValid()"></span>

Binding Issues with KnockoutJs and Breeze - Navigation Properties

My app is based on the HotTowel template so it includes Durandal, Knockout & Breeze. I have a page with 3 tables side by side. The first table has a list of "templates', the 2nd table shows "sections" for the selected "template" and the 3rd table shows "items" for the selected "section". The "sections" and "items" tables are collections accessed via navigation properties. I find that I get intermittent binding issues. The data in the "templates" table always shows correctly, however related "sections" and "items" sometimes show correctly and other times one of the other is not populated. It would seem to be a timing issue. My view model and view are below. Am I just going about all of this the wrong way?
define(['services/dataservice', 'services/logger', 'services/model'],
function (ds, logger, model) {
var templates = ko.observableArray();
var selectedTemplate = ko.observable();
var selectedSection = ko.observable();
var selectedItem = ko.observable();
var newTemplateTitle = ko.observable();
var newSectionTitle = ko.observable();
var newItemTitle = ko.observable();
function activate() {
newTemplateTitle('');
newSectionTitle('');
newItemTitle('');
logger.log('Templates view activated', null, 'templates', false);
return ds.getTemplatePartials(templates, false, false);//.then(succeeded);
//function succeeded() {
// var firstTemplate = templates()[0];
// setSelectedTemplate(firstTemplate);
//}
}
templates.subscribe(function() {
var firstTemplate = templates()[0];
setSelectedTemplate(firstTemplate);
});
var deactivate = function () {
templates([]);
};
function refresh() {
return ds.getTemplatePartials(templates, true, false);
}
var viewAttached = function (view) {
bindEventToList(view, '#template-list', setSelectedTemplate);
bindEventToList(view, '#section-list', setSelectedSection);
bindEventToList(view, '#item-list', setSelectedItem);
return true;
};
var addTemplate = function () {
var newTemplate = ds.createEntity(model.entityNames.document);
newTemplate.title(newTemplateTitle());
newTemplate.isTemplate(true);
newTemplate.organisation(ds.getCurrentOrganisation()());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
templates.push(newTemplate);
templates.sort();
newTemplateTitle('');
}
};
var addSection = function () {
var newSection = ds.createEntity(model.entityNames.section);
newSection.title(newSectionTitle());
newSection.isTemplate(true);
newSection.document(selectedTemplate());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
newSectionTitle('');
}
};
var addItem = function () {
var newItem = ds.createEntity(model.entityNames.item);
newItem.title(newItemTitle());
newItem.isTemplate(true);
newItem.section(selectedSection());
return ds.saveChanges().then(saveSucceeded);
function saveSucceeded() {
newItemTitle('');
}
};
var isTemplateSelected = function (template) {
if (template && selectedTemplate()) {
var thisId = ko.utils.unwrapObservable(selectedTemplate().id);
return ko.utils.unwrapObservable(template.id) == thisId;
}
return false;
};
var isSectionSelected = function (section) {
if (section && selectedSection()) {
var thisId = ko.utils.unwrapObservable(selectedSection().id);
return ko.utils.unwrapObservable(section.id) == thisId;
}
return false;
};
var isItemSelected = function(item) {
if (item && selectedItem()) {
var thisId = ko.utils.unwrapObservable(selectedItem().id);
return ko.utils.unwrapObservable(item.id) == thisId;
}
return false;
};
var vm = {
activate: activate,
deactivate: deactivate,
templates: templates,
//sections: sections,
//items: items,
selectedTemplate: selectedTemplate,
selectedSection: selectedSection,
selectedItem: selectedItem,
title: 'Template Maintenance',
refresh: refresh,
viewAttached: viewAttached,
addTemplate: addTemplate,
addSection: addSection,
addItem: addItem,
newTemplateTitle: newTemplateTitle,
newSectionTitle: newSectionTitle,
newItemTitle: newItemTitle,
isTemplateSelected: isTemplateSelected,
isSectionSelected: isSectionSelected,
isItemSelected: isItemSelected
};
return vm;
//#region internal methods
function setSelectedTemplate(data) {
if (data) {
selectedTemplate(data);
return selectedTemplate().entityAspect.loadNavigationProperty("sections").then(setFirstSectionSelected);
} else {
return false;
}
function setFirstSectionSelected() {
setSelectedSection(selectedTemplate().sections()[0]);
}
}
function setSelectedSection(data) {
if (data) {
selectedSection(data);
return selectedSection().entityAspect.loadNavigationProperty("items").then(setFirstItemSelected);
} else {
selectedSection();
selectedItem();
return false;
}
function setFirstItemSelected() {
setSelectedItem(selectedSection().items()[0]);
}
}
function setSelectedItem(data) {
if (data) {
selectedItem(data);
} else {
selectedItem();
}
}
function bindEventToList(rootSelector, selector, callback, eventName) {
var eName = eventName || 'click';
$(rootSelector).on(eName, selector, function () {
var item = ko.dataFor(this);
callback(item);
return false;
});
}
//#region
}
);
<section>
<div class="row-fluid">
<header class="span12">
<button class="btn btn-info pull-right push-down10" data-bind="click: refresh">
<i class="icon-refresh"></i> Refresh</button>
<h4 class="page-header" data-bind="text: title"></h4>
</header>
</div>
<div class="row-fluid">
<section class="span3">
<header class="input-append">
<input id="newTemplateName"
type="text"
data-bind="realTimeValue: newTemplateTitle"
placeholder="New template name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addTemplate, disable: newTemplateTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Templates</th>
</tr>
</thead>
<tbody>
<!-- ko foreach: templates -->
<tr id="template-list" data-bind="css: { 'selected': $root.isTemplateSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: templates().length"></span></span>
</article>
</section>
<section class="span5">
<header class="input-append">
<input id="newSectionName"
type="text"
data-bind="realTimeValue: newSectionTitle"
placeholder="New section name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addSection, disable: newSectionTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article data-bind="if: selectedTemplate">
<table class="table table-striped table-bordered table-hover" >
<thead>
<tr>
<th data-bind="text: 'Sections for ' + selectedTemplate().title()"></th>
</tr>
</thead>
<tbody>
<!-- ko foreach: selectedTemplate().sections() -->
<tr id="section-list" data-bind="css: { 'selected': $root.isSectionSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: selectedTemplate().sections().length"></span></span>
</article>
</section>
<section class="span4">
<header class="input-append">
<input id="newItemName"
type="text"
data-bind="realTimeValue: newItemTitle"
placeholder="New item name"
class="input-medium" />
<button class="btn btn-info add-on" data-bind="click: addItem, disable: newItemTitle() === ''">
<i class="icon-plus"></i> Add</button>
</header>
<article data-bind="if: selectedSection">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th data-bind="text: 'Items for ' + selectedSection().title()"></th>
</tr>
</thead>
<tbody>
<!-- ko foreach: selectedSection().items() -->
<tr id="item-list" data-bind="css: { 'selected': $root.isItemSelected($data) }">
<td data-bind="text: title" />
</tr>
<!-- /ko -->
</tbody>
</table>
<span>Count: <span data-bind="text: selectedSection().items().length"></span></span>
</article>
</section>
</div>
Similar issue (same server, same client but sometimes some navigators not working in breeze) happened to me. In my opinion it can be a timing bug. Or the create/load order of entities count.
I've changed this paralell async load entities from server:
return promise = Q.all([
getPackage(),
getClubPartials(null, true),
getAddressPartials(null, true),
getEventPartials(null, true)
]).then(success);
to this get them one by one:
return getClubPartials(null, true).then(function () {
getAddressPartials(null, true).then(function () {
getEventPartials(null, true).then(function () {
return getPackage().then(success);
})
})
});
And my problem gone!
There is just a lot of code to wade through and try to make sense of in the imagination.
You seem to say it works some of the time. That does sound like a timing issue.
One thing that is disturbing is the async methods (e.g. setSelectedTemplate) that return either false or a promise; not sure why the inconsistency. But that is probably not the real problem.
You could try putting a setTimeout(..., 10) before exiting the async methods. See if that changes the behavior.
If that doesn't reveal it, you'll have to boil it down to just those the essentials that reveal the problem.
Sadly no sudden flash of insight today.
Update June 3
My first concern is that some of your methods return promises and some return the value false. I'd feel more comfortable if they all returned promises. Look at Q.resolve().
Other code baffles me. For example, what is going on in the many variations on this pattern:
function setSelectedItem(data) {
if (data) {
selectedItem(data);
} else {
selectedItem();
}
}
The else{...} isn't doing anything useful. It unwraps the selectedItem property ... and discards the value. What is the point?
And what is the difference between this:
thisId = ko.utils.unwrapObservable(selectedTemplate().id); // obscure
and this?
thisId = selectedTemplate().id(); // clear
Are you unsure whether selectedTemplate().id is a KO observable? The only reason to use unwrapObservable is when you are unsure.
As for timing, you can let KO know that it should re-fresh a binding by calling valueHasMutated() on an observable. For example:
function setFirstItemSelected() {
setSelectedItem(selectedSection().items()[0]);
selectedItem.valueHasMutated();
}
It might help. I don't know ... you're stacking a long chain of dependencies and it isn't easy to see which are bailing out when. That would take study of actual data flows as well as the code. You cannot reasonably expect your StackOverflow audience to work that hard for free.
Try cutting this way down to a super-simple example that displays the troublesome behavior.
Best of luck.

Get markers inside OpenLayers bounding box

I have drawn a map on my page using OPENLAYERS 3.0.
And in document.ready() i have drawn the map and have plotted few markers on it using
some Longitude and latitude combinations.
And i have added draw line,polygon and select feature on my map.
My idea is to plot few markers on the map while page load, and i would like to a
draw a ploygon or bounding box and then on clicking those selections i should be
able to get the markers plotted inside those selection, is it possible to do this
without looping, anyone please give me a suggestion to accomplish this.
my HTML and JAVASCRIPT code is as follows
var map, layer;
var drawControls;
OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';
$('document').ready(function () {
console.log('in');
OpenLayers.ProxyHost = "/proxy/?url=";
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", { layers: 'basic' });
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(0, 0), 0);
var newl = new OpenLayers.Layer.Text("text", { location: "./content/textfile.txt" });
map.addLayer(newl);
var markers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(markers);
var size = new OpenLayers.Size(21, 25);
var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
//markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0, 0), icon));
var halfIcon = icon.clone();
//markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0, 45), halfIcon));
var Latitudes = '12.98267,13.00118,12.97161,12.97977,12.92828,12.97597';
var Longitudes = '80.26338,80.2565,80.24343,80.25288,80.23621,80.22121';
var LatArray = Latitudes.split(',');
var LonArray = Longitudes.split(',');
for (var g = 0; g < LatArray.length; g++) {
marker = new OpenLayers.Marker(new OpenLayers.LonLat(LonArray[g], LatArray[g]), icon.clone());
//marker.setOpacity(0.2);
marker.events.register('mousedown', marker, function (evt) { alert(this.icon.url); OpenLayers.Event.stop(evt); });
markers.addMarker(marker);
}
//marker = new OpenLayers.Marker(new OpenLayers.LonLat(90, 10), icon.clone());
//marker.setOpacity(0.2);
//marker.events.register('mousedown', marker, function (evt) { alert(this.icon.url); OpenLayers.Event.stop(evt); });
//markers.addMarker(marker);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.zoomToMaxExtent();
halfIcon.setOpacity(0.5);
var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;
var vectors = new OpenLayers.Layer.Vector("Vector Layer",
{
renderers: renderer
});
vectors.events.on(
{
'featureselected': function (feature) {
$('counter').innerHTML = this.selectedFeatures.length;
$('myd').innerHTML = 'this.selectedFeatures.length :' + this.selectedFeatures.length + 'this.selectedFeatures[0].geometry.bounds :' + this.selectedFeatures[0].geometry.bounds;
},
'featureunselected': function (feature) {
$('counter').innerHTML = this.selectedFeatures.length;
$('myd').innerHTML = 'UNSEL this.selectedFeatures.length :' + this.selectedFeatures.length + 'this.selectedFeatures[0].geometry.bounds :' + this.selectedFeatures[0].geometry.bounds;
}
});
map.addLayers([layer, vectors]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
drawControls =
{
point: new OpenLayers.Control.DrawFeature(
vectors, OpenLayers.Handler.Point
),
line: new OpenLayers.Control.DrawFeature(
vectors, OpenLayers.Handler.Path
),
polygon: new OpenLayers.Control.DrawFeature(
vectors, OpenLayers.Handler.Polygon
),
select: new OpenLayers.Control.SelectFeature(
vectors,
{
clickout: false, toggle: false,
multiple: false, hover: false,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey", // shift key adds to selection
box: true
}
),
selecthover: new OpenLayers.Control.SelectFeature(
vectors,
{
multiple: false, hover: true,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey" // shift key adds to selection
}
)
};
for (var key in drawControls) {
map.addControl(drawControls[key]);
}
});
function init()
{
}
function toggleControl(element)
{
for (key in drawControls) {
var control = drawControls[key];
if (element.value == key && element.checked) {
control.activate();
}
else {
control.deactivate();
}
}
}
function update()
{
var clickout = document.getElementById("clickout").checked;
if (clickout != drawControls.select.clickout)
{
drawControls.select.clickout = clickout;
}
var box = document.getElementById("box").checked;
if (box != drawControls.select.box)
{
drawControls.select.box = box;
if (drawControls.select.active)
{
drawControls.select.deactivate();
drawControls.select.activate();
}
}
}
<div id="content"></div>
<h1 id="title">
Markers Layer Example</h1>
<div id="tags">
Marker, event, mousedown, popup, inco</div>
<div id="shortdesc">
Show markers layer with different markers</div>
<div id="map" class="smallmap">
</div>
<ul id="controlToggle">
<li>
<input type="radio" name="type" value="none" id="noneToggle" onclick="toggleControl(this);"
checked="checked" />
<label for="noneToggle">
navigate</label>
</li>
<li>
<input type="radio" name="type" value="point" id="pointToggle" onclick="toggleControl(this);" />
<label for="pointToggle">
draw point</label>
</li>
<li>
<input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" />
<label for="lineToggle">
draw line</label>
</li>
<li>
<input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
<label for="polygonToggle">
draw polygon</label>
</li>
<li>
<input type="radio" name="type" value="selecthover" id="selecthoverToggle" onclick="toggleControl(this);" />
<label for="selecthoverToggle">
Select features on hover</label>
</li>
<li>
<input type="radio" name="type" value="select" id="selectToggle" onclick="toggleControl(this);" />
<label for="selectToggle">
select feature (<span id="counter">0</span> features selected)</label>
<ul>
<li>
<input id="box" type="checkbox" checked="checked" name="box" onchange="update()" />
<label for="box">
select features in a box</label>
</li>
<li>
<input id="clickout" type="checkbox" name="clickout" onchange="update()" />
<label for="clickout">
click out to unselect features</label>
</li>
</ul>
</li>
</ul>
<div id="myd">
</div>
This may be helpful.
I have found complete details at below location:
https://gis.stackexchange.com/questions/115500/how-to-find-markers-in-selected-dragbox-openlayers-3
You can also check live demo here:
http://jsfiddle.net/GFarkas/fk1mqq25/1/

Resources