jquery validate method not found error on mvc4 - forms

I am working on top of the sample MVC4 template to build a wizard form, I have taken the source from http://afana.me/post/create-wizard-in-aspnet-mvc-3.aspx
When I trigger the java script that makes the 'next' button i get below error
var validator = $('form').validate(); // obtain validator
Uncaught TypeError: Object [object Object] has no method 'validate'
Below is complete JS portion trigger with the next button.
$("#next-step").click(function () {
var $step = $(".wizard-step:visible"); // get current step
var validator = $('form').validate(); // obtain validator
var anyError = false;
$step.find("input").each(function () {
if (!validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
if (anyError)
return false; // exit if any error found
I have included the library sources in the mvc4 bundles.
I am able to get the client side validation successfully using unobtrusive js.
But invoking the validation on next button fails.
Any help on how to fix this would be very helpful

I was able to figure out the problem.
The MVC4 template had a js reference at the end of the body tag.
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
This overrides every other jquery library and hence the method x not found.

UPDATE ONE YEAR LATER
To elaborate,
VS 2013 using MVC4 adds to the _Layout partial view
#Scripts.Render("~/bundles/jquery")
a redundant second time after
#Scripts.Render("~/bundles/jqueryval") has been declared
So the redeclaration of #Scripts.Render("~/bundles/jquery") at the bottom will disable useful methods as .valid() in the jqueryval bundle.
Remove it to fix.

Related

ERPnext: How to use custom script in web form

This script works great in the document but fails when used in the web form. Console logs “frm is not defined” (the error is marked on the frm in the second line, before “.page.wrapper…”). How should I modify it in order to adapt to a web form? I’ve tried using DOM by referencing it by id and using an onclick event but didn’t work.
frappe.web_form.after_load = () => {
frm.page.wrapper.find(".a1").on("click", function(evt){
frappe.web_form.set_df_property("a1", "options", "<img src=LINK>");
refresh_field("a1");
frm.set_value("r1", 1);
refresh_field("r1");
});
};
Thanks!

how to refresh jstree with html instead rebuilding it

my code builds an html and initiates the jstree with that html :
var html = buildHtmlunorderedList()
$("#tree").html(html);
$("#tree").jstree({
"core":{"multiple":false},
"state":{"key":"vmsTree22"},
"plugins":["state","sort"]
}).bind("select_node.jstree",handleLeftClick);`
This work perfect.
now , every few minutes the html is built again and i want to refresh the jstree with it without the need to destroy it and initiate again (which cause a flick every time the tree is built again) :
inside a loop {
html = buildHtmlunorderedList();
var tree = $('#tree').jstree({
"core":{"data":html}
});
tree.refresh(true);
}
but i am getting an error : Uncaught TypeError: Cannot read property 'className' of undefined
(in jstree.js : var c = this.get_container_ul()[0].className;)
which seams it doesn't find the first children of class jstree-children.
what i am doing wrong ?
I didn't find any straight forward example of how to refresh the entire html of the tree without destroying it and build it again.
thanks for any help
You can replace data as below. Check demo - Fiddle.
$("#tree").jstree().settings.core.data = newData;
$("#tree").jstree().refresh(true);

writing a Jacada Interaction extension

I want to create an "extension" for a Jacada Interaction (to extend functionality), in my case to parse and assign the numerical part of serialNumber (a letter, followed by digits) to a numeric global ("system") variable, say serialNumeric. What I am lacking is the structure and syntax to make this work, including the way to reference interaction variables from within the extension.
Here is my failed attempt, with lines commented out to make it innocuous after failing; I think I removed "return page;" after crashing, whereupon it still crashed:
initExtensions("serialNumeric", function(app){
app.registerExtension("loaded", function(ctx, page) {
// Place your extension code here
//$('[data-refname="snum"]').val('serialNumber');
// snum = Number(substring(serialNumber,1))
});
});
Here is an example of one that works:
/**
* Description: Add swiping gestures to navigate the next/previous pages
*/
initExtensions("swipe", function(app) {
// Swipe gestures (mobile only)
app.registerExtension('pageRenderer', function(ctx, page) {
page.swipe(function(evt) {
(evt.swipestart.coords[0] - evt.swipestop.coords[0] > 0)
? app.nextButton.trigger('click')
: app.backButton.trigger('click')
});
return page;
});
});
After reading the comment below, I tried the following, unsuccessfully (the modified question variable is not written back to that variable). It rendered poorly in the comment section, so I am putting it here:
initExtensions("serialNumeric", function(app){
app.registerExtension("loaded", function(ctx, page) {
var sernum = new String($('[data-refname="enter"] input'));
var snumeric = new String(sernum.substr(1));
$('[data-refname="enter"] input').val(snumeric);
});
});
I would like to understand when this code will run: it seems logical that it would run when the variable is assigned. Thanks for any insight ~
In your case, you extend loaded event. You don't have to return the page from the extension like in your working example below.
The page argument contains the DOM of the page you have just loaded, the ctx argument contains the data of the page in JSON form. You can inspect the content of both arguments in the browser's inspection tools. I like Chrome. Press F12 on Windows or Shift+Ctrl+I on Mac.
The selector $('[data-refname="snum"] input') will get you the input field from the question with the name snum that you defined in the designer. You can then place the value in the input field with the value from the serialNumber variable.
$('[data-refname="snum"] input').val(serialNumber);
You can also read values in the same way.
You can't (at this point) access interaction variables in the extension, unless you place theses variables inside question fields.
Here is a simple example how to put your own value programmatically into a input field and cause it to read it into the model, so upon next it will be sent to the server. You are welcome to try more sophisticated selectors to accommodate for your own form.
initExtensions("sample", function(app){
app.registerExtension("loaded", function(ctx, page) {
// simple selector
var i = $('input');
// set new value
i.val('some new value');
// cause trigger so we can read into our model
i.trigger('change');
});
});

How to overwrite form method on form created by code?

On a form created in AOT you can rewrite methods by right click and overwrite. How can you do the same on the form which are created by X++ code?
For example. How to change close method so it will call info("close"); before closing on this:
form = new Form();
formBuildDataSource = form.addDataSource("Table");
formBuildDesign = form.addDesign("Design");
form.design().caption("Caption");
…
args = new Args();
formRun = classfactory.formRunClass(args);
formRun.run();
formRun.detach();
I am using AX2012
Typically you will want to execute a predefined method. You can then use the registerOverrideMethod method of form controls. This is explained here.
In the call to registerOverrideMethod always provide the third argument, being the object holding the method.
formButtonControl.registerOverrideMethod(
methodStr(FormButtonControl,clicked), //method to override
methodStr(testClass,testMethod), //method to invoke
new testClass()); //object of class containing method
It is of cause also possible to save source to the AOT using class TreeNode method AOTSetSource.
An example here.
You will need to save the form to AOT and compile before executing with FormRun.

Locating text within a div's ul/li

using .NET MVC/Razor, I am working on setting the validation summary manually client side using the following method for a few js client side operations which will not be handled in data annotations:
function RenderError(message) {
var myDiv = $('[data-valmsg-summary="true"]');
myDiv.removeClass("validation-summary-valid");
myDiv.addClass("validation-summary-errors");
var list = myDiv.find('ul');
$("<li />").html(message).appendTo(list);
}
This works fine, but obviously repeats the errors. What is the simplest way to check and see if the message has already been entered in a list item? Keeping in mind that I already have a handle to the div itself?
Thanks in advance
You could check in a if statement if the data-valmsg-summary field is true and skip it accordingly, does it make sense?