sfWidgetFormDoctrineJQueryAutocompleter - events not working - javascript

I'm using the sfWidgetFormDoctrineJQueryAutocompleter from the sfFormExtraPlugin, an try to bind some event to the widget.
According to http://jqueryui.com/demos/autocomplete/#event-search there is a way to bind an event to the launch of a search.
However, it doesn't seems to work on the widget.
My code:
$this->widgetSchema['author_id'] = new sfWidgetFormDoctrineJQueryAutocompleter(array(
'model' => 'Employee',
'method' => 'getFullName',
'method_for_query' => 'findOneByEmployeeNumber',
'url' => '/backend_dev.php/employee/search',
'config' => '{
minChars: 3,
search: function(event, ui) { alert("Search!"); } //Should popup an alert() when the search is launched.
}'
));
However, when I fill the form, the search is launched, results are shown, but no alert is displayed.
Any ideas ?
Thanks.
Edit
Generated Javascript:
<label for="document_author_id">Author</label>
<input type="hidden" id="document_author_id" value="00000006" name="document[author_id]">
<input type="text" id="autocomplete_document_author_id" value="Michaƫl Jones" name="autocomplete_document[author_id]" autocomplete="off" class="ac_input">
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#autocomplete_document_author_id")
.autocomplete('/backend_dev.php/employee/search', jQuery.extend({}, {
dataType: 'json',
parse: function(data) {
var parsed = [];
for (key in data) {
parsed[parsed.length] = { data: [ data[key], key ], value: data[key], result: data[key] };
}
return parsed;
}
}, {
minChars: 3,
search: function(event, ui) { alert("Search!"); }
}))
.result(function(event, data) { jQuery("#document_author_id").val(data[1]); });
});
</script>

Try to put this at the end of your form.php (?) template
<?php javascript_tag(); ?>
jQuery().ready(function(){
// or use ID #autocomplete_document_author_id
jQuery(".ac_input").search(function(event, ui){
alert("Search!");
});
});
<?php end_javascript_tag(); ?>

Related

Yii2 Dynamic Form Select2 Change Event not working from second index

