Changing JavaScript variable dynamically - javascript

This is my program skeleton http://jsfiddle.net/zhwzY/
$(document).ready(function(){
$("#btnSend").click(function(){
var option = {
'delay' : false,
'helpSpanDisplay' : 'help-block',
'disableSubmitBtn' : false
};
if($('#agree').is(':checked')){
form_input = 'input:not("#reason")';
}else{
form_input = 'input';
}
var metric = [
[ form_input, 'presence', 'Please fill this textbox!']
];
$("#frm").nod(metric, option);
});
});
From the snippet, I try to make variable "form_input" to switch to a new value depend on the checkbox. With this method, I can prevent NOD (validation plugins) from validating unecessary input. But the variable "form_input" is not changing to the new value upon updating.
Please help.
P/s : No external reference to the NOD library in jsFiddle.

Related

How can ajax based Select2 pre-population be formatted?

We've found several examples of pre-populating selected option for Select2, however none of them we could find deal with formatted list and selection options. We have a JS fiddle at https://jsfiddle.net/gpsx62de/26/ that illustrates the issue. In that fiddle, you can type and L or whatever into the select search and the data is returned, the list is formatted, and if you select something, the selection is formatted.
However if you click the button in that JS Fiddle which is intended to simulate pre-population per https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2 the data is returned (you can uncomment the console.log to see it), but the formatted selection shows undefined for the intended values. Does anyone know of a way to get the formatted values for pre-populated data to display correctly?
// Set up the Select2 control
$('#mySelect2').select2({
ajax: {
url: '/api/students'
}
});
// Fetch the preselected item, and add to the control
var studentSelect = $('#mySelect2');
$.ajax({
type: 'GET',
url: '/api/students/s/' + studentId
}).then(function (data) {
// create the option and append to Select2
var option = new Option(data.full_name, data.id, true, true); //**** DOES IT MATTER WHAT IS PASSED HERE BECAUSE WE ARE NOT DISPLAY THE OPTION TEXT?? ***
studentSelect.append(option).trigger('change');
// manually trigger the `select2:select` event
studentSelect.trigger({
type: 'select2:select',
params: {
data: data //**** THIS DOES NOT SEEM TO SUPPORT FORMATTED SELECTIONS, SO HOW CAN THIS BE DONE? ***
}
});
});
The problem is in format_selection function. The format of the object it receives depends on how it was created. When you use new Option(text, value) it receives only the properties of this Option object, not your original object containing all user info.
A workaround is to check of either possible values in the fuction:
function format_selection(obj) {
let name = obj.name || obj.element.text;
let email = obj.email || obj.element.email;
return $(`<div><b>${name}</b></div><div>(${email})</div>`);
}
For this to work you should append the de property on you Option object:
var option = new Option(data.name, data.id, true, true);
option.email = data.email;
$('#sel').append(option).trigger('change');
The problem, in https://jsfiddle.net/gpsx62de/26/ is with the
function format_selection(obj) {
// Just add this to see the obj
console.log(obj);
return $(`<div><b>${obj.text}</b></div><div>(${obj.id})</div>`);
}
The obj object just contains the Option class data, so:
id: "1",
selected: true,
text: "Leanne Graham",
title: ""
So you have to find a way to pass "data.email" to the "format_selection" method
EDIT
This could be a solution
$('#btn').on('click', function() {
$.ajax({
type: 'GET',
url: 'https://jsonplaceholder.typicode.com/users/1'
})
.then(function(data) {
console.log(data)
// create the option and append to Select2
$('#sel').append($('<option />') // Create new <option> element
.val(data.id) // Set value
.text(data.name) // Set textContent
.prop('selected', true)
.attr('data-name', data.name) // Don't know why the .data(key, value) isn't working...
.attr('data-email', data.email))
.trigger('change');
}); //then
}); //click
And
function format_selection(obj) {
return $(`<div><b>${obj.element.dataset.name}</b></div><div>(${obj.element.dataset.email})</div>`);
}
This is the fiddle https://jsfiddle.net/947jngtu/

