The k-add-button works only one times. - javascript

The a href with k-add-button in the viewtemplate works only on times, not multible times. Have anybody a idea why, or mybe a sample or solution that's work correctly?
If the k-add-button is outside from the template, it works fine.
<div id="example"></div>
<script type="text/x-kendo-template" id="viewtemplate">
<div class='k-widget'>
<span>Filter:</span><span>#:filtertext#</span><span>Filterwert:</span><span>#:filterwert#</span>
<a class="k-button k-edit-button" ><span class="k-icon k-edit"></span></a>
<a class="k-button k-delete-button" ><span class="k-icon k-delete"></span></a>
<a class="k-button k-add-button" ><span class="k-icon k-add"></span></a>
</div>
</script>
<script type="text/x-kendo-template" id="editTemplate">
<div class='k-widget'>
<input type="text" class="k-textbox" data-bind="value:filtertext" name="filtertext" required="required" validationMessage="required" />
<span data-for="filtertext" class="k-invalid-msg"></span>
<input type="text" class="k-textbox" data-bind="value:filterwert" name="filterwert" required="required" validationMessage="required" />
<span data-for="filterwert" class="k-invalid-msg"></span>
<a class="k-button k-update-button" ><span class="k-icon k-update"></span></a>
<a class="k-button k-cancel-button" ><span class="k-icon k-cancel"></span></a>
</div>
</script>
<script type="text/javascript">
$(document).ready(function () {
var dataSource = new kendo.data.DataSource({
data: [ { filternr: 0, filtertext: "SA-Code", filterwert:"123"} ],
schema: {
model: {
id: "filternr",
fields: {
filternr: { type: "number" },
filtertext: { type: "string" },
filterwert: { type: "string" }
}
}
}
});
var listView = $("#example").kendoListView({
dataSource: dataSource,
template: kendo.template($("#viewtemplate").html()),
editTemplate: kendo.template($("#editTemplate").html()),
}).data("kendoListView");
$(".k-add-button").click(function(e) {
listView.add();
e.preventDefault();
});
}); // Ende $(document).ready()
</script>

I have modified your code slightly at this dojo: list view template with button
You will hopefully notice the following changes I have made.
I have added a DataBound event to your listview object like so:
editTemplate: kendo.template($("#editTemplate").html()),
dataBound: onDataBound
I have then wrapped your button click event in the appropriate function called onDataBound
The reason the button is not working correctly is that once the data you have added to the dataSource is saved and then re-read the template is re-rendered and this then removes the event handlers from the buttons that you associated then with. In order to re-link them we reattach it as part of the dataBound event and then everything is working happily.
If you need more info let me know.
Hopefully the example shows what it is doing.

Related

Kendo UI List View - switches model instance on Edit

