I'm trying to capture if the enter key has been pressed and execute a search. This is the viewmodel for the search page.
(function ()
{
a.viewModels.userSearch = function (view, params) {
$view = $(view);
var self = a.viewModel({
users: a.collection({
url: '/admin/Account/SearchUsers',
query: {
SearchText: null
}
}).fetch(),
setPageIndex: setPageIndex,
search: search
});
$view.keypress(function (e) {
if (e.keyCode == 13) {
self.search(e);
}
});
function search(e) {
self.users.query.rowCount = 0;
self.users.query.pageIndex = 1;
self.users.fetch();
}
function setPageIndex(e) {
e.preventDefault();
self.users.query.set('pageIndex', $(e.currentTarget).data('page-index'));
self.users.fetch();
}
return self;
}
Now, this works. The problem is that it works only after pressing the 'Enter' key 2 times. Seems like I'm missing something related to the scope but js ain't my cup of tea.
If it is of any help, here goes my view model function:
function viewModel(viewModelConfig) {
var self = kendo.observable($.extend({
busy: 0,
resultMessage: null,
clearResultMessage: clearResultMessage
}, viewModelConfig));
self.bind('change', onChange);
function onChange(change) {
var errorProp, errorMsg, infoProp, infoMsg;
if (change.field.endsWith('.busy')) {
if (self.get(change.field))
self.set('busy', self.busy + 1);
else if (self.busy > 0)
self.set('busy', self.busy - 1);
}
else if (change.field.endsWith('.resultMessage')) {
var data = self.get(change.field);
self.set('resultMessage', data);
}
}
function clearResultMessage(e)
{
if (e) e.preventDefault();
self.set('resultMessage', null);
return false;
}
return self;
}
I have a similar setup on my site, and using MVVM, just add the custom enter binding within the data-bind attribute of the element to link to the function within the view-model you wish to execute.
The code to add the custom binder is as such:
kendo.data.binders.widget.enter = kendo.data.Binder.extend({
init: function(element, bindings, options) {
kendo.data.Binder.fn.init.call(this, element, bindings, options);
var binding = this.bindings.enter;
$(element.element).keyup(function(e) {
if( e.which === 13 )
bindings.get();
});
},
refresh: $.noop
});
Related
I have a model say 'my.attendance' , also have a form view for this which contains some attendance details.What i need is when i open this form view it should always open in Edit mode.So i can directly enter the attendance without clicking Edit button each time.
You have to extend the ViewManager to achieve this.
odoo.define('my_module.view_manager', function (require) {
"use strict";
var ViewManager = require('web.ViewManager');
ViewManager.include({
custom_events: {
execute_action: function(event) {
var data = event.data;
this.do_execute_action(data.action_data, data.env, data.on_closed)
.then(data.on_success, data.on_fail);
},
search: function(event) {
var d = event.data;
_.extend(this.env, this._process_search_data(d.domains, d.contexts, d.groupbys));
this.active_view.controller.reload(_.extend({offset: 0}, this.env));
},
switch_view: function(event) {
if ('res_id' in event.data) {
this.env.currentId = event.data.res_id;
}
var options = {};
console.log(event.data)
if (event.data.view_type === 'form' && !this.env.currentId) {
options.mode = 'edit';
} else if (event.data.mode) {
options.mode = event.data.mode;
}
// Extra added code
if (event.data.model){
if (event.data.model == 'my.model'){ // Checking the particular model.
options.mode = 'edit';
}
}
this.switch_mode(event.data.view_type, options);
},
env_updated: function(event) {
_.extend(this.env, event.data);
},
push_state: function(event) {
this.do_push_state(event.data);
},
get_controller_context: '_onGetControllerContext',
switch_to_previous_view: '_onSwitchToPreviousView',
},
});
});
I'm trying to seperate concerns using the module pattern and everything is going Ok except that I'm trying to delegate the dom strings from a module (the UIController module) to another actually I succeeded at doing it once but I don't know what is happening know it didn't work
as you see above the Domstrings object is inside the UIcontroller module so I expose it to the public so the other modules could use it
and as you see I did it before and it works fine without any problem as you see below
but when I use it inside the internalController module I got this error
so here is where I'm using it in:
so here is my code and thank you in advance:
JS
var internalController = (function(UICtrl) {
addItem: function(day, from, to, text, goingToCkecked) {
var newPlan, ID,Dom=UICtrl.getDOMstrings();
if (day === 'pick the day') {
document.querySelector(Dom.errorCase).style.visibility = "visible";
document.querySelector(".optionList").classList.add("error-red");
} else {
document.querySelector(".error-case").style.visibility = "hidden";
document.querySelector(".optionList").classList.remove("error-red");
console.log("that is me");
}
document.querySelector("#optionList").addEventListener("change", function(e) {
document.querySelector(".error-case").style.visibility = "hidden";
document.querySelector(".optionList").classList.remove("error-red");
});
})(UIController);
var UIController = (function() {
var DOMstrings = {
inputDay: ".optionList",
inputTimeF: ".inputTime",
inputTimeT: ".inputTime2",
inputText: ".inputText",
goingToCkecked: ".checkboxx",
inputBtn: ".add__btn",
planContainer: ".container",
errorCase: ".error-case",
optionList: ".optionList",
};
return {
getInput: function() {
return {
inputDay: document.querySelector(DOMstrings.inputDay).value,
inputTimeF: document.querySelector(DOMstrings.inputTimeF).value,
inputTimeT: document.querySelector(DOMstrings.inputTimeT).value,
inputText: document.querySelector(DOMstrings.inputText).value,
goingToCkecked: document.querySelector(DOMstrings.goingToCkecked).checked,
};
},
getDOMstrings: function() {
return DOMstrings;
},
}
}
};
})();
var controller = (function(interCtrl, UICtrl) {
var input, newPlan;
function setupEventListeners() {
var DOM = UICtrl.getDOMstrings();
document.querySelector(DOM.inputBtn).addEventListener("click", ctrlAddPlans);
document.addEventListener("keypress", function(e) {
if (e.keyCode === 13) {
ctrlAddPlans();
}
});
}
return {
init: function() {
console.log('the app has started');
setupEventListeners();
},
};
})(internalController, UIController);
controller.init();
// setInterval(function() {
// }, 100);
setTimeout(function() {
document.querySelector(".plansBackground").classList.add("height");
}, 1000);
I'm facing a minor problem. When I right click on the page and press examine (page's source code) in Google Chrome, I'm getting the error below. This file (ui-nestable.min.js) is required for my page to work properly and the interesting side of it my page works properly. I did research on the internet but did not find any results for this error.
Error Image
ui-nestable.min-js Code:
var UINestable = function () {
var updateOutput = function (e) {
var list = e.length ? e : $(e.target),
output = list.data('output');
if (window.JSON) {
output.val(window.JSON.stringify(list.nestable('serialize'))); //, null, 2));
} else {
output.val('JSON browser support required for this demo.');
}
};
return {
//main function to initiate the module
init: function () {
// activate Nestable for list 1
$('#nestable_list_1').nestable({
group: 1
})
.on('change', updateOutput);
// activate Nestable for list 2
$('#nestable_list_2').nestable({
group: 1
})
.on('change', updateOutput);
// output initial serialised data
updateOutput($('#nestable_list_1').data('output', $('#nestable_list_1_output')));
updateOutput($('#nestable_list_2').data('output', $('#nestable_list_2_output')));
$('#nestable_list_menu').on('click', function (e) {
var target = $(e.target),
action = target.data('action');
if (action === 'expand-all') {
$('.dd').nestable('expandAll');
}
if (action === 'collapse-all') {
$('.dd').nestable('collapseAll');
}
});
$('#nestable_list_3').nestable();
}
};
}();
jQuery(document).ready(function() {
UINestable.init();
});
you not use all nestable list in your page .
you must be remove all the extra code .
like that
var UINestable = function () {
var updateOutput = function (e) {
var list = e.length ? e : $(e.target),
output = list.data('output');
if (window.JSON) {
output.val(window.JSON.stringify(list.nestable('serialize'))); //, null, 2));
} else {
output.val('JSON browser support required for this demo.');
}
};
return {
//main function to initiate the module
init: function () {
// activate Nestable for list 1
$('#nestable_list_1').nestable({
group: 1
}).on('change', updateOutput);
// output initial serialised data
updateOutput($('#nestable_list_1').data('output', $('#nestable_list_1_output')));
$('#nestable_list_menu').on('click', function (e) {
var target = $(e.target),
action = target.data('action');
if (action === 'expand-all') {
$('.dd').nestable('expandAll');
}
if (action === 'collapse-all') {
$('.dd').nestable('collapseAll');
}
});
}
};
}();
jQuery(document).ready(function() {
UINestable.init();
});
I have some code as follows -
var app = {
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
document.addEventListener('backbutton',this.receivedEvent.backbutton(),false);
^-- //not working
},
onDeviceReady: function() {
this.receivedEvent('deviceready');
},
receivedEvent: function(id) {
var originalLocation, partnership;
function fadeOut(element, direction) {
....
};
function fadeIn(element, direction) {
.....
}
function formFadeIn(direction) {
fadeIn($("#dataform"), direction);
};
function formFadeOut(direction) {
fadeOut($("#dataform"), direction);
};
function backbutton () {
var current = $("#home").attr("page-current");
var prev = $("#home").attr("page-prev");
if (current == "dataform" && prev == "partnertype") {
formFadeOut("opposite");
partnertypeFadeIn("opposite");
setPage("country", "partnertype")
$("#selectcountry").attr("disabled", false).val("AF")
} else if (current == "dataform" && prev == "country") {
formFadeOut("opposite");
countryFadeIn("opposite");
} else if (current == "partnertype" && prev == "country") {
partnertypeFadeOut("opposite");
countryFadeIn("opposite");
} else {
window.location.reload()
}
}
}
};
app.initialize();
So I need to bind the event "backbutton" to the function backbutton() within receivedEvent. function backbutton() is invoking local functions within receivedEvent such as formFadeIn() etc.
I am unable to figure out the exact syntax on binding.
What I've tried -
this.receivedEvent.backbutton //no response
this.receivedEvent.backbutton() //no response
this.receivedEvent.bind(this).backbutton //causes infinite looping on the page
exporting the backbutton() function as return { backbutton : backbutton } //no response
What do I have to do to access function backbutton() from app.initialize() without loosing context?
You could try :
var app = {
initialize: function() {
document.addEventListener('backbutton',this.myBackButtonFunction, false);
},
myBackButtonFunction: function() {
// Your code
}
receivedEvent: function(id) {
// Can also be invoked from here
this.myBackButtonFunction();
},
};
app.initialize();
I'm developing a SPA webapplication and I'm running into a problem. I have a input field that accepts text like so:
<input type="text"
data-bind="typeahead: containers(),
updater: containerupdatefunction,
attr: { placeholder: 'ABCD-123456-7' },
event: { change: checkContainerNumber },
value: containerNumber,
style: { backgroundColor: containerNumberCorrect() ? 'rgba(0,255,0,0.4)' : 'rgba(255,0,0,0.4)' } "
required />
Everything is loaded correctly. Here is what I want but can't get to work:
When I click the input field and enter a character I get a list with autocomplete words that works fine, However, when I click one of them the update functions both are triggered. If containerupdatefunction is triggered before checkContainerNumber then my value is loaded correctly but this only happens 1 out of 10 times.
I need those 2 update functions because this input field also allows the user to input a new number. But this needs to be checked first to.
Any idea how I can solve this? Something with ValueUpdate (already tried but okay)?
If the function that is housed in the event: change{checkContainerNumber } is triggered before the updater: then the value I get is the value of a couple of characters I entered. So not the autocomplete when I selected one of those.
Could someone please help, if there is something missing or you need more information please tell me.
Remember the updater function is only triggered when you click a value of the autocomplete list.
Here is the knockout-bootstrap binding:
// Bind twitter typeahead
ko.bindingHandlers.typeahead = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var $element = $(element);
var allBindings = allBindingsAccessor();
var typeaheadArr = ko.utils.unwrapObservable(valueAccessor());
$element.attr("autocomplete", "off")
.typeahead({
'source': typeaheadArr,
'minLength': allBindings.minLength,
'items': allBindings.items,
'updater': allBindings.updater
});
}
};
Here is my modelview:
this.checkContainerNumber = function(item, element) {
var t = $(element.target).val();
};
this.containerupdatefunction = function(item, element) {
var t = item;
containerNumber(item);
return item;
};
/*
this.checkContainerNumber = function (item, element) {
if (!updaterTriggered()) {
if (containerNumber().length == 13) {
checkContainerNumberFunction(containerNumber());
updaterTriggered(true);
} else {
containerNumberCorrect(false);
}
}
return;
};
function checkContainerNumberFunction(containerNumberToCheck) {
try {
if (mapContainers[containerNumberToCheck].ContainerNumber() != undefined) {
container(mapContainers[containerNumberToCheck]);
return;
}
} catch(err) {
}
if (containerNumberToCheck.trim().length == 13 && containerNumberToCheck != undefined) {
$.get(
"http://localhost:60312/api/baseapi/checkContainerDigit?digit=" + containerNumberToCheck,
function (data) {
if (data == true) {
containerNumberCorrect(true);
} else {
containerNumberCorrect(false);
}
updaterTriggered(false);
}
);
} else {
containerNumberCorrect(false);
updaterTriggered(false);
}
};
this.updateViewAfterContainerSelection = function (item) {
if (!updaterTriggered()) {
updaterTriggered(true);
containerNumber(item);
checkContainerNumberFunction(containerNumber());
}
return item;
};
*/
This is what I tried so far!