Why subscribe event of dropdown is being called on load knockoutJs?

This may be a basic question but I am unable to get any solution.
I am trying to show a list of formats in a dropdown. I am using knockout binding to do so. I want to show a specific value initially.
When user selects some other value from the dropdown it should show the selected value (which is working fine).
On selecting any option I want to get the selected value so that I can send it to the server. I am using subscribefor that.
Below is my code:
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.formatArrayDefault = ko.observable({text :format1});
obj.formatArrayDefault.subscribe(function(newValue){
alert("default value " + format1);
alert("new value in subscribe " + newValue.text);
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>
You can run the above snippet and check, alert inside subscribe is coming on loading and changing the value to be displayed to the first value in the array.
Why subscribe is called on load and why the value is changed to first value?
What mistake I am doing?
If the question is duplicate can someone give link to the solution (I searched here but could not get any solution).
if you just want the value of the dropdown after any change.
just take a observable and set it as value it the drop down and initially it will be blank and in your subscribe function just add a line of comparision if the value of drop down is empty dont call the alert function.
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.initialLoad = true;
obj.formatArrayDefault = ko.observable(format1);
obj.formatArrayDefault.subscribe(function(newValue){
if(obj.initialLoad) {
obj.initialLoad = false;
}
else {
alert("Hello");
}
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="projectUserAccess workflowSetOptions" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>
===EDIT===
$(document).ready(function(){
var model = {
selectedType: 2 //default Type
};
var viewModel = {
selectedType: ko.observable(model.selectedType)
, availableTypes: ko.observableArray([
{ Label: 'Type1', Code: 1 }
, { Label: 'Type2', Code: 2 }
, { Label: 'Type3', Code: 3 }
])
};
ko.applyBindings(viewModel, $("#content")[0]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
<select data-bind="value: selectedType, options: availableTypes, optionsText: 'Label', optionsValue: 'Code', optionsCaption: 'Please select...'"></select><br/>
You've selected Type: <span data-bind="text: selectedType"></span>
</div>
Your array contains plain objets. In javascript, object comparison works like this:
var obj1 = { a: 1 };
var obj2 = { a: 1 };
console.log(obj1 === obj2); // false
console.log(obj1 === obj1); // true
It checks the actual object instance that is referenced by a variable, not the way it looks. Many libraries contain a "deepEquals" function that you can use to check if two objects actually look similar, but knockout doesn't use such a mechanism.
So when you set your initial selection, its value might be similar to the object at formatArray()[0], but knockout won't be able to mach the two together. I.e.:
obj.formatArrayDefault() === obj.formatArray()[1]; // false
Now, when applying bindings, knockout tries to solve the mismatch between selection and source data. It can't find an <option> element to match with the selection that is passed to the value binding.
It has to render a selected option, so it defaults to the first one. This is when your initial object gets replaced by formatArray()[0] and the subscription is triggered.
Here's a solution: we put an actual reference to the first object in our initial value!
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.formatArrayDefault = ko.observable(obj.formatArray()[1]);
obj.formatArrayDefault.subscribe(function(newValue){
console.log("default value " + format1);
console.log("new value in subscribe " + newValue.text);
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>

How to pass selected value as extra parameter to ajax call

my coding part
$("#demo-input").tokenInput("data/autosuggest-search-city.php",
{
searchDelay: 2000,
minChars: 3,
tokenLimit: 10
});
I want to send the selected values as extra parameter to "data/autosuggest-search-city.php".
For example,
Initially I search and select one value from list
then again searching, this time I want to send the 1st selected value to server.
How to do this?
TokenInput plugin doesn't support that natively.
You can however make a simple workaround to update "AJAX url" whenever a token is added or removed from selection.
Use onAdd and onDelete callbacks to trigger "AJAX url" changes;
Get selected tokens using selector.tokenInput("get") method;
Set the new "AJAX url" by updating .data("settings").url of the element;
// cache the original url:
var token_url = "data/autosuggest-search-city.php";
$("#demo-input").tokenInput(token_url, {
searchDelay : 2000,
minChars : 3,
tokenLimit : 10,
onAdd : function(){
urlChange.call(this);
},
onDelete : function(){
urlChange.call(this);
}
});
function urlChange(){
var tokens = '', token_list = $(this).tokenInput("get");
// proceed if any token/s are selected:
if(token_list.length){
// loop through the selected tokens (if more than one is selected)
$.each(token_list, function(i, token){
// use token "id" (or "name" if you wish) and separate them with comma:
tokens += token.id + ',';
});
// update url:
$(this).data("settings").url = token_url + '?selected_tokens='+tokens.replace(/,+$/,'');
}else{
// leave original url if no tokens are selected:
$(this).data("settings").url = token_url;
}
};

adding element with duplicate id 'FileULoader' FileUploader

createContent : function(oController) {
var oFileUploader = new sap.ui.commons.FileUploader({
id: "FileULoader",
//uploadUrl : "UploadFileServelet", // URL to submit the form to
name: "simpleUploader", // name of the input type=file element within the form
// uploadOnChange: true, // immediately upload the file after selection
buttonOnly: false,
buttonText: "Upload"
}).addStyleClass("downloadBtn");
oFileUploader.attachUploadComplete(oController.doFileLoadComplete);
//var uploadBtn=new sap.ui.commons.buttons{this.creatId("upLoadFile"),}
var oMatrix = new sap.ui.commons.layout.MatrixLayout({
layoutFixed : true,
width : '400px',
columns : 1 });
var text = new sap.ui.commons.TextView({text:"Confirm that the data will be wiped out once you upload new data file."});
oMatrix.createRow(oFileUploader);
oMatrix.createRow(text);
var oDialog = new sap.ui.commons.Dialog({
title:"FileUpload",
resizable:false,
modal:true,
showCloseButton:true,
contentBorderDesign:"Box",
content:[
oMatrix
],
buttons:[
new sap.ui.commons.Button({text:"Confirm", tooltip:"Confirm",press:function(e){oController.doFileUpload();oDialog.close();}}),
new sap.ui.commons.Button({text:"Cancel", tooltip:"Cancle",press:function(e){oDialog.close();}}),
]
});
return oDialog;
i used in two views . when i call the fileUploader the error turns out。
i have to use the id to identify the fileloder controller. to get the input file information .
update:
_uploadCourse:function(){
if (!this.dialogUploadFile) {
this.dialogUploadFile = sap.ui.jsfragment("courseUP",
"adminView.dialogUploadFile", this);
}
this.dialogUploadFile.open();
},
_uploadCourse : function() {
if (!this.dialogUploadFile) {
this.dialogUploadFile = sap.ui.jsfragment("certiUploadFile",
"adminView.dialogUploadFile", this);
}
this.dialogUploadFile.open();
},
this is how i use the fragment. but is still go wrong with thew same error;
#Allen Zhang
You mentioned you used the code in two views. You can't create a dialog twice with the same id of Fileupload control. Use different id for different views.
Updated:
Define id for your fragment usage:
<core:Fragment id="myFrag" fragmentName='my.frag' type='JS' />
Define fileupload id by calling createId:
var oFileUploader = new sap.ui.commons.FileUploader({
id: this.createId("FileULoader"),
//uploadUrl : "UploadFileServelet", // URL to submit the form to
name: "simpleUploader", // name of the input type=file element within the form
// uploadOnChange: true, // immediately upload the file after selection
buttonOnly: false,
buttonText: "Upload"
}).addStyleClass("downloadBtn");
Also see my answers about fragment usage and get control inside fragment.
Is an option that you do not use id for the file uploader control, and do it like this?
createContent : function(oController) {
this.oFileUploader = new sap.ui.commons.FileUploader({
To access it, you do
view.oFileUploader
where view is the javascript handle of one of your two views.
-D

.uploadifySettings not working as expected

I'm using uploadify and the function to change the settings doesn't seem to be working.
I'm basing my code from the following example:
#(‘#someID’).uploadifySettings(’scriptData’, {‘name’ : some.val()});
So here's what I'm doing:
// INITIALIZATION
$("#"+elementId).uploadify({
// other data
"scriptData": {
"token": token
}
});
Later on I want to update the scriptData:
$("#"+elementId).uploadifySettings("scriptData",{"token": "pleasework"});
... but this is not working, it's still using the scriptData set during the initialization.
What am I doing wrong?
UPDATE: I need to do this because I need to handle tokens. Here's the worflow:
1- Get a token
2- Init uploadify with this token
3- Upload a file
4- Get another token asynchronously
5- Add the token to the already initialized uploadify (bugged)
6- Go to 3
I tried doing this on initialization:
"scriptData": {
"token": $(".token").val()
}
... and update .token on step 4
This doesn't work either
UPDATE 2: Also if I do:
"scriptData": {
"token": getAToken()
}
with
function getAToken(){
alert("abcd");
return "sometoken";
}
... I can see that the function getAToken only gets called once (only 1 alert)
This works for me, adding a unique nonce to every file upload
function setScriptData(){
$("#product_attachment").uploadifySettings("scriptData",
{
'_fsg_distro_session' : '<%= u cookies["_fsg_distro_session"] %>',
'authenticity_token' : '<%= u form_authenticity_token if protect_against_forgery? %>',
'nonce' : new Date().getTime() + "<%= #current_user.id %>"
}
);
console.debug($("#product_attachment").uploadifySettings("scriptData"));
}
$("#product_attachment").uploadify({
uploader : '/uploadify/uploadify.swf',
script : '/products/temp_upload',
cancelImg : '/uploadify/cancel.png',
fileDataName : 'asset[temp_file]',
'queueID' : 'fileQueue',
onComplete : function(event, ID, fileObj, response, data){ fileOnCompleteHandler(event,data); },
onSelect : setScriptData,
auto : true,
multi : false,
buttonImg : '/images/attach.png',
fileNameMaxLength : 30
});
I am using the latest Uploadify (2.1.0) and JQuery (1.4.1)
I've looked at the source and I notice that uploadifySettings() has an optional, undocumented (it does not appear here) third parameter. Apparently if you set it to true as in $("#"+elementId).uploadifySettings("scriptData",{"token": "pleasework"}, true); it will clobber the existing settings for scriptData and perhaps that will have some impact.
But based on the source I can't exactly tell what impact a change in settings necessarily has.
uploadifySettings:function(settingName, settingValue, resetObject) {
var returnValue = false;
jQuery(this).each(function() {
if (settingName == 'scriptData' && settingValue != null) {
if (resetObject) {
var scriptData = settingValue;
} else {
var scriptData = jQuery.extend(settings.scriptData, settingValue);
}
var scriptDataString = '';
for (var name in scriptData) {
scriptDataString += '&' + name + '=' + escape(scriptData[name]);
}
settingValue = scriptDataString.substr(1);
}
returnValue = document.getElementById(jQuery(this).attr('id') + 'Uploader').updateSettings(settingName, settingValue);
});
That code is from version 2.1.0.
Is there a way to potentially decide on the settings before initialization?
Also, I found this existing SO question: Uploadify updateSettings problems.
Try defining the function in-line at initialization? IE:
"scriptData": {
"token": function() { return $("#token").val(); }
}
I'm not sure why this would be different than some of your other solutions though.
FOUND THE SOLUTION:
I had a mistake in the "onSelect" function. I had misspelled the element id name, instead file_upload I had fileUpload and thats why it didnt update the scriptData parameter. I know its a silly mistake but easy to be made. Here is the whole onSelect function:
'onSelect' : function(event,data) {
$("#file_upload").uploadifySettings('scriptData', {'id' : $('#name_of_the_element').val()}
);
}
So check if this is the problem

Categories