How to initialize and load values for MultiSelect / Numeric / FileUpload within a KendoUI Custom Popup Editor? - popup

I'm trying out KendoUI Web and I'm trying to get the multiselect, numeric, and fileupload widgets to display and function correctly in my custom popup editor. When clicking the Edit button the popup does not display multiselect, numeric, and fileupload correct and I cannot load the default value from the grid row into the multiselect widget (for example '1,2' in the sample data. When i click the Save button within the popup editor all the fields should populate into my text box (which seem to be working ok). I would like to stick to the HTML method of initializing widgets rather than using MVC.
If someone could please help with my issues.
I am unsure how to initialize the widgets (multiselect, numeric, and fileupload) because if i put the javascript initialization in the template, I get errors.
I cannot load default values from the grid row into my multiselect dropdown.
Does anyone know what needs to be done to get this to work correctly?
Here is my current code at http://jsfiddle.net/Xwtq3/
<h2>")
Users</h2>")
")
<div id=""example"" class=""k-content"">")
")
<input name=""txtAdvancedSearchString"" type=""text"" onchange=""javascript:setTimeout('__doPostBack")
")
(\'txtAdvancedSearchString\',\'\')', 0)"" onkeypress=""if (WebForm_TextBoxKeyHandler(event) == false) return false;"" ")
")
id=""txtAdvancedSearchString"" />")
<script>")
var mydata = [{")
guid: ""D007DD39-540B-4bc3-9900-39A8B931EB19"",")
fullname: ""Jeff"",")
email: ""jeffkent#testemail.com"",")
groups: ""1,2"",")
administrator: ""1"",")
url: ""jeff.jpg""")
}, {")
guid: ""E8CFD49A-3B85-4093-AE52-F55C73E12A7B"",")
fullname: ""Frank"",")
email: ""testemail#email.com"",")
groups: ""3,4"",")
administrator: ""1"",")
url: ""todd.jpg""")
}];")
</script>")
<div id=""grid""></div>")
<div id=""details""></div>")
<script>")
var wnd,")
detailsTemplate;")
")
$(document).ready(function() {")
")
")
var grid = $(""#grid"").kendoGrid({")
dataSource: {")
pageSize: 20,")
data: mydata")
},")
pageable: true,")
groupable: true,")
selectable: ""row"",")
reorderable: true,")
sortable: true,")
filterable: true,")
columnMenu: true,")
height: 430,")
columns: [{")
field: ""fullname"",")
title: ""Full Name""")
}, {")
field: ""email"",")
title: ""Email""")
}, {")
field: ""groups"",")
title: ""Groups""")
}, {")
field: ""administrator"",")
title: ""User Role""")
}, {")
field: ""url"",")
title: ""File URL""")
}, {")
command: {")
text: ""Edit"",")
click: showDetails")
},")
title: "" "",")
width: ""140px""")
}]")
}).data(""kendoGrid"");")
")
wnd = $(""#details"")")
.kendoWindow({")
title: ""Download"",")
modal: true,")
visible: false,")
resizable: false,")
width: 300")
}).data(""kendoWindow"");")
")
detailsTemplate = kendo.template($(""#template"").html());")
});")
")
function showDetails(e) {")
e.preventDefault();")
")
")
var dataItem = this.dataItem($(e.currentTarget).closest(""tr""));")
wnd.content(detailsTemplate(dataItem));")
wnd.center().open();")
}")
</script>")
<script type=""text/x-kendo-template"" id=""template"">")
<div id = ""details-container"" > <h2 > View / Edit User </h2>")
<table cellspacing=""6"" cellpadding=""3"">")
<tr>")
<td><label ID=""lblID"" for=""txtID"">ID:</label > <br /> <input type = ""text""")
id = ""txtID""")
class = ""k-textbox""")
placeholder = """"")
value = ""#= guid #"" > </input></td > </tr>")
<td><label ID=""lblFirstName"" for=""txtFirstName"">First Name:</label > <br /> <input type = ""text""")
id = ""txtFirstName""")
class = ""k-textbox""")
placeholder = """"")
value = ""#= fullname #"" > </input></td > </tr>")
<tr>")
<td>")
<!--MultiSelect Dropdown-->")
")
<select name=""groups"" id=""groups"" class=""k-item"" multiple=""multiple"" data-role=""dropdownlist"">")
<option value=""1"">HR</option > < option value = ""2"" > 1099 < /option>")
<option value=""3"">Insurance Form</option > < option value = ""4"" > Claim Form < /option>")
<option value=""4"">Timeoff Requests</option >")
")
</select>")
")
<!--MultiSelect Dropdown end--></td >")
")
</tr>")
<tr><td> ")
<input id=""txtMaxAdmins"" type=""number"" value=""#=administrator#"" min=""0"" max=""100"" />")
")
")
")
</td></tr >")
")
")
<tr> <td> <label")
for = ""upload"" > Document Types: </label>")
Choose a transparent .png for best results<br /> <input id = ""upload""")
type = ""file"" value=""#=url#"" />")
")
")
</td></tr> <tr > <td colspan = ""2"" > <button ID = ""btnSave""")
class = ""k-button""")
onclick = ""CallServer()"" > Save </button></td> </tr>")
</table> </div>")
</script>")
<script>")
function CallServer() {")
var userinput = ($(""#txtID"").val()) + '|' + ($(""#txtFirstName"").val()) + '|' + ($(""#groups"").val());")
document.getElementById(""txtAdvancedSearchString"").value = userinput;")
")
//alert(userinput);")
__doPostBack('__Page', 'e');")
}")
</script>")
</div>")

You need to tell KendoUI to use the html elements as kendo controls.

Related

VueJS lifecycle after submit form

I would like to plot some d3js chars in vuejs after performing an API call to get some data. To do so, I created a form whose input is used to collect the data from the API. Once I submit the form, I call my d3js function to plot the charts based on the retrieved data. I want the plotting functions to be called only when the data is not empty. To do so, I used the conditional rendering v-if based on the length of the data. So far so good. My problem is that once the plots are rendered if I type anything in the form, a new plot will be created as if every time the if statement is evaluated again and again, I don't know if it is related to lifecycle or not, but how can avoid this behavior?
<template>
<meta charset="utf-8">
<h4>Associate Information</h4>
<form #submit.prevent="onSubmit">
<input placeholder="Associate Id" v-model="associateId" /> <br />
<input placeholder="Starting date" v-model="initialDate" /> <br />
<input placeholder="Ending date" v-model="finalDate" /> <br />
<button v-on:click="getAssociatesbyIdAndDates()">submit</button>
</form>
<div class="chart" v-if="dailyData.length">
{{ DailyBillabilityLinePlot() }}
{{ WeeklyMonthlyQuarterlyBarPlot(weeklyData) }}
</div>
<div class="linePlot"></div>
<div class="barPlot" v-if="weeklyData.length">
<button v-on:click="WeeklyMonthlyQuarterlyBarPlot(weeklyData)">Weekly</button>
<button v-on:click="WeeklyMonthlyQuarterlyBarPlot(monthlyData)">Monthly</button>
<svg id="chart" viewBox="0 0 960 300"></svg>
</div>
</template>
<script>
import * as d3 from 'd3'
export default {
name: 'Timecard',
props: {
msg: String
},
data() {
return {
apiUrl: "",
myNumber: 0,
environment: "",
apiTst:"",
name:"",
initialDate: "",
finalDate: "",
associateId: "",
dailyData: [],
weeklyData:[],
monthlyData:[],
}
},
methods: {
WeeklyMonthlyQuarterlyBarPlot(data){
// plot a d3 bar plot
},
DailyBillabilityLinePlot() { // plot another d3 line plot}
getAssociatesbyIdAndDates() {
// Connect to the backend and get the list of associates
// http://localhost:8080/timecards/period/test/274/2020-04-14/2020-04-22
console.log("Fetching the data for an associates from the backend based on initial date and final date...");
this.axios.get(this.apiUrl + "test/period/test/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
.then(response => {
this.dailyData = response.data;
console.log(response.status);
})
.catch(error => {
console.error(error);
})
this.axios.get(this.apiUrl + "test/weekly/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
.then(response => {
this.weeklyData = response.data;
console.log(response.status);
})
.catch(error => {
console.error(error);
})
this.axios.get(this.apiUrl + "test/monthly/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
.then(response => {
this.monthlyData = response.data;
console.log(response.status);
})
.catch(error => {
console.error(error);
})
},}
onSubmit() {
let consultantApi = {
name: this.name,
initialDate: this.initialDate,
finalDate: this.finalDate,
}
this.$emit('consultantApi-submitted', consultantApi)
this.name = ''
this.initialDate = ''
this.finalDate = ''
}
},
mounted: function() {
this.apiUrl = process.env.VUE_APP_BACKEND_API;
this.environment = process.env.NODE_ENV;
}
Initial Form
D3 plots after submitting the completed form
Creation of new d3 plots whenever I press any key in the form
Yes, this is because updating any model will re-render the entire component.
To get around it, I find the simplest way is to put the chart into another component so that the re-render is then guarded.
Example:
var app = Vue.createApp({
data() {
return {
abc: 'ABC',
list: [1, 2, 3]
};
}
});
app.component("my-chart", {
template: `<div >{{Math.random()}}</div>`
});
app.mount("#app");
<script src="https://unpkg.com/vue#3.0.6/dist/vue.global.prod.js"></script>
<div id="app">
<input v-model="abc" />
<div v-if="list.length">
{{Math.random()}}
</div>
<my-chart></my-chart>
</div>
I think your bug is in the parent component. I would try to check how often does it emmit the consultantApi. It seems like your form keeps submitting on input change event and not on form submit.

How do I trim long text with three dots of Node in jstree?

When long text documents are uploaded then my popup's width gets altered.
Is there any way to trim long text with three dots for tree node's text?
Following is my HTML code to create tree structure
<div class="col-md-12" style="height:100%;overflow:auto" ng-if="IsTree">
<oe-jstree source="AssemblyDocuments"
name="documenttree"
is-upload-file="true"
options="treeOptions"
tree-node-creator="createNode(item)"
on-item-selected="NodeSelected(item)"
on-item-created="NodeCreated(item, callback)"
on-item-renamed="NodeRenamed(item, callback)"
on-item-removed="NodeRemoved(item, callback)"
on-item-archived="NodeArcive(item, callback)"
on-item-download="onItemDownload(item, callback)"
on-item-tagged="onItemTagged(item, callback)"
tag-list="TagMst"
is-read-only="isReadOnly"
id="documenttree"></oe-jstree>
</div>
How can I cut text and show three dots with a tooltip?
$scope.createNode = function (nodedata) {
if (nodedata.Name != null)
nodedata.Name = nodedata.Name.trim();
var node = {
id: nodedata.Id,
text: nodedata.Name.substr(0, 60) + (nodedata.Name.length > 60 ? "..." : ""),
state: {
opened: true
},
type: nodedata.isFile == true ? File : Folder,
icon: nodedata.isFile == true ? (nodedata.Archive == true ? 'jstree-zip' : 'jstree-file') : 'jstree-folder',
children: GetChilders(nodedata),
FileTagDetails: nodedata.FileTagDetails,
model: nodedata,
a_attr: {
title: nodedata.Name
}
};
return node;
};
By using text: nodedata.Name.substr(0, 60) + (nodedata.Name.length > 60 ? "..." : ""), you can achieve 3 dots

convert script from jQuery 1.9 to 1.8

this script works in jQuery 1.9, but does not work in 1.8. How to convert this script to jQuery 1.8 ?
NOT Working Demo on jsfiddle
Working Demo on jsfiddle
HTML
<div id="container">
<div id="c1" class="aaa" style="text-align:right; color:red top:100px; ">child 1</div>
<div id="c2" class="aaa" style="text-align:left; top:200px; ">child 2</div>
</div>
jQuery script
$("#container").children().each( function () {
alert("element ID = " + $(this).attr('id'));
var styleProps = $(this).css(["width",
"height",
"color",
"background-color",
"text-align",
"left",
"top",
"right",
"bottom"]);
$.each(styleProps, function (prop, value) {
alert(prop + " = " + value);
});
});
The css function accepting an array wasn't implemented until 1.9.
You'll probably have to do it by hand if you're using 1.8 (loop through the values one at a time).
var styleNames = ["width", "height", "color", ...etc... ];
var i;
var $elem = jQuery(this);
for (i = 0; i < styleNames.length; ++i) {
alert(styleNames[i] + " = " + $elem.css(styleNames[i]));
}

Lift - Returning Errors and Updating Parent Div Class From Ajax Form

I have an ajax form which which is currently returning errors using the S.error() method. This is fine but I also want to add a new css class to one of the elements parent div tags. I have tried to do this with the JE.Call() method with no avail. Is anyone could point me in the right direction it would be really appreciated.
Snippet Code
class Register {
private var user = User.createRecord
private var pw2 = ""
private var dob = ""
private var errors = new Array[String](7)
val whence = S.referer openOr "/"
Thread.sleep(400)
def registerUser(): JsCmd = {
errors(0) = User.validateUsername(user.username.is)
errors(1) = User.validateEmail(user.email.is)
errors(2) = User.validatePhone(user.phone.is)
errors(3) = User.validateCity(user.city.is)
errors(4) = User.validateDOB(dob)
errors(5) = User.validatePassword(user.uPw.is)
errors(6) = User.validateSecondPW(user.uPw.is, pw2)
if(errors.count(_ != "") == 0) {
user.uPw.set(User.hashPassword(user.uPw.is, user.id.is.toString))
user.dob.set(User.stringToDate(dob))
user.save
println("User id " + user.id.is.toString + " added to database")
S.redirectTo(whence)
}else{
if(errors(0) != "")
S.error("username-error", errors(0))
JE.Call("addError(username-error)")
......
}
}
def form = {
"id=username" #> SHtml.text("", user.username.set(_), "placeholder" -> "Username") &
"id=email" #> SHtml.email("", user.email.set(_), "placeholder" -> "Email") &
"id=phone" #> SHtml.text("", user.phone.set(_), "placeholder" -> "Tel") &
"id=city" #> SHtml.text("", user.city.set(_), "placeholder" -> "City") &
"id=dob" #> SHtml.text("", dob = _, "placeholder" -> "DOB") &
"id=password" #> SHtml.password("", user.uPw.set(_), "placeholder" -> "Password") &
"id=passwordCheck" #> SHtml.password("", pw2 = _, "placeholder" -> "Confirm Password") &
"type=submit" #> SHtml.ajaxSubmit("Register", () => registerUser, "class" -> "btn")
}
}
HTML Template
<h2>Register</h1>
<form class="lift:form.ajax?class=form-horizontal">
<div class="lift:Register.form">
<div id="id1" class="control-group">
<label class="control-label" for="username">Username:</label>
<div class="controls">
<input id="username">
<span id="username-error" class="help-inline"></span>
</div>
</div>
<div class="controls">
<button type="submit" ></button>
</div>
</div>
</form>
Javascript Function
<script>
function addError(id) {
$("#"+id).closest(".control-group").addClass("error");
}
addError("email-error")
</script>
Try to change the Call function.
JE.Call("addError","username-error").cmd
I recommend giving up on JavaScript abstractions in Lift and use plain Run Object everywhere. So In your case I'd use:
Run("addError(username-error)")

Editing and deleting a newly added table row using Jquery

I'm adding new rows dynamically to the existing table, the first column of the table holds the Edit & Delete buttons. I'm facing 2 problems with this:
Not able to Edit and Delete newly added rows, tried .live but couldn't make it work
Not able to get the record id of the newly added rows (ajax returns the record when new rows are added).
Code looks like this:
Adding new rows:
<script type="text/javascript">
$(function() {
$('#btnSubmit').click(function() {
var oEmployee = new Object();
oEmployee.Title = $("#Title").val();
oEmployee.Middlename = $("#MiddleName").val();
oEmployee.Lastname = $("#LastName").val();
oEmployee.Email = $("#Email").val();
var DTO = {'employee': oEmployee};
var options = {
type: "POST",
url: "WebService.asmx/InsertEmployee",
data: JSON.stringify(DTO),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
if (response.d != "") {
if (parseInt(response.d) >= 1) {
var contactID;
contactID = parseInt(response.d);
$('#tblEmployee tbody tr:first').after("<tr id=" + contactID + "><td><input type='button' class='newContactID' value='Edit'/> <input type='button' value='Delete'/></td><td align=center>" + contactID + "</td><td align=center>" + oEmployee.Title + "</td><td align=center>" + oEmployee.Middlename + "</td><td align=center>" + oEmployee.Lastname + "</td><td align=center>" + oEmployee.Email + "</td><tr>"); // need to hook up editing and deleting function to the newly added rows }
else {
alert("Insert Failed \n" + response.d);
}
}
}
};
//Call the webservice
$.ajax(options);
});
});
</script>
Code for editing and deleting:
$(function() {
$("#tblEmployee > tbody > tr ").each(function() {
var TRID = $(this).attr("id");
$(this).find("td:first > input[value=Edit]").click(function() {
ResetOtherRowEdit();
ChangeTableCellToTextbox(TRID);
$(this).hide();
$("#tblEmployee > tbody > tr[id=" + TRID + "] > td:first> input[value=Delete]").hide();
return false;
});
$(this).find("td:first > input[value=Update]").click(function() {
UpdateRow(TRID);
});
$(this).find("td:first > input[value=Delete]").click(function() {
DeleteRow(TRID);
});
$(this).find("td:first > input[value=Cancel]").click(function() {
CancelEdit(TRID);
});
});
});
What is the best way to approach this? Editing and deleting of records work fine when they're pulled off the database.
Update
This is how the code looks like now, just began dabbling with Jquery a month back, still trying to get my head around it.
$(function() {
$("#tblEmployee > tbody > tr ").live('click', function(e) {
var TRID = $(this).attr("id");
var $target = $(e.target);
if ($target.is('#btnEdit')) {
$(this).find("td:first > input[value=Edit]").click(function() {
ResetOtherRowEdit();
ChangeTableCellToTextbox(TRID);
$(this).hide();
$("#tblEmployee > tbody > tr[id=" + TRID + "] > td:first> input[value=Delete]").hide();
return false;
});
}
else if ($target.is('#btnUpdate')) {
$(this).find("td:first > input[value=Update]").click(function() {
UpdateRow(TRID);
});
}
else if ($target.is('#btnCancel')) {
$(this).find("td:first > input[value=Cancel]").click(function() {
CancelEdit(TRID);
});
}
else if ($target.is('#btnDelete')) {
$(this).find("td:first > input[value=Delete]").click(function() {
DeleteRow(TRID);
});
}
});
});
HTML codes looks like this:
<ItemTemplate>
<tr id='<%# Eval("ContactID") %>'>
<td width="10%">
<input type="button" value="Edit" id="btnEdit"/>
<input type="button" value="Delete" id="btnDelete"/>
<input type="button" value="Update" style="display:none" id="btnUpdate" />
<input type="button" value="Cancel" style="display:none" id="btnCancel"/>
</td>
<td width="10%" align="center"><%# Eval("ContactID")%></td>
<td width="20%" align="center"><%# Eval("Title")%></td>
<td width="20%" align="center"><%# Eval("MiddleName")%></td>
<td width="20%" align="center"><%# Eval("LastName")%></td>
<td width="20%" align="center"><%# Eval("EmailAddress")%></td>
</tr>
</ItemTemplate>
You could take advantage of DOM traversal and .live() to make this work. Add a listener using .live() to the rows of the table. Inside this method, determine which element was clicked (e.currentTarget). You can use a simple conditional to check if it was a button that needs to react. Then, use DOM traversal to nail down what you want to have happen. For example, if e.currentTarget is the delete button, the you can use $(this).closest('tr').remove(); to delete the row. If you need to interact with the data through ajax, make your ajax function support passing in whatever valus you'd need (id) to perform the delete. In order to obtain the id, you'll need to get it from the ajax call and put it somewhere inside the DOM so you can retrieve it when you need it. You can always toss in a 'title' attribute when the tr is generated.
Here is a same script with php
http://www.amitpatil.me/add-edit-delete-rows-dynamically-using-jquery-php/
// Add new record
$(document).on("click","."+editbutton,function(){
var id = $(this).attr("id");
if(id && editing == 0 && tdediting == 0){
// hide editing row, for the time being
$("."+table+" tr:last-child").fadeOut("fast");
var html;
html += "<td>"+$("."+table+" tr[id="+id+"] td:first-child").html()+"</td>";
for(i=0;i<columns.length;i++){
// fetch value inside the TD and place as VALUE in input field
var val = $(document).find("."+table+" tr[id="+id+"] td[class='"+columns[i]+"']").html();
input = createInput(i,val);
html +='<td>'+input+'</td>';
}
html += '<td><img src="'+updateImage+'"> <img src="'+cancelImage+'"></td>';
// Before replacing the TR contents, make a copy so when user clicks on
trcopy = $("."+table+" tr[id="+id+"]").html();
$("."+table+" tr[id="+id+"]").html(html);
// set editing flag
editing = 1;
}
});