ng-model fails to bind the values entered with a touch event - javascript

I'm using a JQuery + Bootstrap keyboard that is configured specifically only for touch inputs in my Angular app (If i use the mouse to click on the keys, keyboard will close without typing any. It is written to close on on click events).
Mobile-first-Virtual-Keyboard-Plugin-With-jQuery-Bootstrap
My problem is when i enter something to an input box whcih is binded to my controller using ng-model like the following code,
<input autocomplete="false" class="textInputSeeThrough keyboard"
ng-model="patientNIC" type="text" id="nic"
name="patientNICTxtbox" autofocus
placeholder="--- ENTER NIC NUMBER ---">
it does not get binded properly. But if i use plain javascript to traverse the DOM and get the element value in my controller instead of using $scope to get the value, i can get the value properly.
var val1 = $scope.patientNIC; // this doesn't work
var val2 = document.getElementById("nic"); // this works
alert(val1);
alert(val2.value);
So it is clearly not something wrong with the Keyboard. Does angular js have any known problems working with touch events? I couldn't find any. Can someone explain me why this is happening? Thanks in advace.

Simple answer is: Angular doesn't know about changing in input. Every change must be wrap in $apply or $timeout.
Look at this
Update Angular model after setting input value with jQuery

No Need to worry about, set values to input element using jquery / Javascript .
Please paste the following script in your html block / js (jquery)
!function (n, t) { "use strict"; var r = n.fn.val; n.fn.val = function (n) { if (!arguments.length) return r.call(this); var e = r.call(this, n); return t.element(this[0]).triggerHandler("input"), e } }(window.jQuery, window.angular);
Even we don't need to reassign values to ng object / trigger the input individually.
cheers !

Related

Overriding difficult view model

I am trying to replace some text in an input field using JS but the view model overrides my commands each time. This is the HTML I start with:
<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
<input type="hidden" name="product[variants][][price]" id="product_variants__price" value="25.00" bind="price" data-dirty-trigger="true">
<input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric" bind-event-focus="onFocus(this)" bind-event-blur="onBlur(this)" bind-event-input="onInput(this)">
</td>
I run this JS:
jQuery('#product_variants__price').siblings().removeAttr('bind-event-focus');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-input');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-blur');
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("34.00");
jQuery('#product_variants__price').val("34.00");
And I'm left with the following HTML:
<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
<input type="hidden" name="product[variants][][price]" id="product_variants__price" value="34.00" bind="price" data-dirty-trigger="true">
<input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric">
</td>
The problem is that each time I click the input field the value is reverted to what it was when the page loaded.
I've also tried running the command in the parent td along with my value change, to simulate the editing of a variant and preventing default with no success:
jQuery('#product_variants__price').siblings().bind('input', function (e) {
e.preventDefault();
return false;
});
jQuery('#product_variants__price').siblings().bind('focus', function (e) {
e.preventDefault();
return false;
});
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("£34.00");
jQuery('#product_variants__price').val("£34.00");
jQuery('#product_variants__price').siblings().keydown()
Parent td function:
new Shopify.EditVariantPrice(jQuery('#product_variants__price').parent())
So how can I successfully edit this value in the inputs and also update the Shopify view model?
You can try this for yourself by going here:
https://jebus333.myshopify.com/admin/products/2521183043
login jebus333#mailinator.com
password shop1
EDIT: I've tried to find the view model on the page but with no success. Plus, there are no network calls when editing the values in the input fields, leading me to believe the values are being pulled back from somewhere on page.
Try this:
var old = Shopify.EditVariantPrice.prototype.onFocus;
Shopify.EditVariantPrice.prototype.onFocus = function(t) {
this.price = '50.00'; // Use the price you want here
old.call(this, t);
};
jQuery('#product_variants__price').siblings().triggerHandler("focus");
jQuery('#product_variants__price').siblings().triggerHandler("blur");
If it works for you, it's possible that the following will be sufficient:
Shopify.EditVariantPrice.prototype.onFocus = function(t) {
this.price = '50.00'; // Use the price you want here
};
Well, there is a kind of a dirty solution...
First of all you'll need a sendkeys plugin. In fact that means you'll need to include this and this JS libraries (you can just copy-paste them in the console to test). If you don't want to use the first library (I personally find it quite big for such a small thing) you can extract only the key things out of it and use only them.
The next step is creating the function which is going to act like a real user:
function input(field, desiredValue) {
// get the currency symbol while value is still pristine
var currency = field.val()[0];
// move focus to the input
field.click().focus();
// remove all symbols from the input. I took 10, but of course you can use value.length instead
for (var i = 0; i < 10; i++) field.sendkeys("{backspace}");
// send the currency key
field.sendkeys(currency);
// send the desired value symbol-by-symbol
for (var i = 0; i < desiredValue.length; i++) field.sendkeys(desiredValue[i]);
}
Then you can simply call it with the value you wish to assign:
input($("#product_variants__price").next(), "123.00");
I did not really manage to fake the blur event because of lack of the time; that is why I was forced to read the currency and pass .00 as a string. Anyway you already have a way to go and a quite working solution.
Looks like you're trying to automate editing of variant prices of products in Shopify's admin panel.
Instead of playing around with the DOM of Shopify's admin page, I'll suggest using Shopify's bulk product editor which lets you set prices of all variants in a single screen. I feel that you'll have better luck setting the variant prices using JavaScript on the bulk product editor page.
Clicking on the 'Edit Products' button as shown in the screenshot below will open the bulk product editor.
Also check if browser based macro recording plugins like iMacro can be of your help (you can also code macros with JS in iMacro).