I have a simple Kendo List view, with static data from an array of four Note objects
var notes = [{"note_id":1,"content":"This is Note 1","created":"2019-05-08 00:39:34"},
{"note_id":2,"content":"This is note 2","created":"2015-06-04 15:49:26"},
{"note_id":3,"content":"This is note 3","created":"2015-06-03 15:49:26"},
{"note_id":4,"content":"This is note 4","created":"2015-06-02 15:49:26"}];
I've got separate templates for display and edit of the Notes
<script type="text/x-kendo-tmpl" id="NoteTemplate">
<div class="product-view k-widget">
<dl>
<dt>#:kendo. toString(created, "dd/MM/yyyy HH:mm")#</dt>
<dd>#=(content)#</dd>
</dl>
<div class="edit-buttons">
<a class="k-button k-edit-button" href="\\#"><span class="k-icon k-i-edit"></span></a>
<a class="k-button k-delete-button" href="\\#"><span class="k-icon k-i-close"></span></a>
</div>
</div>
<input type="hidden" name="type_id" value="0" data-bind="value:type_id" />
</script>
<script type="text/x-kendo-tmpl" id="NoteEditTemplate">
<div class="product-view k-widget">
<dl>
<dt>#:kendo. toString(created, "dd/MM/yyyy HH:mm")#</dt>
<dd>
<div data-bind="value:content">
#=content#
</div>
</dd>
<div class="edit-buttons">
<a class="k-button k-update-button" href="\\#"><span class="k-icon k-i-check"></span></a>
<a class="k-button k-cancel-button" href="\\#"><span class="k-icon k-i-cancel"></span></a>
</div>
</div>
</script>
The issue is, when the user clicks the "pencil" icon to edit "Note 2", the edit template is rendered but with the model for Note 3
If the user cancels edit more, they again see the display template rendering Note 2
So it seems like the Kendo component is switching from Note 2 to note 3 when we go into edit mode... Why is it doing this?
See the running demo here:
https://dojo.telerik.com/oNosOCUv/3
I made 3 changes:-
Adding schema to the datasource.
Closing dl tag in EditNoteTemplate.
Move the hidden input into the the parent div, because Kendo is assigning the data uid to this element.
<script type="text/x-kendo-tmpl" id="NoteTemplate">
<div class="product-view k-widget">
<dl>
<dt>#:kendo. toString(created, "dd/MM/yyyy HH:mm")#</dt>
<dd >#=(content)#</dd>
<input type="hidden" name="type_id" value="0" data-bind="value:type_id" />
</dl>
<div class="edit-buttons">
<a class="k-button k-edit-button" href="\\#"><span class="k-icon k-i-edit"></span></a>
<a class="k-button k-delete-button" href="\\#"><span class="k-icon k-i-close"></span></a>
</div>
</div>
</script>
<script type="text/x-kendo-tmpl" id="NoteEditTemplate">
<div class="product-view k-widget">
<dl>
<dt>#:kendo. toString(created, "dd/MM/yyyy HH:mm")#</dt>
<dd>
<div data-bind="value:content">
#=content#
</div>
</dd>
</dl>
<div class="edit-buttons">
<a class="k-button k-update-button" href="\\#"><span class="k-icon k-i-check"></span></a>
<a class="k-button k-cancel-button" href="\\#"><span class="k-icon k-i-cancel"></span></a>
</div>
</div>
</script>
<script>
var notes = [
{"note_id":1,"content":"This is Note 1","created":"2019-05-08 00:39:34"},
{"note_id":2,"content":"This is note 2","created":"2015-06-04 15:49:26"},
{"note_id":3,"content":"This is note 3","created":"2015-06-03 15:49:26"},
{"note_id":4,"content":"This is note 4","created":"2015-06-02 15:49:26"}
];
$(document).ready(
function() {
var dataSource = new kendo.data.DataSource({
data: notes,
schema: {
model: {
id: "note_id",
fields: {
note_id: { type: "number" },
content: { type: "string" },
created: { type: "date" }
}
}
}});
var listView = $("#notes-list").kendoListView({
dataSource: dataSource,
template: kendo.template($("#NoteTemplate").html()),
editTemplate: kendo.template($("#NoteEditTemplate").html())
}).data("kendoListView");
});
</script>
<div id="notes-list"></div>

Knockout why does my first form.submit work but not the others?

