Error Event Dojo Change event and query feature layer - dojo

From a select list and a feature layer, I´m trying to make a query feature layer but I don´t know what´s going on
<select name="select1" id="select">
<option value="Artesania">Artesania</option>
<option value="Banco" selected="selected">Banco</option>
<option value="Bar">Bar</option>
<option value="Bodega">Bodega</option>
<option value="Boutique">Boutique</option>
<option value="Discoteca">Discoteca</option>
/select>
var mapMain;
require([
"esri/map",
"dojo/ready",
"dojo/parser",
"dojo/on",
"dojo/dom",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"esri/dijit/HomeButton",
"esri/dijit/Scalebar",
"esri/layers/FeatureLayer",
"esri/tasks/QueryTask",
"esri/tasks/query",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/Color",
"dijit/form/Select"],
function (Map,
ready,
parser,
on,
dom,
BorderContainer,
ContentPane,
HomeButton,
Scalebar,
FeatureLayer,
QueryTask,
Query,
SimpleMarkerSymbol,
SimpleLineSymbol,
Color
) {
ready(function () {
parser.parse();
// Create the map
mapMain = new Map("cpCenter", {
basemap: "topo",
center: [-5.61094, 36.016],
zoom: 15
});//map
var home = new HomeButton({
map: mapMain
}, "HomeButton");
home.startup();//homebutton
var scalebar = new Scalebar({
map: mapMain,
scalebarUnit: "dual"
});//scalebar
I suspect my problem is the event change
on(select, "change", function(evt){
var SeleccLocal = dom.byId("select").value;
alert("Valor del select es: " + SeleccLocal);
Define a query, after that I will create a Feature Layer
var query = new Query();
query.where = "Tienda = " + SeleccLocal;
query.returnGeometry = true;
console.log(query)
> Create a new symbol
var marker = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 10,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([255,0,0]), 1),
new Color([0,255,0,0.25]));
Create a FeatureLayer with a query selection
var localOSM = new FeatureLayer(localesOSM);
localOSM.selectFeatures(query,FeatureLayer.SELECTION_NEW);
//localOSM.setDefinitionExpression("Tienda = Discoteca");
Add the symbol into feature layer
localOSM.setSelectionSymbol(marker);
Add Feature Layer
mapMain.addLayer(localOSM);
});//on select
});//ready
});//requiere
And I always obtain the same error
dojo.io.script error Error: Failed to execute query.
at Object.h.load (init.js:885)
at init.js:191
at c (init.js:76)
at d (init.js:76)
at b.Deferred.resolve.callback (init.js:77)
at c (init.js:76)
at d (init.js:76)
at b.Deferred.resolve.callback (init.js:77)
at init.js:1507
at k (init.js:199)

Related

Concat value into API url in Vue

I am trying something very simple in Vue and can't get it to work.. I want my API url to update with 2 new values (valueFrom and valueTwo). I am using fetch for this.
When I console log the values, they work (2021-06-17 etc). But as soon as I put them in the url, it just comes up empty.
Here are my input fields:
<label for="dateFrom" class="mr-sm-2">From</label>
<b-form-datepicker id="dateFrom" v-model="valueFrom" class="mb-2 mr-sm-4 mb-sm-0 w-25" :min="min" :max="max"></b-form-datepicker>
<label for="dateTo" class="mr-sm-2">To</label>
<b-form-datepicker id="dateTo" v-model="valueTo" class="mb-2 mr-sm-4 mb-sm-0 w-25" :min="min" :max="max"></b-form-datepicker>
Here is the button that calls the fetch:
<b-button variant="primary" #click="$fetch()">Search</b-button>
Here is my Vue code:
data() {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const minDate = new Date(today);
const maxDate = new Date(today);
maxDate.setMonth(maxDate.getMonth() + 6);
return {
items: {},
valueFrom: '',
valueTo: '',
min: minDate,
max: maxDate
}
},
async fetch() {
const api = 'https://apiurl.com/ajax/locationSearchJSON/?location=Edinburgh&arrival=${this.valueFrom}&arrivalTime=12%3A00&departure={$this.valueTo}&departureTime=12%3A00
this.items = await fetch(api).then(res => res.json())
}
I also tried concating them in the javascript way (' + this.valueFrom + ') but that just rendered an empty string as well...
You can try using the backticks/backquotes (``) in place of the apostrophes. So your url will end up as below:
`https://apiurl.com/ajax/locationSearchJSON/?location=Edinburgh&arrival=${this.valueFrom}&arrivalTime=12%3A00&departure=${this.valueTo}&departureTime=12%3A00`
Also check the second variable this.valueTo has been added to the url correctly. In your case above this is how you've added it:
{$this.valueTo}
It should be:
${this.valueTo}

