Control page behavior by key board - javascript

I need control the behavior page by key board ... I was trying like this:
this.showSearcherCustomerKeyCommand = function (data, event) {
if (event.shiftKey && event.keyCode == 49) {
alert("Combination done !");
}
};
And I set the binding in a secction, after I've set the bindings in a div, and the result was unsuccessfully ... So what I need is that the behavior of my page can be controlled by keyboard ... That my user can make this combination: Crtl + 1, ctrl + 2, whatever and that by knockout I can show, hide (modal), apply or cleannode bindings, and another things ... It's possible ?? Thanks ...
UPDATE
Here is my view model:
Billing.BillingViewModel = function () {
this.billingDate = ko.observable();
this.billingCode = ko.observable();
this.billingId = ko.observable();
this.billingIva = ko.observable(0);
this.billingSubTotal = ko.observable(0);
this.billingTotal = ko.observable(0);
this.billingObservations = ko.observable("");
this.billingDetails = ko.observableArray();
this.billingState = ko.observable();
this.billingClient = new Billing.ClientViewModel();
this.billingCurrentProductSelected = new Billing.ProductViewModel();
this.showSearcherCustomerKeyCommand = function (data, event) {
if (event.shiftKey && event.keyCode == 49) {
alert("Combination done !");
}
};
};
Here is when apply the bindings:
Billing.SetViewModel = function () {
theMainViewModel = Billing.PrepareBilling();
theManagerViewModel = new Billing.ManagerBillingViewModel();
theGeneralViewModel = new Billing.GeneralViewModel();
ko.applyBindings(theMainViewModel.Billing, $("#" + Billing.BillingHeaderSecction)[0]);
ko.applyBindings(theMainViewModel.Billing, $("#" + Billing.BillFooterSecction)[0]);
ko.applyBindings(theMainViewModel.Billing, $("#" + Billing.BillProductChoosenSecction)[0]);
ko.applyBindings(theMainViewModel.Billing, $("#" + Billing.BillDetailsSecction)[0]);
ko.applyBindings(theMainViewModel.FinishBilling, $("#" + Billing.BillFinishSecction)[0]);
ko.applyBindings(theManagerViewModel, $("#" + Billing.ManagerSecction)[0]);
ko.applyBindings(theMainViewModel, $("#" + Billing.BillActionsSecction)[0]);
ko.applyBindings(theMainViewModel, $("#" + Billing.SelectorModalSearcherCustomerId)[0]);
ko.applyBindings(theMainViewModel, $("#" + Billing.SelectorModalSearcherProductId)[0]);
//ko.applyBindings(theGeneralViewModel, $("#" + Billing.BillGeneralSecction)[0]);
theManagerViewModel.theBillings.push(theMainViewModel);
Billing.SetMask();
};
And here is my secction tag control (HTML):
<section id="BillHeaderSecction" **data-bind="event: { keypress: billingClient.showSearcherCustomerKeyCommand }, valueupdate: 'afterkeydown'"**>
<input type="hidden" id="hdfBillingId" name="BillingId" data-bind="value: billingId" />
<table style="width: 100%">
<tr>
<td style="width: 30%">
<label>Cliente</label>
<input style="width: 100%" type="text" readonly name="Client" id="txtClient" data-bind="value: billingClient.name" />
</td>
<td style="width: 5%"></td>
<td style="width: 30%">
<label>Fecha</label>
<input style="width: 100%" type="text" readonly name="CreationDate" id="txtCreationDate" data-bind="value: billingDate" />
</td>
<td style="width: 5%"></td>
<td style="width: 30%">
<label>Código</label>
<input style="width: 100%" type="text" readonly name="BillingCode" id="txtBillingCode" data-bind="value: billingCode" />
</td>
</tr>
</table>
</section>
PD: I've put on bold the secction tag that I want the being controlled by keyboard