I have three views which posts a JSON-object to backend to generate a PDF. The first in the hierarchy works, not the two others. The code is practically identical, and uses the same method to programmatically add a hidden input-field with the JSON-data.
I cannot for the life of me figure out what the problem is.
First i thought Knockout was creating the problem since the form-elements are added in a foreach-loop, in a AJAX-success-event, but every view is identical in this respect.
I've tried all variations of renaming, also I've tried to create the form and input programatically, appending them to the body and submitting. Still only the first works.
WORKING VIEW:
<div data-bind="visible: rep.messages().length > 0">
<div data-bind="foreach: rep.messages">
<div id="error" data-bind="css: color">
<div><span data-bind="css: icon"></span></div>
<div><div data-bind="html: text"></div></div>
<div>
<form action="/createPDF.html" method="POST" id="individlonpdf" name="loneandringar" target="_blank">
<span onclick=""></span>
Skriv ut
</form>
</div>
</div>
</div>
</div>
NOT WORKING VIEW:
<div data-bind="visible: rem.newEmployeeMessages().length > 0" id="rem-msg-area">
<div data-bind="foreach: rem.newEmployeeMessages">
<div id="error" data-bind="css: color">
<div><span data-bind="css: icon"></span></div>
<div><div data-bind="html: text"></div></div>
<div>
<form action="/createPDF.html" method="POST" id="ateranstallpdf" name="avanmalan" target="_blank">
<span onclick=""></span>
Skriv ut
</form>
</div>
</div>
</div>
</div>
JAVASCRIPT
Each click event-method is then directed towards the same print-method
Not-working:
rem.print = function(){
mainPdfPrint("ateranstallpdf", data, "avanmalan");
}
Working:
rep.print = function () {
mainPdfPrint("individlonpdf", data, "loneandringar");
}
The main-method:
function mainPdfPrint(formid, datasource, name, stringified) {
formid = "#" + formid;
var url = $(formid).attr("action");
var data = stringified ? datasource : JSON.stringify(datasource);
var inp = $("<input>", { "value": data, "name": name, "type": "hidden" });
if ($(formid + " input:hidden").length) {
$(formid + " input:hidden").remove();
}
$(formid).append(inp);
IK.global.logAnalytics(url);
document.forms[name].submit();
}
Both working and non-working form-elements are part of the document.forms-collection as they should be.
Any suggestions would be greatly appreciated!
UPDATE
After suggestions here, I've tried a different approach:
<div class="col-xs-12" id="" data-bind="visible:messages().length > 0">
<div data-bind="foreach: messages">
<div class="col-xs-12" id="error" data-bind="css:color">
<div class="col-xs-12 msg-templates">
<div class="col-xs-1 no-pad-l info-sign">
<span class="glyphicon" data-bind="css:icon"></span>
</div>
<div class="col-xs-9 no-pad-l">
<div class="col-xs-12 no-pad-lr msg" data-bind="html:text"></div>
</div>
<div class="col-xs-2 no-pad-lr text-right print">
<form class="col-xs-12 no-pad-l" action="/foretag/individkort/skapaPdfAvanmalan.html" method="POST" id="avanmalanpdf" name="avanmalan" target="_blank">
<span class="glyphicon glyphicon-print" onclick=""></span>
<input type="hidden" name="avanmalan" data-bind="value:ko.toJSON($root.printableEmployee)" />
Skriv ut
</form>
</div>
</div>
</div>
</div>
</div>
The problem still persists however, but setting a delay in the print-method triggers the submit-event:
self.print = function () {
setTimeout(function () {
document.forms.avanmalan.submit();
}, 600);
}
Your approach indicates that you seem to be not really familiar with knockout and try to do too much in a "jQuery" kind of way.
With knockout, your user interface is a function of your view model. All changes in the DOM have to be a result of changes in the underlying data. The task of manually adding input fields with JS code is not part of this approach.
In the following, there is no custom code that modifies the DOM. Everything is done by knockout.
var vm = {
rep: {
messages: [
{ color: '', icon: '', text: '<b>Message 1</b> - Text', data: 'some data here 1' },
{ color: '', icon: '', text: '<b>Message 2</b> - Text', data: 'some data here 2' },
{ color: '', icon: '', text: '<b>Message 3</b> - Text', data: 'some data here 3' }
]
},
catchPost: function () {
// dummy function to prevent an actual form POST
console.log("...would send the following data to the server:");
console.log(ko.toJSON(this.data, null, 2));
return false;
}
};
ko.applyBindings(vm);
button.submit {
border: 0px none;
padding: 0;
margin: 0;
text-decoration: underline;
background-color: transparent;
color: blue;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="with: rep">
<div data-bind="foreach: messages">
<div id="error" data-bind="css: color">
<div><span data-bind="css: icon"></span></div>
<div><div data-bind="html: text"></div></div>
<div>
<form action="/createPDF.html" method="POST" target="_blank" data-bind="submit: $root.catchPost">
<input type="hidden" name="loneandringar" data-bind="value: ko.toJSON(data)">
<button class="submit" id="print-tgl">Skriv ut</button>
</form>
</div>
</div>
</div>
</div>
There is no need for any custom code in such a simple scenario. Unless you have an explicit dependency on jQuery UI (or a similar library), I suggest you remove jQuery from your application altogether. You can use a dedicated Ajax library if you require it - such as reqwest - but generally speaking, jQuery is more of a hindrance than a help in knockout applications.

knockout.js afterRender does not work in a jquery pop-up

<div data-bind="style: { display: !koIsHidden() ? 'inline-block' : 'none'}">
<button id="hideButton" type="button" title="Hide" onclick="javascript:openJuiPopup('#hidePopup')" style="background: none; border: none">
<i id="hideCross" class="fa fa-2x fa-times" data-bind="attr: { 'data-applicationKey': application.applicationKey }"></i>
</button>
</div>
This button loads a pop-up that looks like this
The code for the popup looks like:
<div id="hidePopup" class="popup ui-content" data-role="popup">
<!-- ko foreach: { data: previewApplications(), afterRender: renderPopup} -->
<form id="hider" style="display:inline;" method="post" data-bind="attr: {action: '#(MVC.GetLocalUrl(MVC.HireOrgJobApplication.ViewApplication(Model.CurrentOrganization.CustomUrl, Model.Job.JobKey, "xxx/ajax-hide")))'.replace('xxx', application.applicationKey)}">
#Html.AntiForgeryToken()
<input type="hidden" name="ApplicationKey" data-bind="attr:{ value : application.applicationKey }" />
<input type="hidden" name="HideReasonId" value="7" />
<button type="submit" class="btn btn-danger jui-tooltip" data-bind="text: application.hideButtonSendRejectionInsteadOfHide === true ? 'Reject' : 'Hide', attr: { title: application.hideButtonSendRejectionInsteadOfHide === false ? 'Reject' : 'Hide'}"></button>
</form>
<!--/ko-->
</div>
And the js code that calls it:
$("#hidePopup").dialog({
dialogClass: "no-close",
position: { my: "bottom", at: "bottom", of: $("#hideCross"), collision: "none" },
autoOpen: false,
draggable: true,
}).dialog("widget").find(".ui-dialog-titlebar").hide();
The detail isn't that important, but one thing important in this code is
<!-- ko foreach: { data: previewApplications(), afterRender: renderPopup} -->
Due to the afterRender feature of knockout js, this should loop through elements in previewApplications() and run the function renderPopup.
The renderPopup looks like
self.renderPopup = function (element, data) {
$(element).find("form#hider").ajaxForm(function () {
alert("heyyyyy");
});
};
This should just simply find a form with id = hider, and run alert("heyyyy").
But it doesn't work.
Notice that afterRender worked totally fine when i put it outside of the popup.
Please help!
EDIT:
I can add more info to this question.
It's not about afterRender, but the ajaxForm just does not work for the popup.
Any idea?
EDIT2:
self.renderApplication = function (element, data) {
filter: ($(element).filter("form#hider")[0]).ajaxForm(function () {
data.koIsHidden(true);
});
};
I tried this and
$(element).filter(("form#hider")[0]).ajaxForm(function () {
data.koIsHidden(true);
});
The code above gives me the error that i wrote in the comment, and the second one gives me no error, but still doesnt catch the renderApplication function.
Call renderPopup like a function - afterRender: renderPopup() or you may have to try $root.renderPopup() or $parent.renderPopup().

Jquery how send hidden value to my script

I use ASP.NET MVC and Jquery. I have icon, when I click on it shows dialog box.
Reports.cshtml:
<a class="dialog-opener" href="#">
<input type="hidden" name="reportID" value="#view.ReportCode"/>
<i class="material-icons right">more_vert</i>
</a>
in this dialog box I have form it is partial view
SubscriptionForm.cshtml:
<div id="dialog-modal" title="Basic model dialog">
#using (Html.BeginForm("SubscriptionForm", "Subscription", FormMethod.Get)) {
#Html.AntiForgeryToken()
...
</div>
_LayoutForAll.chhtml:
$(function () {
$('#dialog-modal').dialog({
dialogClass: 'ui-dialog-osx',
autoOpen: false,
width: 800,
title:"Formularz subskrypcji",
show: {
duration: 1000
},
hide: {
duration: 1000
}
});
$('.dialog-opener').click(function () {
var reportId = $("[type=hidden]").val();
$("#dialog-modal").dialog("open");
alert(reportId);
});
});
I need send reportId from Reports.cshtml and date from form SubscriptionForm to my controller, I don't now how do this.
give ID to your hidden filed and get value using jquery
<a class="dialog-opener" href="#">
<input type="hidden" id="myhiddenfield" name="reportID" value="#view.ReportCode"/>
<i class="material-icons right">more_vert</i>
</a>
below code use for get value from hidden field.
$('.dialog-opener')
.click(function () {
var reportId = $("#myhiddenfield").val();
$("#dialog-modal").dialog("open");
alert(reportId);
});
try above code . its working fine.

Why is extending an extended view not working in ember.js?

I am trying to create a modal view and have a base class that all modals need and then extending it for more specific functionality.
PlanSource.Modal = Ember.View.extend({
isShowing: false,
hide: function() {
this.set("isShowing", false);
},
close: function() {
this.set("isShowing", false);
},
show: function() {
this.set("isShowing", true);
}
});
PlanSource.AddJobModal = PlanSource.Modal.extend({
templateName: "modals/add_job",
createJob: function() {
var container = $("#new-job-name"),
name = container.val();
if (!name || name == "") return;
var job = PlanSource.Job.createRecord({
"name": name
});
job.save();
container.val("");
this.send("hide");
}
});
I render it with
{{view PlanSource.AddJobModal}}
And have the view template
<a class="button button-green" {{action show target=view}}>+ Add Job</a>
{{#if view.isShowing}}
<div class="modal-wrapper">
<div class="overlay"></div>
<div class="dialog box box-border">
<div class="header">
<p class="title">Enter a job name.</p>
</div>
<div class="body">
<p>Enter a name for your new job.</p>
<input type="text" id="new-job-name" placeholder="Job name">
</div>
<div class="footer">
<div class="buttons">
<a class="button button-blue" {{action createJob target=view}} >Create</a>
<a class="button" {{action close target=view}}>No</a>
</div>
</div>
</div>
</div>
{{/if}}
The problem is that when I click the button on the modal dialog, it gives me an "action createJob" can not be found. Am I extending the objects incorrectly because it works if I put the createJob in the base Modal class.
Fixed
There was an issue somewhere else in my code. The name got copied and so it was redefining it and making the method not exist.

Categories