How to test datepicker in non-angular website using Protractor

Help, please,to correctly write a test of datepicker.
I have an unclickable field where my selected date will be set:
<input type="text" class="submit hasDatepicker" placeholder="License Expiry Date*"
name="website_field[bGl==]"
id="website_field_bGl" value="" size="16"
readonly="readonly">
with clickable button that opens a date-form:
<img class="ui-datepicker-trigger" src="images/calendar.png" alt="Select date"
title="Select date">
month:
<select class="ui-datepicker-month" data-handler="selectMonth" data-
event="change"><option value="0">Jan</option></select> ...
year:
<select class="ui-datepicker-year" data-handler="selectYear" data-
event="change"><option value="2000">2000</option></select> ...
and a script:
$(function(){
$( "#website_field_bGljZW5zZSBleHBpcnkgZGF0ZQ"
).datepicker({
changeMonth: true,
changeYear: true,
firstDay:1,
dateFormat: "yy-mm-dd",
showOn: "button",
buttonImage: "images/calendar.png",
buttonImageOnly: true,
buttonText: "Select date",
minDate: "2000-01-01",
yearRange: "2000:+15"
}).attr("readonly", "readonly");
});
I need to set a date, for example: 2020-07-14.
How to do this?
Thanks.
I did smth primitive and it works. But maybe there is more 'pro' variant available?:
var LicenceExpiryDateInputField =
element(by.id('website_field_bGljZW5zZSBleHBpcnkgZGF0ZQ'));
var LicenceExpiryDateButton = $('img.ui-datepicker-trigger');
var LicenceExpiryDateForm = element(by.id('ui-datepicker-div'));
var SelectMonth = $('select.ui-datepicker-month').$('[value="6"]');
var SelectYear = $('select.ui-datepicker-year').$('[value="2020"]');
var SelectDate = element(by.linkText('14'));
LicenceExpiryDateButton.click();
expect(LicenceExpiryDateForm.isPresent()).toBe(true);
SelectMonth.click();
expect(SelectMonth.isSelected()).toBe(true);
expect(SelectMonth.getText()).toEqual('Jul');
SelectYear.click();
expect(SelectYear.isSelected()).toBe(true);
expect(SelectYear.getText()).toBe('2020');
SelectDate.click();
expect(...Here i need to check somehow LicenceExpiryDateInputField on correct data (2020-07-14)...)

How to dynamically populate a Picker using Alloy with Appcelerator?

