Getting "Change" event for a text field whose contents is changed by jQuery - live

I've made some pretty checkboxes using some pretty simple jQuery
HTML
<span class="iconElement checkBox" id="update_Check"></span>
<input type="text" id="update" name="update" value="0" class="hidden savedData" />
JS
$('.checkBox').live('click', function (e) {
if ($(this).hasClass('disabled') != true) {
$(this).toggleClass('checked')
var thisValue = parseInt($(this).next().val());
var newValue = (thisValue - 1) * (-1); // enusures the output is either 1 or 0, [ (1-1)*-1=0 and (0-1)*-1 =1 ]
$(this).next().val(newValue);
};
});
This is simply a span with a nice CSS background sprite, which when clicked changes toggles it's "checked" class, adjusting the CSS sprite from a "Tick" to an empty box. At the same time it also changes the content of a text field (hidden by CSS class 'hidden') to a 1 or a 0 to indicate whether the box is checked.
It has to have this 1 or 0 as when the data is passed to the next stage I have to have a value, an unchecked checkbox sends no value.
This all works fine!
BUT... I also need to be able to detect the "change" event of the hidden text field.
This is to be controlled by the "savedData" class.
$('.savedData').live('change', function () {
// do stuff now we know this has been changed
});
I could of course include this within the "click" event in the code above, but that's not practical for the application.
It seems that the "change" even is only trigger by elements which are changed by the keyboard or mouse, anything changed by jQuery is not being flagged.
Initially I was using hidden input type and thought that was the issue, but have changed them all to text type now and the problem is still there!
Any tips?!

It seems that the "change" even is only trigger by elements which are changed by the keyboard or mouse, anything changed by jQuery is not being flagged.
Yes, that is correct. That is precisely how this works. Only changes made by the user trigger event handlers: programmatic changes do not. The only way to trigger them is to do so yourself:
$(this).next().val(newValue).change();
The .change() triggers a change event on the element, so the handler will be called.

Related

Angular checkbox labels not firing change events

i have implemented a group checkbox component as explained in this SO post:
Angular how to get the multiple checkbox value?
All is working well except i have one issue, the labels of the check boxes do not trigger change events, only the actual checkbox portion. In the plunker below, try clicking both the checkbox square and the label, both trigger the checkbox and update the data model but only the checkbox portion fires a change. I suspect its something to do with the transcluded value.
See this plunker
http://plnkr.co/edit/BAhzLYo9e4H8PdAt9lGR?p=preview
Code
<checkbox-group [(ngModel)]="selectedItems">
<checkbox *ngFor="let item of availableItems"
[value]="item"
(change)="onItemChange($event, item)">
{{item}}
</checkbox>
</checkbox-group>
<p>Selected items - {{selectedItems | json}}</p>
Use on click event listener instead of on change. like this
(click)="onItemChange($event, item)"
If you are using ngModel, you can also use the (ngModelChange) event.
I have some normal checkboxes <input type="checkbox"/>, and the (click) and the (change) events are never fired.
With (ngModelChange), it works (should also work with other tags than <input type="checkbox"/>, if they are using ngModel):
<input type="checkbox"
(ngModelChange)="selectAllForBatchImport($event)"
[ngModel]="areAllEntriesChecked"/>
The $event parameter will be a boolean if ngModelChange is fired from a checkbox (instead of e.g. a MouseEvent when using (click) or (change)).
By using ngModel and ngModelChange, you split up the banana-box [(ngModel)], so that you can do the change (and maybe additional work) yourself, instead of [(ngModel)], which does a "simple" ngModelChange-update by itself.

Tracking changes in textbox in scala js

I've a text box in my html file and I want to detect whenever a user changes the value of it and determine its updated value also. html code for text box is :
<input type="text" name="amount" id="amount" value="0" onchange="Demo().change(id,value)">
and in my scala file, I've implemented a function 'change' as :
#JSExport
def change(id:String):Unit={
appendPar(document.body,"Text Box value is changed and the new value is : "+document.getElementById(id).getAttribute("value"))
}
But it is not working in my case. What am I doing wrong here ?
Any suggestions ?
UPDATE : It is firing the event only when I press enter after altering the value in text box. Further, it is showing updated value as "0". How can I make it fetch from the text box instead of my pre defined value ?
You can use input event instead of change if you can ignore IE<=9.
The DOM input event is fired synchronously when the value of an or element is changed
From MDN.
Note that for non-text/textarea inputs (e.g. checkboxes, radio buttons, etc.) there are additional browser compatibility caveats, but you can just use change event on those. See http://caniuse.com/#search=input for details.
I also don't see where the variable id is coming from in your code. You should pass the string "amount" instead of id if that's what you want, like this: Demo().change("amount"). That would be quite unreusable, but it should at least work.
If you want the method to be more generic, note that javascript passes an Event object to all event handlers, and it has a target key which contains the HTML element on which the event happened (in this case that would be your textarea). You can get then easily get the value of that target.
If this is confusing, I suggest you try to implement this in JS first, and then translate this into Scala. You don't want to be fighting on both fronts at the same time.
You'll need to use one of the onkey handlers. For example:
Note that IIRC, this will also trigger if the user moves around with the arrow keys. So if you really want to only be called if it changes, you'll need to introduce a variable and check:
var lastValue: String = ""
#JSExport
def change(id:String): Unit = {
val newValue = document.getElementById(id).getAttribute("value")
if (lastValue != newValue) {
appendPar(document.body,
"Text Box value is changed and the new value is : " + newValue)
lastValue = newValue
}
}