keydown and keypress will give you different values for event.keyCode. I guess you have to use keydown instead.
Look this Keyevent Tester
I just tested your code with keydown and keypress events:
...
var showSearcherCustomerKeyCommand = function (event) {
if (event.shiftKey && event.keyCode == 49) {
alert("Combination done ! (Fired by keydown event)");
}
};
window.onkeydown = showSearcherCustomerKeyCommand; // alert 49
window.onkeypress = showSearcherCustomerKeyCommand; // alert 33
And... event will be the first parameter passed to your function.
http://jsfiddle.net/01teg8yL/2/

Related

HTML Script capturing text and performing events with its own value

I'm trying to capture the value of 2 text inputs and performs functions when the user press enter key.
I'm using Internet Explorer 11.
<script type="text/javascript">
function myFuncion(arg1, arg2) {
window.alert("arg1:" + arg1 + ", arg2:" + arg2);
}
</script>
Now, the text inputs code
<input type="text" size="6" name="nameAnotherText" id="idAnotherText" value=""
onkeydown = "if (event.keyCode == 13) {
myFuncion('" + document.getElementById("idText").textContent + "', '"
+ document.getElementById('idAnotherText').value + "');
}"
/>
<input type="text" size="6" name="nameText" id="idText" value=""
onkeydown = "if (event.keyCode == 13) {
myFuncion('" + document.getElementById("idText").textContent + "', '"
+ document.getElementById('idAnotherText').value + "');
}"
/>
Is it not working.
Unfortunately this not works:
<button onclick="myFuncion('" +
document.getElementById(\"idAnotherText\").textContent + "', '" +
document.getElementById(\"idText\").textContent + "')" >Press Me</button>
<button onclick="myFuncion(" +
document.getElementById(\"idAnotherText\").textContent + ", " +
document.getElementById(\"idText\").textContent + ")" >Press Me</button>
<button onclick="myFuncion(" +
document.getElementById('idAnotherText').textContent + ", " +
document.getElementById('idText').textContent + ")" >Press Me</button>
How solve this?
Or something https://stackoverflow.com/a/155272/811293 but is not working:
Remove quotes from the function arguments. You also have to use value instead of textContent to grab the values from input fields in both cases. Try the following:
function myFuncion(arg1, arg2) {
window.alert("arg1:" + arg1 + ", arg2:" + arg2);
}
<input type="text" size="6" name="nameAnotherText" id="idAnotherText" value=""
onkeydown = "if (event.keyCode == 13) {
myFuncion(document.getElementById('idText').value, document.getElementById('idAnotherText').value);
}"
/>
<input type="text" size="6" name="nameText" id="idText" value=""
onkeydown = "if (event.keyCode == 13) {
myFuncion(document.getElementById('idText').value, document.getElementById('idAnotherText').value);
}"
/>
Writing JavaScript in HTML is not a good idea. You might do the following which is more cleaner:
function myFuncion(event) {
if (event.keyCode == 13) {
var txt1 = document.getElementById('idText').value;
var txt2 = document.getElementById('idAnotherText').value;
window.alert("txt1:" + txt1 + ", txt2:" + txt2);
}
}
<input type="text" size="6" name="nameAnotherText" id="idAnotherText" value="" onkeydown = "myFuncion(event);"/>
<input type="text" size="6" name="nameText" id="idText" value="" onkeydown = "myFuncion(event);"/>
If you are in a form with a submit button you need to return false from your event handler or your form will auto submit when return is pressed while in an input.
As a general rule you should avoid trying to handle Return presses in inputs in a form. This breaks the expected behavior of forms on the internet which is that they submit when return is pressed. Instead register a callback on the submit event of the form and do it (validations, ajax, etc.) there instead.
Rewriting the javascript makes it work. In general avoid putting actual code into the code
With this as the javascript
function myOnKeyDown(event) {
if (event.keyCode == 13) {
var text_value = document.getElementById("idText").value
var another_text_value = document.getElementById("idAnotherText").value
myFunction(text_value, another_text_value);
}
}
function myFunction(arg1, arg2) {
window.alert("arg1:" + arg1 + ", arg2:" + arg2);
}
You can have this in your html
<input type="text" size="6" name="nameAnotherText" id="idAnotherText" value="" onkeydown="myOnKeyDown(event)"/>
<input type="text" size="6" name="nameText" id="idText" value="" onkeydown="myOnKeyDown(event)"/>
This should allow your code to run.
I usually try to go as native as possible.
The way you can go about is to wrap the input fields with form tag and add event listener to the submit event.
Try the following.
const form = document.getElementById('myform');
form.addEventListener('submit', onSubmit, false);
form.submit = onSubmit;
function onSubmit(event) {
if (event) {
event.preventDefault();
}
console.log('submitted');
const input1 = document.getElementById('input1').value;
const input2 = document.getElementById('input2').value;
console.log({
input1,
input2
});
}
<form id="myform">
<input type="text" id="input1">
<input type="text" id="input2">
<button type="submit" style="display: none"></button>
</form>

1 button 2 functions

I've got a conflict issue with a form. The idea is that I need to store the datas in the form field in a table with a local storage in Javascript, and I need to send an email simultaneously with the same button with PHP. When I try it, either the button implement the table, either it send the mail. It depends of the position of the action inside the arrows. Here is my code :
<script>
var Contacts = {
index: window.localStorage.getItem("Contacts:index"),
$table: document.getElementById("contacts-table"),
$form: document.getElementById("contacts-form"),
$button_save: document.getElementById("contacts-op-save"),
$button_discard: document.getElementById("contacts-op-discard"),
init: function() {
// initialize storage index
if (!Contacts.index) {
window.localStorage.setItem("Contacts:index", Contacts.index = 1);
}
// initialize form
Contacts.$form.reset();
Contacts.$button_discard.addEventListener("click", function(event) {
Contacts.$form.reset();
Contacts.$form.id_entry.value = 0;
}, true);
Contacts.$form.addEventListener("submit", function(event) {
var entry = {
id: parseInt(this.id_entry.value),
first_name: this.first_name.value,
last_name: this.last_name.value,
company: this.company.value,
address: this.address.value,
city: this.city.value,
zip: this.zip.value,
state: this.state.value,
country: this.country.value,
phone: this.phone.value,
email: this.email.value,
nature_of_contact: this.nature_of_contact.value,
};
if (entry.id == 0) { // add
Contacts.storeAdd(entry);
Contacts.tableAdd(entry);
}
else { // edit
Contacts.storeEdit(entry);
Contacts.tableEdit(entry);
}
this.reset();
this.id_entry.value = 0;
event.preventDefault();
}, true);
// initialize table
if (window.localStorage.length - 1) {
var contacts_list = [], i, key;
for (i = 0; i < window.localStorage.length; i++) {
key = window.localStorage.key(i);
if (/Contacts:\d+/.test(key)) {
contacts_list.push(JSON.parse(window.localStorage.getItem(key)));
}
}
if (contacts_list.length) {
contacts_list
.sort(function(a, b) {
return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0);
})
.forEach(Contacts.tableAdd);
}
}
Contacts.$table.addEventListener("click", function(event) {
var op = event.target.getAttribute("data-op");
if (/edit|remove/.test(op)) {
var entry = JSON.parse(window.localStorage.getItem("Contacts:"+ event.target.getAttribute("data-id")));
if (op == "edit") {
Contacts.$form.first_name.value = entry.first_name;
Contacts.$form.last_name.value = entry.last_name;
Contacts.$form.company.value = entry.company;
Contacts.$form.address.value = entry.address;
Contacts.$form.city.value = entry.city;
Contacts.$form.zip.value = entry.zip;
Contacts.$form.state.value = entry.state;
Contacts.$form.country.value = entry.country;
Contacts.$form.phone.value = entry.phone;
Contacts.$form.email.value = entry.email;
Contacts.$form.nature_of_contact.value = entry.nature_of_contact;
Contacts.$form.id_entry.value = entry.id;
}
else if (op == "remove") {
if (confirm('Are you sure you want to remove "'+ entry.first_name +' '+ entry.last_name +'" from your contacts?')) {
Contacts.storeRemove(entry);
Contacts.tableRemove(entry);
}
}
event.preventDefault();
}
}, true);
},
storeAdd: function(entry) {
entry.id = Contacts.index;
window.localStorage.setItem("Contacts:index", ++Contacts.index);
window.localStorage.setItem("Contacts:"+ entry.id, JSON.stringify(entry));
},
storeEdit: function(entry) {
window.localStorage.setItem("Contacts:"+ entry.id, JSON.stringify(entry));
},
storeRemove: function(entry) {
window.localStorage.removeItem("Contacts:"+ entry.id);
},
tableAdd: function(entry) {
var $tr = document.createElement("tr"), $td, key;
for (key in entry) {
if (entry.hasOwnProperty(key)) {
$td = document.createElement("td");
$td.appendChild(document.createTextNode(entry[key]));
$tr.appendChild($td);
}
}
$td = document.createElement("td");
$td.innerHTML = '<a data-op="edit" data-id="'+ entry.id +'">Edit</a> | <a data-op="remove" data-id="'+ entry.id +'">Remove</a>';
$tr.appendChild($td);
$tr.setAttribute("id", "entry-"+ entry.id);
Contacts.$table.appendChild($tr);
},
tableEdit: function(entry) {
var $tr = document.getElementById("entry-"+ entry.id), $td, key;
$tr.innerHTML = "";
for (key in entry) {
if (entry.hasOwnProperty(key)) {
$td = document.createElement("td");
$td.appendChild(document.createTextNode(entry[key]));
$tr.appendChild($td);
}
}
$td = document.createElement("td");
$td.innerHTML = '<a data-op="edit" data-id="'+ entry.id +'">Edit</a> | <a data-op="remove" data-id="'+ entry.id +'">Remove</a>';
$tr.appendChild($td);
},
tableRemove: function(entry) {
Contacts.$table.removeChild(document.getElementById("entry-"+ entry.id));
}
};
Contacts.init();
</script>
<form action="mailer.php" method="post" class="onerow">
<label class="col6">First name:
<input type="text" name="first_name" />
</label>
<label class="col6">Last name:
<input type="text" name="last_name" />
</label>
<label class="col6">Company:
<input type="text" name="company" />
</label>
<label class="col6">Address:
<input type="text" name="address" />
</label>
<label class="col6">City:
<input type="text" name="city" />
</label>
<label class="col6">Postal/zip code:
<input type="text" name="zip" />
</label>
<label class="col6">State/province:
<input type="text" name="state" />
</label>
<label class="col6">Country:
<input type="text" name="country" />
</label>
<label class="col6">Phone number:
<input type="text" name="phone" />
</label>
<label class="col6">Email:
<input type="text" name="email" />
</label>
<label class="col12">Why are you looking for our solutions ?
<SELECT name="nature_of_contact" size="1">
<OPTION>I'm a distributor and I want to sell your products in my country.
<OPTION>I'm a beautician I want to buy a product.
<OPTION>I'm a doctor.
<OPTION>I'm a distributor.
</SELECT>
</label>
<div class="col12">
<input type="button" id="contacts-op-discard" value="Discard" />
<input type="submit" id="contacts-op-save" value="Save" />
<input type="hidden" name="id_entry" value="0" />
</div>
</form>
</div>
<div></div>
<div id="tablecontrol" class="col12">
<h1>Contacts</h1>
<table id="contacts-table">
<tr id="contacts-head">
<th>ID</th>
<th>First name</th>
<th>Last name</th>
<th>Company</th>
<th>Address</th>
<th>City</th>
<th>Postal/Zip</th>
<th>State/province</th>
<th>Country</th>
<th>Phone number</th>
<th>Email</th>
<th>Kind of prospect</th>
<th>Actions</th>
</tr>
</table>
</div>
</div>
See JSFIDDLE
One way would be:
Change the submit button from type 'submit' to 'button' and add the event onClick()to it.
Create a function -let's say readFromdata()- that reads the values from your form. Store the data into a container.
Create a function -let's say sendFromdata()- that sends the data to your php script. Hint: Ajax would be your friend. Configure your Ajax so, that the data will be send asyncrosly.
Create a function -let's say printFOverview()- that extends your html table, for the displaying the result.
Call sendFromdata() and printFOverview() within the function readFromdata() and pass the data container to these methods.
Add the call readFromdata() to the attribute onClick().
You could do the following:
Add an event.preventDefault() to your handler
Then store things in localStorage
If things are stored submit the form with Contacts.$form.submit();
EDIT
Change the event handler from submit to click and remove it from the form to add it to the Contacts.$button_save button and add a preventDefault() just after.
As you changed the event handler from the form to the button you need to change the form values from this to Contacts.$form because this was in the scope of the form which is not the case anymore.
Contacts.$button_save.addEventListener("click", function(event) {
event.preventDefault();
var entry = {
id: parseInt(Contacts.$form.id_entry.value),
first_name: Contacts.$form.first_name.value,
last_name: Contacts.$form.last_name.value,
// and so on
Remove the input type="submit" and create a normal button instead:
<button id="contacts-op-save">Save</button>
Then you could submit the form after storing in storeAdd / storeEdit functions as said with Contacts.$form.submit();.
storeAdd: function(entry) {
entry.id = Contacts.index;
window.localStorage.setItem("Contacts:index", ++Contacts.index);
window.localStorage.setItem("Contacts:"+ entry.id, JSON.stringify(entry));
Contacts.$form.submit();
},
storeEdit: function(entry) {
window.localStorage.setItem("Contacts:"+ entry.id, JSON.stringify(entry));
Contacts.$form.submit();
},
storeRemove: function(entry) {
window.localStorage.removeItem("Contacts:"+ entry.id);
// eventually here too?
Contacts.$form.submit();
},
Also you call the form element by its id , but the form has no id assigned.
$form: document.getElementById("contacts-form")
So give your form that ID:
<form id="contacts-form" action="mailer.php" method="post" class="onerow">

How to access an observable element from observable array in knockout.js and change its value

I am creating a ViewModel as:
function PurchaseOrderViewModel() {
var self = this;
self.seqNo = ko.observable(1);
self.barcode = ko.observable('');
self.expDate = ko.observable('');
self.importDate = ko.observable('');
self.name = ko.observable('');
}
And on keypress event of barcode addOrder event gets executed:
function OrderCollection() {
var self = this;
self.ShirtOrder = ko.observableArray([new PurchaseOrderViewModel()]);
self.addOrder = function (data, event) {
if (event.keyCode == 13) {
//Here before pushing new object to self.ShirtOrder. I want to access current object and change its expDate and importDate value.
var _SO = new PurchaseOrderViewModel();
_SO.seqNo = $("#SOBody > tr").length + 1;
self.ShirtOrder.push(_SO);
}
};
}
HTML:
<tbody data-bind="foreach: ShirtOrder()" id="SOBody">
<tr>
<td>
<input type="text" value="1" class="req measurment" data-bind="value: seqNo" />
</td>
<td>
<input type="text" class="" data-bind="value: barcode, valueUpdate: 'afterkeydown',
event: { keypress: $parent.addOrder }" />
</td>
<td>
<input type="date" class="req measurment" data-bind="value: expDate" />
</td>
<td>
<input type="date" class="req measurment" data-bind="value: importDate" />
</td>
<td>
<input type="text" class="req measurment" data-bind="value: name" />
</td>
</tr>
</tbody>
When Enter key event is pressed in barcode textbox. The import date and export date value should be changed and also a new TR should be created. I am not able to change the value.
Well you just need to do something like this
View Model:
function OrderCollection() {
var self = this;
self.ShirtOrder = ko.observableArray([new PurchaseOrderViewModel()]);
self.addOrder = function (data,event) {
if (event.keyCode == 13) {
data.expDate('2014-10-27'); // you get current instance here
data.importDate('2015-01-20');
var _SO = new PurchaseOrderViewModel();
self.ShirtOrder.push(_SO);
}
};
}
$(function() {
ko.applyBindings(new OrderCollection());
});
Catch here is When using type="date" you should always use the format yyyy-MM-dd (W3C standard) for setting .
Working fiddle here

knockout automatically presses button after updating view

I have a table with TRbind in foreach loop:
<tbody data-bind="foreach: data">
<tr>
<td><input type="text" class="form-control" data-bind="value: DeviceSerialNumber" required /></td>
<td><input type="datetime" class="form-control datepicker" placeholder="Od" data-bind="value: StartDate" required /></td>
<td><button class="btn btn-default" data-bind='click: $root.removeRow'>Delete</button></td>
</tr>
</tbody>
the button is bind to this function:
self.removeRow = function (eq) {
self.data.removeAll([eq]);
};
I add data in this way:
var a = new Eq();
console.log(self);
a.StartDate(self.StartDateTemp());
a.DeviceId(self.DeviceTemp());
console.log(a);
console.log(self.data().length);
self.data.push(a);
console.log(self.data().length);
and data is:
var ViewModel = function () {
var self = this;
self.DeviceTemp = ko.observable();
self.StartDateTemp = ko.observable();
self.data = ko.observableArray([]);
}
The problem is occurring only in IE10. If I add anything to the data array the view is Updated. As in the view I add the is button bind to remove at the end of the tr. For unknown reason knockout or browser clicks that button and removes freshly added row.
Can You help me?
JSFIDDLE
Try adding return false after self.data.push(a); self.Test(""); to prevent event from bubbling:
self.searchKeyboardCmd = function (data, event) {
if (event.keyCode == 13) {
if ((self.StartDateTemp() === undefined)
|| (self.number() != 1 && self.Test() != undefined)
&& (self.number() != 1 && self.Test() != "")) {
alert("Bledna konfiguracja. Urzadzenia posiadajace numer seryjny nie moga byc dodane wiecej niz 1 raz")
return true;
}
if (self.number() < 1 || isNaN(self.number())) {
alert("Bledna ilosc");
return true;
}
var a = new Eq();
a.StorageId(self.StorageTemp());
a.StartDate(self.StartDateTemp());
a.DeviceSerialNumber(self.Test());
a.DeviceId(self.DeviceTemp());
a.Issue(self.Issue())
a.IssueDesc(self.IssueDesc());
a.Quantity(self.number());
a.Project(self.Project());
a.MeUser(self.MeUser());
self.data.push(a);
self.Test("");
return false;
}
return true;
};

Updating value when overriding enter press

I have page when I have input and a button.
<div>
<div class="input-group">
<span class="input-group-addon">Enter test</span>
<input type="Text" class="form-control" data-bind="value:Test, event: { keypress: searchKeyboardCmd}" required />
</div>
</div>
<button data-bind=' event:{click:foo}' class="btn btn-default">Submit</button>
and my code:
var ViewModel = function () {
var self = this;
self.Test = ko.observable();
self.data = ko.observableArray([]);
self.DeviceId = ko.observable();
self.number = ko.observable(1);
self.MeUser = ko.observable(true);
self.searchKeyboardCmd = function (data, event) {
if (event.keyCode == 13)
alert("Znalazlem enter " + ko.toJSON(self));
return true;
};
self.foo = function () {
alert("foo");
}
};
ko.applyBindings(new ViewModel());
});
And I have problems with my code. I catch enter with this code:
self.searchKeyboardCmd = function (data, event) {
if (event.keyCode == 13)
alert("Znalazlem enter " + ko.toJSON(self));
return true;
};
It's catches perfectly but binded object is updated after calling alert. So in the first enter I null in value Test. After second enter I have first value and so on. Can anyone suggest me how to modify this code?
The problem is that the event is executed before the blur event (which is when the value is updated. You can make sure the update gets updated after every keystroke by adding valueupdate: 'afterkeydown' to the input:
<div>
<div class="input-group">
<span class="input-group-addon">Enter test</span>
<input type="Text" class="form-control"
data-bind="valueUpdate: 'afterkeydown', value:Test, event: { keypress: searchKeyboardCmd}" required />
</div>
</div>
<button data-bind=' event:{click:foo}' class="btn btn-default">Submit</button>

Categories

Resources