Is there a way to populate a picker dynamically? This works for option dialogs:
view.xml:
<OptionDialog id="distributionPointsOptionDialog">
<Options>
<Option id="{dp}"></Option>
</Options>
</OptionDialog>
controller.js:
var dp = [];
for (var j in _data) {
if (_data[j].country == country) {
dp.push(_data[j].city + "-" + _data[j].dp_name);
}
}
$.distributionPointsOptionDialog.options = dp;
Is there a way to do the same for a multi-column picker? I tried unsuccessfully to populate a single-column picker.
controller.js:
var fs = Ti.Filesystem;
var installedFonts = fs.getFile(fs.resourcesDirectory+ "/fonts").getDirectoryListing();
Ti.API.info("list of resourcesDirectory fonts: " + JSON.stringify(installedFonts));
var fonts = [];
for (var j in installedFonts) {
fonts.push(installedFonts[j]);
}
$.testPicker.column = fonts;
views.xml:
<Picker id="testPicker" selectionIndicator="true" height="Ti.UI.SIZE" width="70%" visible="true" zIndex="200" useSpinner="true">
<Column>
<Row title="{fonts}"></Row>
</Column>
</Picker>
This results in an error:
ERROR] : message = "undefined is not an object (evaluating '$model.__transform')";
There are couple of wrong things with your implementation.
useSpinner property has been deprecated, so please remove that from your code.
The way you are implementing Options & Pickers is a process of Alloy-Model binding.
For dynamic Options, you can simply use below code:
<OptionDialog id="distributionPointsOptionDialog"></OptionDialog>
$.distributionPointsOptionDialog.options = ['Helvetica', 'Arial', 'Times New Roman'];
<Option id="{dp}"></Option> - this syntax is used for Model data binding
For Picker, use below code:
var fonts = [];
fonts[0]=Ti.UI.createPickerRow({title:'Helvetica'});
fonts[1]=Ti.UI.createPickerRow({title:'Arial'});
fonts[2]=Ti.UI.createPickerRow({title:'Times New Roman'});
fonts[3]=Ti.UI.createPickerRow({title:'Georgia'});
$.testPicker.add(fonts);
OR
var column = Ti.UI.createPickerColumn();
column.add( Ti.UI.createPickerRow({ title: 'Helvetica' }) );
column.add( Ti.UI.createPickerRow({ title: 'Arial' }) );
column.add( Ti.UI.createPickerRow({ title: 'Times New Roman' }) );
column.add( Ti.UI.createPickerRow({ title: 'Georgia' }) );
$.testPicker.columns = [column];
For Pickers, in short, you can either use $.testPicker.add() method, or you can set columns like this $.testPicker.columns = [column1, column2, column1, ...]
Read more here How to add Columns or Rows in Pickers
or
How to add column(s) in Picker

Product autocomplete input on module (Prestashop)