TinyMCE - preserve style and function of selected element

I have decided to 'enhance' a textarea in a form with TinyMCE... however, doing so has interrupted the styling and jQuery functionality of the original element, as TinyMCE wraps that element in an iframe and a few divs. What I'd love to be able to do is to get the TinyMCE functionality (preserving text formatting, etc.) but not lose the styling and functions that I had associated with the original textarea. I looked through the TinyMCE documentation, but couldn't seem to find anything about this. Does anyone have any thoughts on how to accomplish this?
My form features the textarea like so:
<head>
<script>tinymce.init( { selector: 'textarea' } );</script>
</head>
<div class="form-element">
<div class="label-container">
<label for="body">Post</label><span class="warning">Please fill out this field</span>
</div>
<textarea id="body" class="input-field" name="body"></textarea>
</div>
but adding TinyMCE breaks the label/textarea relationship.
Also, jQuery functionality is broken, such as this validation script:
$("form").submit(function(e){
tinyMCE.triggerSave();
var inputFields = $(".input-field");
var proceed = true;
for(var i = 0; i < inputFields.length; i++){
if($(inputFields[i]).val() == ""){
$(inputFields[i]).css("border", "solid 3px #E86F3A");
$(inputFields[i]).prev().find(".warning").show();
var proceed = false;
e.preventDefault();
}
else{
$(inputFields[i]).css("border", "none");
$(inputFields[i]).prev().find(".warning").hide();
};
};
//OTHER STUFF...
});
since the textarea.input-field is no longer picked up in the inputFields variable.
So, in a nutshell, I'm looking for the TinyMCE wrapper to 'inherit' the styling and functionality of the element that it is attached to. Possible?
As you have correctly surmised when you invoke TinyMCE on a <textarea> the original <textarea> is no longer visible on the page and its replaced by an <iframe> and series of <div> elements.
If you want to keep the underlying <textarea> in sync you can use the tinymce.triggerSave() method. This will update all of the underlying <textarea> elements with the current value of the appropriate instance of TinyMCE.
You can do this when someone tries to save/submit the content or you can try to perform this when certain editor events happen (https://www.tinymce.com/docs/advanced/events/#editorevents). Unless you need real time accuracy of the contents of the <textarea> its far easier to call the triggerSave() method right before you perform you jQuery validation.
Note: Putting a border on the <textarea> won't have any impact on TinyMCE as you no longer see the underlying <textarea>. You can certainly try to add CSS to the editor's HTML in real time. The outer border of TinyMCE 4.4 has these classes attached:
class="mce-tinymce mce-container mce-panel"
...but do note that these classes could change over time so if you upgrade TinyMCE check to make sure your CSS still works before upgrading.

In-line item editing in Lift / handling 2 different form submit needs on one page

OK, so first off, let's start with me acknowledging that the bind( ... ) way of binding Lift forms is so last week! :) I do know that, and I just haven't gone back to update this code yet. Also, I trust now that there's some really slick Lifty way to do this. That's what I seek. I'm stumped as to even how to hack something together. That said...
I have a list of Items that I initially display non-editable, and the title of each Item is an ajax-enabled link that calls to the server and replaces that line-item with an editable form of the Item (I use SetHtml to swap the form in at the < li> that listed that Item).
"parent" Items List view looks something like this
< form data-lift="form.ajax">
< div data-lift="creategamewizard?multipart=true" id="wizardform">
< ul>
< li>Item 1< /li>
< li>Item 2< /li>
< /ul>
some more form elements
< button>Submit< /button>
< input type="hidden" id='298356928734' />
< /div>
< form>
This ajax submit (via the hidden field) calls processSubmit().
The SetHtml that swaps in the editableItem form looks something like this.
NOTE: At the end of the following listing, the "save" binding has no server-side code tied to it because the "parent" submit button is already on the page, and when I put another hidden field in this binding or tried to tie any code directly to the Edit Item Save button, that code and the "parent" submit got triggered. So the approach below was to try to use the "parent" submit for both the parent submit as well as the Edit Item submit.
<a href="javascript://" onclick={ajaxOnClickHandler(editItemClickHandler(item.id.get))}>{item.title.get}</a>
def ajaxOnClickHandler(jsHandler: ()=>JsCmd) =
{
SHtml.onEvent( e => jsHandler()).toJsCmd+";return false;"
}
def editItemClickHandler(itemId: String): ()=>JsCmd = ()=>
{
trace.logAjaxComm("ExistingItem.Edit()")
JsCmds.SetHtml("LiId"+itemId, getEditableItem(promo) )
}
def getEditableItem(itemId) =
{
bind( ...
"promotitle" -> SHtml.text(editablePromo.get.promotitle.is,
(s:String) => {
trace.logUIDataManipulation("Saving new promo Title["+s+"]");
editablePromo.get.promotitle(s)
}, "id" -> "promotitle"),
"save" -> SHtml.button("Save", ()=> {})
)
}
Then when the user selects an Item, and the editable Item form is plugged in, there's "another" submit button that should ajax submit the form data for that item, and then swap back in the (now updated) nonEditable version of the data.
The problem for me is the submission. In addition to the Edit Item form above, I've got a ajaxified submit button on the "parent" non-editable list page to handle submitting some fields below the list. The Edit Item "save"-> binding adds a button, which should do (and in fact does) nothing for itself, but it does trigger the "Parent" submit button. And I route that submit to do the save of the Edit Item form.
The non-editable Item and the editable item code swaps fine, but changes made in the editable Item form is not saved, and I figured out that that was happening because the elements in the editable Item form are not being submitted at all, following is an example of a log message I don't see at all...
bind( ... "promotitle" -> SHtml.text(editablePromo.get.promotitle.is,
(s:String) => {
trace.logUIDataManipulation("Saving new promo Title["+s+"]");
editablePromo.get.promotitle(s)
}, "id" -> "promotitle")
)
In a normal ajaxified form, all element handlers are called (if there are changes to the field, I guess...) in order of rendering, with the submit/hidden elements' handlers being called last (if they're last in the bind list.
so finally, let's get around to my question:
if you're doing in-place editing like this, how do I manage 2 submit buttons (the one for the non-editable list page plus the additional one that gets added when editing an item)?
I'm sure I don't need to refresh the page, but I can't figure out how you'd do this with Ajax.
Maybe alternatively, the in-place editable form can be submitted as a non-submit ajax action, ie. somehow that doesn't trigger the parent submit?
For anyone tripping over this question, I figured I'd share the solution I eventually found...
1)The problem was that the submit (for AJAX this is the hidden html tag) happened before the editable Item's field handlers were called. So when the AJAX update that collapsed the editable Item back into just a non-Editable list item, the data hadn't yet been updated. So what was displayed in non-editable form didn't show the update, yet if I refreshed the page in the browser, the update had been saved to the database and now showed properly.
2)The reason for the mal-ordering is that Lift assigns each form tag's server-side handler an id (which are "monotonically increasing" with an additional string added to the end). That's fine until you do an ajax live-update of a form and add fields (as I did when I inserted the Editable Item fields). These newly-added fields were assigned server-side ids that came after the hidden field that got generated as part of the initial page rendering.
3)The solution was to explicitly shove the hidden field into a much higher id using S.formGroup. See here for more details...
The example from the last link below is as follows (and differs from mine in that it uses SHtml.submit, whereas I use SHtml.hidden). It adds the constant 1,000 to the submit button's server-side handler id:
"type=submit" #> S.formGroup(1000) {
SHtml.submit("Submit", process)
}
Discussion of a problem that is essentially the same as mine: https://groups.google.com/forum/#!topic/liftweb/MYJQeVlOYFM
Description of id assignment and S.formGroup under heading "Server side function order.":
https://www.assembla.com/spaces/liftweb/wiki/cool_tips
And lastly, linked to from the last link is some example code:
https://groups.google.com/forum/#!topic/liftweb/E9z7PVhogQw

Lock/unlock form with toggle

I'm looking for a way to have a button toggeling the field of my form. When "locking" the form with the toggle button no data can be typed. When "unlocking" data should be allowed to be typed. What I want to achieve with this is simple avoiding users to accidentally type.
I found the code below and it works. Only problem is that it only applies to one input field. I want it to work on more that one.
<input type="checkbox" id="yourBox">
<input type="text" id="yourText">
<script>
document.getElementById('yourBox').onchange = function() {
document.getElementById('yourText').disabled = this.checked;
};
</script>
Mark the fields you want to disable with a CSS class, and then use jQuery to disable them.
jQuery - Disable Form Fields
If you want a pure Javascript solution, just repeat this line
document.getElementById('yourText').disabled = this.checked;
for each field.
Or, you can do something like this this: How to Get Element By Class in JavaScript?. Note that you can assign multiple CSS classes to the same field, so assign another class to identify those fields that need to be disabled.