I was trying to create a dynamic form for one of my project. I initialized a ajax request to retrieve value for a field.
<div class="row">
<div class="col-md-4">
<?php echo $form->field($modelAddress, "[{$i}]rt_item")->widget(Select2::class, [
'data' => $invListData,
'options' => ['placeholder' => '--Select Request Type--', 'class' => 'form-control'],
'pluginOptions' => [
'allowClear' => true
],
'pluginEvents' => [
'select2:select' => 'function(params) {
var itemVal = $(this).val();
var attrID = $(this).attr("id").replace(/[^0-9.]/g, "");
$.ajax({
"url" : "units",
"type" : "post",
"data" : {itemID: itemVal},
success: function (data) {
console.log(data);
console.log(attrID);
$("#reqitems-"+attrID+"-rt_unit").val(data);
},
error: function (errormessage) {
//do something else
alert("not working");
}
});
}',
],
]); ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelAddress, "[{$i}]rt_unit")->textInput(['maxlength' => true, 'readOnly' => 'true']) ?>
</div>
The ajax is working perfectly in the first index of the dynamic form. But unfortunately from the send index, nothing is happening. I checked couple of questions & answers in stackoverflow for the situation, but everything failed.
Can anyone help me to find a solution?
Hi found a solution in an alternative way using jquery.
Since the elements are dynamically loaded, we need dynamically generate via AJAX or something similar the following input element. I removed the pluginEvent and initialized a new class for dynamic field.
<?php echo $form->field($modelAddress, "[{$i}]rt_item")->widget(Select2::class, [
'data' => $invListData,
'options' => ['placeholder' => '--Select Request Type--', 'class' => 'reqItem form-control'],
'pluginOptions' => [
'allowClear' => true
]); ?>
Then manually I wrote jquery script to read the element.
<script>
$(document).on("change", ".reqItem", function() {
var itemVal = $(this).val();
var attrID = $(this).attr("id").replace(/[^0-9.]/g, "");
$.ajax({
"url": "units",
"type": "post",
"data": {
itemID: itemVal
},
success: function(data) {
console.log(data);
console.log(attrID);
$("#reqitems-" + attrID + "-rt_unit").val(data);
},
error: function(errormessage) {
//do something else
alert("not working");
}
});
});
But still I am working to find the appropriate solution using Yii.

Navigating a json file to create desired array for jquery autocomplete

I am programming an autocomplete function for a search bar that features names of places in Norway.
I collect the data from a REST api URL provided by a third party.
Example with input "st" and two results:
{
"sokStatus":{
"ok":"true",
"melding":""
},
"totaltAntallTreff":"81280",
"stedsnavn":[
{
"ssrId":"23149",
"navnetype":"By",
"kommunenavn":"Larvik",
"fylkesnavn":"Vestfold",
"stedsnavn":"Stavern",
"aust":"214841.84",
"nord":"6550500.29",
"skrivemaatestatus":"Godkjent",
"spraak":"NO",
"skrivemaatenavn":"Stavern",
"epsgKode":"25833"
},
{
"ssrId":"506202",
"navnetype":"By",
"kommunenavn":"Stord",
"fylkesnavn":"Hordaland",
"stedsnavn":"Stord",
"aust":"-32194.93",
"nord":"6665261.05",
"skrivemaatestatus":"Godkjent",
"spraak":"NO",
"skrivemaatenavn":"Stord",
"epsgKode":"25833"
}
]
}
I want to have the autocomplete array contain the "stedsnavn" features from all the returned results in the json file. so for the above example it would be [Stavern, Stord].
I built my code based off a template/tutorial i found online. When I run it now the autocomplete suggestion is the "totaltAntallTreff" feature so for the json above it would suggest 81280.
Edit: What I really need to know is how to properly query the json where I now only have response(data). I have tried several methods ($.map, $.each) but whenever I modify my code it ends up giving no autocomplete suggestions.
See my code below
$(function () {
var getData = function (request, response) {
$.getJSON(
"https://ws.geonorge.no/SKWS3Index/ssr/json/sok?antPerSide=5&eksakteForst=false&navn=" + request.term + "*",
function (data) {
(response(data));
});
};
var selectItem = function (event, ui) {
$("#myText").val(ui.item.value);
return false;
}
$("#myText").autocomplete({
source: getData,
select: selectItem,
minLength: 1,
change: function() {
$("#myText").val("").css("display", 2);
}
});
});
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery.ui.autocomplete.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<div id="menu-container">
<input type="text" id="myText" />
</div>
Given the JSON structure provided, you could get the result with the following:
let json_data = {
"sokStatus": {
"ok": "true",
"melding": ""
},
"totaltAntallTreff": "81280",
"stedsnavn": [{
"ssrId": "23149",
"navnetype": "By",
"kommunenavn": "Larvik",
"fylkesnavn": "Vestfold",
"stedsnavn": "Stavern",
"aust": "214841.84",
"nord": "6550500.29",
"skrivemaatestatus": "Godkjent",
"spraak": "NO",
"skrivemaatenavn": "Stavern",
"epsgKode": "25833"
},
{
"ssrId": "506202",
"navnetype": "By",
"kommunenavn": "Stord",
"fylkesnavn": "Hordaland",
"stedsnavn": "Stord",
"aust": "-32194.93",
"nord": "6665261.05",
"skrivemaatestatus": "Godkjent",
"spraak": "NO",
"skrivemaatenavn": "Stord",
"epsgKode": "25833"
}
]
}
let values = json_data.stedsnavn.map(item => item.skrivemaatenavn);
values.forEach(value => {
$("#list").append(`<li>${value}</li>`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="list"><ul>
As to what json_data.stedsnavn.map(item => item.skrivemaatenavn); is doing:
json_data.stedsnavn.map(item => item.skrivemaatenavn);
// Get the "stedsnavn" key from the data, an array
// Map each object in the array to
// its "skrivemaatenavn" key

Kendo UI javascript : remote bind form

I'm having trouble getting started with binding a Form to a remote Datasource in Kendo UI for javascript
I have verified that the ajax call returns the correct JSONP payload, e.g:
jQuery31006691693527470279_1519697653511([{"employee_id":1,"username":"Chai"}])
Below is the code:
<script type="text/javascript">
$(document).ready(function() {
var viewModel = kendo.observable({
employeeSource: new kendo.data.DataSource({
transport: {
read: {
url: baseUrl + "/temp1",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {
models: kendo.stringify(options.models)
};
}
return options;
}
},
batch: true,
schema: {
model: {
id: "employee_id",
fields:{
employee_id: { type: "number" },
username: { type: "string" }
}
}
}
}),
hasChanges: false,
save: function() {
this.employeeSource.sync();
this.set("hasChanges", false);
},
change: function() {
this.set("hasChanges", true);
}
});
kendo.bind($("#item-container"), viewModel);
viewModel.employeeSource.read();
});
</script>
<div id="item-container">
<div class="row">
<div class="col-xs-6 form-group">
<label>Username</label>
<input class="form-control k-textbox" type="text" id="username" data-bind="value: username, events: { change: change }" />
</div>
</div>
<button data-bind="click: save, enabled: hasChanges" class="k-button k-primary">Submit All Changes</button>
</div>
No errors are thrown, but I was expecting my username text form field to be populated with the value 'Chai', and so on.. but it doesn't
Your textbox is bound to a username property but this doesn't exist on your view-model, nor is it being populated anywhere. Assuming your datasource correctly holds an employee after your call to read(), you will need to extract it and set it into your viewmodel using something like this:
change: function(e) {
var data = this.data();
if (data.length && data.length === 1) {
this.set("employee", data[0]);
this.set("hasChanges", true);
}
}
And modify the binding(s) like this:
<input class="form-control k-textbox" type="text" id="username"
data-bind="value: employee.username, events: { change: change }" />
You should also be aware that the change event is raised in other situations, so if you start using the datasource to make updates for example, you'll need to adapt that code to take account of the type of request. See the event documentation for more info. Hope this helps.

Send multiple field arrays via ajax to Laravel 5

I need help with saving a drag n drop menu order. I use http://farhadi.ir/projects/html5sortable to drag and update the list. Each menu item has two hidden fields: id and order. The order is updated dynamically when dropped. I don't know how to turn the fields id and order into a correct array so I can update via AJAX into Laravel.
HTML - Menu :
<div>
<input name="menu[1][id]" type="hidden" value="1">
<input name="menu[1][order]" class="new-order" type="hidden" value="3">
</div>
<div>
<input name="menu[2][id]" type="hidden" value="2">
<input name="menu[2][order]" class="new-order" type="hidden" value="4">
</div>
<div>
<input name="menu[3][id]" type="hidden" value="3">
<input name="menu[3][order]" class="new-order" type="hidden" value="5">
</div>
jQuery - Drag/drop, update order value then send via ajax :
// Sortable options
$('.nav-pages__items').sortable({
handle: '.nav-pages__drag',
items: ':not(.home)'
}).bind('sortupdate', function() {
// When dropped clear list order
$(this).find('input[name=menu]').attr('value', '');
// Then update list order
$('.nav-pages__items li:not(.home)').each(function(i, element) {
element = i+1;
$(this).find('input.new-order').attr('value'),
$(this).find('input.new-order').attr('value', + element);
});
// !! Somehow create array to send/save !!
// Ajax to send
$.post('/menu-update', {
_token: token,
id: id,
order: order
}, function(data) {
if (data.status == 'success') {
console.log('success: ', data);
} else if (data.error == 'error') {
console.log('error: ', data);
};
});
});
PHP/Laravel - Not got this far (without errors):
public function update()
{
$menu = Input::all();
$save = Page::where('id', $menu['id'])->update([
'order' => $menu['order']
]);
if ($save) {
$response = [
'status' => 'success',
'msg' => 'Message here',
'id' => $menu['id'],
'order' => $menu['order'],
];
};
return Response::json($response);
}
To summarise:
Get the id and order for each field group
Loop though them in js and crate correct array
Send array to Laravel and update order based on id
Also, if there's a much simpler way to do this, I'm all ears.
I don't believe you need those hidden inputs -- what about something like:
jQuery:
// Sortable options
$('.nav-pages__items').sortable({
handle: '.nav-pages__drag',
items: ':not(.home)'
}).bind('sortupdate', function() {
// Collect the new orderings
var newOrders = [];
$('.nav-pages__items li:not(.home)').each(function(i, element) {
var id = $(element).data('id'); // Set a data-id attribute on each li
var order = i;
newOrders[order] = id;
});
// Ajax to send
$.post('/menu-update', {
_token: token,
newOrders: newOrders
}, function(data) {
if (data.status == 'success') {
console.log('success: ', data);
} else if (data.error == 'error') {
console.log('error: ', data);
};
});
});
PHP/Laravel:
public function update()
{
$responses = [];
foreach (Input::get('newOrders') AS $order => $id) {
$save = Page::where('id', $id)->update([
'order' => $order
]);
if ($save) {
$response[$id] = [
'status' => 'success',
'msg' => 'Message here',
'id' => $id,
'order' => $order,
];
}
}
return Response::json($responses);
}

Allowing select2 jquery ajax in tag mode to repeat tags

I am using select2-jquery to bring several items from the server (ajax) and the allow the user to select several of them, it works fine but I cannot select any given tag more than once and that's a requirement I'll paste some of my code, hopefully it helps. I have inspected the ajax requests and i can see the same data getting back from the server under the same search terms, but once an item is selected the select2 does NOT displays it anymore
This is a part of my View:
<div class="form-group">
#Html.LabelFor(m => m.Vals, T("Values"), new { #class = "control-label col-md-2" })
<div class="col-md-7">
<input id="Values" name="Values" type="hidden" style="width: 100%" data-url="#Url.Action("Action", "Controller")" />
</div>
</div>
And this is the JS part:
$(function () {
var fullTemplateString = 'some template string';
var resultTemplateString = 'other template';
var $selectInput = $('#Values');
initilizeSelect2($selectInput, fullTemplateString, resultTemplateString);
});
function initilizeSelect2($selectInput, fullTemplate, resultTemplate) {
$selectInput.select2({
placeholder: "Select Labs",
minimumInputLength: 2,
multiple: true,
tokenSeparators: [","],
tags: false,
ajax: {
url: $selectInput.data('url'),
dataType: 'json',
quietMillis: 250,
data: function(term, page) {
return {
term: term,
};
},
results: function(data, page) {
return {
results: data
};
}
},
formatSelection: function (item) {
return format(item, resultTemplate);
},
formatResult: function (item) {
return format(item, fullTemplate);
},
escapeMarkup: function (m) { return m; }
});
}
function format(item, templateString) {
var result = templateString
.replace(/\^\^id\^\^/g, item.id)
.replace(/\^\^icon\^\^/g, item.icon)
.replace(/\^\^text\^\^/g, item.name)
.replace(/\^\^desc\^\^/g, item.desc);
return result;
}
I am using select2 version:3.4.5 extensively in this project so any changes in this regard would be very painful
Thanks in advance
after a lot of search and debugging through the select2 code i found a way (hack) to pull this out by removing the css class .select2-selected that prevents already selected elements from displaying again. I know this isn't the best solution there is, but it is working now. I really welcome any improvements or better solutions

Categories