I'm developing a prestashop module that has to make lists of existing products.
For the configuration panel of the module, using renderForm() and getContent(), I'm trying to replicate the "accesories" capability, where you start writing some info of a product on an input, and it shows the products that are a match. When selecting that product, it gets added on a list. Like this:
This a screenshot of Catalog / Products / Associations tab.
I'm trying with PS 1.6.0.14 and PS1.6.1.0RC3. How would I replicate this functionality to get lists of products on a module configuration panel?
I tried looking here Prestashop AdminProductsController.php but I don't really understand where half of that info is coming from.
There is an autocomplete plugin in prestashop you got to use that for this. Its in js->jquery->plugins you got to add this plugin into your module to make it work.
I think that to achieve that functionality, the renderForm() function won't be enough since you have to bind some javascript and some custom html.
The process of writing a fully functional module is a bit long but by taking the accessories functionality as a starting point it wont be so hard and you will always have a reference on "how-to-do-it".
I would go with this:
1) first create your
getContent()
function to be able to show the custom template and the product associated by your module so we will have something along:
public function getContent(){
//post process part to save the associations
if(Tools::isSubmit('saveMyAssociations'){
... //we will see it later
}
$my_associations = MyModule::getAssociationsLight($this->context->language->id,Tools::getValue('id_product')); //function that will retrieve the array of all the product associated on my module table.
$this->context->smarty->assign(array(
'my_associations' => $my_associations,
'product_id' => (int)Tools::getValue('id_product')
));
return $this->display(__FILE__, 'views/templates/admin/admintemplate.tpl'); //custome template to create the autocomplete
}
//our little function to get the already saved list, for each product we will retrieve id, name and reference with a join on the product/product_lang tables.
public static function getAssociationsLight($id_lang, $id_product, Context $context = null)
{
if (!$context)
$context = Context::getContext();
$sql = 'SELECT p.`id_product`, p.`reference`, pl.`name`
FROM `'._DB_PREFIX_.'my_associations`
LEFT JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product`= `id_product_2`)
'.Shop::addSqlAssociation('product', 'p').'
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
)
WHERE `id_product_1` = '.(int)$id_product;
return Db::getInstance()->executeS($sql);
}
2) create a template that will be able to show the automplete and the list.
Here we will loop trough the saved associations to create our autocomplete list, and we will do it with some hidden field to keep track of the ids/name and also a visible list were we will have a delete button for each row.
<input type="hidden" name="inputMyAssociations" id="inputMyAssociations" value="{foreach from=$my_associations item=accessory}{$accessory.id_product}-{/foreach}" />
<input type="hidden" name="nameMyAssociations" id="nameMyAssociations" value="{foreach from=$my_associations item=accessory}{$accessory.name|escape:'html':'UTF-8'}¤{/foreach}" />
<div id="ajax_choose_product_association">
<div class="input-group">
<input type="text" id="product_autocomplete_input_association" name="product_autocomplete_input_association" />
<span class="input-group-addon"><i class="icon-search"></i></span>
</div>
</div>
<div id="divMyAssociations">
{foreach from=$my_associations item=accessory}
<div class="form-control-static">
<button type="button" class="btn btn-default delAssociation" name="{$accessory.id_product}">
<i class="icon-remove text-danger"></i>
</button>
{$accessory.name|escape:'html':'UTF-8'}{if !empty($accessory.reference)}{$accessory.reference}{/if}
</div>
{/foreach}
</div>
<input type="submit" name="submitMyAssociations" id="submitMyAssociations" value="Send"/>
<input type="hidden" name="productId" id="productId" value="{$product_id|escape:'html'}"/>
3) Now we can add the javascript to bind an autocomplete on the main input and perform all the logic for each action
$(document).ready(function(){
//our function wrapper.
var initMyAssociationsAutocomplete = function (){
//initialize the autocomplete that will point to the default ajax_products_list page (it returns the products by id+name)
$('#product_autocomplete_input_association')
.autocomplete('ajax_products_list.php', {
minChars: 1,
autoFill: true,
max:20,
matchContains: true,
mustMatch:true,
scroll:false,
cacheLength:0,
formatItem: function(item) {
return item[1]+' - '+item[0];
}
}).result(addAssociation);
//as an option we will add a function to exclude a product if it's already in the list
$('#product_autocomplete_input_association').setOptions({
extraParams: {
excludeIds : getAssociationsIds()
}
});
};
//function to exclude a product if it exists in the list
var getAssociationsIds = function()
{
if ($('#inputMyAssociations').val() === undefined)
return '';
return $('#inputMyAssociations').val().replace(/\-/g,',');
}
//function to add a new association, adds it in the hidden input and also as a visible div, with a button to delete the association any time.
var addAssociation = function(event, data, formatted)
{
if (data == null)
return false;
var productId = data[1];
var productName = data[0];
var $divAccessories = $('#divCrossSellers');
var $inputAccessories = $('#inputMyAssociations');
var $nameAccessories = $('#nameMyAssociations');
/* delete product from select + add product line to the div, input_name, input_ids elements */
$divAccessories.html($divAccessories.html() + '<div class="form-control-static"><button type="button" class="delAssociation btn btn-default" name="' + productId + '"><i class="icon-remove text-danger"></i></button> '+ productName +'</div>');
$nameAccessories.val($nameAccessories.val() + productName + '¤');
$inputAccessories.val($inputAccessories.val() + productId + '-');
$('#product_autocomplete_input_association').val('');
$('#product_autocomplete_input_association').setOptions({
extraParams: {excludeIds : getAssociationsIds()}
});
};
//the function to delete an associations, delete it from both the hidden inputs and the visible div list.
var delAssociations = function(id)
{
var div = getE('divMyAssociations');
var input = getE('inputMyAssociations');
var name = getE('nameMyAssociations');
// Cut hidden fields in array
var inputCut = input.value.split('-');
var nameCut = name.value.split('¤');
if (inputCut.length != nameCut.length)
return alert('Bad size');
// Reset all hidden fields
input.value = '';
name.value = '';
div.innerHTML = '';
for (i in inputCut)
{
// If empty, error, next
if (!inputCut[i] || !nameCut[i])
continue ;
// Add to hidden fields no selected products OR add to select field selected product
if (inputCut[i] != id)
{
input.value += inputCut[i] + '-';
name.value += nameCut[i] + '¤';
div.innerHTML += '<div class="form-control-static"><button type="button" class="delAssociation btn btn-default" name="' + inputCut[i] +'"><i class="icon-remove text-danger"></i></button> ' + nameCut[i] + '</div>';
}
else
$('#selectAssociation').append('<option selected="selected" value="' + inputCut[i] + '-' + nameCut[i] + '">' + inputCut[i] + ' - ' + nameCut[i] + '</option>');
}
$('#product_autocomplete_input_association').setOptions({
extraParams: {excludeIds : getAssociationsIds()}
});
};
//finally initialize the function we have written above and create all the binds.
initMyAssociationsAutocomplete();
//live delegation of the deletion button to our delete function, this will allow us to delete also any element added after the dom creation with the ajax autocomplete.
$('#divMyAssociations').delegate('.delAssociation', 'click', function(){
delAssociations($(this).attr('name'));
});
});
4) now you just need to save the associations made by your module autocomplete, and i suggest to perform it by first deleting any association made on a given product and then saving all of them. so you don't have to care about inserting or updating an entry
public function getContent(){
//post process part
if(Tools::isSubmit('saveMyAssociations'){
$product_id = (int)Tools::getValue('productId');
// see the function below, a simple query to delete all the associations on a product
$this->deleteMyAssociations($product_id);
if ($associations = Tools::getValue('inputMyAssociations'))
{
$associations_id = array_unique(explode('-', $associations));
if (count($associations_id))
{
array_pop($associations_id);
//insert all the association we have made.
$this->changeMyAssociations($associations_id, $product_id);
}
}
}
}
protected function deleteMyAssociations($product_id){
return Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'my_associations` WHERE `id_product_1` = '.(int)$product_id);
}
protected function changeMyAssociations($associations_id, $product_id){
foreach ($associations_id as $id_product_2)
Db::getInstance()->insert('my_associations', array(
'id_product_1' => (int)$product_id,
'id_product_2' => (int)$id_product_2
));
}
I hope it can help you to go through all of this.

MVC4 dropdown helper with references

I use MVC4 and trying to make dropdown with links. I wrote a helper:
public static MvcHtmlString LanguageSelectorDropdown(this System.Web.Mvc.HtmlHelper helper, string name)
{
var culture = Thread.CurrentThread.CurrentCulture;
IList<Culture> data = new CultureRepository().GetEnabled();
var items = new List<SelectListItem>();
items.AddRange(
(from item in data
select new SelectListItem()
{
Text = #"<a href='/Home/Edit/3'>I am a link</a>", //it's only example. Here I run the other method to get dynamic link
Value = item.ID.ToString(),
Selected = culture.Name.Equals(item.ID)
}).ToList());
return new MvcHtmlString(HttpUtility.HtmlDecode(helper.DropDownList(name, items).ToString()));
}
At the end of this method I have:
helper.DropDownList(name, items).ToString() = "<select id=\"LanguageSelector\" name=\"LanguageSelector\"><option value=\"de-DE\"><a href='/Home/Edit/3'>I am a link</a></option>\r\n<option value=\"en-US\"><a href='/Home/Edit/3'>I am a link</a></option>\r\n<option selected=\"selected\" value=\"ru-RU\"><a href='/Home/Edit/3'>I am a link</a></option>\r\n</select>"
HttpUtility.HtmlDecode(helper.DropDownList(name, items).ToString()) = "<select id=\"LanguageSelector\" name=\"LanguageSelector\"><option value=\"de-DE\"><a href='/Home/Edit/3'>I am a link</option>\r\n<option selected=\"selected\" value=\"ru-RU\"><a href='/Home/Edit/3'>I am a link</a></option>\r\n</select>"
In result html page:
<select id="LanguageSelector" name="LanguageSelector">
<option value="de-DE">I am a link</option>
<option value="en-US">I am a link</option>
<option value="ru-RU" selected="selected">I am a link</option>
</select>
It looks like links disappeared. Is there any way to force it work?