I have sample of layers stored on my database, I tried to display names of this layers in a panel, each layer is associated to a checkbox. When I check each checkbow I want to add its correspondent layer on map and remove it from map when checkbox is unchecked. My problem is I can't remove layers from map.
Here is my php and jquery snippet code:
**jquery file **
$.get( $("#myForm5").attr("action"),
$("#myForm5 :input").serializeArray(),
function(data) {
$("#Liste").html(data);
$('input[id^="DisplayCheckbox"]').on('change', function()
{
var CoordItem = $(this).parents("div.parent").find("li#Lis te").text();
var content = $(this).val();
var DataItem = $(this).parents("div.parent").find("li#ListeData").text();
var array = DataItem.split(',');
var dataDomaine = $.parseJSON(CoordItem);
var geojsonFeature =
{
"type": "Feature",
"properties": {
"name": content,
},
"geometry": {
"type": dataDomaine.type,
"coordinates":dataDomaine.coordinates
}
};
var layer = L.geoJson(geojsonFeature);
if($(this).is(":checked"))
{
layer.addTo(map);
map.fitBounds(layer.getBounds());
}else
{
map.removeLayer(layer);
});//end change checkbox
});//end get function
php file
<?php
......
echo '<ul>'
echo '<div id="' . $row2['nom'] . '" class="col-sm-10 parent"><li class="Liste" id="idListe">' . $row2['nom'] . '</li>
<div class="checkbox DisplayLayer">
<label><input type="checkbox" name="id" id="DisplayCheckbox" value="' . $row2['nom'] . '"></label></div>
<li id="ListeData" name="id" style="display:none;">' . $tostring. '</li>';
.......
echo '<li id="ListeGeom" name="id" style="display:none;">' . $row3[0]. '</li></div><br/>';
echo '</ul>
?>
It's because you are removing "new created" feature - there is no reference to existing layer.
Before layer.addTo(map) give a layer private property, e.g layer._id = 1. And in an else block, let's iterate over all layers and try to find it by id. Something like this:
map.eachLayer(function(layer){
if(layer._id == 1) map.removeLayer(layer)
})
Related
I would like to plot some d3js chars in vuejs after performing an API call to get some data. To do so, I created a form whose input is used to collect the data from the API. Once I submit the form, I call my d3js function to plot the charts based on the retrieved data. I want the plotting functions to be called only when the data is not empty. To do so, I used the conditional rendering v-if based on the length of the data. So far so good. My problem is that once the plots are rendered if I type anything in the form, a new plot will be created as if every time the if statement is evaluated again and again, I don't know if it is related to lifecycle or not, but how can avoid this behavior?
<template>
<meta charset="utf-8">
<h4>Associate Information</h4>
<form #submit.prevent="onSubmit">
<input placeholder="Associate Id" v-model="associateId" /> <br />
<input placeholder="Starting date" v-model="initialDate" /> <br />
<input placeholder="Ending date" v-model="finalDate" /> <br />
<button v-on:click="getAssociatesbyIdAndDates()">submit</button>
</form>
<div class="chart" v-if="dailyData.length">
{{ DailyBillabilityLinePlot() }}
{{ WeeklyMonthlyQuarterlyBarPlot(weeklyData) }}
</div>
<div class="linePlot"></div>
<div class="barPlot" v-if="weeklyData.length">
<button v-on:click="WeeklyMonthlyQuarterlyBarPlot(weeklyData)">Weekly</button>
<button v-on:click="WeeklyMonthlyQuarterlyBarPlot(monthlyData)">Monthly</button>
<svg id="chart" viewBox="0 0 960 300"></svg>
</div>
</template>
<script>
import * as d3 from 'd3'
export default {
name: 'Timecard',
props: {
msg: String
},
data() {
return {
apiUrl: "",
myNumber: 0,
environment: "",
apiTst:"",
name:"",
initialDate: "",
finalDate: "",
associateId: "",
dailyData: [],
weeklyData:[],
monthlyData:[],
}
},
methods: {
WeeklyMonthlyQuarterlyBarPlot(data){
// plot a d3 bar plot
},
DailyBillabilityLinePlot() { // plot another d3 line plot}
getAssociatesbyIdAndDates() {
// Connect to the backend and get the list of associates
// http://localhost:8080/timecards/period/test/274/2020-04-14/2020-04-22
console.log("Fetching the data for an associates from the backend based on initial date and final date...");
this.axios.get(this.apiUrl + "test/period/test/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
.then(response => {
this.dailyData = response.data;
console.log(response.status);
})
.catch(error => {
console.error(error);
})
this.axios.get(this.apiUrl + "test/weekly/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
.then(response => {
this.weeklyData = response.data;
console.log(response.status);
})
.catch(error => {
console.error(error);
})
this.axios.get(this.apiUrl + "test/monthly/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
.then(response => {
this.monthlyData = response.data;
console.log(response.status);
})
.catch(error => {
console.error(error);
})
},}
onSubmit() {
let consultantApi = {
name: this.name,
initialDate: this.initialDate,
finalDate: this.finalDate,
}
this.$emit('consultantApi-submitted', consultantApi)
this.name = ''
this.initialDate = ''
this.finalDate = ''
}
},
mounted: function() {
this.apiUrl = process.env.VUE_APP_BACKEND_API;
this.environment = process.env.NODE_ENV;
}
Initial Form
D3 plots after submitting the completed form
Creation of new d3 plots whenever I press any key in the form
Yes, this is because updating any model will re-render the entire component.
To get around it, I find the simplest way is to put the chart into another component so that the re-render is then guarded.
Example:
var app = Vue.createApp({
data() {
return {
abc: 'ABC',
list: [1, 2, 3]
};
}
});
app.component("my-chart", {
template: `<div >{{Math.random()}}</div>`
});
app.mount("#app");
<script src="https://unpkg.com/vue#3.0.6/dist/vue.global.prod.js"></script>
<div id="app">
<input v-model="abc" />
<div v-if="list.length">
{{Math.random()}}
</div>
<my-chart></my-chart>
</div>
I think your bug is in the parent component. I would try to check how often does it emmit the consultantApi. It seems like your form keeps submitting on input change event and not on form submit.
I am trying to separate my Views and ViewModels in a Kendo Mobile app (ie. not MVC). I have a remote datasource in a ViewModel and cannot get it to work - I am sure it is something simple (I can't find a Kendo example that uses a Remote DataSource in a ViewModel - it is all inline. (http://demos.telerik.com/kendo-ui/web/mvvm/remote-binding.html, http://docs.telerik.com/kendo-ui/getting-started/framework/datasource/overview)
It just shows this "function (e){var n=this;return e===t?n._data:(n._data=this._observe(e),n._ranges=[],n._addRange(n._data),n._total=n._data.length,n._process(n._data),t)}" and not the actual data.
games.html View
<div id="tabstrip-home"
data-role="view"
data-title="Games"
data-model="app.gamesService.viewModel">
<ul class="games-list"
data-bind="source: gamesDataSource"
data-template="template">
</ul>
</div>
<script type="text/x-kendo-template" id="template">
<div class="product">
<h3>#:ProductName#</h3>
<p>#:kendo.toString(UnitPrice, "c")#</p>
</div>
</script>
games.js ViewModel
(function (global) {
var GamesViewModel, app = global.app = global.app || {};
GamesViewModel = kendo.data.ObservableObject.extend({
gamesDataSource: new kendo.data.DataSource({
transport: {
read: {
url: "http://demos.telerik.com/kendo-ui/service/Products",
dataType: "jsonp"
}
}
})
});
app.gamesService = {
viewModel: new GamesViewModel()
};
})(window);
I found an example and managed to get this working, although the javascript is a little different. I'll have to read up on
(function (global) {
var GamesViewModel,
app = global.app = global.app || {};
GamesViewModel = kendo.data.ObservableObject.extend({
gamesDataSource: null,
init: function () {
var that = this,
dataSource;
kendo.data.ObservableObject.fn.init.apply(that, []);
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "http://demos.telerik.com/kendo-ui/service/Products",
dataType: "jsonp"
//ProductID":1,"ProductName":"Chai","UnitPrice":18,"UnitsInStock":39,"Discontinued":false
}
}
});
that.set("gamesDataSource", dataSource);
}
});
app.gamesService = {
viewModel: new GamesViewModel()
};
})(window);
I want . Auto complete text box with multiple keyword. it's from database. if I use jQuery and do operation in client side mean. If the database size is huge, it leads to some issues. I need to know how this is done on the server side and get proper result.
I have already seen this topic but the operation is done on the client side. I need it from the database directly.
<html>
<head>
<title>Testing</title>
<link href="css/jquery-ui-1.10.3.custom.css" rel="stylesheet" type="text/css" />
<style type="text/css">
.srchHilite { background: yellow; }
</style>
<script src="scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="scripts/jquery-ui-1.10.3.custom.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
NewAuto();
});
function NewAuto() {
var availableTags = ["win the day", "win the heart of", "win the heart of someone"];
alert(availableTags); // alert = win the day,win the heart of,win the heart of someone
$("#tags").autocomplete({
source: function(requestObj, responseFunc) {
var matchArry = availableTags.slice(); // Copy the array
var srchTerms = $.trim(requestObj.term).split(/\s+/);
// For each search term, remove non-matches.
$.each(srchTerms, function(J, term) {
var regX = new RegExp(term, "i");
matchArry = $.map(matchArry, function(item) {
return regX.test(item) ? item : null;
});
});
// Return the match results.
responseFunc(matchArry);
},
open: function(event, ui) {
// This function provides no hooks to the results list, so we have to trust the selector, for now.
var resultsList = $("ul.ui-autocomplete > li.ui-menu-item > a");
var srchTerm = $.trim($("#tags").val()).split(/\s+/).join('|');
// Loop through the results list and highlight the terms.
resultsList.each(function() {
var jThis = $(this);
var regX = new RegExp('(' + srchTerm + ')', "ig");
var oldTxt = jThis.text();
jThis.html(oldTxt.replace(regX, '<span class="srchHilite">$1</span>'));
});
}
});
}
</script>
</head>
<body>
<div>
<label for="tags">
Multi-word search:
</label>
<input type="text" id="tags" />
</div>
</body>
</html>
take a look to Select2 it may help you.
Select2 is a jQuery based replacement for select boxes. It supports
searching, remote data sets, and infinite scrolling of results.
link
In your code, you have provided source as array. As you mentioned in comments, problem is how to get the data to source in jquery.
To make this work,
You need to do following
load jquery in header, which is you have already done.
Provid array,string or function for the source tag. [See api for
the source tag][1]
[1]: http://api.jqueryui.com/autocomplete/#option-source
In your serverside script, provid Jason encoded string.
If you check the API, you can see they have clear mentioned this.
Here is the jquery code
$(function() {
$( "#option_val" ).autocomplete({
dataType: "json",
source: 'search.php',
minLength: 1,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
});
});
</script>
Here is the php code, Sorry if you use differnt serverside script language.
<?php
// Create connection
$con=mysqli_connect("localhost","wordpress","password","wordpress");
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result=mysqli_query($con,"select * from wp_users");
while($row = mysqli_fetch_array($result))
{
$results[] = array('label' => $row['user_login']);
}
echo json_encode($results);
mysqli_close($con);
?>
I'm implementing a search form that displays suggestions as you start typing but can't get it to work..the problem is that when you start typing it doesn't shows any suggestion. Can you help me to get the code right? Many thanks!
This is the code:
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<div><input id="autocomplete" type="text"></div>
<script>
$("input#autocomplete").autocomplete({
source: [
{ id : "Google", value : "Google"},
{ id : "Yahoo", value : "Yahoo"},
],
minLength: 1,
open: function(event, ui) {
$("ul.ui-autocomplete").unbind("click");
var data = $(this).data("autocomplete");
console.log(data);
for(var i=0; i<=data.options.source.length-1;i++)
{
var s = data.options.source[i];
$("li.ui-menu-item a:contains(" + s.value + ")").attr("href", "/" + s.id);
}
}
});
/*
$("input#autocomplete").bind("autocompleteselect", function(event, ui) {
//alert(ui.item.id + ' - ' + ui.item.value);
//document.location.href = ui.item.id + '/' + ui.item.value;
//event.preventDefault;
} );
*/
</script>
Here Is the code:
<div id="search">
<input list="results" id="project" onkeydown="if (event.keyCode == 13) { checkInput(this.value); return false; }" />
</div>
The avaible results...
<datalist id="results">
<option>Demo</option>
<option>Example</option>
<option>pizza</option>
</datalist>
Finally the javascript
function checkInput(searchQuery)
{
if(searchQuery=="Home")
{
window.location = "Home.html";
}
else if(searchQuery == "Contact")
{
window.location = "Contact.html";
}
else if(searchQuery == "Sitemap")
{
window.location = "Sitemap.html";
}
else
{
window.location = "noresult.html";
}
}
So that way when ever someone goes to search they have a limited amount of options in the pre-populated list and which ever one they select leads them to your target page! I can't take all the credit, but I hope that helps!
I'm adding new rows dynamically to the existing table, the first column of the table holds the Edit & Delete buttons. I'm facing 2 problems with this:
Not able to Edit and Delete newly added rows, tried .live but couldn't make it work
Not able to get the record id of the newly added rows (ajax returns the record when new rows are added).
Code looks like this:
Adding new rows:
<script type="text/javascript">
$(function() {
$('#btnSubmit').click(function() {
var oEmployee = new Object();
oEmployee.Title = $("#Title").val();
oEmployee.Middlename = $("#MiddleName").val();
oEmployee.Lastname = $("#LastName").val();
oEmployee.Email = $("#Email").val();
var DTO = {'employee': oEmployee};
var options = {
type: "POST",
url: "WebService.asmx/InsertEmployee",
data: JSON.stringify(DTO),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
if (response.d != "") {
if (parseInt(response.d) >= 1) {
var contactID;
contactID = parseInt(response.d);
$('#tblEmployee tbody tr:first').after("<tr id=" + contactID + "><td><input type='button' class='newContactID' value='Edit'/> <input type='button' value='Delete'/></td><td align=center>" + contactID + "</td><td align=center>" + oEmployee.Title + "</td><td align=center>" + oEmployee.Middlename + "</td><td align=center>" + oEmployee.Lastname + "</td><td align=center>" + oEmployee.Email + "</td><tr>"); // need to hook up editing and deleting function to the newly added rows }
else {
alert("Insert Failed \n" + response.d);
}
}
}
};
//Call the webservice
$.ajax(options);
});
});
</script>
Code for editing and deleting:
$(function() {
$("#tblEmployee > tbody > tr ").each(function() {
var TRID = $(this).attr("id");
$(this).find("td:first > input[value=Edit]").click(function() {
ResetOtherRowEdit();
ChangeTableCellToTextbox(TRID);
$(this).hide();
$("#tblEmployee > tbody > tr[id=" + TRID + "] > td:first> input[value=Delete]").hide();
return false;
});
$(this).find("td:first > input[value=Update]").click(function() {
UpdateRow(TRID);
});
$(this).find("td:first > input[value=Delete]").click(function() {
DeleteRow(TRID);
});
$(this).find("td:first > input[value=Cancel]").click(function() {
CancelEdit(TRID);
});
});
});
What is the best way to approach this? Editing and deleting of records work fine when they're pulled off the database.
Update
This is how the code looks like now, just began dabbling with Jquery a month back, still trying to get my head around it.
$(function() {
$("#tblEmployee > tbody > tr ").live('click', function(e) {
var TRID = $(this).attr("id");
var $target = $(e.target);
if ($target.is('#btnEdit')) {
$(this).find("td:first > input[value=Edit]").click(function() {
ResetOtherRowEdit();
ChangeTableCellToTextbox(TRID);
$(this).hide();
$("#tblEmployee > tbody > tr[id=" + TRID + "] > td:first> input[value=Delete]").hide();
return false;
});
}
else if ($target.is('#btnUpdate')) {
$(this).find("td:first > input[value=Update]").click(function() {
UpdateRow(TRID);
});
}
else if ($target.is('#btnCancel')) {
$(this).find("td:first > input[value=Cancel]").click(function() {
CancelEdit(TRID);
});
}
else if ($target.is('#btnDelete')) {
$(this).find("td:first > input[value=Delete]").click(function() {
DeleteRow(TRID);
});
}
});
});
HTML codes looks like this:
<ItemTemplate>
<tr id='<%# Eval("ContactID") %>'>
<td width="10%">
<input type="button" value="Edit" id="btnEdit"/>
<input type="button" value="Delete" id="btnDelete"/>
<input type="button" value="Update" style="display:none" id="btnUpdate" />
<input type="button" value="Cancel" style="display:none" id="btnCancel"/>
</td>
<td width="10%" align="center"><%# Eval("ContactID")%></td>
<td width="20%" align="center"><%# Eval("Title")%></td>
<td width="20%" align="center"><%# Eval("MiddleName")%></td>
<td width="20%" align="center"><%# Eval("LastName")%></td>
<td width="20%" align="center"><%# Eval("EmailAddress")%></td>
</tr>
</ItemTemplate>
You could take advantage of DOM traversal and .live() to make this work. Add a listener using .live() to the rows of the table. Inside this method, determine which element was clicked (e.currentTarget). You can use a simple conditional to check if it was a button that needs to react. Then, use DOM traversal to nail down what you want to have happen. For example, if e.currentTarget is the delete button, the you can use $(this).closest('tr').remove(); to delete the row. If you need to interact with the data through ajax, make your ajax function support passing in whatever valus you'd need (id) to perform the delete. In order to obtain the id, you'll need to get it from the ajax call and put it somewhere inside the DOM so you can retrieve it when you need it. You can always toss in a 'title' attribute when the tr is generated.
Here is a same script with php
http://www.amitpatil.me/add-edit-delete-rows-dynamically-using-jquery-php/
// Add new record
$(document).on("click","."+editbutton,function(){
var id = $(this).attr("id");
if(id && editing == 0 && tdediting == 0){
// hide editing row, for the time being
$("."+table+" tr:last-child").fadeOut("fast");
var html;
html += "<td>"+$("."+table+" tr[id="+id+"] td:first-child").html()+"</td>";
for(i=0;i<columns.length;i++){
// fetch value inside the TD and place as VALUE in input field
var val = $(document).find("."+table+" tr[id="+id+"] td[class='"+columns[i]+"']").html();
input = createInput(i,val);
html +='<td>'+input+'</td>';
}
html += '<td><img src="'+updateImage+'"> <img src="'+cancelImage+'"></td>';
// Before replacing the TR contents, make a copy so when user clicks on
trcopy = $("."+table+" tr[id="+id+"]").html();
$("."+table+" tr[id="+id+"]").html(html);
// set editing flag
editing = 1;
}
});