Context
Our web application has a feature for example "Create Employee". It shows three pages (1 of n) to allow user to enter relevant information on each page. On page 3, Save button allow user to save the employee. If user enter a incorrect value in a field on page 1 (something server can only verify) and server reports an error, the default behavior is to display page 1 with error message on top and the relevant field is mark as red.
Problem Statement
Above was all working until recent few build shows a breaking behavior. In above mentioned scenario, on error, the page 2 is displayed instead of page 1. Everything else is working fine like error message is correct, field on page 1 is marked red.
Analysis
I tried looking into pagination logic in java script, reverted back to version changes which was working. I also tried solution proposed here, here. I also cleared browser cache and reopen it.
Nothing worked.
Then I discovered major changes in UI code base was introduction of AntiForgeryToken(). I removed it from page and controller and everything worked again. I checked AntiForgeryToken() is not throwing exception.
Question
I am not sure how AntiForgeryToken() is affecting pagination code in java script?
What can I try to know more about the root cause?
Any proposed solution, remember, can not live without AntiForgeryToken()?
Thanks in advance.
Just in case it helps someone else who is novice like me in Java Script/JQuery.
The pagination logic in Java Script selects a page to display based on an index calculated through Index() method of JQuery and it considers number of form elements.
Since AntiForgeryToken() adds a hidden form element the index was wrongly calculated to 1 instead of 0 (for page 1). That was the role AntiForgeryToken() was playing.
The solution is to pass pagination group identifier to Index() method so it does not consider any other element than which belongs to pagination only.
That was it.
Learning from this problem, always be more specific while finding HTML elements with JQuery or any other JS library. JQuery did provide the means but unfortunately since things was working previously the original author did not utilized the power of Index() method.
Related
I’m writing a WebExtension that identify fields using a given criterion in a web page.
The content script which is loaded with every page and iframe does its job well identifying and highlighting those fields.
Now I want to count the total number of said fields in a page as the user sees it, that is, including its iframes, and display this number over the browserAction icon (as adblock displays a count over its action icon).
My plan was to use setBadgeText in the action script to clear the current counter, then issue a tabs.sendMessage({req:"countFields"}), and then let every content script respond to that message by getting the current value of the badgeText and increase it with the number of fields it found on its part of the page.
Well, that does not work well. I’m getting erratic values when a page contains iFrames. I guess this is a synchronization problem, when content scripts from different parts of the page try to get the badge value and update it.
I’ve also tried navigating through window.frames from a top level content script ("all_frames":false), but that won’t work either, since cross script errors can prevent me from descending all iFrames (using the online version of tinyMce for example)
Well, at this point, I’m asking for help and advice on how to solve my problem.
Any clue or pointer would be very much welcome !
I found the answer to that problem !
Since I believe knowing where to find for answers to a specific kind of problems (here, WebExtension development) is part of the answer, I give the link to that answer on the right place instead of just repeating here what was given me there.
https://discourse.mozilla.org/t/collect-infos-on-all-iframes-of-current-page-solved/30453
I am using your Angular JS Input Dropdown control, and I've followed the code example you put on your demo page to implement the control on a page in my PHP Laravel based website. I have found a problem with the implementation, though, and I was unable to identify what triggered it or how to fix it, so I was hoping that one of you may be of some assistance.
The issue consists of the control not getting rendered into the page until I refresh the page, then it shows up and works perfectly fine, right until I leave the page and get back to it; forcing me to refresh the page every time I re-enter it to be able to use the control.
To elaborate further, the control does not get rendered, but the page acknowledges that there is supposed to be a control on the page, which is why it displays a white blank space at the position where the control is supposed to be. So, I am pretty sure that it's a rendering issue.
The website is using Voyager which has a navigation sidebar, and if the page is entered via the sidebar button, the issue occurs, while if it was entered directly through the url bar or refreshed, then it works fine.
Has this ever happened to anyone before, and if so, how should I go on about fixing it? If not, then what do you propose might be the issue?
Thanks for taking your time to read this issue, and have a wonderful day.
Link to Angular control repository: https://github.com/hannaholl/angular-input-dropdown
EDIT: This issue was self-fixed.
Solution: Manually bootstrap Angular JS.
This issue was self-fixed.
Solution: Manually bootstrap Angular JS.
A few months ago I used the excellent advice over here to create a survey in Qualtrics with some javascript code that saved people's responses (given by moving a slider) as embedded data. It all hinges on being able to call some functions when the "Next" button is clicked, as is found under $('NextButton').onclick = function (event) in the above link.
I wanted to reuse that survey this weekend, and found that the data was no longer being saved. After fiddling around a bit, I realised that currently, any such function will now only be run the first time the "next" button is clicked, and not on any subsequent time. In other words, precisely the same javascript will either work or do nothing depending on whether it happens to be the first time the next button is clicked.
I mailed Qualtrics asking for advice, and their support person mailed back with the following:
The old application that ran our surveys would reload the page each time you went to a new page in the survey. The current application that runs our surveys is a one page app and going to the next page in a survey does not refresh that entire page, it just presents a different section.
I couldn't find anything on the Qualtrics website giving more information about the aforementioned update, or indicating whether there's a new CSS selector that could be used to select the currently-displayed "next" button, replacing $("NextButton"), and I have no idea how to reverse engineer a Qualtrics survey web page to work it out for myself.
Can anyone suggest how the code in the linked answer above might be altered to work on the updated Qualtrics platform? Or can anyone confirm whether their old code still works, in which case I'm mis-identifying what the problem is.
I have insufficient reputation to comment on the above-linked solution to point out this issue, but perhaps someone else could do so. I'll update this if I get any more information from Qualtrics support.
Qualtrics uses two survey engines: the older SE and the newer JFE. Qualtrics Support was referring to JFE. You can force Qualtrics to use SE by adding the parameter Q_JFE=0 to your survey link. That might be a quick fix.
That said, adding an event listener to the NextButton has never worked reliably with either SE or JFE. Qualtrics has its own event listeners on the Next Button that interfere. The most reliable method is to use JavaScript to hide the NextButton, then add your own button that performs any process you need, then at the end clicks NextButton. See example here.
I haven't tried T. Gibbon's Q_JFE=0 suggestion above, and the suggestion to hide the Next button didn't work for me (though it's possible this was just because I did it wrong - perhaps someone could comment if it worked for them).
When I mailed Qualtrics, their suggestion was to add an event listener as follows, and then remove it before applying another.
document.getElementById('NextButton').addEventListener(function (event) {
doStuff();
});
However, since I'm just a psychologist who wants to get data quickly rather than a javascript programmer, I wasn't sure just how to go about 'removing an event listener', and decided to try what I thought was a simpler solution, in that it doesn't rely on having some functions run when the 'next' button is clicked.
For each question that contains a slider whose data I want to save (I had just one such question per page), I included the following, to save the ID for that particular question as embedded data. Each question's ID is saved with a unique tag ('q1ID' in the following). I had one such question per page.
Qualtrics.SurveyEngine.setEmbeddedData('q1ID', this.getQuestionInfo().QuestionID);
Then once all the slider-type questions had been presented, on the following page I included this code:
Qualtrics.SurveyEngine.addOnload(function()
{
var tags = ['q1','q2', 'q3'];
var pipedStrings = {'QID356':'${q://QID356/TotalSum}',
'QID357':'${q://QID357/TotalSum}',
'QID358':'${q://QID358/TotalSum}'};
tags.forEach(function(tag) {
var qID = Qualtrics.SurveyEngine.getEmbeddedData(tag + 'ID');
var response = pipedStrings[qID];
Qualtrics.SurveyEngine.setEmbeddedData(tag, response);
});
});
Initially, I'd tried what I thought was more sensible:
tags.forEach(function(tag) {
var qID = Qualtrics.SurveyEngine.getEmbeddedData(tag + 'ID');
var response = '${q://' + qID + '/TotalSum}';
Qualtrics.SurveyEngine.setEmbeddedData(tag, response);
});
But as pointed out here, Qualtrics won't allow you to fetch data by concatenating a variable into a string like this. Consequently, even though it seems a ridiculously roundabout what to do it, I created the pipedStrings object that has a list of all the question IDs I needed (which I found by exporting the survey to a text file and searching for my question tags).
This allowed me to save the responses to slider questions as embedded data, with the keys listed in tags. If anyone has a simpler approach, avoiding have to create the dictionary of pre-formatted strings, please do comment.
Have been working on a smaller project with php here and got lost. I'll explain in two parts.
Part 1: I have index.php and a getitem.php. Index contains a form with multiple select objects with no options (at start) with the exception of one. After selecting an item from the one with options available I make a query via getitem.php&[parameters_here]. The php then echoes options with values and texts.
This form then guides you to fill every field this way. These options are added on the go with object.innerhtml. Everything fine.
The problem kicks in when you hit the refresh button. Select items lose their options (with the exception of the one). How to keep these settings on refresh? Keeping them in a _SESSION? Checking the session for every single select item seems too brute force.
Part 2: Would fixing this help me out with a library like this; to see the dynamic options with images? I believe these two parts are connected.
Thanks.
About Part 1:
The key point is refreshing the page. First let us consider the case what is happening now - you are probably keeping the options selected using $_POST. After the selection and reloading is done it shows the response of POST action [as your data is being posted into the same page - guessing from your scenario]. Now when somebody reloads the browser the POST request becomes empty. So all the selections are lost.
There can be lots of ways/tricks for this.
$_SESSION can be one of them / $_COOKIE can be one of them / through some JS you can use browser local storage, etc.
The main concept will be the fact to keep the values somewhere where a browser refresh doesn't effect. So though $_SESSION seems brut force to you -- it is a logical option.
About Part 2:
I think these two parts are not connected. As long as you are using regular select options for showing your options - they are not connected -- as your part two deals with styling your option values not how the work.
I have a little web app (which only has 1 page) that allows user to input and select some options. The input texts and selections will be displayed in another div in the form of table. You may want to refer to the example here: http://jsfiddle.net/xaKXM/5/
In this fiddle, you can type anything and after you clicked submit it will get the text input and append them to another table #configtableTable
$('#labels #labelTable tr:last').after(addmore);
$('#configtable #configtableTable tr:last').after(displaymore);
I'm using cherrypy as a mini web server (and thus major codes are written in python) and i know that it has session here but i have no idea how to use it at all as the example given is not really what i want to see.
FYI, i'm not using PHP at all and everything is in a single page. i simply show and hide them. But I want the page to remain as showing #configtableTable and hiding #labelTable even after refresh. Note that the fiddle is just part of the web app which will only show all these after getting a reply from another device.
Not sure about cookie because all the links i've found seem broken. How about jQuery session? Is it applicable in my case? I need some examples of application though :(
okay, to conclude my questions:
1. can i save the page state after refresh? and how? which of the methods mention above is worth trying? is there any examples for me to refer? or any other suggestions?
2. can i simply DISABLE refresh or back after reaching a page?
Thanks everyone in advance :)
Don't disable Refresh and / or back navigation. It's a terrible idea - user's have a certain expectation of what actions those buttons will perform and modifying that leads to a bad user experience.
As for saving state, while you could use session or cookies, if you don't need that data server side, you can save the state on client side as well.
For example, you could use localStorage
Alternatively, you could create an object out of the data in the table, JSON.stringify() it and append it to the url like this: example.com#stateData.
In case of either option, at page load, you'd have to check if there is state data. if you find there is, then use it to recreate the table, instead of displaying the form.
The disadvantage of the first, is that not all browsers support localStorage.
The disadvantage of the second is that URLs have a length limit and so this solution won't necessarily work for you if you're expecting large amounts of data.
EDIT
It appears that Midori does support most HTML5 features including localStorage however, it's turned off by default.. (I'm trying to find a better reference). If you can, just point Midori to html5test to see what HTML5 features it supports.