ERPnext: How to use custom script in web form - erpnext

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!

Related

Remove submitted state in submission handler

I am trying to reset a form so that it appears to Drupal 8 that it hasn't been submitted. So far I have been unable to do this, as I cannot find any available methods (setSubmitted() hardcodes it to TRUE without a FALSE option). The reason is this isn't a full submit, but a submit of one field after which I would like the user to be redirected to another page that has another form, and I would like this secondary form to use the value obtained in the first step.
In the submit handler for the first part I use this to redirect:
$form_state->setRedirect('my.route', [], []);
And this works, but when the form reaches the second form (it seems) that the second form thinks it is a submission. As a result any submit buttons I add to the second form seem to make it auto-submit, and this breaks my user journey.
In the submit for the first part I have tried:
$form_state->setRebuild(TRUE);
$form_state = new FormState();
unset($form_state);
Tried the above in various configurations to no avail. They all prevent/ignore the setRedirect call that I make afterwards. The reason I want/need to do it this way is I want to preserve the POST method used.
Do you want to obtain something similar to what core search module does? It has simple SearchBlockForm that sends data to more complex SearchPageForm.
SearchBlockForm uses GET method (though you may use POST):
$form['#method'] = 'get';
and has no id and token fields:
function search_form_search_block_form_alter(&$form, FormStateInterface $form_state) {
$form['form_build_id']['#access'] = FALSE;
$form['form_token']['#access'] = FALSE;
$form['form_id']['#access'] = FALSE;
}
BTW, the last change allows you to avoid running submit callbacks.
Hope this helps.

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');
});
});

Protractor + ionicPopup

Has anyone succeeded in using Protractor to detect an ionicPopup alert?
I've tried all the workarounds suggested here but no luck.
I need Protractor to detect the alert and check the text in the alert.
Here's the class I wrote to test that the popup exists and to ensure the text is correct in the header and body:
var TestUtilities = function(){
this.popup = element(by.css('.popup-container.popup-showing.active'));
//Tests to see if $ionicPopup.alert exists
this.popupShouldExist = function() {
expect(this.popup.isDisplayed()).toBeTruthy();
};
//Tests to see if $ionicPopup.alert contains the text provided in the argument exists in the header
this.popupContainsHeaderText = function (text) {
this.popupShouldExist();
expect(this.popup.element(by.css('.popup-head')).getText()).toMatch(text);
};
//Tests to see if $ionicPopup.alert contains the text provided in the argument exists in the body
this.popupContainsText = function (text) {
this.popupShouldExist();
expect(this.popup.element(by.css('.popup-body')).getText()).toMatch(text);
};
};
module.exports=TestUtilities;
Also check out this site for more on testing Ionic in protractor it talks about how to check to see if the popup exists: http://gonehybrid.com/how-to-write-automated-tests-for-your-ionic-app-part-3/
I've tested Ionic popups successfully by setting the popup variable as follows:
var popup = element(by.css('.popup-container.popup-showing.active'));
And in the test:
expect(popup.isDisplayed()).toBeTruthy();
Ionic Popups are just made of DOM elements, so you should be able to use normal locators to find/test them. Because they're not made of alerts, the workarounds in the issue you linked to are probably not useful.
I got it - I saw a lot of issues out there trying to do it in very complex ways, but in the end I tried this and it turns out to be this simple.
Inspect your element and find its ng-repeat value, then
var button = element(by.repeater('button in buttons')).getText()
You also need to have the browser sit out somehow for a couple seconds so it doesn't resolve to the tests while the ionic popup isn't actually there.
For that, browser.sleep(3000);
That's it! However, getting the other button in there is proving to be a little problem. var button = element(by.repeater('button in buttons')).get(0) or .get(1) return undefined is not a function.
Please accept the answer if you like it! If I figure out how to get the other button, I'll post it here.

jquery validate method not found error on mvc4

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.

Atk4 Step by Step form doesn't load Facebook Like Buttons

I have a array with list of sites, I'm coding a step by step form using http://codepad.agiletoolkit.org/newsletter example.
In the second step I put Like Buttons using the following code:
$attr = array (
'data-send' => FALSE,
'data-layout' => 'button_count',
'data-width' => 100,
'data-show-faces' => FALSE
);
foreach($this->sites as $k => $site) {
$div = $form->add('View_HtmlElement')->setElement('div')->set(NULL);
$attr['data-href'] = $site;
$div->addClass('fb-like');
$div->setAttr($attr);
}
This works good when I access directly, but when I try to access via next button, the Like Buttons doesn't load.
Any solution for this?
The reason why the facebook and some other buttons may not work with AJAX pages is because facebook scripts generally process your HTML only during initial load of the page. When the form in your example goes to next step, it uses AJAX to load additional form. As a result you will need to either manually trigger facebook's scripts to re-walk your page or perform redirects instead of reload. You would need to change:
$this->js()->atk4_load($this->api->getDestinationURL('./step2'))
->execute();
to
$this->js()->univ()->location($this->api->getDestinationURL('./step2'))
->execute();
You may also find this article useful: http://agiletoolkit.org/blog/adding-twitter-button-to-ajax-page/