Dynamically how to make checkbox check/uncheck in angularjs controller using ng-click

I am new to Angular JS. When the user check/uncheck on a check box, I am calling a function in a controller using ng-click. I am passing $event to the function in controller. Using the $event, I am able to get the srcElement inside the controller function. Now I would like to set the previous check/uncheck value to the check box based on certain conditions.
$scope.isAccessChanged = function(event){
if (some condition) {
var elem = angular.element(event.srcElement);
/** here how to set the elem value back to whatever it was before.*/
}
};
Lets say you have check box like
<input ng-model="form.isSelected" type="checkbox">
All you need to do is:
$scope.form.isSelected = !$scope.form.isSelected;
Avoid DOM manipulation and limit jQuery use as much as possible in angular.
I recommend using jQuery only in directives to make it less of an available option.
Try this out:
<input type="checkbox" ng-model="foShizzle" ng-click="isAccessChanged()"/>
$scope.isAccessChanged = function(event){
if(some condition){
$scope.foShizzle = !$scope.foShizzle; // This will reverse the user's decision
}
}

Setting Default value of input textbox in Jquery EasyUI dialog

I have googled and looked throughout the whole documentation and could not figure out why value of input text is not shown. I am using FireFox latest version and below is what I have done so far.
<input name="amount" class="easyui-validatebox" id="d_amount" value="">
In regular html or php page we can give value="300" to set default value, but in EasyUI, it is not possible. So I was thinking possible alternative like below:
<script>
var m = '300';
document.getElementById("d_amount").value.innerHTML=m;
</script>
Nothing is shown and I am not getting any error. Any EasyUI expert, please help me.
NOTE: this input field is inside the dialog
To set the default value, you have to set the value attribute. However, that does not necessarily update the value property so you need to do both. So given:
<input name="amount" class="easyui-validatebox" id="d_amount" value="">
set the default value by setting the value attribute:
var input = document.getElementById('d_amount')
input.setAttribute('value', 'whatever');
now set the value property:
input.value = 'whatever';
Note that you can also get a reference to the input as a member of the form that it's in:
var input = document.formName.d_amount;
Use the below code
$("#d_amount").numberbox({
min:0,
precision:2,
value:300
})
Reference : numberbox
Or try this one
$("#d_amount").textbox({
buttonText:'Search',
iconCls:'icon-man',
iconAlign:'left',
value:"300"
});
Reference : textbox
use this code to set the value inside $(document).ready(function(){}
....
$("#d_amount").numberbox('setValue','300');
....
if still not working, just try to set name and id as the same name and id
<input name="d_amount" class="easyui-validatebox" id="d_amount" value="">
I am always working with this numberbox and it's working
I have found your thread because I am also having the same issue and I have just across this thing today. Your case is a little bit different (maybe) then my case because you want to set the default which can be changed by the user later (I believe). In my case, the value will be fixed (will not be changed) so I have applied a trick and hopefully it can give some ideas to you and others who are having same issue. Please refer below:
In first page says pageA.php:
<select name="myThing" id="myThing">
<option value="Your Desired Value" selected="selected">Something</option>
</select>
Still in the same page, under your $(document).ready( function(){ put the code below:
$("#myThing").val($("#myThing option:first").val());
That code is to make sure your desired value appears at the first row in the drop down. I say this because in EasyUI it seems when I use drop down and put single option, the first row will be blank and the second row will hold your input. So that is the trick to ensure your desired value appears on top and selected. Put the select under the form then during normal post, you will be able to get the value of it in the posted page. Enjoy. Thank you.
Suggestion: if your value can be changed by user, use placeholder and you can hide the default value from user using my trick.
try this
document.getElementById("d_amount").value=m;
you don't need innerHTML
I found the answer here. The trick is to use the code inside $(function(){});
$(function(){
var m=300;
$('#d_amount').textbox('setValue', m);
});
I too had this problem and it was solved using the following
First my input was in the form like this:
<input name="hostFirstName" id="hostFirstName" class="easyui-textbox">
I needed to load content from the db then pre-fill the input with this data so the user could edit the content.
I used the following javascript.
NOTE: i didn't hide this away inside an anonymous function() and it is working. I tested this first from the F12 console to make sure it was working before changing my code.
//populate with existing data
$('#hostFirstName').textbox('setValue', "Is this working?");
The docs on jeasyui.com don't provide this example when you look at the textbox api reference. But they do provide an example when looking at the combobox (http://www.jeasyui.com/documentation/index.php#) the combobox and textbox use the same setValue method.
Hopefully this works for you like it does for me.

How can I use the jQuery Autocomplete plugin for linked input fields?

I'm using the jQuery Autocomplete plugin. I have two input fields on a form, inputfield1 and inputfield2.
I attached autocomplete to the first field. When the that field loses focus, I want to check if a value was entered and if so, then make an AJAX call to retrieve some "\n"-separated strings and use them to drive autocomplete on the second field.
Below is the code I'm using to do that:
/*Receive data from server for autocomplete*/
$("#inputfield1").autocomplete("<url1>");
$("#inputfield1").blur(function(){
// Attach autocomplete if inputfield1 field is not empty
if($("#inputfield1").val() != ""){
var url = "<url2>?q="+$("#inputfield1").val();
$.get(url,function(data){
result=data.split("\n");
$("#inputfield2").autocomplete(result);
});
}
});
But a strange thing is happening: I am able to attach autocomplete to the first field successfully, but I have to give focus twice to the second field in order to use autocomplete on it. Is there any way to fix this problem?
Try this simplified test. If this works check if your result really contains what you think (alert it or write it to console). There could be other characters after splitting (namely whitespace (leading spaces, \t or \r) try trimming every value of the result array.
var data1 = ["a123", "b123", "c123", "d123", "e123", "f123", "g123", "h123", "i123", "j123", "k123", "l123", "m123", "n123", "o123", "p123", "q123", "r123", "s123", "t123", "u123", "v123", "w123", "x123", "y123", "z123"];
var data2 = 'a123\nb123\nc123\nd123\ne123\nf123\ng123\nh123\ni123\nj123\nk123\nl123\nm123\nn123\no123\np123\nq123\nr123\ns123\nt123\nu123\nv123\nw123\nx123\ny123\nz123';
$("#inputfield1").autocomplete(data1);
$("#inputfield1").blur(function(){
if($("#inputfield1").val() != ""){
var result=data2.split("\n");
$("#inputfield2").autocomplete(result);
}
});
I found this code in the current version of the autocomplete plugin:
.click(function(event) {
$(target(event)).addClass(CLASSES.ACTIVE);
select();
// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
input.focus();
return false;
It seems to put focus back on itself after a click. This might be messing you up.
Instead of handling the blur() event, maybe you'll have better luck if you handle the autocomplete plugin's result() event.
/*Receive data from server for autocomplete*/
$("#inputfield1").autocomplete("<url1>");
$("#inputfield1").result(function(event, data, formatted){
// Attach autocomplete if inputfield1 field is not empty
if(data){
var url = "<url2>?q="+data;
$.get(url,function(data1){
result=data1.split("\n");
$("#inputfield2").autocomplete(result);
});
}
});
Make sure you're using the latest version of the Autocomplete plugin. There was a bug in versions prior to 1.1 where if you enabled autocomplete on a field after that field had focus (as would happen in your example if you tabbed from the first input field directly into the second) it wouldn't work properly until focus was lost and then restored again...
Here's a quick demo that shows this construct working with the latest Autocomplete version.
You say you need to select #inputfield2 twice so the autocomplete event binds to it, right?
I'm just thinking.. can it be possible that you are using your tab key on your keyboard to select #inputfield2 and when that doesn't work you select #inputfield2 with your mouse? If so, isn't it possible that the #inputfield1 blur event doesn't kick in until you "unselect" it with your mouse (maybe some kind of bug)?
I haven't tried this, it's just a thought.

dojo.data.ItemFileReadStore: Invalid item argument with Dijit combobox

I have a jsp page with a dijit.form.ComboBox which is populated by a dojo.data.ItemFileReadStore connecting to a back end java server. It works almost as expected, the combobox shows the results correectly. Problem is that I receive a 'dojo.data.ItemFileReadStore: Invalid item argument.' when scrolling in a results list with the keyboard arrow keys. Selecting with the mouse however works fine.
Dojo version is 1.2.3
This is how I've put it in place on my jsp:
<input type="text" id="value"
dojoType="dijit.form.ComboBox"
autoComplete="false"
searchAttr="name"
forceValidOption="true"
hasDownArrow="false"
onKeyUp="populateValue"
/>
<script type="text/javascript">
function populateValue() {
valueWidget = dijit.byId("value");
var selectedValue = valueWidget.getValue();
var url = "${contextPath}/someUrl?selectedValue=" + selectedValue + "%";
store = new dojo.data.ItemFileReadStore({url:url});
valueWidget.store = store;
return;
}
</script>
Here is the JSON I receive from the server:
{"items":[
{"name":"My string 1","label":"My string 1"},
{"name":"My string 2","label":"My string 2"},
{"name":"Mev.","label":"Mev."}],
"identifier":"name"}
Any idea what's going wrong here?
Solved it. Problem seemed to be the onKeyUp event on the combobox. When I changed this to onKeyPress, arrowing down the list gives no more errors.
Compared to onKeyUp, onKeyPress gives me in fact a delay of one character because the event is triggered when the character is not actually typed already. Any idea how I could overcome this?

Categories